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

Wake up from sleep mode

Hello,

       I want to use ble_app_uart example. I'm usign nRF52832 with nRF5_SDK v15. I need to put the MCU in sleep mode. I can do that. When the MCU awakes from sleep, I do not want to run the BLE stack directly. I will make some measurements and then if it is needed, I will run the BLE stack. 

      How can I do this ? any idea ?

Best Regards 

Parents
  • Hi

    If you configure an app_timer callback you will be woken up at regular intervals, so that you can make your measurements, do some calculations, or whatever else you need to do, independently of what the BLE stack is doing. 

    The BLE stack will have it's own internal events that will wake up the CPU when the BLE stack needs it, but this is invisible to the application (until the BLE stack sends an event that you need to process). 

    I don't know what you mean about only running the BLE stack when you need to. If the BLE stack is advertising, or in a BLE connection, it will need to run the MCU at regular intervals to keep the connection/advertising running. 

    Best regards
    Torbjørn

  • Hello Torbjørn

    We are designing a very low power circuit Which will be sleeping most of the time. The device will wake up with 2 triggering event occurs and then start advertising for communication via BLE. The triggering events are NFC and GPIO. In fact, We only need to advertise When the NFC wakes up the MCU. When GPIO wakes up the MCU, MCU will only do some measurement and go to sleep again. I think that I can explain the working principle of my design.

    I have an experimental code one works and the other not. Could you please say that Why the is not working does not work ?

    Not Working

        reset_reason = NRF_POWER->RESETREAS;
        printf("0x%08x\r\n",reset_reason );
    
        if(reset_reason == 0x00080000)          // NFC Wake up
        {
          init_ble();
          initBLEflag = 1;
          NRF_POWER->RESETREAS = 0xffffffff;
          while(1);
          
        }
        else if(reset_reason == 0x00010000)     // GPIO Wake up
        {
          initBLEflag = 0;
          nrf_gpio_pin_clear(19);
          NRF_POWER->RESETREAS = 0xffffffff;
          sleep_mode_enter();
        }
        else
        {
            NRF_POWER->RESETREAS = 0xffffffff;
            sleep_mode_enter();
        }
       

    Working

        reset_reason = NRF_POWER->RESETREAS;
        printf("0x%08x\r\n",reset_reason );
    
        if(reset_reason == 0x00080000)          // NFC Wake up
        {
          init_ble();
          initBLEflag = 1;
          while(1);
          
        }
        else if(reset_reason == 0x00010000)     // GPIO Wake up
        {
          initBLEflag = 0;
          nrf_gpio_pin_clear(19);
          NRF_POWER->RESETREAS = 0xffffffff;
          sleep_mode_enter();
        }
        else
        {
            NRF_POWER->RESETREAS = 0xffffffff;
        }

  • Hi

    It's a bit hard to know exactly why the last one works and not the first, without seeing the rest of the code, but I would have to assume it is caused by the missing sleep_mode_enter() call in the else {} clause. 

    I assume sleep_mode_enter() enables system OFF sleep mode, and if the code is allowed to exit the else{} clause instead of entering system OFF then the program flow might be broken (impossible to say for sure without seeing what happens after the if/else). 

    Best regards
    Torbjørn

  • you can find my full code below.

    static void init_ble(void)
    {
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        advertising_start();
    }
    
    
    int main(void)
    {
        bool erase_bonds;
    
        uart_init();
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
    
    
        reset_reason = NRF_POWER->RESETREAS;
        printf("0x%08x\r\n",reset_reason );
    
        if(reset_reason == 0x00080000)          // NFC Wake up
        {
          init_ble();
          initBLEflag = 1;
          while(1);
          
        }
        else if(reset_reason == 0x00010000)     // GPIO Wake up
        {
          initBLEflag = 0;
          nrf_gpio_pin_clear(19);
          NRF_POWER->RESETREAS = 0xffffffff;
          sleep_mode_enter();
        }
        else
        {
            NRF_POWER->RESETREAS = 0xffffffff;
        }
        
        for (;;)
        {
            nrf_delay_ms(1);
        }
    }

  • Hi

    Thanks for the code. 

    It confirms that your code will get stuck if you leave the else {} clause, since you are left in the for(;;) loop forever without ever entering system OFF again. The only way to return to the top of main then is to perform a power or pin reset. 

    Best regards
    Torbjørn

  • With RESETREAS it is always better to do a bit pattern compare with an AND.  Resetreas accumulates flags until a power cycle.  You could inadvertently have a spare flag set that would cause your equal statement to fail.

Reply Children
No Data
Related