3 Replies Latest reply on Apr 6, 2017 10:07 AM by e.pratt_1639216

    Deep sleep and GPIO interrupts execution order

    simone.giacomucci_2251526

      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.

        • 1. Re: Deep sleep and GPIO interrupts execution order
          e.pratt_1639216

          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.

          • 2. Re: Deep sleep and GPIO interrupts execution order
            simone.giacomucci_2251526

            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

               

            • 3. Re: Deep sleep and GPIO interrupts execution order
              e.pratt_1639216

              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

                 

                   }

                 

              }