Explorar o código

sensecap solar: add poweroff command and board power/LED parity

Specter242 hai 5 meses
pai
achega
e323755990

+ 1 - 1
docs/nrf52_power_management.md

@@ -42,7 +42,7 @@ Shutdown reason codes (stored in GPREGRET2):
 | RAK WisMesh Tag | No | No | No |
 | Heltec Mesh Solar | No | No | No |
 | LilyGo T-Echo / T-Echo Lite | No | No | No |
-| SenseCAP Solar | No | No | No |
+| SenseCAP Solar | Yes | Yes | Yes |
 | WIO Tracker L1 / L1 E-Ink | No | No | No |
 | WIO WM1110 | No | No | No |
 | Mesh Pocket | No | No | No |

+ 3 - 1
src/helpers/CommonCLI.cpp

@@ -194,7 +194,9 @@ uint8_t CommonCLI::buildAdvertData(uint8_t node_type, uint8_t* app_data) {
 }
 
 void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, char* reply) {
-    if (memcmp(command, "reboot", 6) == 0) {
+    if (memcmp(command, "poweroff", 8) == 0 || memcmp(command, "shutdown", 8) == 0) {
+      _board->powerOff();  // doesn't return
+    } else if (memcmp(command, "reboot", 6) == 0) {
       _board->reboot();  // doesn't return
     } else if (memcmp(command, "clkreboot", 9) == 0) {
       // Reset clock

+ 50 - 2
variants/sensecap_solar/SenseCapSolarBoard.cpp

@@ -3,8 +3,43 @@
 
 #include "SenseCapSolarBoard.h"
 
+#ifdef NRF52_POWER_MANAGEMENT
+const PowerMgtConfig power_config = {
+  .lpcomp_ain_channel = PWRMGT_LPCOMP_AIN,
+  .lpcomp_refsel = PWRMGT_LPCOMP_REFSEL,
+  .voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK
+};
+
+void SenseCapSolarBoard::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 SenseCapSolarBoard::begin() {
-  NRF52Board::begin();
+  NRF52BoardDCDC::begin();
+
+  pinMode(BATTERY_PIN, INPUT);
+  pinMode(VBAT_ENABLE, OUTPUT);
+  digitalWrite(VBAT_ENABLE, LOW);
+  analogReadResolution(12);
+  analogReference(AR_INTERNAL_3_0);
+  delay(50);
+
+#ifdef PIN_USER_BTN
+  pinMode(PIN_USER_BTN, INPUT_PULLUP);
+#elif defined(PIN_BUTTON1)
+  pinMode(PIN_BUTTON1, INPUT_PULLUP);
+#endif
 
 #if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL)
   Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL);
@@ -12,10 +47,23 @@ void SenseCapSolarBoard::begin() {
 
   Wire.begin();
 
+#ifdef LED_GREEN
+  pinMode(LED_GREEN, OUTPUT);
+  digitalWrite(LED_GREEN, HIGH);
+#endif
+#ifdef LED_BLUE
+  pinMode(LED_BLUE, OUTPUT);
+  digitalWrite(LED_BLUE, LOW);
+#endif
+
 #ifdef P_LORA_TX_LED
   pinMode(P_LORA_TX_LED, OUTPUT);
   digitalWrite(P_LORA_TX_LED, LOW);
 #endif
 
+#ifdef NRF52_POWER_MANAGEMENT
+  checkBootVoltage(&power_config);
+#endif
+
   delay(10);   // give sx1262 some time to power up
-}
+}

+ 24 - 0
variants/sensecap_solar/SenseCapSolarBoard.h

@@ -5,6 +5,11 @@
 #include <helpers/NRF52Board.h>
 
 class SenseCapSolarBoard : public NRF52BoardDCDC {
+protected:
+#ifdef NRF52_POWER_MANAGEMENT
+  void initiateShutdown(uint8_t reason) override;
+#endif
+
 public:
   SenseCapSolarBoard() : NRF52Board("SENSECAP_SOLAR_OTA") {}
   void begin();
@@ -31,4 +36,23 @@ public:
   const char* getManufacturerName() const override {
     return "Seeed SenseCap Solar";
   }
+
+  void powerOff() override {
+    digitalWrite(LED_GREEN, LOW);
+    digitalWrite(LED_BLUE, LOW);
+
+#ifdef PIN_USER_BTN
+    while (digitalRead(PIN_USER_BTN) == LOW);
+    nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_USER_BTN]), NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);
+#elif defined(PIN_BUTTON1)
+    while (digitalRead(PIN_BUTTON1) == LOW);
+    nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_BUTTON1]), NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);
+#endif
+
+#ifdef NRF52_POWER_MANAGEMENT
+    initiateShutdown(SHUTDOWN_REASON_USER);
+#else
+    sd_power_system_off();
+#endif
+  }
 };

+ 4 - 2
variants/sensecap_solar/platformio.ini

@@ -10,13 +10,15 @@ build_flags = ${nrf52_base.build_flags}
   -I src/helpers/nrf52
   -UENV_INCLUDE_GPS
   -D NRF52_PLATFORM=1
+  -D NRF52_POWER_MANAGEMENT
   -D RADIO_CLASS=CustomSX1262
   -D WRAPPER_CLASS=CustomSX1262Wrapper
-  -D P_LORA_TX_LED=12
+  -D P_LORA_TX_LED=11
   -D P_LORA_DIO_1=1
   -D P_LORA_RESET=2
   -D P_LORA_BUSY=3
   -D P_LORA_NSS=4
+  -D PIN_USER_BTN=PIN_BUTTON1
   -D LORA_TX_POWER=22
   -D SX126X_RXEN=5
   -D SX126X_TXEN=RADIOLIB_NC
@@ -96,4 +98,4 @@ build_src_filter = ${SenseCap_Solar.build_src_filter}
   +<../examples/companion_radio/*.cpp>
 lib_deps =
   ${SenseCap_Solar.lib_deps}
-  densaugeo/base64 @ ~1.4.0
+  densaugeo/base64 @ ~1.4.0

+ 7 - 1
variants/sensecap_solar/variant.h

@@ -32,6 +32,7 @@
 // Buttons
 #define PIN_BUTTON1             (13)
 #define PIN_BUTTON2             (20)
+#define PIN_USER_BTN            PIN_BUTTON1
 
 #define VBAT_ENABLE             (19)    // Output LOW to enable reading of the BAT voltage.
 
@@ -41,6 +42,11 @@
 #define ADC_MULTIPLIER          (3.0F) // 1M, 512k divider bridge
 #define ADC_RESOLUTION          (12)
 
+// nRF52 power management settings
+#define PWRMGT_VOLTAGE_BOOTLOCK (3300) // Won't boot below this voltage (mV)
+#define PWRMGT_LPCOMP_AIN       (7)    // AIN7 = P0.31 = BATTERY_PIN
+#define PWRMGT_LPCOMP_REFSEL    (2)    // 3/8 VDD (~3.38-3.71V)
+
 // Serial interfaces
 #define PIN_SERIAL1_RX          (7)
 #define PIN_SERIAL1_TX          (6)
@@ -82,4 +88,4 @@
 #define EXTERNAL_FLASH_DEVICES P25Q16H
 #define EXTERNAL_FLASH_USE_QSPI
 
-#endif
+#endif