├── library.properties ├── .gitignore ├── examples └── power_off │ └── power_off.ino ├── src ├── Arduino_nRF5x_lowPower.h └── Arduino_nRF5x_lowPower.cpp └── README.md /library.properties: -------------------------------------------------------------------------------- 1 | name=Arduino nRF5x lowPower 2 | version=0.1.0 3 | author=Marc-Oliver Ristau 4 | maintainer=Marc-Oliver Ristau 5 | sentence=LowPower library for the nRF5x 6 | paragraph=Designed to work with nRF5x 7 | category=Device Control 8 | url= 9 | architectures=* 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /examples/power_off/power_off.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file power_off.ino 4 | @author Marc-Oliver Ristau 5 | @version 1.0 6 | 7 | Example Sketch to demonstrate Power Off Mode and wakeup by interrupt 8 | Any external interrupt would work, buttons, interrupt capable sensors, .. 9 | It will go to power off mode after some loop cycles. 10 | interrupt will reset the cycle counter. 11 | 12 | @section HISTORY 13 | 14 | v1.0 - First Release 15 | */ 16 | /**************************************************************************/ 17 | 18 | #include // LowPower Library for nRF5x 19 | 20 | #define INTERRUPT_PIN 19 21 | #define LOOP_CYCLES 500 22 | #define CYCLE_TIME_MS 100 23 | 24 | volatile int cycles = 0; 25 | volatile bool int1 = false; 26 | 27 | void intHandler() { 28 | cycles = 0; 29 | int1 = true; 30 | } 31 | 32 | void setup() { 33 | pinMode(INTERRUPT_PIN, INPUT); 34 | 35 | attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), intHandler, RISING); 36 | nRF5x_lowPower.enableWakeupByInterrupt(INTERRUPT_PIN, RISING); 37 | } 38 | 39 | void loop() { 40 | 41 | if (cycles >= LOOP_CYCLES) { 42 | nRF5x_lowPower.powerMode(POWER_MODE_OFF); 43 | } 44 | 45 | cycles++; 46 | delay(CYCLE_TIME_MS); 47 | } -------------------------------------------------------------------------------- /src/Arduino_nRF5x_lowPower.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Arduino_nRF5x_lowPower.h 4 | @author Marc-Oliver Ristau 5 | @version 0.1.1 6 | 7 | Arduino library for nRF5x lowPower modes 8 | 9 | @section HISTORY 10 | 11 | v0.1.0 - First Release 12 | v0.1.1 - updated comments 13 | */ 14 | /**************************************************************************/ 15 | 16 | #ifndef ARDUINO_NRF5X_LOWPOWER_H 17 | #define ARDUINO_NRF5X_LOWPOWER_H 18 | 19 | #if (ARDUINO >= 100) 20 | #include "Arduino.h" 21 | #else 22 | #include "WProgram.h" 23 | #endif 24 | 25 | #include 26 | #include 27 | 28 | typedef enum { 29 | POWER_MODE_OFF = 0x01, // shuts down the nRF5x 30 | POWER_MODE_LOW_POWER = 0x02, // nRF5x low power mode 31 | POWER_MODE_CONSTANT_LATENCY = 0x03 // nRF5x constant latency mode 32 | } nRF5x_powermodes_t; 33 | 34 | class Arduino_nRF5x_lowPower { 35 | public: 36 | void powerMode(nRF5x_powermodes_t mode); 37 | void enableDCDC(); 38 | void disableDCDC(); 39 | void enableWakeupByInterrupt(uint32_t pin, uint32_t mode); 40 | void disableWakeupByInterrupt(uint32_t pin); 41 | private: 42 | void powerOff(void); 43 | void constLat(void); 44 | void lowPower(void); 45 | uint8_t checkForSoftDevice(void); 46 | }; 47 | 48 | extern Arduino_nRF5x_lowPower nRF5x_lowPower; 49 | 50 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino_nRF5x_lowPower 2 | Arduino Power Management Library for nRF5x 3 | 4 | ## Usage 5 | 6 | * PowerMode 7 | * ```nRF5x_lowPower.powerMode(POWER_MODE_OFF);``` to completely shutdown the nRF5x 8 | * ```nRF5x_lowPower.powerMode(POWER_MODE_LOW_POWER);``` to switch to low power mode (default mode) 9 | * ```nRF5x_lowPower.powerMode(POWER_MODE_CONSTANT_LATENCY);``` to switch to constant latency mode 10 | 11 | * DCDC 12 | * ```nRF5x_lowPower.enableDCDC();``` to enable the DC/DC converter 13 | * ```nRF5x_lowPower.disableDCDC();``` to disable the DC/DC converter 14 | 15 | * Interrupt for WakeUp from PowerOff 16 | * ```nRF5x_lowPower.enableWakeupByInterrupt(uint32_t pin, uint32_t mode);``` to enable the Sense Interrupt 17 | * pin is the nRF5x Pin 18 | * mode can be any of the following (HIGH, RISING, LOW, FALLING) 19 | * ```nRF5x_lowPower.disableWakeupByInterrupt(uint32_t pin);``` to disable the Sense Interrupt 20 | 21 | ## Documentation 22 | 23 | ### SYSTEM ON 24 | 25 | #### Constant latency 26 | 27 | In constant latency mode the CPU wakeup latency and the PPI task response will be constant and kept at a minimum. This is secured by forcing a set of base resources on while in sleep. The advantage of having a constant and predictable latency will be at the cost of having increased power consumption. The constant latency mode is selected by triggering the CONSTLAT task. 28 | 29 | #### Low power 30 | 31 | In low power mode the automatic power management system, described in System ON mode, ensures the most efficient supply option is chosen to save the most power. The advantage of having the lowest power possible will be at the cost of having varying CPU wakeup latency and PPI task response. The low power mode is selected by triggering the LOWPWR task. 32 | 33 | http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/power.html?cp=2_1_0_17_2#unique_1349410009 34 | 35 | ### SYSTEM OFF 36 | 37 | When the device is in POWER_MODE_OFF, it can be woken up by following signals: 38 | 39 | * The DETECT signal, optionally generated by the GPIO peripheral 40 | * The ANADETECT signal, optionally generated by the LPCOMP module 41 | * The SENSE signal, optionally generated by the NFC module to “wake-on-field” 42 | * A reset 43 | 44 | http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/power.html?cp=2_1_0_17_1#unique_1707892264 45 | 46 | ### Current consumption 47 | 48 | http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/pmu.html?cp=2_1_0_16_0#unique_1291325043 49 | 50 | ## Dependencies 51 | 52 | This library depends on the Arduino nRF5 package (https://github.com/sandeepmistry/arduino-nRF5) 53 | 54 | ## Compatibility 55 | 56 | This library should be compatible with all boards supported by the Arduino-nRF5 57 | -------------------------------------------------------------------------------- /src/Arduino_nRF5x_lowPower.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Arduino_nRF5x_lowPower.cpp 4 | @author Marc-Oliver Ristau 5 | @version 0.1.1 6 | 7 | Arduino library for nRF5x lowPower modes 8 | 9 | @section HISTORY 10 | 11 | v0.1.0 - First Release 12 | v0.1.1 - updated comments 13 | */ 14 | /**************************************************************************/ 15 | 16 | #include 17 | #include 18 | 19 | #include "Arduino_nRF5x_lowPower.h" 20 | 21 | /**************************************************************************/ 22 | /*! 23 | @brief Sends nRF5x to desired powermode 24 | */ 25 | /**************************************************************************/ 26 | void Arduino_nRF5x_lowPower::powerMode(nRF5x_powermodes_t mode) { 27 | switch(mode) { 28 | case POWER_MODE_OFF: 29 | powerOff(); 30 | break; 31 | case POWER_MODE_LOW_POWER: 32 | lowPower(); 33 | break; 34 | case POWER_MODE_CONSTANT_LATENCY: 35 | constLat(); 36 | break; 37 | } 38 | } 39 | 40 | /**************************************************************************/ 41 | /*! 42 | @brief enables the builtin DCDC Converter 43 | */ 44 | /**************************************************************************/ 45 | void Arduino_nRF5x_lowPower::enableDCDC() { 46 | // NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ 47 | if (checkForSoftDevice() == 1) { 48 | sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); 49 | } else { 50 | NRF_POWER->DCDCEN = 1; 51 | } 52 | } 53 | 54 | /**************************************************************************/ 55 | /*! 56 | @brief disables the builtin DCDC Converter 57 | */ 58 | /**************************************************************************/ 59 | void Arduino_nRF5x_lowPower::disableDCDC() { 60 | // NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ 61 | if (checkForSoftDevice() == 1) { 62 | sd_power_dcdc_mode_set(NRF_POWER_DCDC_DISABLE); 63 | } else { 64 | NRF_POWER->DCDCEN = 0; 65 | } 66 | } 67 | 68 | /**************************************************************************/ 69 | /*! 70 | @brief enable Sense mode on selected pin, so it can wake the nRF5x from power off 71 | */ 72 | /**************************************************************************/ 73 | void Arduino_nRF5x_lowPower::enableWakeupByInterrupt(uint32_t pin, uint32_t mode) { 74 | NRF_GPIO->PIN_CNF[pin] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Msk); 75 | switch (mode) { 76 | case HIGH: 77 | case RISING: 78 | NRF_GPIO->PIN_CNF[pin] |= ((uint32_t)GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos); 79 | break; 80 | case LOW: 81 | case FALLING: 82 | NRF_GPIO->PIN_CNF[pin] |= ((uint32_t)GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos); 83 | break; 84 | default: 85 | return; 86 | } 87 | } 88 | 89 | /**************************************************************************/ 90 | /*! 91 | @brief disable Sense mode on selected pin 92 | */ 93 | /**************************************************************************/ 94 | void Arduino_nRF5x_lowPower::disableWakeupByInterrupt(uint32_t pin) { 95 | NRF_GPIO->PIN_CNF[pin] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Msk); 96 | NRF_GPIO->PIN_CNF[pin] |= ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); 97 | } 98 | 99 | /**************************************************************************/ 100 | /*! 101 | @brief Sends nRF5x to power off mode 102 | */ 103 | /**************************************************************************/ 104 | void Arduino_nRF5x_lowPower::powerOff(void) { 105 | if (checkForSoftDevice() == 1) { 106 | // SoftDevice enabled 107 | sd_power_system_off(); 108 | } else { 109 | // No SoftDevice 110 | NRF_POWER->SYSTEMOFF = 1; 111 | } 112 | } 113 | 114 | /**************************************************************************/ 115 | /*! 116 | @brief Sends nRF5x to constant latency mode 117 | */ 118 | /**************************************************************************/ 119 | void Arduino_nRF5x_lowPower::constLat(void) { 120 | //NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ 121 | if (checkForSoftDevice() == 1) { 122 | // SoftDevice enabled 123 | sd_power_mode_set(NRF_POWER_MODE_CONSTLAT); 124 | } else { 125 | // No SoftDevice 126 | NRF_POWER->TASKS_CONSTLAT = 1; 127 | } 128 | } 129 | 130 | /**************************************************************************/ 131 | /*! 132 | @brief Sends nRF5x to low power mode 133 | */ 134 | /**************************************************************************/ 135 | void Arduino_nRF5x_lowPower::lowPower(void) { 136 | //NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ 137 | if (checkForSoftDevice() == 1) { 138 | // SoftDevice enabled 139 | sd_power_mode_set(NRF_POWER_MODE_LOWPWR); 140 | } else { 141 | // No SoftDevice 142 | NRF_POWER->TASKS_LOWPWR = 1; 143 | } 144 | } 145 | 146 | /**************************************************************************/ 147 | /*! 148 | @brief Checks if a softdevice is present 149 | @return 1=softdevice, 0=no softdevice 150 | */ 151 | /**************************************************************************/ 152 | uint8_t Arduino_nRF5x_lowPower::checkForSoftDevice(void) { 153 | uint8_t check; 154 | sd_softdevice_is_enabled(&check); 155 | 156 | return check; 157 | } 158 | 159 | Arduino_nRF5x_lowPower nRF5x_lowPower; --------------------------------------------------------------------------------