Browse Source

Power off ThinkNode M3: wake on button, cut peripheral rails

The long press already reached board.powerOff(), but nothing armed a wake
source, so the board stayed dead until a reset or a USB reconnect. Arm the
user button (pull-up + SENSE_LOW) before entering SYSTEMOFF, after waiting
for the release: SENSE is level triggered and a still pressed button wakes
the board up immediately. If the button is never released, reboot instead:
SYSTEMOFF would wake up right away anyway, so make the reset explicit.

GPIO output latches survive SYSTEMOFF, so shut the switched rails down as
well (GNSS, RGB led supply, EEPROM, battery divider, EN1/EN2, PWR_EN), in a
shutdownPeripherals() override so they go down after the radio and the GNSS
receiver. Give pins 36 and 34 a name while there.

Tested on a ThinkNode M3 companion_radio_ble: a long press powers the board
off (the USB device disappears and stays away), a short press brings it
back, and holding the button past the timeout reboots.
pull/3068/head
Ermanno Baschiera 2 days ago
parent
commit
adb93565e0
  1. 36
      variants/thinknode_m3/ThinkNodeM3Board.cpp
  2. 11
      variants/thinknode_m3/ThinkNodeM3Board.h
  3. 8
      variants/thinknode_m3/variant.cpp
  4. 2
      variants/thinknode_m3/variant.h

36
variants/thinknode_m3/ThinkNodeM3Board.cpp

@ -13,6 +13,42 @@ void ThinkNodeM3Board::begin() {
delay(10); // give sx1262 some time to power up
}
void ThinkNodeM3Board::shutdownPeripherals() {
NRF52Board::shutdownPeripherals(); // display, LoRa radio and GNSS receiver
// GPIO output latches survive SYSTEMOFF, so every switched rail still enabled
// here keeps draining the battery while the board looks powered off
digitalWrite(PIN_GPS_POWER, !GPS_POWER_ACTIVE);
digitalWrite(LED_POWER, LOW); // RGB led supply
digitalWrite(EEPROM_POWER, LOW);
digitalWrite(BAT_POWER, LOW); // battery voltage divider
digitalWrite(PIN_EN1, LOW);
digitalWrite(PIN_EN2, LOW);
digitalWrite(PIN_PWR_EN, LOW);
}
void ThinkNodeM3Board::powerOff() {
// turn off all leds, sd_power_system_off will not do this for us
digitalWrite(PIN_LED_BLUE, !LED_STATE_ON);
digitalWrite(PIN_LED_GREEN, !LED_STATE_ON);
digitalWrite(PIN_LED_RED, !LED_STATE_ON);
// the button is what powers the board back on, and SENSE is level triggered:
// wait for the release, or the board wakes up as soon as it goes SYSTEMOFF
uint32_t started_at = millis();
while (digitalRead(BUTTON_PIN) == LOW) {
if (millis() - started_at > 10000) { // button held down for too long, or stuck:
reboot(); // SYSTEMOFF would wake up right away anyway
}
delay(10);
}
delay(50); // debounce the release
nrf_gpio_cfg_sense_input(g_ADigitalPinMap[BUTTON_PIN], NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
// power off board
NRF52Board::powerOff();
}
uint16_t ThinkNodeM3Board::getBattMilliVolts() {
int adcvalue = 0;

11
variants/thinknode_m3/ThinkNodeM3Board.h

@ -42,13 +42,6 @@ public:
return 0;
}
void powerOff() override {
// turn off all leds, sd_power_system_off will not do this for us
digitalWrite(PIN_LED_BLUE, !LED_STATE_ON);
digitalWrite(PIN_LED_GREEN, !LED_STATE_ON);
digitalWrite(PIN_LED_RED, !LED_STATE_ON);
// power off board
NRF52Board::powerOff();
}
void shutdownPeripherals() override;
void powerOff() override;
};

8
variants/thinknode_m3/variant.cpp

@ -71,10 +71,10 @@ void initVariant()
pinMode(EEPROM_POWER, OUTPUT);
digitalWrite(EEPROM_POWER, HIGH);
pinMode(36, OUTPUT);
digitalWrite(36, HIGH);
pinMode(34, OUTPUT);
digitalWrite(34, HIGH);
pinMode(PIN_EN1, OUTPUT);
digitalWrite(PIN_EN1, HIGH);
pinMode(PIN_EN2, OUTPUT);
digitalWrite(PIN_EN2, HIGH);
pinMode(LED_POWER, OUTPUT);
digitalWrite(LED_POWER, HIGH);

2
variants/thinknode_m3/variant.h

@ -42,6 +42,8 @@
#define EEPROM_POWER (7)
#define BAT_POWER (17)
#define PIN_PWR_EN (16)
#define PIN_EN1 (36) // P1.4, buzzer supply
#define PIN_EN2 (34) // P1.2
////////////////////////////////////////////////////////////////////////////////

Loading…
Cancel
Save