Skip to content

Commit 2b6a608

Browse files
committed
LBT implementation for LR1121
Extract EnableLBT function
1 parent 6b69443 commit 2b6a608

8 files changed

Lines changed: 110 additions & 46 deletions

File tree

.github/workflows/build.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ jobs:
108108
mkdir -p $OUTDIR
109109
mv .pio/build/${{ matrix.target }}/*.{elrs,bin} $OUTDIR >& /dev/null || :
110110
;;
111+
*LR1121*)
112+
# release builds
113+
PLATFORMIO_BUILD_FLAGS="-DRegulatory_Domain_EU_CE_2400 -DRegulatory_Domain_FCC_915" pio run -e ${{ matrix.target }}
114+
OUTDIR=~/artifacts/firmware/LBT/`echo ${{ matrix.target }} | sed s/_via.*//`
115+
mkdir -p $OUTDIR
116+
mv .pio/build/${{ matrix.target }}/*.{elrs,bin} $OUTDIR >& /dev/null || :
117+
118+
PLATFORMIO_BUILD_FLAGS="-DRegulatory_Domain_FCC_915" pio run -e ${{ matrix.target }}
119+
OUTDIR=~/artifacts/firmware/FCC/`echo ${{ matrix.target }} | sed s/_via.*//`
120+
mkdir -p $OUTDIR
121+
mv .pio/build/${{ matrix.target }}/*.{elrs,bin} $OUTDIR >& /dev/null || :
122+
;;
111123
*)
112124
# release build
113125
PLATFORMIO_BUILD_FLAGS="-DRegulatory_Domain_FCC_915" pio run -e ${{ matrix.target }}

src/lib/LBT/LBT.cpp

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "common.h"
33
#include "logging.h"
44
#include "LBT.h"
5+
#include "config.h"
56

67
LQCALC<100> LBTSuccessCalc;
78
static uint32_t rxStartTime;
@@ -10,14 +11,38 @@ static uint32_t rxStartTime;
1011
#define LBT_RSSI_THRESHOLD_OFFSET_DB 0
1112
#endif
1213

13-
bool LBTEnabled = false;
14+
static bool LBTEnabled = false;
1415
static uint32_t validRSSIdelayUs = 0;
1516

16-
static uint32_t ICACHE_RAM_ATTR SpreadingFactorToRSSIvalidDelayUs(
17-
SX1280_RadioLoRaSpreadingFactors_t SF,
18-
uint8_t radio_type
19-
)
17+
void EnableLBT()
2018
{
19+
#if defined(Regulatory_Domain_EU_CE_2400)
20+
LBTEnabled = config.GetPower() > PWR_10mW;
21+
#if defined(RADIO_LR1121)
22+
LBTEnabled = LBTEnabled && (ExpressLRS_currAirRate_Modparams->radio_type == RADIO_TYPE_LR1121_LORA_2G4 || ExpressLRS_currAirRate_Modparams->radio_type == RADIO_TYPE_LR1121_GFSK_2G4);
23+
#endif
24+
#endif
25+
}
26+
27+
static uint32_t ICACHE_RAM_ATTR SpreadingFactorToRSSIvalidDelayUs(uint8_t SF, uint8_t radio_type)
28+
{
29+
#if defined(RADIO_LR1121)
30+
if (radio_type == RADIO_TYPE_LR1121_LORA_2G4)
31+
{
32+
switch((lr11xx_radio_lora_sf_t)SF)
33+
{
34+
case LR11XX_RADIO_LORA_SF5: return 100;
35+
case LR11XX_RADIO_LORA_SF6: return 141;
36+
case LR11XX_RADIO_LORA_SF7: return 218;
37+
case LR11XX_RADIO_LORA_SF8: return 218;
38+
default: return 218;
39+
}
40+
}
41+
if (radio_type == RADIO_TYPE_LR1121_GFSK_2G4)
42+
{
43+
return 60 + 20; // switching time (60us) + 20us settling time (seems fine when testing)
44+
}
45+
#elif defined(RADIO_SX128X)
2146
// The necessary wait time from RX start to valid instant RSSI reading
2247
// changes with the spreading factor setting.
2348
// The worst case necessary wait time is TX->RX switch time + Lora symbol time
@@ -37,24 +62,22 @@ static uint32_t ICACHE_RAM_ATTR SpreadingFactorToRSSIvalidDelayUs(
3762

3863
if (radio_type == RADIO_TYPE_SX128x_LORA)
3964
{
40-
switch(SF)
41-
{
42-
case SX1280_LORA_SF5: return 100;
43-
case SX1280_LORA_SF6: return 141;
44-
case SX1280_LORA_SF7: return 218;
45-
case SX1280_LORA_SF8: return 480;
46-
default: return 480;
47-
}
65+
switch((SX1280_RadioLoRaSpreadingFactors_t)SF)
66+
{
67+
case SX1280_LORA_SF5: return 100;
68+
case SX1280_LORA_SF6: return 141;
69+
case SX1280_LORA_SF7: return 218;
70+
case SX1280_LORA_SF8: return 480;
71+
default: return 480;
72+
}
4873
}
49-
else if (radio_type == RADIO_TYPE_SX128x_FLRC)
74+
if (radio_type == RADIO_TYPE_SX128x_FLRC)
5075
{
5176
return 60 + 20; // switching time (60us) + 20us settling time (seems fine when testing)
5277
}
53-
else
54-
{
55-
ERRLN("LBT not support on this radio type");
56-
return 0;
57-
}
78+
#endif
79+
ERRLN("LBT not support on this radio type");
80+
return 0;
5881
}
5982

6083
static int8_t ICACHE_RAM_ATTR PowerEnumToLBTLimit(PowerLevels_e txPower, uint8_t radio_type)
@@ -65,8 +88,8 @@ static int8_t ICACHE_RAM_ATTR PowerEnumToLBTLimit(PowerLevels_e txPower, uint8_t
6588
// different RF frontends.
6689
// TODO: Maybe individual adjustment offset for differences in
6790
// rssi reading between bandwidth setting is also necessary when other BW than 0.8MHz are used.
68-
69-
if (radio_type == RADIO_TYPE_SX128x_LORA)
91+
#if defined(RADIO_LR1121)
92+
if (radio_type == RADIO_TYPE_LR1121_LORA_2G4)
7093
{
7194
switch(txPower)
7295
{
@@ -78,7 +101,7 @@ static int8_t ICACHE_RAM_ATTR PowerEnumToLBTLimit(PowerLevels_e txPower, uint8_t
78101
default: return -71 + LBT_RSSI_THRESHOLD_OFFSET_DB;
79102
}
80103
}
81-
else if (radio_type == RADIO_TYPE_SX128x_FLRC)
104+
if (radio_type == RADIO_TYPE_LR1121_GFSK_2G4)
82105
{
83106
switch(txPower)
84107
{
@@ -90,11 +113,34 @@ static int8_t ICACHE_RAM_ATTR PowerEnumToLBTLimit(PowerLevels_e txPower, uint8_t
90113
default: return -73 + LBT_RSSI_THRESHOLD_OFFSET_DB;
91114
}
92115
}
93-
else
116+
#elif defined(RADIO_SX128X)
117+
if (radio_type == RADIO_TYPE_SX128x_LORA)
94118
{
95-
ERRLN("LBT not support on this radio type");
96-
return 0;
119+
switch(txPower)
120+
{
121+
case PWR_10mW: return -61 + LBT_RSSI_THRESHOLD_OFFSET_DB;
122+
case PWR_25mW: return -65 + LBT_RSSI_THRESHOLD_OFFSET_DB;
123+
case PWR_50mW: return -68 + LBT_RSSI_THRESHOLD_OFFSET_DB;
124+
case PWR_100mW: return -71 + LBT_RSSI_THRESHOLD_OFFSET_DB;
125+
// Values above 100mW are not relevant, default to 100mW threshold
126+
default: return -71 + LBT_RSSI_THRESHOLD_OFFSET_DB;
127+
}
97128
}
129+
if (radio_type == RADIO_TYPE_SX128x_FLRC)
130+
{
131+
switch(txPower)
132+
{
133+
case PWR_10mW: return -63 + LBT_RSSI_THRESHOLD_OFFSET_DB;
134+
case PWR_25mW: return -67 + LBT_RSSI_THRESHOLD_OFFSET_DB;
135+
case PWR_50mW: return -70 + LBT_RSSI_THRESHOLD_OFFSET_DB;
136+
case PWR_100mW: return -73 + LBT_RSSI_THRESHOLD_OFFSET_DB;
137+
// Values above 100mW are not relevant, default to 100mW threshold
138+
default: return -73 + LBT_RSSI_THRESHOLD_OFFSET_DB;
139+
}
140+
}
141+
ERRLN("LBT not support on this radio type");
142+
#endif
143+
return 0;
98144
}
99145

100146
void ICACHE_RAM_ATTR SetClearChannelAssessmentTime(void)
@@ -103,10 +149,16 @@ void ICACHE_RAM_ATTR SetClearChannelAssessmentTime(void)
103149
return;
104150

105151
rxStartTime = micros();
106-
validRSSIdelayUs = SpreadingFactorToRSSIvalidDelayUs((SX1280_RadioLoRaSpreadingFactors_t)ExpressLRS_currAirRate_Modparams->sf, ExpressLRS_currAirRate_Modparams->radio_type);
152+
validRSSIdelayUs = SpreadingFactorToRSSIvalidDelayUs(ExpressLRS_currAirRate_Modparams->sf, ExpressLRS_currAirRate_Modparams->radio_type);
107153

108154
#if defined(TARGET_TX)
109-
Radio.RXnb(SX1280_MODE_RX, validRSSIdelayUs);
155+
#if defined(RADIO_LR1121)
156+
Radio.RXnb(LR1121_MODE_RX, validRSSIdelayUs);
157+
#elif defined(RADIO_SX128X)
158+
Radio.RXnb(SX1280_MODE_RX, validRSSIdelayUs);
159+
#else
160+
#error No continuous receive mode defined for this radio type
161+
#endif
110162
#endif
111163
}
112164

src/lib/LBT/LBT.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
#include "POWERMGNT.h"
55
#include "LQCALC.h"
6-
#include "SX1280Driver.h"
6+
#include "SX12xxDriverCommon.h"
77

88
extern LQCALC<100> LBTSuccessCalc;
9-
extern bool LBTEnabled;
109

10+
void EnableLBT();
1111
void ICACHE_RAM_ATTR SetClearChannelAssessmentTime(void);
1212
SX12XX_Radio_Number_t ICACHE_RAM_ATTR ChannelIsClear(SX12XX_Radio_Number_t radioNumber);
13+
#else
14+
inline void EnableLBT() {}
1315
#endif

src/lib/LR1121Driver/LR1121.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,11 @@ void ICACHE_RAM_ATTR LR1121Driver::SetPaConfig(bool isSubGHz, SX12XX_Radio_Numbe
432432
hal.WriteCommand(LR11XX_RADIO_SET_PA_CFG_OC, Pabuf, sizeof(Pabuf), radioNumber);
433433
}
434434

435-
void LR1121Driver::SetMode(lr11xx_RadioOperatingModes_t OPmode, SX12XX_Radio_Number_t radioNumber)
435+
void LR1121Driver::SetMode(lr11xx_RadioOperatingModes_t OPmode, SX12XX_Radio_Number_t radioNumber, uint32_t incomingTimeout)
436436
{
437437
WORD_ALIGNED_ATTR uint8_t buf[5] = {0};
438+
uint32_t tempTimeout;
439+
438440
switch (OPmode)
439441
{
440442
case LR1121_MODE_SLEEP:
@@ -461,6 +463,7 @@ void LR1121Driver::SetMode(lr11xx_RadioOperatingModes_t OPmode, SX12XX_Radio_Num
461463

462464
case LR1121_MODE_RX:
463465
// 7.2.2 SetRx
466+
tempTimeout = incomingTimeout ? (incomingTimeout * 1000 / RX_TIMEOUT_PERIOD_BASE_NANOS) : timeout;
464467
buf[0] = timeout >> 16;
465468
buf[1] = timeout >> 8;
466469
buf[2] = timeout & 0xFF;
@@ -696,9 +699,9 @@ bool ICACHE_RAM_ATTR LR1121Driver::RXnbISR(SX12XX_Radio_Number_t radioNumber)
696699
return true;
697700
}
698701

699-
void ICACHE_RAM_ATTR LR1121Driver::RXnb(lr11xx_RadioOperatingModes_t rxMode)
702+
void ICACHE_RAM_ATTR LR1121Driver::RXnb(lr11xx_RadioOperatingModes_t rxMode, uint32_t incomingTimeout)
700703
{
701-
SetMode(LR1121_MODE_RX, SX12XX_Radio_All);
704+
SetMode(LR1121_MODE_RX, SX12XX_Radio_All, incomingTimeout);
702705
}
703706

704707
bool ICACHE_RAM_ATTR LR1121Driver::GetFrequencyErrorbool()

src/lib/LR1121Driver/LR1121.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class LR1121Driver: public SX12xxDriverCommon
4141
bool FrequencyErrorAvailable() const { return false; }
4242

4343
void TXnb(uint8_t * data, SX12XX_Radio_Number_t radioNumber);
44-
void RXnb(lr11xx_RadioOperatingModes_t rxMode = LR1121_MODE_RX);
44+
void RXnb(lr11xx_RadioOperatingModes_t rxMode = LR1121_MODE_RX, uint32_t incomingTimeout = 0);
4545

4646
uint32_t GetIrqStatus(SX12XX_Radio_Number_t radioNumber);
4747
void ClearIrqStatus(SX12XX_Radio_Number_t radioNumber);
@@ -69,7 +69,7 @@ class LR1121Driver: public SX12xxDriverCommon
6969

7070
WORD_ALIGNED_ATTR uint8_t rx_buf[32] = {};
7171

72-
void SetMode(lr11xx_RadioOperatingModes_t OPmode, SX12XX_Radio_Number_t radioNumber);
72+
void SetMode(lr11xx_RadioOperatingModes_t OPmode, SX12XX_Radio_Number_t radioNumber, uint32_t incomingTimeout = 0);
7373

7474
// LoRa functions
7575
void ConfigModParamsLoRa(uint8_t bw, uint8_t sf, uint8_t cr, SX12XX_Radio_Number_t radioNumber);

src/python/build_flags.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ def get_version():
148148

149149
if '-DRADIO_SX127X=1' in build_flags or '-DRADIO_LR1121=1' in build_flags:
150150
# disallow setting 2400s for 900
151-
if fnmatch.filter(build_flags, '*-DRegulatory_Domain_ISM_2400') or \
152-
fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_CE_2400'):
151+
if '-DRADIO_SX127X=1' in build_flags and \
152+
(fnmatch.filter(build_flags, '*-DRegulatory_Domain_ISM_2400') or
153+
fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_CE_2400')):
153154
print_error('Regulatory_Domain 2400 not compatible with RADIO_SX127X/RADIO_LR1121')
154155

155156
# require a domain be set for 900

src/src/rx_main.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ void SetRFLinkRate(uint8_t index, bool bindMode) // Set speed of RF link
349349
expresslrs_mod_settings_s *const ModParams = get_elrs_airRateConfig(index);
350350
expresslrs_rf_pref_params_s *const RFperf = get_elrs_RFperfParams(index);
351351

352+
EnableLBT();
353+
352354
// Binding always uses invertIQ
353355
bool invertIQ = bindMode || (UID[5] & 0x01);
354356

@@ -1684,10 +1686,6 @@ static void setupRadio()
16841686

16851687
DynamicPower_UpdateRx(true); // Call before SetRFLinkRate(). The LR1121 Radio lib can now set the correct output power in Config().
16861688

1687-
#if defined(Regulatory_Domain_EU_CE_2400)
1688-
LBTEnabled = (config.GetPower() > PWR_10mW);
1689-
#endif
1690-
16911689
Radio.RXdoneCallback = &RXdoneISR;
16921690
Radio.TXdoneCallback = &TXdoneISR;
16931691

@@ -2031,9 +2029,7 @@ static void CheckConfigChangePending()
20312029
LostConnection(false);
20322030
config.Commit();
20332031
devicesTriggerEvent();
2034-
#if defined(Regulatory_Domain_EU_CE_2400)
2035-
LBTEnabled = (config.GetPower() > PWR_10mW);
2036-
#endif
2032+
EnableLBT();
20372033
Radio.RXnb();
20382034
}
20392035
}

src/src/tx_main.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -771,9 +771,7 @@ void ResetPower()
771771
POWERMGNT::setPower((PowerLevels_e)config.GetPower());
772772
}
773773
// TLM interval is set on the next SYNC packet
774-
#if defined(Regulatory_Domain_EU_CE_2400)
775-
LBTEnabled = (config.GetPower() > PWR_10mW);
776-
#endif
774+
EnableLBT();
777775
}
778776

779777
static void ChangeRadioParams()

0 commit comments

Comments
 (0)