Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

After sleep_mode_enter() function, MCU never wakes up

Hello,

           I'm usign nRF52832 with nRF5_SDK v15. I modified the example "ble_app_uart". I just remove the ble functions and added gpiote functions to wake up the MCU from sleep mode. I also add a line in the main to put the MCU in sleep mode.

           My problem is that When BLE functions are in my code, My code works fine and MCU wakes up from sleep. However, When I remove the BLE functions in my code, the MCU never wakes up from sleep.

           What is wrong with my code ? Can someone help ? 

Best Regards

int main(void)
{
    bool erase_bonds;

    // Initialize.
    uart_init();
    log_init();
    timers_init();
    buttons_leds_init(&erase_bonds);
    power_management_init();
    
    nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true); 
    config.pull = NRF_GPIO_PIN_PULLUP;
    err_code = nrf_drv_gpiote_in_init(3, &config, pin_event_handler);
    nrf_drv_gpiote_in_event_enable(3, true);
    
    // Enter main loop.
    for (;;)
    {
        nrf_delay_ms(1);

        x++;
        if(x>10000) sleep_mode_enter();
    }
}

static void sleep_mode_enter(void)
{
    uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);

    // Prepare wakeup buttons.
    //err_code = bsp_btn_ble_sleep_mode_prepare();
    //APP_ERROR_CHECK(err_code);

    nrf_gpio_cfg_sense_set(3, NRF_GPIO_PIN_SENSE_LOW);

    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
}

  • That's a funky way to enter sleep.  I assume the thought is if it keeps running the in the for loop then it's not asleep.

    Offhand I would guess that you haven't allowed sufficient clocks after your gpio call for everything to take before you call system off.  gpiote takes up to 2 pclks for things to configure. 

    Also, you realize that there is a difference between sleep and system off?  The only way, I know, to come out of system off is with a soft reset.  So the program counter goes back to zero, but you can optionally keep ram and gpio alive.

  • Instead of using the button driver here is a nice easy way to do the same thing:

    uint32_t err_code;

    NRF_GPIO->DIRCLR = (1L<<BUTTON_1);  //define your button however you wish
    NRF_GPIO->PIN_CNF[BUTTON_1] = (0x3000C);

    NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;

    err_code = sd_ble_gap_adv_stop();  //Depending on how you are using the SD you may need to use a different API. This was from basic beacon app.

    APP_ERROR_CHECK(err_code);

    __NOP(); //this is a quick way to get a little delay
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    err_code = sd_power_system_off();

    APP_ERROR_CHECK(err_code); //this isn't really necessary since it never returns

    I think that is it.  I had to copy it out piecemeal. 

  • err_code = sd_ble_gap_adv_stop();

    Above line gives an error. I'am using "ble_app_uart" example. Which function should I use instead of the above function ?

    In addition When I use the sd_power_system_off(); function, does it retains the ram and gpio content ?

  • As I noted in the comments, you need to stop the ble using whichever command is correct for your application and SD version. Just look up the correct API for this.

    If you are not running the SD, then you should be writing to the power registers directly to invoke system off.

    There is an example call ram_retention in the SDK and there are many blog entries on the subject.

    The default ram retention state of system off is covered thoroughly in the product spec.

Related