A further deep sleep discovery. The NRF gpio pin config registers persist through deep sleep, this is so you can setup pin states the are retained whilst deep sleeping.
When you use a GPIO via the arduino core, e.g. pinMode(x, INPUT), the pin state is changed to input direction AND the pin is connected to the NRF GPO input buffer. This connection to the input buffer seems to draw ~6uA per pin. The default state of an NRF pin is DISCONNECTED but you cannot use the arduino pinMode() function to put the pin back into this state having previously used it as an input.
The solution is to do it yourself, you can either set the pin state back to default using:
nrf_gpio_cfg_default(g_ADigitalPinMap[ARDUINO_PIN_NUMBER]);
or I’ve written this convenience function that explicitly sets the correct pin config:
void disconnectPin(uint32_t ulPin) {
if (ulPin >= PINS_COUNT) {
return;
}
ulPin = g_ADigitalPinMap[ulPin];
NRF_GPIO_Type * port = nrf_gpio_pin_port_decode(&ulPin);
port->PIN_CNF[ulPin] =
((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
| ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
| ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
}
I haven’t done any testing of pins put into OUTPUT state but these will continue to draw whatever power they were drawing before deep sleep, I discovered the above issue/solution when attempting to disable pins (by setting them to INPUT) when not in use.
So my shutdown code now looks like this:
void sleepFlash() {
flashTransport.begin();
flashTransport.runCommand(0xB9);
flashTransport.end();
}
void disconnectPin(uint32_t ulPin) {
if (ulPin >= PINS_COUNT) {
return;
}
ulPin = g_ADigitalPinMap[ulPin];
NRF_GPIO_Type * port = nrf_gpio_pin_port_decode(&ulPin);
port->PIN_CNF[ulPin] =
((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
| ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
| ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
}
void shutdown() {
//sleep flash
sleepFlash();
//disconnect any pins used
disconnectPin(D1);
disconnectPin(D2);
//setup pin for wakeup
nrf_gpio_cfg_sense_input(g_ADigitalPinMap[D3], NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
//power off
sd_power_system_off();
}