feat(firmware): runtime PHY lock + drop post-TX self-RX on announces

- "LOCK:<T|C|R>" serial command pins the radio to one PHY for debugging /
  focused RX testing; "LOCK:" resumes the normal RTC scan
- clear rxFlag after a Reticulum announce TX so the TX-done interrupt no longer
  makes the bridge log a phantom "reception" of its own packet

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian 2026-07-01 20:32:39 +01:00
parent a62d989c9e
commit bf31f84676

View File

@ -105,6 +105,7 @@ static int activeIdx = 0;
static uint32_t totalPkts = 0;
static uint32_t dwellStart = 0;
static uint32_t frame = 0;
static char lockNet = 0; // if T/C/R, pin the radio to that PHY (debug/test)
// Outbound message queued from the serial console ("T:hello", or bare "hello"
// == all nets). Flushed on the matching PHY window so the radio is tuned right.
@ -512,6 +513,7 @@ static void sendReticulumAnnounce() {
for (size_t i = 0; i < p; i++) Serial.printf("%02x", pkt[i]); // for RNS cross-validation
Serial.println();
radio.startReceive();
rxFlag = false; // discard the TX-done interrupt so we don't self-RX our packet
}
// Known Reticulum destinations we've heard announces from.
@ -1022,6 +1024,17 @@ static void pollSerialTx() {
n = 0;
continue;
}
// "LOCK:R" pins the radio to one PHY for testing; "LOCK:" resumes scanning.
if (n >= 5 && strncmp(buf, "LOCK:", 5) == 0) {
char L = toupper(buf[5]);
if (L == 'T' || L == 'C' || L == 'R') {
for (size_t k = 0; k < NUM_CONFIGS; k++)
if (CONFIGS[k].letter == L) { activeIdx = (int)k; applyConfig(CONFIGS[k]); }
lockNet = L; dwellStart = millis();
Serial.printf(" [lock] pinned to %c\n", L);
} else { lockNet = 0; Serial.println(" [lock] released — scanning"); }
n = 0; continue;
}
if (n > 0) {
const char* msg = buf;
strcpy(txNets, "TCR"); // default: all networks
@ -1069,8 +1082,8 @@ void loop() {
pollSerialTx();
// Non-blocking scan: rotate the radio when the dwell window elapses, so the
// display keeps animating smoothly the whole time.
if (millis() - dwellStart >= DWELL_MS) {
// display keeps animating smoothly the whole time. Skipped while pinned.
if (!lockNet && millis() - dwellStart >= DWELL_MS) {
activeIdx = (activeIdx + 1) % NUM_CONFIGS;
applyConfig(CONFIGS[activeIdx]);
dwellStart = millis();