Recover SX1262 from stuck transmit busy
This commit is contained in:
1 parent
9051955c6c
commit
e6c878a011
2 files changed
+39
-1
No files matched your search
@@ -6,6 +6,10 @@
|
||||
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
|
||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
|
||||
|
||||
#ifndef SX126X_TX_BUSY_TIMEOUT_MS
|
||||
#define SX126X_TX_BUSY_TIMEOUT_MS 1000UL
|
||||
#endif
|
||||
|
||||
class CustomSX1262 : public SX1262 {
|
||||
public:
|
||||
CustomSX1262(Module *mod) : SX1262(mod) { }
|
||||
@@ -105,6 +109,35 @@ class CustomSX1262 : public SX1262 {
|
||||
return busy != RADIOLIB_NC && this->mod->hal->digitalRead(busy);
|
||||
}
|
||||
|
||||
// RadioLib waits without a deadline for BUSY to fall after SetTx. A radio
|
||||
// fault there blocks the entire main loop until the MCU watchdog reboots
|
||||
// the node. Keep the normal launch behavior, but return the same timeout
|
||||
// used by bounded RadioLib SPI waits so the wrapper can reset the radio.
|
||||
int16_t launchMode() override {
|
||||
if (this->stagedMode != RADIOLIB_RADIO_MODE_TX) {
|
||||
return SX1262::launchMode();
|
||||
}
|
||||
|
||||
this->mod->setRfSwitchState(this->txMode);
|
||||
int16_t state = this->setTx(RADIOLIB_SX126X_TX_TIMEOUT_NONE);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
this->stagedMode = RADIOLIB_RADIO_MODE_NONE;
|
||||
return state;
|
||||
}
|
||||
|
||||
const unsigned long started = millis();
|
||||
while (isChipBusy()) {
|
||||
yield();
|
||||
if (millis() - started >= SX126X_TX_BUSY_TIMEOUT_MS) {
|
||||
this->stagedMode = RADIOLIB_RADIO_MODE_NONE;
|
||||
return RADIOLIB_ERR_SPI_CMD_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
this->stagedMode = RADIOLIB_RADIO_MODE_NONE;
|
||||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
bool isReceiving() {
|
||||
if (isChipBusy()) return false; // asleep, cannot be mid-receive
|
||||
|
||||
@@ -136,4 +169,4 @@ class CustomSX1262 : public SX1262 {
|
||||
readRegister(RADIOLIB_SX126X_REG_RX_GAIN, &rxGain, 1);
|
||||
return (rxGain == RADIOLIB_SX126X_RX_GAIN_BOOSTED);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -595,6 +595,11 @@ bool RadioLibWrapper::startSendRaw(const uint8_t* bytes, int len) {
|
||||
MESH_DEBUG_PRINTLN("RadioLibWrapper: error: startTransmit(%d)", err);
|
||||
idle(); // trigger another startRecv()
|
||||
_board->onAfterTransmit();
|
||||
if (err == RADIOLIB_ERR_SPI_CMD_TIMEOUT) {
|
||||
// A stuck BUSY line cannot be repaired with another SPI command. Radios
|
||||
// with a reset pin recover immediately; others use their safest fallback.
|
||||
recoverRadio(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user