Interrupts with BLE

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

cross mob
DaPi_1514011
Level 3
Level 3
First like received

Hi,

   

Most examples of getting deepsleep operating with BLE follow this pattern:

   

        CyBle_ProcessEvents();                      // service BLE stack events
        CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);      // put BLESS into lowest power mode
       
        intrStatus = CyEnterCriticalSection();      // disable interrupts
        blessState = CyBle_GetBleSsState();         // get current BLESS state
        if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP)
        {
            CySysPmDeepSleep();                     // 1.3uA current consumption
        }        
        else if (blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) // BLESS is active
        {
            CySysPmSleep();                         // ~1.6mA current consumption
        }
        CyExitCriticalSection(intrStatus);          // re-enable interrupts

   

The issue with this is that the critical section disables interrupts [CyEnterCriticalSection].  This means my ISRs don't fire.  If I bring the sleeps outside the critical section, BLESS get's stuck in an internal state loop calling sleep.

   

How can I go into deep sleep with BLESS running, but still service interrupts?

   

Thanks, Dave

0 Likes
1 Solution
Anonymous
Not applicable

It is important that the code to handle the low-power transitions is protected in a critical section and that interrupts are not allowed to change the thread of operation. In the code snippet, this critical section is bound by the CyEnterCriticalSection() function at the beginning and the CyExitCriticalSection() function at the end. If you do not put the code in this critical section, it may result in race conditions between the system and the BLESS in entering the BLESS low-power modes, causing the device to enter an unknown state from which it cannot recover.

   

So you need to put the low power codes in the critical section.

View solution in original post

0 Likes
2 Replies
Anonymous
Not applicable

It is important that the code to handle the low-power transitions is protected in a critical section and that interrupts are not allowed to change the thread of operation. In the code snippet, this critical section is bound by the CyEnterCriticalSection() function at the beginning and the CyExitCriticalSection() function at the end. If you do not put the code in this critical section, it may result in race conditions between the system and the BLESS in entering the BLESS low-power modes, causing the device to enter an unknown state from which it cannot recover.

   

So you need to put the low power codes in the critical section.

0 Likes

Hi

   

It does appear from experience that that is required as it breaks if I don't do that.

   

However we have a UART with ISR configured.  That does not fire when in deep sleep inside the critical section:

   

CY_ISR(RxWake)
{
   UART_IR_rx_wake_ClearInterrupt();
   SHOW_STATE_Write(1);
   wakeFromIR++;
}

   

 

   

setup...

   

 

   

    // when we receive data, generate an interrupt
    UART_IR_RX_WAKEUP_IRQ_StartEx(RxWake);

 

   

 

   

DeepSleep code:

   

 

   

    UART_IR_Sleep();
    CySysPmDeepSleep();
    UART_IR_Wakeup();

   

 

   

And the ISR fires all the time except when put into deepsleep inside the critical section.  Move it outside the critical section and it fires fine.

   

How do we go into deep sleep inside the critical section but still fire the UART ISR?

   

Thanks, Dave