CC2340R5: Wakeup from shutdown doesn't happen when SPI chip-select and two other GPIO pins are used as wakeup lines

Part Number: CC2340R5
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hello,

I have been using the SPI's chip-select line to wakeup. It has been working fine until I added additional two GPIOs as wakeup source. I have repurposed basic_ble_project to reproduce this scenario in isolation from my application.

Main and user task:

void *user_task(void *arg)
{
    bool init_status;

    PowerLPF3_ResetReason resetReason = PowerLPF3_getResetReason();

    if (resetReason == PowerLPF3_RESET_SHUTDOWN_IO)
    {
        PowerLPF3_releaseLatches();
    }

    init_status = user_init();

    if (init_status == false)
    {
        while(1)
        {
            GPIO_toggle(CONFIG_GPIO_LED);
            vTaskDelay(pdMS_TO_TICKS(100));
        }
    }
    else
    {
        while(1)
        {
            GPIO_toggle(CONFIG_GPIO_LED);
            vTaskDelay(pdMS_TO_TICKS(500));

            count++;
            if (count >= 10)
            {
                user_enter_shutdown();
            }
        }
    }
}

int main()
{
  /* Register Application callback to trap asserts raised in the Stack */
  halAssertCback = AssertHandler;
  RegisterAssertCback(AssertHandler);

  Board_init();

  /* Update User Configuration of the stack */
  user0Cfg.appServiceInfo->timerTickPeriod = ICall_getTickPeriod();
  user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();

  /* Initialize all applications tasks */
//  appMain();

  pthread_create(&user_thread, &user_task_attr, &user_task, NULL);

  /* Start the FreeRTOS scheduler */
  vTaskStartScheduler();

  return 0;
}

Helper functions:

static int postNotifyFxn(unsigned int eventType, uintptr_t eventArg,
                           uintptr_t clientArg)
{
    if (eventType == PowerLPF3_ENTERING_SHUTDOWN)
    {
        notified = 1;
        return Power_NOTIFYDONE;
    }

    return Power_NOTIFYERROR;
}

void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
    (void)handle;
    (void)transaction;
}

static bool user_init()
{
    SPI_Params spiParams;
    Power_NotifyObj powerNotifyObj;

    uintptr_t clientArg = count;
    unsigned int eventTypes = PowerLPF3_ENTERING_SHUTDOWN;

    SPI_init();
    SPI_Params_init(&spiParams);

    spiParams.frameFormat         = SPI_POL0_PHA0;
    spiParams.mode                = SPI_PERIPHERAL;
    spiParams.transferCallbackFxn = transferCompleteFxn;
    spiParams.transferMode        = SPI_MODE_CALLBACK;
    spiParams.bitRate             = 4000000;

    spi_handle = SPI_open(CONFIG_SPI_PERIPHERAL, &spiParams);

    if (spi_handle == NULL)
    {
        return false;
    }

    GPIO_write(CONFIG_GPIO_LED, 1);

    Power_registerNotify(&powerNotifyObj, eventTypes, postNotifyFxn, clientArg);

    return true;
}

static void user_enter_shutdown()
{
    int_fast16_t shutdown_status;

    // debug led-off
    GPIO_write(CONFIG_GPIO_LED, 0);

    // close spi
    SPI_transferCancel(spi_handle);
    SPI_close(spi_handle);
    UDMALPF3_channelDisable(0xFF);
    uDMADisable();

    // set wakeup pins
    GPIO_setConfig(CONFIG_GPIO_SPI_PERIPHERAL_CSN, GPIO_CFG_IN_PU | GPIO_CFG_SHUTDOWN_WAKE_LOW);
    GPIO_setConfig(CONFIG_GPIO_BTN1, GPIO_CFG_IN_PU | GPIO_CFG_SHUTDOWN_WAKE_LOW);
    GPIO_setConfig(CONFIG_GPIO_BTN2, GPIO_CFG_IN_PU | GPIO_CFG_SHUTDOWN_WAKE_LOW);

    // enter shutdown
    shutdown_status = Power_shutdown(0, 0);

    // debug led-on when shutdown fails
    if (shutdown_status != Power_SOK)
    {
        GPIO_write(CONFIG_GPIO_LED, 1);
        while(1);
    }
}


This is where I have a problem with wakeup from shutdown. Earlier I did not have lines #65 and #66, but added recently.

  • With lines #64, #65 & #66 all enabled, device wakes up only from CONFIG_GPIO_SPI_PERIPHERAL_CSN pin.



  • With #64 commented, #65 & #66 enabled, device wakes up with other two pins (CONFIG_GPIO_BTN1 and CONFIG_GPIO_BTN2).



  • With #65 & #66 commented, #64 enabled, device still wakes up.

Please find the saleae captures attached here for your reference.

saleae_captures.zip


Question:

It seems there's some kind of dependency with SPI which I am unable to understand or figure out myself. How do I ensure that device wakes up from all 3 sources?

Regards,
Jaimin

  • Followup information:

    MCU: CC2340R5-RGE with our custom PCB
    DIO11: SPI chip select
    DIO8: Button1 /w internal pull-up
    DIO20: Button 2 /w internal pull-up

  • Hello Jaimin,

    I hope you are doing well. I wanted to ask which SDK version this is on, and which chip select type you have enabled. 

    • Hardware chip select No additional action by the application is required.
    • Software chip select The application needs to handle the chip select assertion and de-assertion for the proper SPI peripheral 

    Thanks,
    Alex F

  • I was using SDK v7.40 when I posted this query. For the sake of ruling out SDK version I repeated this activity with v9.11.00.18. I see same behaviour seen in waveforms.

    I have used Hardware based chip-select. Please find my sysconfig attached for you reference.
    /cfs-file/__key/communityserver-discussions-components-files/538/basic_5F00_ble.syscfg.zip

  • Hello Ajmeri Jaimin,

    I performed some tests today with the code below, trying to replicate the issue you found with setting SPI chip select to wakeup (or commenting it out); in my tests I did not notice the same behavior as the device could wakeup from the button press in either case (with or without SPI CS). Could you try the code below on your custom device to see if you get similar results? 

    #define CONFIG_SPI_CONTROLLER           0
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        PowerLPF3_ResetReason resetReason = PowerLPF3_getResetReason();
    
        /* If we are waking up from shutdown, we do something extra. */
        if (resetReason == PowerLPF3_RESET_SHUTDOWN_IO)
        {
            /* Application code must always disable the IO latches when coming out of shutdown */
            PowerLPF3_releaseLatches();
    
        }
        SPI_Handle spi_handle;
        SPI_Params spiParams;
        SPI_Transaction transaction;
        uint32_t i;
        bool transferOK;
        int32_t status;
        /* 1 second delay */
        uint32_t time = 1;
        SPI_init();
        SPI_Params_init(&spiParams);
    
        spiParams.frameFormat         = SPI_POL0_PHA0;
        spiParams.mode                = SPI_PERIPHERAL;
        //spiParams.transferCallbackFxn = transferCompleteFxn;
        spiParams.transferMode        = SPI_MODE_CALLBACK;
        spiParams.bitRate             = 4000000;
    
        spi_handle = SPI_open(CONFIG_SPI_CONTROLLER, &spiParams);
        /* Call driver init functions */
        GPIO_init();
        // I2C_init();
        // SPI_init();
        // Watchdog_init();
        SPI_transferCancel(spi_handle);
        SPI_close(spi_handle);
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        GPIO_setConfig(CONFIG_GPIO_SPI_0_CSN, GPIO_CFG_IN_PU | GPIO_CFG_SHUTDOWN_WAKE_LOW);
        GPIO_setConfig(CONFIG_GPIO_0, GPIO_CFG_IN_PU | GPIO_CFG_SHUTDOWN_WAKE_LOW);
        GPIO_setConfig(CONFIG_GPIO_1, GPIO_CFG_IN_PU | GPIO_CFG_SHUTDOWN_WAKE_LOW);
        /* Turn on user LED */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
            sleep(time);
            GPIO_toggle(CONFIG_GPIO_LED_0);
            /* Go to shutdown */
            Power_shutdown(0, 0);
    }

    Thanks,
    Alex F