mirror of
https://github.com/pelgraine/Meck.git
synced 2026-07-06 17:51:18 +02:00
95c992d966
UITask shutdown (already occurs/unchanged): 1. BLE disabled (_serial->disable()). 2. WiFi disconnected + WIFI_OFF. 3. 4G modem shutdown(). 4. GPS power cut (PIN_GPS_EN LOW). 5. LoRa radio powerOff() (standby mode). 6. Display turnOff(). TDeckBoard::powerOff() (new): 7. btStop() -- BLE controller stop. 8. Peripheral power OFF (PIN_PERF_POWERON LOW) -- keyboard, BQ27220, sensors. 9. LoRa module power OFF (P_LORA_EN LOW) -- cuts power entirely. 10. Hold LoRa NSS high (prevents SX1262 drawing current from floating CS). 11. esp_deep_sleep_start() -- CPU halts, ~10-40uA. Wake (reset button or USB power-on): 12. ESP32-S3 cold boots. 13. TDeckBoard::begin() runs: peripheral power ON, I2C init, LoRa power ON, NSS hold released. 14. App starts fresh -- prefs/contacts/messages load from flash. No LoRa wake during hibernate -- the device is truly off. Only a hardware reset (reset button) or USB power-on wakes the device.
113 lines
4.0 KiB
C++
113 lines
4.0 KiB
C++
#pragma once
|
|
|
|
#include "variant.h" // Board-specific pin definitions
|
|
#include <Wire.h>
|
|
#include <Arduino.h>
|
|
#include "helpers/ESP32Board.h"
|
|
#include <driver/rtc_io.h>
|
|
|
|
// BQ27220 Fuel Gauge Registers
|
|
#define BQ27220_REG_TEMPERATURE 0x06 // Temperature (0.1°K)
|
|
#define BQ27220_REG_VOLTAGE 0x08
|
|
#define BQ27220_REG_CURRENT 0x0C // Instantaneous current (mA, signed)
|
|
#define BQ27220_REG_SOC 0x2C
|
|
#define BQ27220_REG_REMAIN_CAP 0x10 // Remaining capacity (mAh)
|
|
#define BQ27220_REG_FULL_CAP 0x12 // Full charge capacity (mAh)
|
|
#define BQ27220_REG_AVG_CURRENT 0x14 // Average current (mA, signed)
|
|
#define BQ27220_REG_TIME_TO_EMPTY 0x16 // Minutes until empty
|
|
#define BQ27220_REG_AVG_POWER 0x24 // Average power (mW, signed)
|
|
#define BQ27220_REG_DESIGN_CAP 0x3C // Design capacity (mAh, read-only standard cmd)
|
|
#define BQ27220_REG_OP_STATUS 0x3A // Operation status
|
|
#define BQ27220_I2C_ADDR 0x55
|
|
|
|
// T-Deck Pro battery capacity (all variants use 1400 mAh cell)
|
|
#ifndef BQ27220_DESIGN_CAPACITY_MAH
|
|
#define BQ27220_DESIGN_CAPACITY_MAH 1400
|
|
#endif
|
|
|
|
class TDeckBoard : public ESP32Board {
|
|
public:
|
|
void begin();
|
|
|
|
void powerOff() override {
|
|
// True hibernate: deep sleep with no software wake sources.
|
|
// Only a hardware reset (reset button) or USB power-on wakes the device.
|
|
// BLE, WiFi, 4G, GPS, and LoRa are already shut down by UITask
|
|
// before this method is called.
|
|
|
|
btStop(); // Belt and suspenders -- BLE controller stop
|
|
|
|
// Cut power to peripherals (keyboard, BQ27220, sensors)
|
|
pinMode(PIN_PERF_POWERON, OUTPUT);
|
|
digitalWrite(PIN_PERF_POWERON, LOW);
|
|
|
|
// Cut power to LoRa module (radio already in standby from radio_driver.powerOff)
|
|
#ifdef P_LORA_EN
|
|
digitalWrite(P_LORA_EN, LOW);
|
|
#endif
|
|
|
|
// Hold LoRa NSS high to prevent SX1262 drawing current from floating CS
|
|
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
|
|
|
// Enter deep sleep with no wake sources -- only hardware reset wakes
|
|
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
|
|
esp_deep_sleep_start();
|
|
}
|
|
|
|
void enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
|
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
|
|
|
// Make sure the DIO1 and NSS GPIOs are held at required levels during deep sleep
|
|
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
|
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
|
|
|
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
|
|
|
if (pin_wake_btn < 0) {
|
|
esp_sleep_enable_ext1_wakeup((1ULL << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH);
|
|
} else {
|
|
esp_sleep_enable_ext1_wakeup((1ULL << P_LORA_DIO_1) | (1ULL << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH);
|
|
}
|
|
|
|
if (secs > 0) {
|
|
esp_sleep_enable_timer_wakeup(secs * 1000000ULL);
|
|
}
|
|
|
|
// Finally set ESP32 into sleep
|
|
esp_deep_sleep_start(); // CPU halts here and never returns!
|
|
}
|
|
|
|
// Read battery voltage from BQ27220 fuel gauge via I2C
|
|
uint16_t getBattMilliVolts() override;
|
|
|
|
// Read state of charge percentage from BQ27220
|
|
uint8_t getBatteryPercent();
|
|
|
|
// Read average current in mA (negative = discharging, positive = charging)
|
|
int16_t getAvgCurrent();
|
|
|
|
// Read average power in mW (negative = discharging, positive = charging)
|
|
int16_t getAvgPower();
|
|
|
|
// Read time-to-empty in minutes (0xFFFF if charging/unavailable)
|
|
uint16_t getTimeToEmpty();
|
|
|
|
// Read remaining capacity in mAh
|
|
uint16_t getRemainingCapacity();
|
|
|
|
// Read full charge capacity in mAh (learned value, may need cycling to update)
|
|
uint16_t getFullChargeCapacity();
|
|
|
|
// Read design capacity in mAh (the configured battery size)
|
|
uint16_t getDesignCapacity();
|
|
|
|
// Read battery temperature in 0.1°C units (e.g., 256 = 25.6°C)
|
|
int16_t getBattTemperature();
|
|
|
|
// Configure BQ27220 design capacity (checks on boot, writes only if wrong)
|
|
bool configureFuelGauge(uint16_t designCapacity_mAh = BQ27220_DESIGN_CAPACITY_MAH);
|
|
|
|
const char* getManufacturerName() const {
|
|
return "LilyGo T-Deck Pro";
|
|
}
|
|
}; |