Hibernate Fails After User SFlash Write

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

cross mob
Anonymous
Not applicable

I've found lots of answers in this Forum as I've climbed the PRoC learning curve -- thank you all!

   

I've found a curious interaction (PRoC CYBLE-022001 on a Pioneer Kit) to share:

   

If I call CySysPmHibernate() after WriteUserSFlashRow() within a Critical Section (initiated via CyEnterCriticalSection() ), Hibernate fails to hold for a suitable GPIO interrupt.  Processing proceeds through CySysPmHibernate() call as though it wasn't there and the next line of code is executed.  Hibernate never happens, and there is no PRoC reset.

   

The Hibernate call is adapted from Project #6 in the 100 Projects series.  WriteUserSFlashRow() is unchanged from Project #29.  AndyWarne mentions problems with clocks being restored completely by WriteUserSFlashRow() in this Forum Thread:  "http://www.cypress.com/forum/proc-ble/sflash?source=search&keywords=sflash%20%26%20ble&cat=community".  That does not appear to be what is happening here.

   

The solution was to end the Critical Section (with CyExitCriticalSection() ) before the WriteUserSFlashRow() call as shown (*** NO CLUE comment) in this code listing.  Hibernate works properly with this code:

   

-----------------------------------------------

   

void EnterLowPowerMode(void)
{
    CYBLE_BLESS_STATE_T blessState;
    uint8 intrStatus;
    
    uint32 data[USER_SFLASH_ROW_SIZE/4];    // User SFlash variables ************
    uint32 dataIndex;
    uint32 status;
    
//********************************************************************************    
    /* Configure BLESS in Deep-Sleep mode */
    CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);
    
    /* Prevent interrupts while entering system low power modes */
    intrStatus = CyEnterCriticalSection();
    
    /* Get the current state of BLESS block */
    blessState = CyBle_GetBleSsState();
    
    /* If BLESS is in Deep-Sleep mode or the XTAL oscillator is turning on,
     * and it's not time to hibernate, then PRoC BLE can enter Deep-Sleep mode
     * (1.3uA current consumption) */
    
    if((blessState == CYBLE_BLESS_STATE_ECO_ON || 
        blessState == CYBLE_BLESS_STATE_DEEPSLEEP) &&
        hibernate_time < HIBE_TIME)
    {
        CySysPmDeepSleep();
    }
    else if((blessState == CYBLE_BLESS_STATE_ECO_ON || 
        blessState == CYBLE_BLESS_STATE_DEEPSLEEP) &&
        hibernate_time >= HIBE_TIME)
    {
        // Save SaveData in User SFlash non-volatile memory, must write 128B row
        data[0] = SaveData;
        SaveData++;                // new value next time
        
        // load balance of user SFlash write buffer
       for(dataIndex = 1; dataIndex < (USER_SFLASH_ROW_SIZE/4); dataIndex++)
        {
            data[dataIndex] = SFLASH_STARTING_VALUE;
        }
        
        CyExitCriticalSection(intrStatus);      // *** NO CLUE why SFlash write in crit sec prevents
                                                //      Hibernate from working!!?!   Remove it.
        
        // write row 1 (Bytes 128-131 User SFlash)        
        status = WriteUserSFlashRow(1, &data[0]);
        
        // NOW Hibernate
        CySysPmHibernate();
    }
    
    CyExitCriticalSection(intrStatus);
}

   

-----------------------------------------------

   

Anyone have an idea as to what is going on with the Critical Section interaction?

   

Thanks.

   

Jim 

0 Likes
4 Replies
Anonymous
Not applicable

The CriticalSection disables all the interrupts, but hibernate needs interrupt for it to wake up later. So you need to Exit critical section before going into hibernate

0 Likes
Anonymous
Not applicable

Interesting suggestion, but I guess I wasn't clear:  Hibernate works just fine in the Critical Section if the WriteUserSFlashRow() call is not made.  So disabling all interrupts does not appear to stop Hibernate from working.  It is the combination of  WriteUserSFlashRow() before the Hibernate call in a Critical Section that causes the Hibernate call to be ignored or immediately ended.

   

Jim

0 Likes
Anonymous
Not applicable

Hello,

I try to work on 222001 (nightmare ...) but I have more or less the same trouble :

I use the low power modes, it gives good results

When WriteUserSFlashRow() is called from Ble engine, it works fine in sectors 0 to 3

When it's called from ouside, it writes the data but stops the clocks after 10 ms and the system resets

I've tried to disable interrupts, enter critical section,

I don't know where to searh ... If someone have any idea, ...

Best regards

francois

0 Likes
Anonymous
Not applicable

Hello,

After several days of search, I've found that with :

CyBle_Stop();

(void)WriteUserSFlashRow(2, (ulong *)&s);

CyBle_Start((CYBLE_CALLBACK_T)BleCallBack);

Things are much better and the system doen't resets now ...

Best regards

francois

0 Likes