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, For most applications, the device will spend most of its time asleep (i.e. in sd_app_evt_wait). Taking the UART as an example, a well-written application will go to sleep during the transmission of each character if it has nothing else to do. So if you simply call STOPRX and STOPTX each time you reach "sd_app_evt_wait" in your main loop, with no consideration to what the UART is being used for, you will probably end up with an unusable UART. Instead, the UART driver should be written such that it calls STOPRX and STOPTX whenever it is done receiving or transmitting, respectively. Similar arguments go for other drivers. It is also worth mentioning that the different peripherals are not consistent in how they stop. For instance, the TWI peripheral has a "STOPPED" event that you need to wait for after calling the STOP task. The UART has no equivalent "STOPPED" event.

Reply
  • Hi Jarmo, For most applications, the device will spend most of its time asleep (i.e. in sd_app_evt_wait). Taking the UART as an example, a well-written application will go to sleep during the transmission of each character if it has nothing else to do. So if you simply call STOPRX and STOPTX each time you reach "sd_app_evt_wait" in your main loop, with no consideration to what the UART is being used for, you will probably end up with an unusable UART. Instead, the UART driver should be written such that it calls STOPRX and STOPTX whenever it is done receiving or transmitting, respectively. Similar arguments go for other drivers. It is also worth mentioning that the different peripherals are not consistent in how they stop. For instance, the TWI peripheral has a "STOPPED" event that you need to wait for after calling the STOP task. The UART has no equivalent "STOPPED" event.

Children
No Data
Related