Add getCodingRate() to CustomLR1110 and CustomLR1110Wrapper

LR1110 has codingRate as protected field in LR_common.h, so
getCodingRate() is implemented in CustomLR1110 class directly,
and exposed via CustomLR1110Wrapper override.

This enables dynamic MAX_TEXT_LEN calculation for T1000-E
under JP_STRICT mode.
This commit is contained in:
jirogit 2026-03-26 22:51:01 -07:00
parent d7045a1020
commit 73ec37657c
3 changed files with 24 additions and 30 deletions

View file

@ -36,4 +36,8 @@ class CustomLR1110 : public LR1110 {
bool detected = ((irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID) || (irq & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED)); bool detected = ((irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID) || (irq & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED));
return detected; return detected;
} }
uint8_t getCodingRate() const {
return this->codingRate + 4; // RadioLib stores 1-4, return 5-8
}
}; };

View file

@ -31,4 +31,8 @@ public:
bool getRxBoostedGainMode() const override { bool getRxBoostedGainMode() const override {
return ((CustomLR1110 *)_radio)->getRxBoostedGainMode(); return ((CustomLR1110 *)_radio)->getRxBoostedGainMode();
} }
uint8_t getCodingRate() const override {
return ((CustomLR1110 *)_radio)->getCodingRate();
}
}; };

View file

@ -184,53 +184,39 @@ bool RadioLibWrapper::isChannelActive() {
if (_threshold == 0) return false; // interference check is disabled if (_threshold == 0) return false; // interference check is disabled
#ifdef JP_STRICT #ifdef JP_STRICT
// 5ms continuous RSSI sensing // ARIB STD-T108 compliant LBT: continuous RSSI sensing for >= 5ms
// Energy-based sensing required; LoRa CAD not used here —
// CAD detects only LoRa preambles and is not required by ARIB STD-T108
uint32_t sense_start = millis(); uint32_t sense_start = millis();
while (millis() - sense_start < 5) { while (millis() - sense_start < 5) {
if (getCurrentRSSI() > -80.0f) { if (getCurrentRSSI() > -80.0f) {
// RSSI busy: backoff and return without CAD // Channel busy: exponential backoff (tuned for JP 4s airtime)
_busy_count++; _busy_count++;
uint32_t base_ms = 3000; uint32_t base_ms = 2000;
uint32_t max_backoff = min(base_ms * (1u << _busy_count), (uint32_t)20000); uint32_t max_backoff = min(base_ms * (1u << _busy_count), (uint32_t)16000);
uint32_t backoff_until = millis() + random(max_backoff / 2, max_backoff); uint32_t backoff_until = millis() + random(max_backoff / 2, max_backoff);
while (millis() < backoff_until) { while (millis() < backoff_until) {
vTaskDelay(1); vTaskDelay(1); // yield CPU to FreeRTOS tasks including BLE
} }
return true; return true;
} }
vTaskDelay(1); vTaskDelay(1); // yield CPU between RSSI samples
} }
#endif // Channel free: reset busy counter and add small jitter
// CAD
int16_t result = performChannelScan();
state = STATE_IDLE;
startRecv();
if (result != RADIOLIB_CHANNEL_FREE) {
// CAD busy: backoff
_busy_count++;
uint32_t base_ms = 3000;
uint32_t max_backoff = min(base_ms * (1u << _busy_count), (uint32_t)20000);
uint32_t backoff_until = millis() + random(max_backoff / 2, max_backoff);
while (millis() < backoff_until) {
vTaskDelay(1);
}
return true;
}
_busy_count = 0; _busy_count = 0;
// Small jitter even when channel is free to prevent simultaneous TX
// from two nodes that both detect a free channel at the same time
uint32_t jitter_until = millis() + random(0, 500); uint32_t jitter_until = millis() + random(0, 500);
while (millis() < jitter_until) { while (millis() < jitter_until) {
vTaskDelay(1); // yield CPU to FreeRTOS tasks including BLE vTaskDelay(1); // yield CPU to FreeRTOS tasks including BLE
} }
return false; return false;
#else
// Non-JP: original behavior (RSSI threshold only)
return getCurrentRSSI() > _noise_floor + _threshold;
#endif
} }
float RadioLibWrapper::getLastRSSI() const { float RadioLibWrapper::getLastRSSI() const {
return _radio->getRSSI(); return _radio->getRSSI();
} }