Deep sleep and GPIO interrupts execution order

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
sigi_2251526
Level 2
Level 2

Hi,

   

I've got a question about deep sleep and GPIO interrupts waking up a CY8C4247FNI-BL483. If a GPIO interrupt wakes up the device the execution of the program is resumed from the main program (early after CySysPmDeepSleep() ) or from the GPIO ISR? If I need to use a peripheral in the ISR I have to wake it up in the service? If I do so, after the ISR execution, recalling the peripheral_Wakeup() function in the main loop would cause any problem? What is the correct routine for this occurrence?

   

Thank you,

   

Simone.

0 Likes
1 Solution
Anonymous
Not applicable

That is correct. I believe the critical section disables interrupts for handling, but still leaves the interrupts active for waking up the chip from low power modes. 

   

Then, once you exit the critical section, it will re-enable the interrupt handling, and allow the ISR to run/occur.

   

I'm not 100% certain this will work as I'm explaining it, but either way it is worth a test to see if it behaves as desired.

   

Another option, if the critical section addition does not work as desired and doesn't wakeup the unit from low power modes would be to check on calling the peripheral_Wakeup() if the peripheral is already awake, and skip the wakeup if it is (using a ram flag or the cypress api to check it's state). That way, you can call it multiple times with only the first call activating the peripheral, and the rest will merely return without doing anything. Here's an example:

   

void peripheralWakeup() {

   

     static bool Awake = false;//Or true if the peripheral is on by default

   

     if(Awake) {

   

          return;

   

     } else {

   

          peripheralEnable();//enable peripheral wakeup calls/functions here

   

     }

   

}

View solution in original post

0 Likes
3 Replies
Anonymous
Not applicable

For the CySyspmSleep() and CySyspmDeepSleep() power modes, the unit will resume execution at the line following the power mode call. If interrupts are enabled/active when it resumes the execution, then it will jump to the ISR callback, which means that whatever hardware you are using in the ISR needs to be set inside the ISR, or put in the code right after the power mode call with both the power mode call and the wakeup code enclosed by CyEnterCriticalSection() and CyExitCriticalSection() to prevent the interrupt from occurring until you have woken up the hardware.

   

Some of the peripherals keep track of the previous state, and if you call the wakeup function multiple times, then it will save the "previous" state as being awake instead of sleep. This may cause side effects depending on the peripheral, and should be avoided if possible. (The peripheral wakeup() and sleep() functions should have comments on whether or not you can call them multiple times in a row)

   

I would suggest using the CyEnterCriticalSection() and CyExitCriticalSection around the power mode sleep/deep sleep call and peripheral wakeup function. This would ensure that you are not handling the wakeup() function multiple times, in the ISR, or hardware error due to using the peripheral when it isn't awake yet.

0 Likes
sigi_2251526
Level 2
Level 2

If I understand you propose to do the following operations:

   

interruptStatus = CyEnterCriticalSection();

   

peripheral_Sleep();

   

CySysPmDeepSleep();

   

peripheral_Wakeup();

   

CyExitCriticalSection(interruptStatus);

   

am I right?

   

But if I enter on the critical section my device will not be "deaf" to interrupt events? It is supposed to wake up?
And if it wakes up the interrupt event will be served?

   

Thank you for the answer,
Simone

   

0 Likes
Anonymous
Not applicable

That is correct. I believe the critical section disables interrupts for handling, but still leaves the interrupts active for waking up the chip from low power modes. 

   

Then, once you exit the critical section, it will re-enable the interrupt handling, and allow the ISR to run/occur.

   

I'm not 100% certain this will work as I'm explaining it, but either way it is worth a test to see if it behaves as desired.

   

Another option, if the critical section addition does not work as desired and doesn't wakeup the unit from low power modes would be to check on calling the peripheral_Wakeup() if the peripheral is already awake, and skip the wakeup if it is (using a ram flag or the cypress api to check it's state). That way, you can call it multiple times with only the first call activating the peripheral, and the rest will merely return without doing anything. Here's an example:

   

void peripheralWakeup() {

   

     static bool Awake = false;//Or true if the peripheral is on by default

   

     if(Awake) {

   

          return;

   

     } else {

   

          peripheralEnable();//enable peripheral wakeup calls/functions here

   

     }

   

}

0 Likes