Because of this design, the ARM-based MCUs allow transitioning to a low-power mode with interrupts disabled at the ARM-core level. Upon such a transition, the power-management controller stops the CPU clock for the ARM core, but any interrupt enabled at the interrupt controller level can start the CPU clock. As soon as the core starts running again, it can enable interrupts to achieve low interrupt latency.
Listing 6 shows the general strategy of transitioning to a low-power mode for ARM-based MCUs (IAR ARM compiler, AT91SAM MCU).4 The power-management controller stops the CPU clock (AT91C_BASE_PMC->PMC_SCDR = 1) while the interrupts are disabled at the core. The interrupts are enabled only after the CPU wakes up again and executes the __enable_interrupt() intrinsic function. You can see this behavior if you try to break into a running application with a JTAG-based debugger. Usually, the code will stop at the __enable_interrupt() line.
View the full-size image
Speaking of debugging, the sleep mode can interfere with many on-chip debuggers because it stops the CPU clock. Therefore, you must use conditional compilation to include the low-power transition only in the nondebug (production) version of the code.