This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How do I clear IRQ in the status register

Other Parts Discussed in Thread: HALCOGEN

Hi,

I am using the TMS570 Microcontroller Development Stick, with a TMS570LS20216 MCU (ASPGEQQ1).

I can not get the IRQ interrupts working in user mode.

If I manually reset the CPSR register I bit to "0" the interrupts work ok, but I can not do this for the real code.
I have experimented with trying the code snippet in the technical reference manual (section 24.7.1 example 2), but I get the errors "[E003] Unexpected trailing operands" and "[E004] Illegal operand".

Referring to section 24.7.1 example 2: I am not sure how to preserve register R1. It is unclear where I should put the "SWI" instruction. I guess this shoud be in the main program as "asm("swi");? But I am not sure then where the "software interrupt service routine" would be?

The asm file I am using is irq_fiq_en.asm as below.

Regards,
Dave

;-------------------------------------------------------------------------------
; irq_fiq.asm
;
;

    .text
    .arm


;    FIQENABLE .equ 0x40
;    IRQENABLE .equ 0x80

;-------------------------------------------------------------------------------
; FIQ Enable


    .global  _Enable_Fiq
    .asmfunc   

_Enable_Fiq
        MRS R1, CPSR
        BIC R1, R1, 0x40
        MSR CPSR_cf, R1
        MOV PC, LR

    .endasmfunc
   

;-------------------------------------------------------------------------------
; IRQ Disable
   
    .global  _Disable_Irq
    .asmfunc   

_Disable_Irq
        MRS R1, CPSR
        ORR R1, R1, 0x80
        MSR CPSR_cf, R1
        MOV PC, LR

    .endasmfunc



;-------------------------------------------------------------------------------
; IRQ Enable

    .global  _Enable_Irq
    .asmfunc


_Enable_Irq
        MRS R1, CPSR
        BIC R1, R1, 0x80
        MSR CPSR_cf, R1
        MOV PC, LR

    .endasmfunc

;-------------------------------------------------------------------------------

 

  • In an old post, I included an example. TMS570 Timer Interrupts

    In this example, I enabled the IRQ and FIQ throuogh swi. You can track down the 'Int_irq_enable;' in the main.c.

    By the way, once FIQ is enabled, You can NOT clear through software.

    Regards

    Haixiao

     

  • I could not easily get your code to work at that time, so I created code from HalCoGen.

    I had to put in _enable_IRQ(); to get the IRQ interrupts to work. But when I put the system into user mode using _coreSetUserModeSync_(); the IRQ interrupts stop working because the CPSR register "I" bit gets set to 1.

    The code works if I use the FIQ interrupts in user mode, so I guess the answer is to use only FIQ interrupts in user mode.

    Regards,
    Dave

  • Can you send me your project generated fromm HalCoGen?  I can look at that.

    Email: haixiao.weng@ti.com

    Regards,

    Haixiao

  • Hello Dave,

    the FIQ on the TMS570 behaves like an NMI, so it cannot be disabled. This is why it's working for you in the FIQ case.

    I'm not familiar with the _coreSetUserModeSync_() function, but it might be that the function is written in a way that it sets the 'I' flag in the CPSR to '1'. Normally the function should only manipulate bits 5:0 in the CPSR, but if it also writes bits 7:6, then that's where it goes wrong.

    If you like you can send the excerpt from the function and let us know what the state of the CPSR is before calling the function, and afterwards.

     

    Regards

    Frank

  • I read your code.

    1. As you already saw, Frank is right. this function write a 0xD0 to CPSR and disabled the IRQ. And since FIQ can not disabled by software once it is enabled, you can still use FIQ.

    2. CPSR bit [4:0] defines different modes, 0x10 is user mode. In this mode, many registers can not be written. After power up, the default mode is privilege mode. In this mode, you have 'do everything'. Once in user mode, you can not write to the CPSR directly to change the mode. Then if you want to write to CPSR, you need to force a interrupt, (for example, a SWI), now you enter FIQ or IRQ mode in the interrupt routine. Here, you can written to SPSR (mirror of CPSR). After that, when you quit the interrupt service routine, the value in SPSR will be copied to CPSR. By doing this, you can modify the CPSR in user mode. In the example I provided earlier, I used this method to write to cpsr to enable the interrupt.

    Regards,

    Haixiao