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.

  • Hi Jarmo,

    Like I said, there aren't a consistent set of commands to shut down each peripheral. You need to read the documentation for each peripheral (in the nRF51 manual) and make sure they are not running to achieve the 3uA usage in "normal" sleep. For instance, for UART you need to stop the transmitter and receiver using the tasks STOPRX and STOPTX. You should call these in the peripheral driver whenever you are done receiving or transmitting, respectively. Obviously exactly when you do this will depend on how you intend to use the interface.

Reply
  • Hi Jarmo,

    Like I said, there aren't a consistent set of commands to shut down each peripheral. You need to read the documentation for each peripheral (in the nRF51 manual) and make sure they are not running to achieve the 3uA usage in "normal" sleep. For instance, for UART you need to stop the transmitter and receiver using the tasks STOPRX and STOPTX. You should call these in the peripheral driver whenever you are done receiving or transmitting, respectively. Obviously exactly when you do this will depend on how you intend to use the interface.

Children
No Data
Related