BLESS Wakeup from deep sleep

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

cross mob
lock attach
Attachments are accessible only for community members.
JiWa_1379161
Level 3
Level 3
5 sign-ins 10 replies posted 5 replies posted

I am looking for some assistance with waking the CYBLE-022001-00 from deep sleep mode. I am using two GPIO ports with tact switches configured on port 0 interrupt line. It is a custom PCB with only the BLE module and switches, not a developers board or dongle.

   

There is no problem putting the entire board into deep sleep where I can see the current drop to uA. The problem I am having is when I press either of the buttons, the CPU wakes up but the BLESS remains in deep sleep thus when it goes to perform a BLE function upon wake up, the code locks up.

   

I tried a few breakpoints in debug mode to see if I can establish what is happening. When the board wakes up, it jumps to MyISR routine. AT this point I checked the BLESS status and it still said deep sleep. I tried using the command CyBle_ExitLPM() upon entering the MyISR but everything locks up with that as well.

   

How can I force the BLESS to wake up?

   

The application is a central device that connects to a peripheral. Once initially paired and if no buttons are pressed, unit goes to sleep. Upon pressing a button, it is to wake up and send a value (depending on which button pressed) to a characteristic in a custom service on the peripheral. Then go back to sleep until next button press. Attached is the main code where all the custom code is located.

   

Any help will be greatly appreciated

   

Thanks

   

Jim

0 Likes
1 Solution
Anonymous
Not applicable

Hi guys,

   

Let me clarify few things regarding the BLESS wakeup:

   

- If any interrupt other the BLESS interrupt wakes up the system from low power, then the BLESS won't wakeup from its low power mode.

   

- The BLESS interrupt and the CyBle_ExitLPM() API wakes up the BLESS from low power.

   

 

   

e.pratt in reply #4 shows how you could use the CyBle_ExitLPM() to wake the BLESS from low power. However, I do not understand why you want the BLESS to wakeup when you press the button. Let the BLESS wakeup when it wants to. All the tasks would be queued up and the packets would be sent in the next interval.

View solution in original post

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

Welcome in the forum, Jim.

   

Besides other solutions the easiest seems to be to place a "Global Signal Reference" onto the topdesign and configure it for port interrupts.

   

Since in deep sleep the high frequency clocks are disabled the internal "Peripheral  Interrupt Controller Unit" (PICU) will be the only source to get you out of there.

   

 

   

Bob

0 Likes
JiWa_1379161
Level 3
Level 3
5 sign-ins 10 replies posted 5 replies posted

Hi Bob

   

I have no problem waking the CPU from deepsleep via the GPIO and interrupts. The issue is after the board wakes up from the GPIO, the BLESS is still in deepsleep mode so I cant send any data over the BLE. To be clear, the GPIO's are waking the board, not the BLESS so I need to manually wake the BLESS from sleep. When I try to use the exitLPM mode, it locks up everything. How can I get the BLESS to be active again and out of low power mode. It appears it doesnt automatically wake up upon an interrupt from a different peripheral other than itself.

   

Jim

0 Likes
Anonymous
Not applicable

Some thoughts:

   

First, handle the ISR for your GPIO interrupt, then do any functions you want done in main rather than the ISR (as that could be the lockup issue cause).

   

Second, afaik the only way to wakeup the BLE module is with the exitLPM() or a BLESS interrupt.

   

Here is the low power implmentation that I use (it runs in main, and thus isn't ISR-linked):

   


void CheckPowerMode() {
    CYBLE_BLESS_STATE_T blessState;
    uint8 intrStatus;
    //if ADC is on, then we can only go to SLEEP
    //if MNPHS is connect, idle, or scan_advertise then we can deep sleep
    
    CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);

   

    if(ADCRunning) {
        intrStatus = CyEnterCriticalSection();
        blessState = CyBle_GetBleSsState();
        if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) {
            CySysClkImoStop();
            CySysPmSleep();
            CySysClkImoStart();
        }
        CyExitCriticalSection(intrStatus);
    } else {
        intrStatus = CyEnterCriticalSection();
        blessState = CyBle_GetBleSsState();
        if((blessState == CYBLE_BLESS_STATE_ECO_ON ||
        blessState == CYBLE_BLESS_STATE_DEEPSLEEP)) {
            CySysPmDeepSleep();
        } else if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) {
            CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_ECO);
            CySysClkImoStop();
            CySysPmSleep();
            CySysClkImoStart();
            CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_IMO);
        }
        CyExitCriticalSection(intrStatus);
    }
    
    CyBle_ExitLPM();
}

   

As you can see, I call CyBle_ExitLPM() after leaving sleep for any reason (since I know I will be using BLE commands, but I could probably optimize it a little). Since your GPIO was the cause of wakeup, it will interrupt and jump to it before it can reach the exitLPM() function call. I would introduce architecture to handle the BLE commands being called after the exitLPM() is called from your main code, rather than trying to do things in the interrupt routine (exitLPM uses interrupts itself to wakeup the BLE module, hence why I suspect that is the reason it isn't working)

0 Likes
Anonymous
Not applicable

Eric,

In your sample code, hat is the ADCRunning() function checking?

Thank you

Andy

0 Likes
Anonymous
Not applicable

ADCRunning is a flag variable to indicate whether the ADC peripheral is actively sampling a voltage; I use it to prevent the unit from modifying flash, going into deep sleep, or trying to use the ADC data before it is ready. Essentially, it is a flag to notify the unit that with the ADC running we should be using the corresponding power saving code instead of the other "deeper" power saving code.

0 Likes
Anonymous
Not applicable

Thank you. I 'm still having issues waking from deep sleep via WDT or a button press. Posted details and project here

Problems with WDT in low power mode

Would appreciate some help

Andy

0 Likes
JiWa_1379161
Level 3
Level 3
5 sign-ins 10 replies posted 5 replies posted

Hi E

   

It made sense what you said regarding the ISR running and not waking up the BLE, I changed things around. However, I am getting some other strange behaviors. First of all the ExitLpm command still locks up, no matter what I do. I cant understand why. What is strange is I found another low power code and implemented as shown below. Everything goes to deep sleep but for some reason the BLESS is now waking the unit up from sleep. Any ideas?

   

void HandleLowPowerMode(void)
{
    #ifdef ENABLE_LOW_POWER_MODE
        /* Local variable to store the status of BLESS Hardware block */
        CYBLE_LP_MODE_T sleepMode;
        CYBLE_BLESS_STATE_T blessState;
        uint8 intrStatus;
        
        /* Put BLESS into Deep Sleep and check the return status */
        sleepMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);
        
        /* Disable global interrupt to prevent changes from any other interrupt ISR */
        CyGlobalIntDisable;
        
        /* Check the Status of BLESS */
        blessState = CyBle_GetBleSsState();
   //     isr_SW1_ClearPending();
        SW1_ClearInterrupt();
        if(sleepMode == CYBLE_BLESS_DEEPSLEEP)
        {
            /* If the ECO has started or the BLESS can go to Deep Sleep, then place CPU 
            * to Deep Sleep */
            if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP)
            {
                CySysPmDeepSleep();
             }
        }
        else
        {
            if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE)
            {
                /* If the BLESS hardware block cannot go to Deep Sleep and BLE Event has not 
                * closed yet, then place CPU to Sleep */
                CySysPmSleep();
            }
        }
 
        CyGlobalIntEnable;
  

   

    #endif

0 Likes
Anonymous
Not applicable

It could be you were modifying the clock (ECO/WCO) that was running the BLE chip? Without seeing a bundle of your project, it would be hard to debug the analog configurations.

   

The ExitLpm is pretty much the only way to wakeup the Cyble chip afaik. You could try doing a soft reset from programming to reset the board and the BLESS system, but I don't know how much luck you would have with that. 

   

If the unit is waking up immediately upon entering sleep or deep sleep, then it is probably an interrupt/flag not being handled somewhere; Either in the BLESS system (your case), or a peripheral waking up the CPU (GPIO port interrupt, etc.)

0 Likes
Anonymous
Not applicable

Hi guys,

   

Let me clarify few things regarding the BLESS wakeup:

   

- If any interrupt other the BLESS interrupt wakes up the system from low power, then the BLESS won't wakeup from its low power mode.

   

- The BLESS interrupt and the CyBle_ExitLPM() API wakes up the BLESS from low power.

   

 

   

e.pratt in reply #4 shows how you could use the CyBle_ExitLPM() to wake the BLESS from low power. However, I do not understand why you want the BLESS to wakeup when you press the button. Let the BLESS wakeup when it wants to. All the tasks would be queued up and the packets would be sent in the next interval.

0 Likes
Anonymous
Not applicable

Waking up the BLESS on wakeup isn't necessary, but for my application it is exclusively BLE using, and thus upon wakeup it will communicate over BLE. But otherwise, I would agree that you should wait until the BLESS wakes up on its own.

   

(Our application is a remote that uses deep-sleep to stay asleep until button push, then relays information about the button press over BLE before returning to sleep.)

0 Likes