andre andre - 1 month ago 16
C Question

How to disable/enable interrupts on a stm32f107 chip?

I have an ARM stm32f107 chip. I'm porting a project from IAR to GCC

IAR provides the following functions to enable and disable interrupts:

#define __disable_interrupt() ...
#define __enable_interrupt() ...


How do I enable / disable interrupt for my chip using GCC?

Answer

I can't answer for ARM but the same function in Coldfire boils down to setting/clearing the Interrupt Priority Level masking register in the CPU. Setting it to the highest number disables/ignores all but non-maskable, setting it to 0 enables all (YMMV).

Worth noting that it's handy to read-back the value when "disabling" and restore when "enabling" to ensure that stacked interrupts don't break each other:

ipl = DisableInts(); // Remember what the IPL was
<"Risky" code happens here>
EnableInts(ipl); // Restore value

This is useful when twiddling interrupt masks, which may cause spurious interrupts, or doing stuff that shouldn't be interrupted.

Functions come out as:

uint8 DisableInts(void)
{
    return(asm_set_ipl(7));
}

uint8 EnableInts(uint8 ipl)
{
    return(asm_set_ipl(ipl));
}

Both of which map to this asm:

asm_set_ipl:
_asm_set_ipl:
/* Modified for CW7.2! */
    link    A6,#-8
    movem.l D6-D7,(SP)

    move.l  D0,D6           /* save argument                 */

    move.w  SR,D7           /* current sr                    */

    move.l  D7,D0           /* prepare return value          */
    andi.l  #0x0700,D0      /* mask out IPL                  */
    lsr.l   #8,D0           /* IPL                           */

    andi.l  #0x07,D6        /* least significant three bits  */
    lsl.l   #8,D6           /* move over to make mask        */

    andi.l  #0x0000F8FF,D7  /* zero out current IPL          */
    or.l    D6,D7           /* place new IPL in sr           */
    move.w  D7,SR

    movem.l (SP),D6-D7
    //lea     8(SP),SP
    unlk    A6
    rts
Comments