Speed Option 3 builds and harden radio IRQ handling
This commit is contained in:
1 parent
6460aaa53b
commit
07c968cb54
8 files changed
+432
-49
No files matched your search
@@ -530,7 +530,9 @@ bool NRF52Board::startOTAUpdate(const char *id, char reply[], bool force_ap) {
|
||||
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
|
||||
Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16);
|
||||
|
||||
Bluefruit.begin(1, 0);
|
||||
if (!Bluefruit.begin(1, 0)) {
|
||||
return false;
|
||||
}
|
||||
ota_ble_started = true;
|
||||
|
||||
// To be consistent OTA DFU should be added first if it exists
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
||||
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
|
||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
|
||||
|
||||
class CustomLLCC68 : public LLCC68 {
|
||||
uint32_t _preambleMillis = 66;
|
||||
uint32_t _maxPayloadMillis = 3934;
|
||||
uint32_t _activityAt = 0;
|
||||
bool _headerSeen = false;
|
||||
|
||||
public:
|
||||
CustomLLCC68(Module *mod) : LLCC68(mod) { }
|
||||
|
||||
@@ -78,10 +80,77 @@ class CustomLLCC68 : public LLCC68 {
|
||||
return true; // success
|
||||
}
|
||||
|
||||
int16_t startReceive() override {
|
||||
return LLCC68::startReceive(
|
||||
RADIOLIB_SX126X_RX_TIMEOUT_INF,
|
||||
RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1UL << RADIOLIB_IRQ_PREAMBLE_DETECTED),
|
||||
RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
|
||||
}
|
||||
|
||||
bool isReceiving() {
|
||||
uint16_t irq = getIrqFlags();
|
||||
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
return detected;
|
||||
uint32_t irq = getIrqFlags();
|
||||
bool preamble = irq & RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED;
|
||||
bool header = irq & RADIOLIB_SX126X_IRQ_HEADER_VALID;
|
||||
bool headerError = irq & RADIOLIB_SX126X_IRQ_HEADER_ERR;
|
||||
uint32_t now = millis();
|
||||
|
||||
if (headerError) {
|
||||
clearIrqFlags(RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_VALID |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_ERR |
|
||||
RADIOLIB_SX126X_IRQ_SYNC_WORD_VALID);
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (!header && _headerSeen) {
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (header) {
|
||||
if (!_headerSeen) {
|
||||
_headerSeen = true;
|
||||
_activityAt = now;
|
||||
}
|
||||
if (now - _activityAt > _maxPayloadMillis) {
|
||||
MESH_DEBUG_PRINTLN("Clearing header IRQ after %ums", _maxPayloadMillis);
|
||||
clearIrqFlags(RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_VALID |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_ERR |
|
||||
RADIOLIB_SX126X_IRQ_SYNC_WORD_VALID);
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (preamble) {
|
||||
if (_activityAt == 0) {
|
||||
_activityAt = now;
|
||||
}
|
||||
if (now - _activityAt > _preambleMillis) {
|
||||
clearIrqFlags(RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
_activityAt = 0;
|
||||
MESH_DEBUG_PRINTLN("Clearing preamble IRQ after %ums", _preambleMillis);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void setPreambleMillis(uint32_t preambleMillis) {
|
||||
_preambleMillis = preambleMillis;
|
||||
MESH_DEBUG_PRINTLN("Set _preambleMillis=%u", _preambleMillis);
|
||||
}
|
||||
|
||||
void setMaxPayloadMillis(uint32_t payloadMillis) {
|
||||
_maxPayloadMillis = payloadMillis;
|
||||
MESH_DEBUG_PRINTLN("Set _maxPayloadMillis=%u", _maxPayloadMillis);
|
||||
}
|
||||
|
||||
bool getRxBoostedGainMode() {
|
||||
@@ -89,4 +158,4 @@ class CustomLLCC68 : public LLCC68 {
|
||||
readRegister(RADIOLIB_SX126X_REG_RX_GAIN, &rxGain, 1);
|
||||
return (rxGain == RADIOLIB_SX126X_RX_GAIN_BOOSTED);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -10,11 +10,17 @@ public:
|
||||
|
||||
protected:
|
||||
bool applyParams(float freq, float bw, uint8_t sf, uint8_t cr) override {
|
||||
return ((CustomLLCC68 *)_radio)->setFrequency(freq) == RADIOLIB_ERR_NONE
|
||||
bool success = ((CustomLLCC68 *)_radio)->setFrequency(freq) == RADIOLIB_ERR_NONE
|
||||
&& ((CustomLLCC68 *)_radio)->setSpreadingFactor(sf) == RADIOLIB_ERR_NONE
|
||||
&& ((CustomLLCC68 *)_radio)->setBandwidth(bw) == RADIOLIB_ERR_NONE
|
||||
&& ((CustomLLCC68 *)_radio)->setCodingRate(cr) == RADIOLIB_ERR_NONE
|
||||
&& updatePreamble(sf);
|
||||
if (!success) return false;
|
||||
|
||||
PacketMillis pm = calcMaxPacketMillis(sf, bw, cr, preambleLengthForSF(sf));
|
||||
((CustomLLCC68 *)_radio)->setPreambleMillis(pm.preambleMillis);
|
||||
((CustomLLCC68 *)_radio)->setMaxPayloadMillis(pm.payloadMillis);
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -74,6 +74,15 @@ class CustomLR1110 : public LR1110 {
|
||||
|
||||
bool getRxBoostedGainMode() const { return _rx_boosted; }
|
||||
|
||||
int16_t startReceive() override {
|
||||
// Make preamble detection visible to CAD while retaining RadioLib's
|
||||
// normal RX-complete and error events.
|
||||
return LR1110::startReceive(
|
||||
RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED,
|
||||
RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1UL << RADIOLIB_IRQ_PREAMBLE_DETECTED),
|
||||
RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
|
||||
}
|
||||
|
||||
// BUSY high means the chip is asleep (RX duty-cycle sleep window) or mid
|
||||
// command; any SPI access would stall until the chip's next listen window.
|
||||
bool isChipBusy() {
|
||||
@@ -95,6 +104,12 @@ class CustomLR1110 : public LR1110 {
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (!header && _headerSeen) {
|
||||
// Another path consumed the header IRQ; reset only our local timer.
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (header) {
|
||||
if (!_headerSeen) { _headerSeen = true; _activityAt = now; };
|
||||
if (now - _activityAt > _maxPayloadMillis) {
|
||||
|
||||
@@ -140,6 +140,15 @@ class CustomSX1262 : public SX1262 {
|
||||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
int16_t startReceive() override {
|
||||
// Make preamble detection visible to CAD while retaining RadioLib's
|
||||
// normal RX-complete and error events.
|
||||
return SX1262::startReceive(
|
||||
RADIOLIB_SX126X_RX_TIMEOUT_INF,
|
||||
RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1UL << RADIOLIB_IRQ_PREAMBLE_DETECTED),
|
||||
RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
|
||||
}
|
||||
|
||||
bool isReceiving() {
|
||||
if (isChipBusy()) return false; // asleep, cannot be mid-receive
|
||||
|
||||
@@ -154,6 +163,12 @@ class CustomSX1262 : public SX1262 {
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (!header && _headerSeen) {
|
||||
// Another path consumed the header IRQ; reset only our local timer.
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (header) {
|
||||
if (!_headerSeen) { _headerSeen = true; _activityAt = now; };
|
||||
if (now - _activityAt > _maxPayloadMillis) {
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
||||
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
|
||||
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04
|
||||
|
||||
class CustomSX1268 : public SX1268 {
|
||||
uint32_t _preambleMillis = 66;
|
||||
uint32_t _maxPayloadMillis = 3934;
|
||||
uint32_t _activityAt = 0;
|
||||
bool _headerSeen = false;
|
||||
|
||||
public:
|
||||
CustomSX1268(Module *mod) : SX1268(mod) { }
|
||||
|
||||
@@ -78,10 +80,77 @@ class CustomSX1268 : public SX1268 {
|
||||
return true; // success
|
||||
}
|
||||
|
||||
int16_t startReceive() override {
|
||||
return SX1268::startReceive(
|
||||
RADIOLIB_SX126X_RX_TIMEOUT_INF,
|
||||
RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1UL << RADIOLIB_IRQ_PREAMBLE_DETECTED),
|
||||
RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
|
||||
}
|
||||
|
||||
bool isReceiving() {
|
||||
uint16_t irq = getIrqFlags();
|
||||
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
return detected;
|
||||
uint32_t irq = getIrqFlags();
|
||||
bool preamble = irq & RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED;
|
||||
bool header = irq & RADIOLIB_SX126X_IRQ_HEADER_VALID;
|
||||
bool headerError = irq & RADIOLIB_SX126X_IRQ_HEADER_ERR;
|
||||
uint32_t now = millis();
|
||||
|
||||
if (headerError) {
|
||||
clearIrqFlags(RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_VALID |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_ERR |
|
||||
RADIOLIB_SX126X_IRQ_SYNC_WORD_VALID);
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (!header && _headerSeen) {
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
if (header) {
|
||||
if (!_headerSeen) {
|
||||
_headerSeen = true;
|
||||
_activityAt = now;
|
||||
}
|
||||
if (now - _activityAt > _maxPayloadMillis) {
|
||||
MESH_DEBUG_PRINTLN("Clearing header IRQ after %ums", _maxPayloadMillis);
|
||||
clearIrqFlags(RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_VALID |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_ERR |
|
||||
RADIOLIB_SX126X_IRQ_SYNC_WORD_VALID);
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (preamble) {
|
||||
if (_activityAt == 0) {
|
||||
_activityAt = now;
|
||||
}
|
||||
if (now - _activityAt > _preambleMillis) {
|
||||
clearIrqFlags(RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
_activityAt = 0;
|
||||
MESH_DEBUG_PRINTLN("Clearing preamble IRQ after %ums", _preambleMillis);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_activityAt = 0;
|
||||
_headerSeen = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void setPreambleMillis(uint32_t preambleMillis) {
|
||||
_preambleMillis = preambleMillis;
|
||||
MESH_DEBUG_PRINTLN("Set _preambleMillis=%u", _preambleMillis);
|
||||
}
|
||||
|
||||
void setMaxPayloadMillis(uint32_t payloadMillis) {
|
||||
_maxPayloadMillis = payloadMillis;
|
||||
MESH_DEBUG_PRINTLN("Set _maxPayloadMillis=%u", _maxPayloadMillis);
|
||||
}
|
||||
|
||||
bool getRxBoostedGainMode() {
|
||||
@@ -89,4 +158,4 @@ class CustomSX1268 : public SX1268 {
|
||||
readRegister(RADIOLIB_SX126X_REG_RX_GAIN, &rxGain, 1);
|
||||
return (rxGain == RADIOLIB_SX126X_RX_GAIN_BOOSTED);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -14,11 +14,17 @@ public:
|
||||
|
||||
protected:
|
||||
bool applyParams(float freq, float bw, uint8_t sf, uint8_t cr) override {
|
||||
return ((CustomSX1268 *)_radio)->setFrequency(freq) == RADIOLIB_ERR_NONE
|
||||
bool success = ((CustomSX1268 *)_radio)->setFrequency(freq) == RADIOLIB_ERR_NONE
|
||||
&& ((CustomSX1268 *)_radio)->setSpreadingFactor(sf) == RADIOLIB_ERR_NONE
|
||||
&& ((CustomSX1268 *)_radio)->setBandwidth(bw) == RADIOLIB_ERR_NONE
|
||||
&& ((CustomSX1268 *)_radio)->setCodingRate(cr) == RADIOLIB_ERR_NONE
|
||||
&& updatePreamble(sf);
|
||||
if (!success) return false;
|
||||
|
||||
PacketMillis pm = calcMaxPacketMillis(sf, bw, cr, preambleLengthForSF(sf));
|
||||
((CustomSX1268 *)_radio)->setPreambleMillis(pm.preambleMillis);
|
||||
((CustomSX1268 *)_radio)->setMaxPayloadMillis(pm.payloadMillis);
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Reference in new issue
Block a user