This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Lowest power mode for an external interrupt with nRF51822?

Our system will awake from an external accelerometer interrupt, so I would need a code fragment which shuts down S110 soft device (and radio of course) and also all the nRF51822 peripherals, as well as RAM retention. Even the real time clock is not needed. The CPU only needs to awake by the external interrupt. My related questions are:

  1. What is the needed code to do that, can I still use sd_app_evt_wait()?
  2. What should I expect as the current consumption in that state?
  3. Further, what is the code to get the system up and running again?
Parents
  • Hi Jarmo,

    The chip supports a very low power (~300nA) "system off" mode from which it can be woken using a transition on a pin. In this mode, the clock does not run. You first have to configure the "SENSE" flag for the pin you wish to use to wake the processor. For instance, the following configures a pin to watch for a low-to-high transition:

    NRF_GPIO->PIN_CNF[pin_number] =
            (NRF_GPIO->PIN_CNF[pin_number] &
             ~GPIO_PIN_CNF_SENSE_Msk) |
            (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos);
    

    Typically you use this along with the "PORT" event, which can be used to respond to transitions on a pin with "SENSE" enabled.

    When using the SoftDevice, you can then enter system off using:

    sd_power_system_off()
    

    This function does not return. When the processor wakes up, it is by a reset (the reset reason register will match "POWER_RESETREAS_OFF_Msk"). If you need to treat this case separately, therefore, you should have the following test early in your startup code:

    uint32_t reset_reason;
    (void)sd_power_reset_reason_get(&reset_reason);
    (void)sd_power_reset_reason_clr(0xffffffff);
    if(POWER_RESETREAS_OFF_Msk & reset_reason)
    {
        /* Handle special-case wake-up by accelerometer */
    }
    

    Alternately, if you don't need current consumption quite this low, you can just turn off all peripherals but leave the 32kHz oscillator running. You just continue to use sd_app_evt_wait as usual. You can get current consumption of ~3uA with this method. Note, however, that there's not a single function to do this, you need to write your peripheral drivers with this mind, such that they are not running except when necessary. For peripherals controlled by the stack (e.g. radio), you just need to disable any active behaviour (disconnect, stop advertising) and the stack will do the rest.

  • Thanks for comments! Although I don't quite understand why there is no "consistent set of commands". For UART, I was earlier instructed to use those STOPRX and STOPTX and that was it, works fine! What about for TWI and SPI? They cannot be much more complicated. Of course, I can start reading documentation as you suggested, but I hoped that asking here would give me a quick shortcut :)

Reply
  • Thanks for comments! Although I don't quite understand why there is no "consistent set of commands". For UART, I was earlier instructed to use those STOPRX and STOPTX and that was it, works fine! What about for TWI and SPI? They cannot be much more complicated. Of course, I can start reading documentation as you suggested, but I hoped that asking here would give me a quick shortcut :)

Children
No Data
Related