Fix peripheral power shutdown and auto-detect Station G3 radio slots
This commit is contained in:
1 parent
c6e43c5530
commit
8eced48d34
103 files changed
+4900
-194
No files matched your search
@@ -4204,7 +4204,10 @@ void loop() {
|
||||
#endif
|
||||
}
|
||||
#if defined(ESP32_PLATFORM)
|
||||
else if (!morse_timing && the_mesh.getNodePrefs()->powersaving_enabled) {
|
||||
else if (!morse_timing && !the_mesh.isDualRadioActive()
|
||||
&& the_mesh.getNodePrefs()->powersaving_enabled) {
|
||||
// The scanner has a zero-delay polling contract and sub-ms RX visits.
|
||||
// Keep the idle yield for USB/logging/button holds, not live radio2.
|
||||
delay(1); // CPU idle remains available while USB/logging/button holds are active.
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "KissModem.h"
|
||||
#include <CayenneLPP.h>
|
||||
#if defined(STATION_G3_ESP32)
|
||||
#include "StationG3RadioSlot.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -467,6 +470,14 @@ void KissModem::handleHardwareCommand(uint8_t sub_cmd, const uint8_t* data, uint
|
||||
if (len != 0) writeHardwareError(HW_ERR_INVALID_LENGTH);
|
||||
else handleGetRadio2(true);
|
||||
break;
|
||||
#if defined(STATION_G3_ESP32)
|
||||
case HW_CMD_GET_RADIO_SLOT:
|
||||
handleGetRadioSlot(len);
|
||||
break;
|
||||
case HW_CMD_SET_RADIO_SLOT:
|
||||
handleSetRadioSlot(data, len);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MESH_HIL_TX_FREQ_MHZ)
|
||||
case HW_CMD_GET_LAB_TX_GUARD: {
|
||||
if (len != 0) {
|
||||
@@ -489,6 +500,48 @@ void KissModem::handleHardwareCommand(uint8_t sub_cmd, const uint8_t* data, uint
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(STATION_G3_ESP32)
|
||||
void KissModem::handleGetRadioSlot(uint16_t len) {
|
||||
if (len != 0) {
|
||||
writeHardwareError(HW_ERR_INVALID_LENGTH);
|
||||
return;
|
||||
}
|
||||
const auto& state = station_g3::slotState();
|
||||
const uint8_t status[KISS_RADIO_SLOT_STATUS_SIZE] = {
|
||||
state.savedMode, state.active, state.detected,
|
||||
static_cast<uint8_t>(state.savedMode != state.bootMode)};
|
||||
writeHardwareFrame(HW_RESP(HW_CMD_GET_RADIO_SLOT), status, sizeof(status));
|
||||
}
|
||||
|
||||
void KissModem::handleSetRadioSlot(const uint8_t* data, uint16_t len) {
|
||||
if (len != 1) {
|
||||
writeHardwareError(HW_ERR_INVALID_LENGTH);
|
||||
return;
|
||||
}
|
||||
if (data[0] > 2) {
|
||||
writeHardwareError(HW_ERR_INVALID_PARAM);
|
||||
return;
|
||||
}
|
||||
static const char* const commands[] = {
|
||||
"set radio.slot auto", "set radio.slot 1", "set radio.slot 2"};
|
||||
char reply[160] = {};
|
||||
if (!_board.handleCommand(commands[data[0]], 0, reply)) {
|
||||
writeHardwareError(HW_ERR_NO_CALLBACK);
|
||||
return;
|
||||
}
|
||||
// handleCommand's bool means "recognized", not "saved". The board is the
|
||||
// single checked-persistence owner; never acknowledge its error as success.
|
||||
if (strncmp(reply, "OK - ", 5) != 0
|
||||
|| station_g3::slotState().savedMode != data[0]) {
|
||||
writeHardwareError(HW_ERR_SAVE_FAILED);
|
||||
return;
|
||||
}
|
||||
// This changes only next-boot selection. No radio retune, probe, RF packet,
|
||||
// physical pin switch or reboot is performed by the KISS control command.
|
||||
writeHardwareFrame(HW_RESP_OK, nullptr, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void KissModem::expireTemporaryRadio2() {
|
||||
if (!_temporary_radio2_active
|
||||
|| (int32_t)(millis() - _temporary_radio2_end_ms) < 0) return;
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
#define HW_CMD_SET_RADIO2_EXT 0x1F
|
||||
#define HW_CMD_GET_RADIO2_EXT 0x20
|
||||
#define HW_CMD_GET_LAB_TX_GUARD 0x21
|
||||
#define HW_CMD_GET_RADIO_SLOT 0x22
|
||||
#define HW_CMD_SET_RADIO_SLOT 0x23
|
||||
|
||||
/* Response code = command code | 0x80. Generic / unsolicited use 0xF0+. */
|
||||
#define HW_RESP(cmd) ((cmd) | 0x80)
|
||||
@@ -91,12 +93,22 @@
|
||||
#define HW_ERR_UNKNOWN_CMD 0x05
|
||||
#define HW_ERR_ENCRYPT_FAILED 0x06
|
||||
#define HW_ERR_TX_BUSY 0x07
|
||||
#define HW_ERR_SAVE_FAILED 0x08
|
||||
|
||||
#define KISS_RADIO_PARAMS_SIZE 10
|
||||
#define KISS_RADIO2_PARAMS_SIZE 13
|
||||
#define KISS_RADIO2_EXT_PARAMS_SIZE 14
|
||||
#define KISS_TEMPRADIO2_PARAMS_SIZE 15
|
||||
#define KISS_MAX_TEMPRADIO2_MINUTES 10080
|
||||
#define KISS_RADIO_SLOT_STATUS_SIZE 4
|
||||
|
||||
/* Station G3 physical socket selection, not the logical radio2 PHY:
|
||||
* GET_RADIO_SLOT: no payload; response 0xA2 payload is
|
||||
* [saved (0=auto,1,2), active (0=none,1,2), detected (bit0=1,bit1=2),
|
||||
* reboot_required (saved mode differs from the mode used at boot)].
|
||||
* SET_RADIO_SLOT: exactly one byte (0=auto,1,2); persistent, reboot-only.
|
||||
* Success is generic OK, failure is framed ERROR (SAVE_FAILED for storage).
|
||||
* Unsupported boards return UNKNOWN_CMD for both additive commands. */
|
||||
|
||||
/* Version 2 adds the logical secondary-radio KISS port and radio2 commands.
|
||||
* Extended radio2 commands are additive; old firmware returns UnknownCmd. */
|
||||
@@ -224,6 +236,10 @@ class KissModem {
|
||||
void handleGetRadio2(bool extended = false);
|
||||
void handleSetTempRadio2(const uint8_t* data, uint16_t len);
|
||||
void handleGetTempRadio2();
|
||||
#if defined(STATION_G3_ESP32)
|
||||
void handleGetRadioSlot(uint16_t len);
|
||||
void handleSetRadioSlot(const uint8_t* data, uint16_t len);
|
||||
#endif
|
||||
void handleGetTxPower();
|
||||
void handleGetVersion();
|
||||
void handleGetCurrentRssi();
|
||||
|
||||
@@ -170,6 +170,13 @@ void setup() {
|
||||
// KISS owns the entire serial byte stream, including gaps between chunks.
|
||||
mesh::setUsbLoggingEnabled(false);
|
||||
mesh::setUsbDebugEnabled(false);
|
||||
#endif
|
||||
#if defined(STATION_G3_ESP32)
|
||||
// G3 can wait in no-radio recovery before modem construction. Bring up
|
||||
// USB now so its prefixed recovery console is reachable on an empty slot.
|
||||
mesh::prepareUsbLoggingPort();
|
||||
Serial.begin(115200);
|
||||
mesh::beginUsbLoggingPort();
|
||||
#endif
|
||||
KISS_BOOT_STAGE("board.before");
|
||||
board.begin();
|
||||
@@ -239,6 +246,7 @@ void setup() {
|
||||
#endif
|
||||
modem = new KissModem(Serial1, identity, rng, radio_driver, board, sensors);
|
||||
#else
|
||||
#if !defined(STATION_G3_ESP32)
|
||||
#if KISS_HWCDC_TRANSPORT
|
||||
// Allocate the USB queues before begin() enables the live driver ISR.
|
||||
mesh::prepareUsbLoggingPort();
|
||||
@@ -247,6 +255,7 @@ void setup() {
|
||||
#if KISS_HWCDC_TRANSPORT
|
||||
mesh::beginUsbLoggingPort();
|
||||
#endif
|
||||
#endif // G3 already started USB before radio discovery, including UART builds.
|
||||
uint32_t start = millis();
|
||||
while (!Serial && millis() - start < 3000) delay(10);
|
||||
delay(100);
|
||||
|
||||
@@ -624,7 +624,9 @@ void loop() {
|
||||
}
|
||||
|
||||
#if defined(ESP32_PLATFORM)
|
||||
if (!morse_timing && !can_power_save && the_mesh.getNodePrefs()->powersaving_enabled) {
|
||||
if (!morse_timing && !can_power_save && !the_mesh.isDualRadioActive()
|
||||
&& the_mesh.getNodePrefs()->powersaving_enabled) {
|
||||
// Live radio2 needs the scanner's zero-delay polling cadence.
|
||||
delay(1); // Idle without suspending USB or the button wake interval.
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -375,7 +375,9 @@ void loop() {
|
||||
#endif
|
||||
}
|
||||
#if defined(ESP32_PLATFORM)
|
||||
if (!morse_timing && !can_power_save && the_mesh.getNodePrefs()->powersaving_enabled) {
|
||||
if (!morse_timing && !can_power_save && !the_mesh.isDualRadioActive()
|
||||
&& the_mesh.getNodePrefs()->powersaving_enabled) {
|
||||
// Live radio2 needs the scanner's zero-delay polling cadence.
|
||||
delay(1); // Keep USB and the button wake interval serviced while idle.
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -375,8 +375,10 @@ void loop() {
|
||||
#endif
|
||||
}
|
||||
#if defined(ESP32_PLATFORM)
|
||||
if (!morse_timing && !can_power_save && (the_mesh.getNodePrefs()->powersaving_enabled
|
||||
if (!morse_timing && !can_power_save && !the_mesh.isDualRadioActive()
|
||||
&& (the_mesh.getNodePrefs()->powersaving_enabled
|
||||
|| the_mesh.isTrackerModeEnabled())) {
|
||||
// Live radio2 needs the scanner's zero-delay polling cadence.
|
||||
delay(1); // Keep USB and the button wake interval serviced while idle.
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in new issue
Block a user