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

This commit is contained in:
Specter242 2026-02-27 22:12:12 -05:00
parent eeae32b25d
commit e323755990
6 changed files with 89 additions and 7 deletions

View file

@ -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 |

View file

@ -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

View file

@ -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
}
}

View file

@ -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
}
};

View file

@ -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

View file

@ -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