mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-07-23 00:20:53 +00:00
Fixed RX power saving RSSI sampling during listen windows
This commit is contained in:
@@ -65,12 +65,15 @@ class CustomLR1110 : public LR1110 {
|
||||
|
||||
bool getRxBoostedGainMode() const { return _rx_boosted; }
|
||||
|
||||
bool isReceiving() {
|
||||
// BUSY high means the chip is asleep (RX duty-cycle sleep window) or mid
|
||||
// command, so it cannot be mid-receive - and the SPI read below would
|
||||
// stall until the chip's next listen window.
|
||||
// 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() {
|
||||
uint32_t busy = this->mod->getGpio();
|
||||
if (busy != RADIOLIB_NC && this->mod->hal->digitalRead(busy)) return false;
|
||||
return busy != RADIOLIB_NC && this->mod->hal->digitalRead(busy);
|
||||
}
|
||||
|
||||
bool isReceiving() {
|
||||
if (isChipBusy()) return false; // asleep, cannot be mid-receive
|
||||
|
||||
uint16_t irq = getIrqStatus();
|
||||
bool detected = ((irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID) || (irq & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED));
|
||||
|
||||
@@ -20,6 +20,9 @@ public:
|
||||
bool isReceivingPacket() override {
|
||||
return ((CustomLR1110 *)_radio)->isReceiving();
|
||||
}
|
||||
bool isChipBusy() override {
|
||||
return ((CustomLR1110 *)_radio)->isChipBusy();
|
||||
}
|
||||
float getCurrentRSSI() override {
|
||||
float rssi = -110;
|
||||
((CustomLR1110 *)_radio)->getRssiInst(&rssi);
|
||||
|
||||
@@ -86,12 +86,15 @@ class CustomSX1262 : public SX1262 {
|
||||
return true; // success
|
||||
}
|
||||
|
||||
bool isReceiving() {
|
||||
// BUSY high means the chip is asleep (RX duty-cycle sleep window) or mid
|
||||
// command, so it cannot be mid-receive - and the SPI read below would
|
||||
// stall until the chip's next listen window.
|
||||
// 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() {
|
||||
uint32_t busy = this->mod->getGpio();
|
||||
if (busy != RADIOLIB_NC && this->mod->hal->digitalRead(busy)) return false;
|
||||
return busy != RADIOLIB_NC && this->mod->hal->digitalRead(busy);
|
||||
}
|
||||
|
||||
bool isReceiving() {
|
||||
if (isChipBusy()) return false; // asleep, cannot be mid-receive
|
||||
|
||||
uint16_t irq = getIrqFlags();
|
||||
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
|
||||
@@ -20,9 +20,12 @@ public:
|
||||
updatePreamble(sf);
|
||||
}
|
||||
|
||||
bool isReceivingPacket() override {
|
||||
bool isReceivingPacket() override {
|
||||
return ((CustomSX1262 *)_radio)->isReceiving();
|
||||
}
|
||||
bool isChipBusy() override {
|
||||
return ((CustomSX1262 *)_radio)->isChipBusy();
|
||||
}
|
||||
float getCurrentRSSI() override {
|
||||
return ((CustomSX1262 *)_radio)->getRSSI(false);
|
||||
}
|
||||
|
||||
@@ -85,12 +85,11 @@ void RadioLibWrapper::resetAGC() {
|
||||
}
|
||||
|
||||
void RadioLibWrapper::loop() {
|
||||
// In RX duty-cycle (powersaving) mode the radio auto-sleeps between listen
|
||||
// windows, so getCurrentRSSI() would read a sleeping frontend and corrupt the
|
||||
// noise floor. Skip adaptive sampling; note this also degrades interference
|
||||
// detection (isChannelActive) while powersaving is enabled.
|
||||
if (!_rx_ps_enabled && state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) {
|
||||
if (!isReceivingPacket()) {
|
||||
if (state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) {
|
||||
// In RX duty-cycle (powersaving) mode only sample while the chip is in a
|
||||
// listen window: during the sleep window the frontend is off, so the RSSI
|
||||
// is meaningless and the SPI read would stall until the next window.
|
||||
if (!(_rx_ps_armed && isChipBusy()) && !isReceivingPacket()) {
|
||||
int rssi = getCurrentRSSI();
|
||||
if (rssi < _noise_floor + SAMPLING_THRESHOLD) { // only consider samples below current floor + sampling THRESHOLD
|
||||
_num_floor_samples++;
|
||||
@@ -231,10 +230,10 @@ int16_t RadioLibWrapper::performChannelScan() {
|
||||
|
||||
bool RadioLibWrapper::isChannelActive() {
|
||||
// int.thresh: RSSI-based interference detection (relative to noise floor).
|
||||
// Skipped in RX duty-cycle mode: the frontend sleeps part of the time, so an
|
||||
// instantaneous RSSI is meaningless and the SPI read would block until the
|
||||
// chip's next listen window.
|
||||
if (!_rx_ps_enabled && _threshold != 0 && getCurrentRSSI() > _noise_floor + _threshold) return true;
|
||||
// In RX duty-cycle mode only checked while the chip is in a listen window
|
||||
// (during the sleep window the frontend is off and the read would stall).
|
||||
if (_threshold != 0 && !(_rx_ps_armed && isChipBusy())
|
||||
&& getCurrentRSSI() > _noise_floor + _threshold) return true;
|
||||
|
||||
// cad: hardware channel activity detection
|
||||
if (_cad_enabled) {
|
||||
|
||||
@@ -30,6 +30,9 @@ protected:
|
||||
virtual int startReceiveMode();
|
||||
virtual void stopReceiveDutyCycle();
|
||||
virtual bool isPacketReady();
|
||||
// true while the chip cannot service SPI (RX duty-cycle sleep window, or
|
||||
// briefly while processing a command); radios expose this via the BUSY pin
|
||||
virtual bool isChipBusy() { return false; }
|
||||
float packetScoreInt(float snr, int sf, int packet_len);
|
||||
virtual bool isReceivingPacket() =0;
|
||||
virtual void doResetAGC();
|
||||
|
||||
Reference in New Issue
Block a user