When can single core Bluetooth go to deep sleep/sleep?

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

cross mob
Anonymous
Not applicable

Hi there,

We have Bluetooth configured to single core m0+ for both Bluetooth controller and host. We are wondering, in reference to the table below, what is considered active mode for BLESS (advertising, connected, transmission, etc.)? Specifically, can we put the core to deep sleep while bluetooth is advertising? Or is only sleep mode possible? We are using a logic analyzer to observe the successful/unsuccessful transitions of Cy_SysPm_DeepSleep() and Cy_SysPm_Sleep(). For Cy_SysPm_Sleep(), the waveforms show successful-successful-unsuccessful cycles while bluetooth is advertising, while Cy_SysPm_DeepSleep() shows cycles of one success followed by multiple unsuccesses.

As for when a bluetooth device is connected, we are wondering the same. If a device is connected but no data is being transmitted/received, could we put the BLESS to sleep mode? Or can the BLESS only be in active mode so long as a device is connected?

pastedImage_0.png

Best,

Steve

0 Likes
17 Replies
MeenakshiR_71
Employee
Employee
100 likes received 50 likes received 25 likes received

Steve,

The BLESS cannot enter low power mode while it is advertising (while the radio is active doing Tx), listening for connection requests (radio active doing Rx) and making connection pings (usual conn Tx/Rx every connection interval period).

Having said that, once you start the stack and advertisement starts, the stack automatically takes care of managing the radio's power modes. The Cy_BLE_Start API registers DeepSleep callbacks and those callbacks makes sure the system does not enter deep sleep while the radio is active (by returning CY_SYSPM_FAIL when calling Cy_SysPm_DeepSleep API). Note that while the device is not allowed to deep sleep during the period when radio is active, it is allowed to sleep. However, there are cases when the radio requires CPU as well (for some processing) - usually interrupts or Cy_BLE_ProcessEvents API.

Anyway, you do not have to worry about calling Cy_SysPm_DeepSleep, the API will automatically put the device to deep sleep when the radio is successfully put into low power mode.

Regards,

Meenakshi Sundaram R

Anonymous
Not applicable

Hi msur,

Thank you, that cleared up a lot of things.

We are curious if the radio gets put into low power mode internally? or do we have to put it into low power mode by calling Cy_SysPm_EnterLowPowerMode()?  We also notice that we are able to put the cpu into deep sleep when a device is connected. Is the radio inactive when data is not transferring but connected to the device?

0 Likes

Hello Steve,

You do not need to call any APIs explicitly for this. The call to Cy_SysPm_Sleep or DeepSleep will automatically check radio's power mode and put the device to sleep/deep sleep. The stack automatically puts the device to low power mode when not active

The Cy_SysPm_EnterLowPowerMode API activates low power modes for various blocks (Linear regulator, active references etc.). This enables further power savings but the cost of reduced performance. For instance, your BOD circuits will function for a voltage ramp rate of 10 mV/s compared to 100 mV/s in normal mode.

Hope this helps.

Regards,

Meenakshi Sundaram R

0 Likes
Anonymous
Not applicable

Msur,

Thank you for the clarification!

As a follow up, we notice that when a device is connected via Bluetooth the cpu fails and successfully enters deep sleep mode. We think it has to do with the current bless state as referenced in the image below. It seems that the state CY_BLE_BLESS_STATE_EVENT_CLOSE only allows deep sleep in some scenarios. Is there a way to check for certain for when the cpu can be put to deep sleep mode?

pastedImage_0.png

0 Likes

Hello Steve,

As of now, the CY_BLE_BLESS_STATE_EVENT_CLOSE state is the closest you can get to returning a successful DeepSleep callback. Since the "Cy_BLE_StackEnterLPM" API might take some time to put the stack to low power mode, you will need to allow the Cy_BLE_DeepSleepCallback to ensure the device enters deep sleep after a call to Cy_SysPm_DeepSleep. I would recommend you do use it that way rather than trying out other logic - as it can get complicated when you start using dual-core mode

Regards,

Meenakshi Sundaram R

0 Likes
Anonymous
Not applicable

Msur,

Thanks for the prompt reply, we really appreciate it! We should note that we are only using single core the for time being - would this still be achievable?

Best,

Steve

0 Likes

It is a yes and no Steve the chances are better with single core but still the controller and stack code does more operations than just a simple register write to put the BLESS to low power mode so you will have to abide by it.

What is the issue you are facing? Let me try to help in that regard

0 Likes
Anonymous
Not applicable

Well, we are looking to reduce the overall power consumption of our device. A large amount of the time, our device will be in bluetooth discoverable/advertising mode, so we thought we could put the device to deep sleep during advertising as before in psoc 4. Previously in psoc 4, at every advertising interval the device would wake by the bless interrupt to process any events and then go back to deep sleep, and wake at the next advertising interval. Is this still achievable with psoc 6?

Best,

Steve

0 Likes

Yes, that is perfectly possible and is implemented much better in PSoC 6. You can probably try and see the time for which the device is in deep sleep for the same BLE profile in both PSoC 6 and PSoC 4. The main difference from a user point is - in P4 you need to do the EnterLPM manually, whereas is P6 the stack automatically (rather in background) enters LPM when done doing advertising Rx/Tx.

0 Likes
Anonymous
Not applicable

Hi msur,

Is it normal behavior that Cy_SysPm_DeepSleep() always returns CY_SYSPM_FAIL while bluetooth is advertising? We are thinking that if the Bless is able to go to deep sleep, then during that time period the cpu should also be able to enter deep sleep.

Best,

Steve

0 Likes

It returns fail only when the radio is doing Tx/Rx (which is typically few 100s of us, depending on the Adv data). Are you seeing the API return fail all the time?

If yes, then can you check if WCO is enabled and is sourcing LFCLK? And check if you are not using Alt HF (BLE ECO) for FLL/PLL (which then clocks your HFCLKs).

Make sure you have enabled the below check box as well in the component -

pastedImage_0.png

Regards,

Meenakshi Sundaram R

0 Likes
Anonymous
Not applicable

Hi msur,

We have found the solution we were looking for! Before we were only checking Cy_BLE_StackGetBleSsState() while a bluetooth device was connected, but it turns out that the same logic also works while bluetooth is advertising. Thank you for your help!

Best,

Steve

0 Likes
Anonymous
Not applicable

Hi msur,

We've run into an unknown problem that was not accounted for before. We are experiencing different results with modifications to cy_ble_hal_int.c as suggested in this forum post Ble connection stops working after 'Max num. of ble connections' times​​. With the modification, when a bluetooth device connects then disconnects, advertising fails to restart after the first advertising timeout. But without any modifications to the file (regular project build), there are connection issues where the bluetooth device can only connect every other connection request (though advertising restarts fine). Below is our current low power code segment. We think it may be an issue when Cy_BLE_StackGetBleSsState() == CY_BLE_BLESS_STATE_EVENT_CLOSE and unsuccessfully enters deep sleep, because when we have the cpu enter regular sleep mode instead, the problem does not occur.

for(;;)

{

     if(!Cy_SysPm_Cm0IsLowPower())

    {

        Cy_SysPm_EnterLowPowerMode();

    }

   

    cy_en_ble_bless_state_t bleSsState = Cy_BLE_StackGetBleSsState();

   

    if(bleSsState == CY_BLE_BLESS_STATE_ACTIVE || bleSsState == CY_BLE_BLESS_STATE_ECO_STABLE)

    {

        cy_en_syspm_status_t apiResult = Cy_SysPm_Sleep(CY_SYSPM_WAIT_FOR_INTERRUPT);

        if(apiResult != CY_SYSPM_SUCCESS)

        {

            Cy_GPIO_Inv(DB_0_PORT,DB_0_NUM);    // Doesn't work

        }

        else

        {

            Cy_GPIO_Inv(DB_1_PORT,DB_1_NUM);    // Work

        }

    }

    else

    {

        cy_en_syspm_status_t apiResult = Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);

        if(apiResult != CY_SYSPM_SUCCESS)

        {

            Cy_GPIO_Inv(DB_2_PORT,DB_2_NUM);    // Doesn't work

        }

        else

        {

            Cy_GPIO_Inv(DB_3_PORT,DB_3_NUM);    // Work

        }

    }

}

0 Likes

Hello Steve,

Really sorry for a long delay - I had been away from my desk and bit busy for the past month. Are you still facing this issue or have you been able to resolve it?

I will take a look again, if it is not resolved yet. If resolved, do post your solution for others to look at

Regards,

Meenakshi Sundaram R

0 Likes
Anonymous
Not applicable

Hi msur,

No problem, we have been working on other tasks meanwhile.

And yes, we are still facing the issue with Bluetooth connectivity and would greatly appreciate your help

Best,

Steve

0 Likes

Steve,

I took a look at the project and added the modified for(;;) loop you provided. If you remember the example I provided earlier, you will need to call ProcessEvents till Advertisement starts. Basically the fix in the cy_ble_hal_int.c file is incomplete without another fix in the stack library - we are using only one half of the fix. The complete fix will be soon out as part of PDL 3.0.4 (in a week or two).

This is how my for(;;) loop looks like (I believe the flag names are self explanatory ) and my advertisement starts fine after every timeout.

for(;;)

    {

        if(processEvents || (!isStackOn) || (!isStartAdvComplete))

        {

            Cy_BLE_ProcessEvents();

           

            processEvents = false;       

        }

       

        if(!Cy_SysPm_Cm0IsLowPower())

        {

            Cy_SysPm_EnterLowPowerMode();

        }      

        cy_en_ble_bless_state_t bleSsState = Cy_BLE_StackGetBleSsState();      

        if(bleSsState == CY_BLE_BLESS_STATE_ACTIVE || bleSsState == CY_BLE_BLESS_STATE_ECO_STABLE)

        {

            cy_en_syspm_status_t apiResult = Cy_SysPm_Sleep(CY_SYSPM_WAIT_FOR_INTERRUPT);

            if(apiResult != CY_SYSPM_SUCCESS)

            {

                Cy_GPIO_Set(DB_0_PORT,DB_0_NUM);    // Doesn't work

            }

            else

            {

                Cy_GPIO_Clr(DB_0_PORT,DB_0_NUM);    // Work

            }

        }

        else

        {

            cy_en_syspm_status_t apiResult = Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);

            if(apiResult != CY_SYSPM_SUCCESS)

            {

                Cy_GPIO_Set(DB_1_PORT,DB_1_NUM);    // Doesn't work

            }

            else

            {

                Cy_GPIO_Clr(DB_1_PORT,DB_1_NUM);    // Work

            }

        }

    }

So please add that code and see if that fixes the issue.

Regards,

Meenakshi Sundaram R

0 Likes

Hi I have a follow up question to this issue.

We are unable to get the PSoC 6 to its lowest current draw (in deep sleep), when the device is connected. We are drawing 300 uA when the device connects. Should the above code, cause the device to drawing on the order of tens of uA when connected or advertising (when not sending data)?

Are there specific oscillator/clock settings that need to be applied as well? We are following the datasheet for the BLE part, but would like to verify our configuration.

Thanks

0 Likes