diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.cpp b/variants/wio-tracker-l1/WioTrackerL1Board.cpp index 4153714e9..ac07c6e93 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.cpp +++ b/variants/wio-tracker-l1/WioTrackerL1Board.cpp @@ -3,11 +3,46 @@ #include "WioTrackerL1Board.h" +#ifdef NRF52_POWER_MANAGEMENT +// Static configuration for power management +// Values set in variant.h defines +const PowerMgtConfig power_config = { + .lpcomp_ain_channel = PWRMGT_LPCOMP_AIN, + .lpcomp_refsel = PWRMGT_LPCOMP_REFSEL, + .voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK +}; + +void WioTrackerL1Board::initiateShutdown(uint8_t reason) { + bool enable_lpcomp = (reason == SHUTDOWN_REASON_LOW_VOLTAGE || + reason == SHUTDOWN_REASON_BOOT_PROTECT); + + pinMode(VBAT_ENABLE, OUTPUT); + digitalWrite(VBAT_ENABLE, enable_lpcomp ? LOW : HIGH); + + if (enable_lpcomp) { + configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel); + } + + enterSystemOff(reason); +} +#endif // NRF52_POWER_MANAGEMENT + void WioTrackerL1Board::begin() { NRF52BoardDCDC::begin(); btn_prev_state = HIGH; - pinMode(PIN_VBAT_READ, INPUT); // VBAT ADC input + // Configure battery voltage ADC (needed for boot voltage check) + pinMode(PIN_VBAT_READ, INPUT); + pinMode(VBAT_ENABLE, OUTPUT); + digitalWrite(VBAT_ENABLE, HIGH); // Disable VBAT divider to save power + analogReadResolution(12); + analogReference(AR_INTERNAL); + +#ifdef NRF52_POWER_MANAGEMENT + // Boot voltage protection check (may not return if voltage too low) + checkBootVoltage(&power_config); +#endif + // Set all button pins to INPUT_PULLUP pinMode(PIN_BUTTON1, INPUT_PULLUP); pinMode(PIN_BUTTON2, INPUT_PULLUP); @@ -15,7 +50,6 @@ void WioTrackerL1Board::begin() { pinMode(PIN_BUTTON4, INPUT_PULLUP); pinMode(PIN_BUTTON5, INPUT_PULLUP); pinMode(PIN_BUTTON6, INPUT_PULLUP); - #if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL) Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL); @@ -30,3 +64,18 @@ void WioTrackerL1Board::begin() { delay(10); // give sx1262 some time to power up } + +uint16_t WioTrackerL1Board::getBattMilliVolts() { + digitalWrite(VBAT_ENABLE, LOW); // Enable VBAT divider + delayMicroseconds(100); // Allow voltage divider to settle + + // Average multiple samples to reduce noise + uint32_t raw = 0; + for (int i = 0; i < 8; i++) { + raw += analogRead(PIN_VBAT_READ); + } + raw = raw / 8; + + digitalWrite(VBAT_ENABLE, HIGH); // Disable divider to save power + return (raw * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096; +} diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.h b/variants/wio-tracker-l1/WioTrackerL1Board.h index 052238e66..e27483280 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.h +++ b/variants/wio-tracker-l1/WioTrackerL1Board.h @@ -8,6 +8,10 @@ class WioTrackerL1Board : public NRF52BoardDCDC { protected: uint8_t btn_prev_state; +#ifdef NRF52_POWER_MANAGEMENT + void initiateShutdown(uint8_t reason) override; +#endif + public: WioTrackerL1Board() : NRF52Board("WioTrackerL1 OTA") {} void begin(); @@ -21,14 +25,7 @@ class WioTrackerL1Board : public NRF52BoardDCDC { } #endif - uint16_t getBattMilliVolts() override { - int adcvalue = 0; - analogReadResolution(12); - analogReference(AR_INTERNAL); - delay(10); - adcvalue = analogRead(PIN_VBAT_READ); - return (adcvalue * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096; - } + uint16_t getBattMilliVolts() override; const char* getManufacturerName() const override { return "Seeed Wio Tracker L1"; diff --git a/variants/wio-tracker-l1/platformio.ini b/variants/wio-tracker-l1/platformio.ini index 75651d695..28cf98ddb 100644 --- a/variants/wio-tracker-l1/platformio.ini +++ b/variants/wio-tracker-l1/platformio.ini @@ -8,6 +8,7 @@ build_flags = ${nrf52_base.build_flags} -I lib/nrf52/s140_nrf52_7.3.0_API/include/nrf52 -I variants/wio-tracker-l1 -D WIO_TRACKER_L1 + -D NRF52_POWER_MANAGEMENT -D RADIO_CLASS=CustomSX1262 -D WRAPPER_CLASS=CustomSX1262Wrapper -D LORA_TX_POWER=22 diff --git a/variants/wio-tracker-l1/variant.h b/variants/wio-tracker-l1/variant.h index 86ad62baa..ffc0e84d9 100644 --- a/variants/wio-tracker-l1/variant.h +++ b/variants/wio-tracker-l1/variant.h @@ -50,6 +50,15 @@ #define ADC_MULTIPLIER (2.0F) #define ADC_RESOLUTION (12) +// Power management boot protection threshold (millivolts) +// Set to 0 to disable boot protection +#define PWRMGT_VOLTAGE_BOOTLOCK 3300 // Won't boot below this voltage + +// LPCOMP wake configuration (voltage recovery from SYSTEMOFF) +#define PWRMGT_LPCOMP_AIN 7 // AIN7 = P0.31 = PIN_VBAT_READ +// Wake when battery voltage recovers to ~3.7V +#define PWRMGT_LPCOMP_REFSEL 12 // 9/16 VDD + // Serial interfaces #define PIN_SERIAL1_RX (7) #define PIN_SERIAL1_TX (6)