1 #if defined(Regulatory_Domain_EU_CE_2400)
6 LQCALC
<100> LBTSuccessCalc
;
7 static uint32_t rxStartTime
;
9 bool LBTEnabled
= false;
10 static uint32_t validRSSIdelayUs
= 0;
12 static uint32_t ICACHE_RAM_ATTR
SpreadingFactorToRSSIvalidDelayUs(
13 SX1280_RadioLoRaSpreadingFactors_t SF
,
17 // The necessary wait time from RX start to valid instant RSSI reading
18 // changes with the spreading factor setting.
19 // The worst case necessary wait time is TX->RX switch time + Lora symbol time
20 // This assumes the radio switches from either TX, RX or FS (Freq Synth mode)
21 // TX to RX switch time is 60us for sx1280
22 // Lora symbol time for the relevant spreading factors is:
27 // However, by measuring when the RSSI reading is stable and valid, it was found that
28 // actual necessary wait times are:
29 // SF5 ~100us (60us + SF5 symbol time)
30 // SF6 ~141us (60us + SF6 symbol time)
31 // SF7 ~218us (60us + SF7 symbol time)
32 // SF8 ~376us (60us + SF8 symbol time) Empirical testing shows 480us to be the sweet-spot
34 if (radio_type
== RADIO_TYPE_SX128x_LORA
)
38 case SX1280_LORA_SF5
: return 100;
39 case SX1280_LORA_SF6
: return 141;
40 case SX1280_LORA_SF7
: return 218;
41 case SX1280_LORA_SF8
: return 480;
45 else if (radio_type
== RADIO_TYPE_SX128x_FLRC
)
47 return 60 + 20; // switching time (60us) + 20us settling time (seems fine when testing)
51 ERRLN("LBT not support on this radio type");
56 static int8_t ICACHE_RAM_ATTR
PowerEnumToLBTLimit(PowerLevels_e txPower
, uint8_t radio_type
)
58 // Calculated from EN 300 328, adjusted for 800kHz BW for sx1280
59 // TL = -70 dBm/MHz + 10*log10(0.8MHz) + 10 × log10 (100 mW / Pout) (Pout in mW e.i.r.p.)
60 // This threshold should be offset with a #define config for each HW that corrects for antenna gain,
61 // different RF frontends.
62 // TODO: Maybe individual adjustment offset for differences in
63 // rssi reading between bandwidth setting is also necessary when other BW than 0.8MHz are used.
65 if (radio_type
== RADIO_TYPE_SX128x_LORA
)
69 case PWR_10mW
: return -61 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
70 case PWR_25mW
: return -65 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
71 case PWR_50mW
: return -68 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
72 case PWR_100mW
: return -71 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
73 // Values above 100mW are not relevant, default to 100mW threshold
74 default: return -71 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
77 else if (radio_type
== RADIO_TYPE_SX128x_FLRC
)
81 case PWR_10mW
: return -63 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
82 case PWR_25mW
: return -67 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
83 case PWR_50mW
: return -70 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
84 case PWR_100mW
: return -73 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
85 // Values above 100mW are not relevant, default to 100mW threshold
86 default: return -73 + LBT_RSSI_THRESHOLD_OFFSET_DB
;
91 ERRLN("LBT not support on this radio type");
96 void ICACHE_RAM_ATTR
SetClearChannelAssessmentTime(void)
101 rxStartTime
= micros();
102 validRSSIdelayUs
= SpreadingFactorToRSSIvalidDelayUs((SX1280_RadioLoRaSpreadingFactors_t
)ExpressLRS_currAirRate_Modparams
->sf
, ExpressLRS_currAirRate_Modparams
->radio_type
);
104 #if defined(TARGET_TX)
105 Radio
.RXnb(SX1280_MODE_RX
, validRSSIdelayUs
);
109 SX12XX_Radio_Number_t ICACHE_RAM_ATTR
ChannelIsClear(SX12XX_Radio_Number_t radioNumber
)
111 if (radioNumber
== SX12XX_Radio_NONE
)
112 return SX12XX_Radio_NONE
;
114 LBTSuccessCalc
.inc(); // Increment count for every channel check
118 LBTSuccessCalc
.add();
119 return SX12XX_Radio_All
;
122 // Read rssi after waiting the minimum RSSI valid delay.
123 // If this function is called long enough after RX enable,
124 // this will always be ok on first try as is the case for TX.
126 // TODO: Better way than busypolling this for RX?
127 // this loop should only run for RX, where listen before talk RX is started right after FHSS hop
128 // so there is no dead-time to run RX before telemetry TX is supposed to happen.
129 // if flipping the logic, so telemetry TX happens right before FHSS hop, then TX-side ends up with polling here instead?
130 // Maybe it could be skipped if there was only TX of telemetry happening when FHSShop does not happen.
131 // Then RX for LBT could stay enabled from last received packet, and RSSI would be valid instantly.
132 // But for now, FHSShops and telemetry rates does not divide evenly, so telemetry will some times happen
133 // right after FHSS and we need wait here.
135 uint32_t elapsed
= micros() - rxStartTime
;
136 if(elapsed
< validRSSIdelayUs
)
138 delayMicroseconds(validRSSIdelayUs
- elapsed
);
141 int8_t rssiInst1
= 0;
142 int8_t rssiInst2
= 0;
143 SX12XX_Radio_Number_t clearChannelsMask
= SX12XX_Radio_NONE
;
144 int8_t rssiCutOff
= PowerEnumToLBTLimit((PowerLevels_e
)POWERMGNT::currPower(), ExpressLRS_currAirRate_Modparams
->radio_type
);
146 if (radioNumber
& SX12XX_Radio_1
)
148 rssiInst1
= Radio
.GetRssiInst(SX12XX_Radio_1
);
149 if(rssiInst1
< rssiCutOff
)
151 clearChannelsMask
|= SX12XX_Radio_1
;
155 if (radioNumber
& SX12XX_Radio_2
)
157 rssiInst2
= Radio
.GetRssiInst(SX12XX_Radio_2
);
158 if(rssiInst2
< rssiCutOff
)
160 clearChannelsMask
|= SX12XX_Radio_2
;
164 // Useful to debug if and how long the rssi wait is, and rssi threshold rssiCutOff
165 // DBGLN("wait: %d, cutoff: %d, rssi: %d %d, %s", validRSSIdelayUs - elapsed, rssiCutOff, rssiInst1, rssiInst2, clearChannelsMask ? "clear" : "in use");
167 if(clearChannelsMask
)
169 LBTSuccessCalc
.add(); // Add success only when actually preparing for TX
172 return clearChannelsMask
;