This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2652R7: Button shutdown/wake-up in on-chip OAD project

Part Number: CC2652R7


Tool/software:

Hi Team,

I am developing a device that can use a button to power on/off after a long press. Previously it worked fine, but recently I added an on-chip OAD feature on it.

After that I found that I can only shutdown the device after a long press but cannot wake it up again.
Here is my main logic of button wake up/shutdown after a long press, I place Boot_init() in the beginning of SimplePeripheral_taskFxn function:

void Boot_Init()
{
PowerCC26X2_ResetReason resetReason = PowerCC26X2_getResetReason();

if(resetReason == PowerCC26X2_RESET_SHUTDOWN_IO)
{
PowerCC26X2_releaseLatches();
BootCountDownCreate();
BootCountDownInit();
GPIO_setConfig(CONFIG_GPIO_MPB_CONST, GPIO_CFG_IN_PU);
uint8_t press = GPIO_read(CONFIG_GPIO_MPB_CONST);
BootServiceRoutine(press);
BootCountEliminate();
GPIO_resetConfig(CONFIG_GPIO_MPB_CONST);
howToBoot = 0x00;
}
else if (resetReason == PowerCC26X2_RESET_TCK_NOISE)
{
howToBoot = 0x01;
}
else if(resetReason == PowerCC26X2_RESET_SYSTEM)
{
howToBoot = 0x02;
}
else if(resetReason == PowerCC26X2_RESET_WARM_RESET) /*Fast Boot*/
{
howToBoot = 0x03;
}
else if(resetReason == PowerCC26X2_RESET_CLK)
{
howToBoot = 0x04;
}
else if(resetReason == PowerCC26X2_RESET_VDDR)
{
howToBoot = 0x05;
}
else if(resetReason == PowerCC26X2_RESET_VDDS)
{
howToBoot = 0x06;
}
else if(resetReason == PowerCC26X2_RESET_PIN)
{
howToBoot = 0x07;
}
else if(resetReason == PowerCC26X2_RESET_POR)
{
howToBoot = 0x08;
}
}

void BootServiceRoutine(uint8_t isWakeUp)
{
uint8_t BOOT_FINISHED = 0x00;
if(isWakeUp == 0)
{
/*If user is still pressing the button, the Count Down timer starts immediately */
uint8_t stillPress = GPIO_read(CONFIG_GPIO_MPB_CONST);
if(stillPress == 0x00)
{
/*Starts Counting Down for BOOTREADY_TIME x BOOTREADY_COUNT seconds*/
BootCountStart();
}
/*We haven't done booting yet! Although you are pressing the button! Don't put down your hand!*/
while(BOOT_FINISHED == 0x00)
{
/* status = 0x01 --> release the button
* status = 0x00 --> press the button
*/
uint8_t status = GPIO_read(CONFIG_GPIO_MPB_CONST);
/*Oh my god! You have released the button! Let me go to sleep again!*/
if(status == 0x01)
{
/*Count-Down Timer Stops*/
BootCountStop();
/*Enters Shut Down Mode again*/
SystemShutDownRoutine();
}
/*If the user is still pressing the button until TIME'S UP, the count down timer stops! Boot Routine is finished! */
/*For each 500 ms timer overflow, bootCount increases by 1.
*To have 1.5 seconds delay, bootReady is 3.
*To see the blink, wait until the bootReady is 3 while you are pressing the button!
* */
if(bootReady >= BOOTREADY_COUNT)
{
/*Count-Down finished*/
BootCountStop();
/*Congratulations! BOOT Process is Done ! Get out of the loop! Enjoy driving! */
BOOT_FINISHED = 0x01;
}
}
}
else if(isWakeUp == 1)
{
while(BOOT_FINISHED == 0x00)
{
/*Enters Shut Down Mode again*/
SystemShutDownRoutine();
}
}
}

void SystemShutDownRoutine()
{
GPIO_resetConfig(CONFIG_GPIO_MPB_CONST);
/* How to wake me up?? */
GPIO_setConfig(CONFIG_GPIO_MPB_CONST,GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_PULL_UP_INTERNAL | GPIO_CFG_SHUTDOWN_WAKE_LOW);
/* Let me sleep! Bye! */
Power_shutdown(0, 0);
while(1)
{

}
}


I wonder if this problem is related to bim_onchip, so I need to implement my button press logic to the bim project?

I am using I am using simplelink_cc13xx_cc26xx_sdk_7_40_00_77 and CCS 12.8.1, could you help me with this problem?

Thanks a lot.

Jermyn

  • Hi Jermyn,

    Good debugging! I agree with your hypothesis, as the main difference between a working version of your button press logic, and non-working, is the usage of bim_onchip.

    Do you have access to the reset pin? If yes, then a quick test I recommend would be:

    1. Get your device to a running state (e.g. erase entire flash, the flash all relevant binaries such as bim, application, etc)
    2. Now press the reset button
    3. Confirm whether your application has started

    Thanks,
    Toby

  • Hi Toby,

    Do you mean the reset pin on the launch pad? If so, sorry that I cannot access the reset pin.

    For my experience, my application will start once I connect to the power source. Then after a long-pressed the button, my device can shut down(enter sleeping mode). It should be woken up after long-pressed again, but it failed.

    I am wondering whether I need to copy the boot-up logic to bim_onchip program? If so, I need to add a syscfg file, but I cannot find any instruction on adding a syscfg file to CC2652R7.

    Do you have any suggestions on it? Thank you so much!

    Best,

    Jermyn

  • Hi Jermyn,

    For my experience, my application will start once I connect to the power source.

    After you've freshly loaded your bim version of project to the device, and you power off then on, do you see the application starting?

    Thanks,
    Toby

  • Hi Tody, 

    During the debugging these days, I found that the problem is the counting logic of my code, after I remove the counting function for the wake-up logic, which I can successfully wake up the device when I do a short press on the button (instead do a long press).

    I think I should correctly configure the clock which is used in the codes I sent earlier:

    #define BOOTREADY_TIME 300
    #define BOOTREADY_COUNT 2

    void BootCountDownCreate()
    {
    Error_init(&eb);
    bootClockTicks = BOOTREADY_TIME * (1000 / Clock_tickPeriod) - 1; // BOOTREADY_TIME to overflow
    //Create BootCountDown clock !!
    bootCountClockHandle = Clock_create(BootCountOVFxn, bootClockTicks, &clkParams, &eb);
    }

    void BootCountDownInit()
    {
    Clock_Params_init(&clkParams);
    clkParams.period = bootClockTicks;
    clkParams.startFlag = FALSE;
    clkParams.arg = (UArg)0x0000;
    Clock_setTimeout(bootCountClockHandle, bootClockTicks);
    Clock_setPeriod(bootCountClockHandle, bootClockTicks);
    }

    void BootCountStart()
    {
    //Set the initial timeout
    Clock_start(bootCountClockHandle);
    }

    void BootCountStop()
    {
    Clock_stop(bootCountClockHandle);
    }

    void BootCountEliminate()
    {
    Clock_delete(&bootCountClockHandle);
    }

    void BootCountOVFxn()
    {
    bootReady++;
    }

    May I know the method is appropriate for wake up a device? If not, what other methods I can try to do a long press on the button to wake up the device?

    Thank you so much.

    Best

    Jermyn 

  • Hi Jermyn,

    From our device perspective, it can wakeup pretty quickly with GPIO (about 10s of usec).

    For a long press/short press detection, if not using additional hardware, then you would need to do some kind of counting like you've done here.
    In this case, it would need to handle the case where you the button press is less than the duration of long press.

    As an example, for shutdown wakeup, the sequence might look like:

    1. Device is in shutdown
    2. User presses/holds button
    3. Device wakes up and enters counting logic
    4. If user releases button BEFORE long press duration, then device goes into shutdown
    5. If user releases button AFTER long press duration, then device starts up the application

    Thanks,
    Toby

  • Hi Toby, 

    Thanks for your replay, I could understand the sequence. But during debugging, I am still confusing what is the root of the problem.

    However, for your previous question, here is the case, there are led display in my device, if the application is start it could be initialized and the led can be turned on. After 

    after I do a long press to a button to shut down the application, then tried to wake it up again by a long press, nothing happened. I could not turn on the display, so I am sure the application didn't start.

    Back to the on-chip OAD which bim_onchip is needed, I learned from the TI Technical Reference Manual, it said the state of the CC13x2x7 and CC26x2x7 device platform after a system reset, power on, or wake up from shutdown is start-up state.

    1) So, does it mean every time I wake up from the shutdown, it may enter the bim_onchip program first? I still need to modify the bim file for shutdown/ wake up?

    2)Then how to add a .syscfg file to bim because I need to enable the GPIO for the external button.

    3)Why when I remove the counting function for the wake-up logic, I can successfully wake up the device when I do a short press on the button (instead do a long press), even I am using the on-chip OAD setting? What exactly is the key to this problem.

    Could you help to clarify these questions, thank you so much.

    Bset,

    Jermyn

  • Hi Jermyn,

    Thank for explaining in more detail about your observations.

    With all these clues, I think the key thing could be that bim is a very bare-bones project, which does not pull in many of the modules that are used in a more sophisticated application, such as calling Clock_* functions.

    As a test, can you instead use a for-loop (instead of Clock_* functions)? Empty for loops will typically take about ~4 cycles per iterations, so as a simple test of 2 sec long press:

    char button_level = readButton(wakeupGpio);
    if (button_level == PRESSED) {
        int i;
        for (i = 0; i < 48000000 * 2 / 4; i++) {
            // delay about 2 sec, assuming 4 cycles per empty for-loop iteration
        }
        button_level = readButton(wakeupGpio);
        if (button_level == PRESSED) {
            // long press detected, startup application normally
        }
    }
    
    // not long pressed, so return to shutdown

    Regarding how to add .syscfg file to the bim project, this is not done by default since bim is a bare-bones project (minimize flash footprint) and doesn't pull in the TI Drivers (such as GPIO_write), register writes can still be used to control to the pins.

    Here is a reference of some register writes I've used in the past to read the pins:

    #include DeviceFamily_constructPath(inc/hw_aon_pmctl.h)
    #include DeviceFamily_constructPath(inc/hw_nvic.h)
    #include DeviceFamily_constructPath(inc/hw_ioc.h)
    #include DeviceFamily_constructPath(driverlib/ioc.h)
    
    // ...
    
    // assume active low backdoor pin
    static const uint8_t ACTIVE_LEVEL = 0;
    uint8_t initBackDoorPin(uint8_t dioNum)
    {
        HWREG(PRCM_BASE + PRCM_O_PDCTL0PERIPH) = PRCM_PDCTL0PERIPH_ON;
        // Wait for stable power
        while((HWREG(PRCM_BASE + PRCM_O_PDSTAT0) &
                PRCM_PDSTAT0_PERIPH_ON) == 0)
        {
        }
        // Enable GPIO clock
        HWREG(PRCM_BASE + PRCM_O_GPIOCLKGR) = PRCM_GPIOCLKGR_CLK_EN;
        HWREG(PRCM_BASE + PRCM_O_CLKLOADCTL)  = PRCM_CLKLOADCTL_LOAD;
        // Enable for edge interrupt on both edges on GPIO-pin to be used for UART_RX
        uint32_t ui32RegOffset = dioNum * 4;
    
        HWREG(IOC_BASE + IOC_O_IOCFG0 + ui32RegOffset) = IOC_IOCFG0_IE  | IOC_IOPULL_UP;
    
        return dioNum;
    }
    uint8_t isBackdoorPinActive(uint8_t dioNum)
    {
        const uint32_t ACTIVE_THRESHOLD = 750;
    
        uint8_t level;
        uint32_t countOfActiveLevel = 0;
    
        uint32_t n;
        for (n = 0; n < 1000; n++)
        {
            level = GPIO_readDio(dioNum);
            if (level == ACTIVE_LEVEL)
            {
                countOfActiveLevel += 1;
            }
        }
    
        return (countOfActiveLevel >= ACTIVE_THRESHOLD);
    }
    
    //...
    
    uint8_t backdoorDio = initBackDoorPin(23);
    if (isBackdoorPinActive(backdoorDio))

    Thanks,
    Toby