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

    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.

  • Nothing has changed even if I put sleep_mode_enter(); in the else condition.

  • So are you saying that the only difference between the working and non working code is the following line at line 8 of your example?

    NRF_POWER->RESETREAS = 0xffffffff;

Reply Children
  • Hi

    Then the issue is probably related to Richard Moldovan's reply. 

    Since you don't reset the RESETREAS register one of the flags might be remaining, and the next time you wake up the incorrect code block is run. 

    For simplicity you should probably just clear the register in the sleep_mode_enter() function, so you don't need to do it explicitly every place where you enter sleep mode. 

    Best regards
    Torbjørn 

Related