Deep Sleep Mode While Connected to Bluetooth

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

cross mob
Anonymous
Not applicable

Hi there,

We were wondering if a peer device is connected to a peripheral via BLE and no BLE events are requested over some time, should the cpu go into deep sleep mode? Currently, it seems that the cpu remains awake since it is continuously observing for possible pending BLE events.

If this is not possible, what is the recommended way to conserve power when BLE is connected but no BLE events are requested for some time?

Edit: After a bit more research, it seems that what we were looking for was to put the BLE sub-system to low power mode. If not, please let us know otherwise. However, we could not find an example project that demonstrates this process.

power-mode-combinations.png

Also, from the documentation it appears that the BLESS-MCU power mode combination Sleep-(Active/Sleep) is possible but the function call Cy_BLE_StackEnterLPM() appears to only allow putting the BLESS into active or deep sleep mode.

0 Likes
1 Solution
NidhinM_71
Employee
Employee
25 solutions authored 10 solutions authored Welcome!

Hello,

You can safely put the device to Sleep or Deep Sleep even when the BLE is connected, without calling any BLE specific low power APIs. Make sure that low power mode is enabled in the BLE component and watch crystal oscillator is enabled and properly configured:

pastedImage_0.png

The only BLE condition you need to check before entering Deep Sleep is:

/* Don't enter low power mode if the stack is not on */

    if(Cy_BLE_GetState() == CY_BLE_STATE_ON)

    {

        /* Enter Deep-sleep mode */

        Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);

     }

Note that if you have other peripherals such as TCPWMs, CapSense, SCBs in your project, you have to make sure that they're also ok to enter Deep Sleep mode.

BLE will automatically wake up the system if an event occurs. In the dual core mode, CM0+ (BLE controller) generates an interrupt to wake up the CM4 if further processing is required. You can register the interrupt handler in CM4 code as:

/* Register the BLE controller (Cortex-M0+) interrupt event handler  */

Cy_BLE_RegisterAppHostCallback(BleControllerInterruptEventHandler);

Please let me know if you have any additional questions.

-Nidhin

View solution in original post

11 Replies
NidhinM_71
Employee
Employee
25 solutions authored 10 solutions authored Welcome!

Hello,

You can safely put the device to Sleep or Deep Sleep even when the BLE is connected, without calling any BLE specific low power APIs. Make sure that low power mode is enabled in the BLE component and watch crystal oscillator is enabled and properly configured:

pastedImage_0.png

The only BLE condition you need to check before entering Deep Sleep is:

/* Don't enter low power mode if the stack is not on */

    if(Cy_BLE_GetState() == CY_BLE_STATE_ON)

    {

        /* Enter Deep-sleep mode */

        Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);

     }

Note that if you have other peripherals such as TCPWMs, CapSense, SCBs in your project, you have to make sure that they're also ok to enter Deep Sleep mode.

BLE will automatically wake up the system if an event occurs. In the dual core mode, CM0+ (BLE controller) generates an interrupt to wake up the CM4 if further processing is required. You can register the interrupt handler in CM4 code as:

/* Register the BLE controller (Cortex-M0+) interrupt event handler  */

Cy_BLE_RegisterAppHostCallback(BleControllerInterruptEventHandler);

Please let me know if you have any additional questions.

-Nidhin

Anonymous
Not applicable

Could you elaborate on the proper configuration for the watch crystal oscillator?

Also, if no BLE specific low power APIs are required, could you explain when a user would might want to call Cy_BLE_StackEnterLPM()?

0 Likes

Under the clocks tab in Design Wide Resources, enable WCO and set the the accuracy value. It's 20ppm if you're using CY8CKIT-062-BLE kit.

pastedImage_2.png

Cy_BLE_StackEnterLPM is a low-level API that is automatically called from Cy_BLE_SleepCallback API when the system enters low power modes. There's no need to use this API for most application firmware since BLE stack automatically takes care of its low power mode entry and exit.

-Nidhin

0 Likes
Anonymous
Not applicable

Thank you for the clarification, however we're still unable to get the device to go to deep sleep mode while ble is connected.

The difference from the example project is that we are currently only using the cm0p core.

In the example project, ble is configured to use dual cores, where the cm0p is the controller and the cm4 handles ble stack events. It seems the cm0p always remains awake (unless put into hibernation when no peer device connects) when ble is connected, and the cm4 only wakes up to handle ble events.

In our case, since we are only using one core, is it possible to have the single core go to sleep when ble is connected but no ble events occur after some time? If so, that is where we are struggling to implement at the moment.

If it helps, here is the current code that we are testing:

void EnterLowPowerMode(void)

{

    DEBUG_PRINTF("Entering deep sleep mode \r\n");    

    DEBUG_WAIT_UART_TX_COMPLETE();

   

    /* Don't enter low power mode if the stack is not on */

    if(Cy_BLE_GetState() == CY_BLE_STATE_ON)

    {

        DEBUG_PRINTF("CY_BLE_STATE_ON \r\n");

        /* Enter Deep-sleep mode */

        Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);

    }

   

    DEBUG_PRINTF("Exiting deep sleep mode \r\n");

    DEBUG_WAIT_UART_TX_COMPLETE();         

}

int main(void)

{

    UART_DEBUG_START();

    DEBUG_PRINTF("\r\n");

    DEBUG_PRINTF("UART works \r\n");

   

    Cy_BLE_Start(StackEventHandler);

   

    __enable_irq(); 

    for(;;)

    {

        EnterLowPowerMode();

        Cy_BLE_ProcessEvents();       

    }

}

Currently, the UART terminal continuously displays all three DEBUG_PRINTF() messages inside EnterLowPowerMode(), when we instead expect it to stop after displaying DEBUG_PRINTF("CY_BLE_STATE_ON \r\n") after some time.

0 Likes
Anonymous
Not applicable

We are speculating that the core is unable to go into deep sleep mode because the BLE stack is unable to go into deep sleep. Although Cy_SysPm_DeepSleep() internally calls Cy_BLE_StackEnterLPM(), we have tried to externally call Cy_BLE_StackEnterLPM(CY_BLE_BLESS_DEEPSLEEP) but it continually returns CY_BLE_BLESS_ACTIVE so the core is not ready to go into deep sleep mode.

Are we are missing some prerequisite to put the BLE stack into low power mode?

0 Likes

Can you please attach the project archive ?

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Of course. I've attached the archive to this comment.

0 Likes

Steve,

There should be no problem in your code, because calling Cy_SysPm_DeepSleep doesn't mean system certainly enter DeepSleep.

You can observe the process using the uart printing function.

In Cy_SysPm_DeepSleep, it will judge if it is proper for BLE stack to enter low-power mode. If the BLE state is still lying in initializing, it would be considered not proper. If the BLE state is in advertising, the system would fall into DeepSleep until the timeout event is triggered if still no device launch a connection.

Therefore, if you debug your code at the beginning of code's execution, the BLE stack is lying in initializing(before CY_BLE_EVT_STACK_ON being generated), it would  surely fail to enter low-power mode.

Please let me know if above helps.

0 Likes
Anonymous
Not applicable

Hi fwan,

Thank you for the response. We should've been more clear about what we're testing and having trouble getting to work. We understand that in the given code, the system will only attempt deep-sleep when the BLE stack is on (after initialization).

What we're having trouble getting to work is after a device has been connected, the system will not go into deep-sleep. With how the code is currently set up and continuously attempting to put the system into deep-sleep, we're expecting the the UART printing function to stop momentarily after a device has been connected and no BLE requests are pending. In the future, we plan to have a function that puts the system to deep-sleep when desired, as the current continuous calls to deep-sleep are for testing purposes.

Also, we observed that the system cannot go into deep-sleep when BLE is advertising. Did you get different results when running the code? Please let me know if the above makes sense and if you've gotten different results from ours.

0 Likes
lock attach
Attachments are accessible only for community members.

Hi Steve,

Yes, I did observe that the system cannot go into deep-sleep when BLE is advertising.

I did the test on CE212736_FindMe project, instead of the one you attached.

Please find the attached UART printing log, and note that there is a time gap between the event CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP(Advertisement started) and event CY_BLE_EVT_TIMEOUT (advertising timeout), which means a successful DeepSleep entering.

I will try testing the case after the device is connected, and get back the results.

0 Likes

Steve,

I did try on your code and found that the cm0+ cannot enter DeepSleep no matter it is advertising or connected. Also I modified your code to work on both cm0+ and cm4, reserving the original code as much as possible, the cm4 could enter DeepSleep normally. Guess there should be some BLE stuff intervened in the low-power mode entering for cm0+.

BTW, I did observe the system can go into deep-sleep when BLE is advertising when tested on CE212736. Sorry for the mistake made in last response.

0 Likes