GPIO Interrupt won't wake from DeepSleep

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

cross mob
Anonymous
Not applicable

I'm working with a CYBLE-022001-00 PROC module and have been struggling trying to solve a problem where I can't get the CPU to wake from deep sleep with a GPIO interrupt.

   

With the following code, I have an input configured to interrupt on falling edge, and have the pin configured with a pullup.  There's also a pin configured as an output and I toggle its state in the ISR...watching it on a scope.

   

With the following code, the output toggles each time I ground the input which shows me the ISR is working as expected.

   

However, if I change the CySysPmSleep() to CySysPmDeepSleep(), it stops working.  It's not waking from deep sleep.  Can anyone confirm that this can be done on this module?

   

 

   

CY_ISR(wakeup_isr)
{
    if(out_on == 0)
    {
        OutPin_Write(1);
        out_on = 1;
    }
    else
    {
        OutPin_Write(0);
        out_on = 0;
    }
    isr_1_ClearPending();
}

   

int main()
{
    OutPin_Write(0);
    isr_1_StartEx(&wakeup_isr);
 
    CyGlobalIntEnable;

   

    for(;;)
    {
        CySysPmSleep();
    }
}

0 Likes
1 Solution
Anonymous
Not applicable

Hi there!

   

I had the same problem and Cypress support helped me to find a solution. You need to place a Global Signal Reference block and configure it to generate a Combined port interrupt (as Bob said).

   

   

You then need to determine which GPIO triggered the interrupt (if you have more than one source). Here is a code example that may help. In this example, one source is on P3.4 and the other is on P3.7:

   


CY_ISR(port_wide_interrupt)

   

{

   

    // Accelerometer INT 1 rising edge interrupt?

   

    if((* (reg32 *) CYREG_GPIO_PRT3_INTR)& (1<<4))

   

    {

   

       
        ACC_INT1_ClearInterrupt();

   

        acc_int_handler();

   

    }

   

    // User button rising or falling edge interrupt?

   

    if((* (reg32 *) CYREG_GPIO_PRT3_INTR)& (1<<7))

   

    {
        USR_BUTTON_ClearInterrupt();

   

        usr_button_int_handler();

   

    }

   

}
 

   


/*

   

   Start port wide interrupt to wake up CPU from Deep Sleep when a GPIO interrupt occurs.

   

    Port wide interrupt handler will determine which interrupt handler must be called.

   

*/

   

    PORT_WIDE_IRQ_StartEx(&port_wide_interrupt);

   

 

   

Good luck!

   

Pieter

   

https://piconomix.com
 

   

 

   

View solution in original post

0 Likes
5 Replies
lock attach
Attachments are accessible only for community members.
rola_264706
Level 8
Level 8
50 likes received 25 likes received 10 likes received

Here is a chart on Sleep and what is working when you are in various sleep types. Also some information on interrupts .

   

0 Likes
Anonymous
Not applicable

Thanks.  I think I understand what works in various modes, and how to setup the interrupt.  Changing from sleep to deep sleep with a working interrupt configuration causes my test to stop working.  This leads me to believe there's something I'm missing about going into deepsleep, or the module I'm designing around doesn't behave the way it should.  I was asking if anyone has this working.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Because there is no high-speed clock available in deep sleep the interrupt controller does not work. Instead the "Global Signal Reference" component can be used to generate an interrupt on (any) port interrupt in deep sleep mode.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi there!

   

I had the same problem and Cypress support helped me to find a solution. You need to place a Global Signal Reference block and configure it to generate a Combined port interrupt (as Bob said).

   

   

You then need to determine which GPIO triggered the interrupt (if you have more than one source). Here is a code example that may help. In this example, one source is on P3.4 and the other is on P3.7:

   


CY_ISR(port_wide_interrupt)

   

{

   

    // Accelerometer INT 1 rising edge interrupt?

   

    if((* (reg32 *) CYREG_GPIO_PRT3_INTR)& (1<<4))

   

    {

   

       
        ACC_INT1_ClearInterrupt();

   

        acc_int_handler();

   

    }

   

    // User button rising or falling edge interrupt?

   

    if((* (reg32 *) CYREG_GPIO_PRT3_INTR)& (1<<7))

   

    {
        USR_BUTTON_ClearInterrupt();

   

        usr_button_int_handler();

   

    }

   

}
 

   


/*

   

   Start port wide interrupt to wake up CPU from Deep Sleep when a GPIO interrupt occurs.

   

    Port wide interrupt handler will determine which interrupt handler must be called.

   

*/

   

    PORT_WIDE_IRQ_StartEx(&port_wide_interrupt);

   

 

   

Good luck!

   

Pieter

   

https://piconomix.com
 

   

 

   

0 Likes
Anonymous
Not applicable

That did it...thanks so much.  Would have never realized that without your help.

   

It's funny, I'm working on an accelerometer application too.  I noticed that in your code.  NXP by any chance?

0 Likes