2020-04-20 03:44 PM
Suppose that my system consists of 3 modules
2020-04-20 03:49 PM
On more thing... I use the LTDC and don't understand all the BSP code. There may be SysTick handlers or other interrupts. I don't want them to interfere with sleeping/waking.
2020-04-20 04:16 PM
Use a global variable to indicate if the function should go to sleep at the end before returning. Note that you can't go to sleep between when a function ends and execution returns to where the function was called. Either go to sleep at the end of the function, or after it's returned.
Edit: Manual says entry to sleep is "WFI or Return from ISR" so possible the above is incorrect in that regard.
2020-04-20 05:52 PM
I had thought of a global variable, but then I need an "if" statement, so the SCB instruction is not last statement in ISR... the if is still being processed.That is
if (endmain == true)
{ // don't go to sleep if main loop has not ended
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; // Enable sleep on exit from ISR
}
__DSB(); // Ensure that waking up starts immediately upon exiting
Is it OK to have this structure? What works?
2020-04-20 06:34 PM
I have decided what to do.
Default setup onCPU is for ISRs to be awake on exit (due to SLEEPONEXIT bit in SCB=0. SCB is a system register.).... no other global variable is needed.
At end of main program, put
__wfi():
This sets the SLEEPONEXIT bit in SCB telling ISRs to continue in sleep upon exit, no other global is needed.
__wfi(); is equivalent to SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
In the EXTI program, put the following at the end
SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;
__DSB();
This clears the SLEEPONEXIT bit in the SCB. All of the other ISRs need no code to decide whether to sleep or be awake on exit for the scenario that I described in my initial question.
2020-04-24 06:31 PM
I noticed that TDK's post can avoid SLEEPONEXIT altogether, and this is what I implemented, but haven't verified that it works yet. The idea is to let interrupts return to execution in the main program before or after sleep was initiated. If they return to main before sleep was initiated, the program continues executing normally. If they return to main after sleep was initiated, the main program puts the system to sleep again.
Program structure of main
int main(void)
{
initialize
while (1)
{
if (runloop == true)
{
most of code in main
runloop = false;
} // END of if(runloop== true)
__wfi();
} // END of main
no interrupt routines contain code relating to sleep
one interrupt routine, an EXTI which wakes up the system, contains the following
runloop = true
Note that if, in addition to wfi, it is desired to alter power regulator settings, that can be coded along with __wfi();