Skip to content

Commit a548ecd

Browse files
committed
Add JP_STRICT 5ms continuous RSSI sensing before TX (ARIB STD-T108)
Under JP_STRICT mode, add energy-based carrier sensing loop before CAD: - Sample RSSI continuously for >= 5ms before each TX attempt - If RSSI exceeds threshold at any point, trigger random backoff - ARIB STD-T108 requires energy-based sensing; LoRa CAD alone is insufficient as it only detects LoRa preambles This satisfies the minimum 5ms continuous sensing requirement for the 920.6-922.2 MHz zone (specified low power radio, LBT mode). Test results (JP LoRa SF12/BW125/CR4-8, simultaneous DM): - 16-char: 2/2 success, delivered within 1:03-1:50 - 1-char: 3/4 success, delivered within 0:46-2:11 (shorter airtime reduces RSSI detection window)
1 parent 0970d6d commit a548ecd

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

src/helpers/radiolib/RadioLibWrappers.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ uint32_t RadioLibWrapper::getEstAirtimeFor(int len_bytes) {
142142

143143
bool RadioLibWrapper::startSendRaw(const uint8_t* bytes, int len) {
144144
_board->onBeforeTransmit();
145+
_tx_start_ms = millis(); // recording TX time
145146
int err = _radio->startTransmit((uint8_t *) bytes, len);
146147
if (err == RADIOLIB_ERR_NONE) {
147148
state = STATE_TX_WAIT;
@@ -157,6 +158,8 @@ bool RadioLibWrapper::isSendComplete() {
157158
if (state & STATE_INT_READY) {
158159
state = STATE_IDLE;
159160
n_sent++;
161+
uint32_t tx_duration = millis() - _tx_start_ms;
162+
MESH_DEBUG_PRINTLN("TX duration: %lu ms (len=%d)", tx_duration);
160163
return true;
161164
}
162165
return false;
@@ -175,6 +178,24 @@ int16_t RadioLibWrapper::performChannelScan() {
175178
bool RadioLibWrapper::isChannelActive() {
176179
if (_threshold == 0) return false; // interference check is disabled
177180

181+
#ifdef JP_STRICT
182+
// ARIB STD-T108 compliant LBT: continuous RSSI sensing for >= 5ms
183+
// Energy-based sensing required; LoRa CAD alone is not sufficient
184+
uint32_t sense_start = millis();
185+
uint32_t sense_duration_ms = 5;
186+
while (millis() - sense_start < sense_duration_ms) {
187+
if (getCurrentRSSI() > _noise_floor + _threshold) {
188+
// Channel busy detected during 5ms sensing window
189+
uint32_t backoff_until = millis() + random(8000, 22000);
190+
while (millis() < backoff_until) {
191+
vTaskDelay(1); // yield CPU to FreeRTOS tasks including BLE
192+
}
193+
return true;
194+
}
195+
vTaskDelay(1); // yield CPU between RSSI samples
196+
}
197+
#endif
198+
178199
int16_t result = performChannelScan();
179200
// scanChannel() triggers DIO interrupt (CAD done) which sets STATE_INT_READY
180201
// via setFlag() ISR. Clear it before restarting RX so recvRaw() doesn't

0 commit comments

Comments
 (0)