mirror of
https://github.com/meshtastic/firmware.git
synced 2026-10-31 04:19:58 -04:00
LoRa LBT: take out the preamble hold on a seen preamble
Revert be3bf1f38. receiveDetected() judges a preamble by its two-preamble
deadline again, and the SX126x IRQ poll clears a bare preamble directly.
hasQueuedTx() stays: periodicRadioMaintenance() still uses it.
This commit is contained in:
1 parent
08fb5c8437
commit
957fbd3f5b
3 files changed
+23
-51
No files matched your search
@@ -119,50 +119,31 @@ bool RadioLibInterface::canSendImmediately()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RadioLibInterface::preambleHoldActive()
|
||||
{
|
||||
// Whatever sent the cleared preamble is off the air one max packet later.
|
||||
if (preambleHoldStart && !Throttle::isWithinTimespanMs(
|
||||
preambleHoldStart, getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader))))
|
||||
preambleHoldStart = 0;
|
||||
return preambleHoldStart != 0;
|
||||
}
|
||||
|
||||
void RadioLibInterface::holdOnPreamble()
|
||||
{
|
||||
// During a hold a refire stays latched, so the first look after it sees an external source and holds again.
|
||||
if (preambleHoldActive())
|
||||
return;
|
||||
iface->clearIrq(1UL << RADIOLIB_IRQ_PREAMBLE_DETECTED);
|
||||
preambleHoldStart = Time::skipZero(Time::getMillis());
|
||||
LOG_TRACE("Preamble seen, cleared, holding TX");
|
||||
}
|
||||
|
||||
bool RadioLibInterface::receiveDetected(uint16_t irq, unsigned long syncWordHeaderValidFlag, unsigned long preambleDetectedFlag)
|
||||
{
|
||||
if (preambleHoldActive())
|
||||
return true;
|
||||
|
||||
if (irq & syncWordHeaderValidFlag) {
|
||||
bool detected = (irq & (syncWordHeaderValidFlag | preambleDetectedFlag));
|
||||
// Handle false detections
|
||||
if (detected) {
|
||||
if (!activeReceiveStart) {
|
||||
activeReceiveStart = Time::skipZero(Time::getMillis());
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart,
|
||||
getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader)))) {
|
||||
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_TRACE("Ignore false header detection");
|
||||
return false;
|
||||
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec)) {
|
||||
if (!(irq & syncWordHeaderValidFlag)) {
|
||||
// The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_TRACE("Ignore false preamble detection");
|
||||
return false;
|
||||
} else {
|
||||
uint32_t maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader));
|
||||
if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) {
|
||||
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
|
||||
activeReceiveStart = 0;
|
||||
LOG_TRACE("Ignore false header detection");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (irq & preambleDetectedFlag) {
|
||||
// Looks come once per CSMA backoff, too rarely to judge a preamble by symbol-time deadline (#11933).
|
||||
// Clear it so the next look sees only a fresh one, and hold TX meanwhile; a clear never aborts RX.
|
||||
holdOnPreamble();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return detected;
|
||||
}
|
||||
|
||||
/// Send a packet (possibly by enquing in a private fifo). This routine will
|
||||
@@ -646,7 +627,6 @@ void RadioLibInterface::handleReceiveInterrupt()
|
||||
// Condition?
|
||||
const bool wasCadHandoff = cadHandoffRxStart != 0;
|
||||
cadHandoffRxStart = 0; // this RX ends the wait either way; the outcome is logged below
|
||||
preambleHoldStart = 0; // likewise the reception a held preamble announced
|
||||
|
||||
if (!isReceiving) {
|
||||
LOG_ERROR("handleReceiveInterrupt called while not in rx mode");
|
||||
|
||||
@@ -353,14 +353,6 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
|
||||
protected:
|
||||
uint32_t activeReceiveStart = 0;
|
||||
// Time::getMillis() when a look cleared PREAMBLE_DETECTED and began holding TX, or 0 if no hold.
|
||||
uint32_t preambleHoldStart = 0;
|
||||
|
||||
/** True while a cleared preamble still holds TX; ends the hold once one max packet has passed. */
|
||||
bool preambleHoldActive();
|
||||
|
||||
/** Clear a bare PREAMBLE_DETECTED and hold TX one max packet, unless a hold is already running. */
|
||||
void holdOnPreamble();
|
||||
|
||||
/** Whether a packet is waiting to transmit; txQueue itself stays private. */
|
||||
bool hasQueuedTx() { return !txQueue.empty(); }
|
||||
|
||||
@@ -379,11 +379,11 @@ template <typename T> void SX126xInterface<T>::handleSoftwareLoraIrqPoll()
|
||||
RADIOLIB_SX126X_IRQ_RX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT | RADIOLIB_SX126X_IRQ_CRC_ERR | RADIOLIB_SX126X_IRQ_HEADER_ERR;
|
||||
const uint16_t noisyRxMask = RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED | RADIOLIB_SX126X_IRQ_HEADER_VALID;
|
||||
|
||||
// A bare PREAMBLE is mid-reception, not an RX event: readData() here would run on nothing. With a TX
|
||||
// queued it goes through the same hold as the TX-path look; HEADER_VALID stays latched for readData().
|
||||
// A bare PREAMBLE is mid-reception, not an RX event. With a TX queued clear only it, so a noise preamble
|
||||
// can't block TX; keep HEADER_VALID latched, as it marks a real frame.
|
||||
const bool preambleOnly = (irq & RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED) && !(irq & RADIOLIB_SX126X_IRQ_HEADER_VALID);
|
||||
if (!pollTxMode && hasQueuedTx() && preambleOnly && ((irq & ~noisyRxMask) == 0U)) {
|
||||
holdOnPreamble();
|
||||
if (!pollTxMode && !txQueue.empty() && preambleOnly && ((irq & ~noisyRxMask) == 0U)) {
|
||||
lora.clearIrqFlags(RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED);
|
||||
scheduleIrqPollTick();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user