Improve support for LoRa coding rate with Long Interleaver (#1606)

* Add error for packet too short

* [SX126x] Add support for Long Interleaver coding rates

* [LR11x0] Add packet length check for long interleaver

* [LR11x0] Update comment on Long Interleaver

* [SX128x] Update Long Interleaver CR 4/8 macro

* [SX128x] Add packet length check for CR 4/8 with long interleaver

* [SX126x] Add definitions for new CR with long interleaver
pull/1607/head
GUVWAF 2025-09-20 11:04:45 +02:00 zatwierdzone przez GitHub
rodzic 5885ede681
commit f35d12421f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
9 zmienionych plików z 72 dodań i 7 usunięć

Wyświetl plik

@ -255,6 +255,11 @@
*/
#define RADIOLIB_ERR_INVALID_IRQ (-29)
/*!
\brief Packet supplied to transmission method was shorter than required.
*/
#define RADIOLIB_ERR_PACKET_TOO_SHORT (-30)
// RF69-specific status codes
/*!

Wyświetl plik

@ -179,6 +179,17 @@ int16_t LR11x0::transmit(const uint8_t* data, size_t len, uint8_t addr) {
RADIOLIB_ASSERT(state);
// check packet length
if (this->codingRate > RADIOLIB_LR11X0_LORA_CR_4_8_SHORT) {
// Long Interleaver needs at least 8 bytes
if(len < 8) {
return(RADIOLIB_ERR_PACKET_TOO_SHORT);
}
// Long Interleaver supports up to 253 bytes if CRC is enabled
if (this->crcTypeLoRa == RADIOLIB_LR11X0_LORA_CRC_ENABLED && (len > RADIOLIB_LR11X0_MAX_PACKET_LENGTH - 2)) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
}
if(len > RADIOLIB_LR11X0_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}

Wyświetl plik

@ -1172,7 +1172,8 @@ class LR11x0: public PhysicalLayer {
is undocumented and not recommended without your own FEC.
\param cr LoRa coding rate denominator to be set.
\param longInterleave Enable long interleaver when set to true.
Note that CR 4/7 is not possible with long interleaver enabled!
Note that with long interleaver enabled, CR 4/7 is not possible, there are packet length restrictions,
and it is not compatible with SX127x radios!
\returns \ref status_codes
*/
int16_t setCodingRate(uint8_t cr, bool longInterleave = false);

Wyświetl plik

@ -200,6 +200,17 @@ int16_t SX126x::transmit(const uint8_t* data, size_t len, uint8_t addr) {
RADIOLIB_ASSERT(state);
// check packet length
if(this->codingRate > RADIOLIB_SX126X_LORA_CR_4_8) {
// Long Interleaver needs at least 8 bytes
if(len < 8) {
return(RADIOLIB_ERR_PACKET_TOO_SHORT);
}
// Long Interleaver supports up to 253 bytes if CRC is enabled
if(this->crcTypeLoRa == RADIOLIB_SX126X_LORA_CRC_ON && (len > RADIOLIB_SX126X_MAX_PACKET_LENGTH - 2)) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
}
if(len > RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
@ -847,9 +858,17 @@ RadioLibTime_t SX126x::getTimeOnAir(size_t len) {
PacketConfig_t packetConfig = {};
if(type == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
uint8_t cr = this->codingRate;
// We assume same calculation for short and long interleaving, so map CR values 0-4 and 5-7 to the same values
if (cr < 5) {
cr = cr + 4;
} else if (cr == 7) {
cr = cr + 1;
}
dataRate.lora.codingRate = cr;
dataRate.lora.spreadingFactor = this->spreadingFactor;
dataRate.lora.bandwidth = this->bandwidthKhz;
dataRate.lora.codingRate = (uint8_t)(this->codingRate + 4);
packetConfig.lora.preambleLength = this->preambleLengthLoRa;
packetConfig.lora.crcEnabled = (bool)this->crcTypeLoRa;

Wyświetl plik

@ -352,9 +352,12 @@ class SX126x: public PhysicalLayer {
\brief Sets LoRa coding rate denominator. Allowed values range from 4 to 8. Note that a value of 4 means no coding,
is undocumented and not recommended without your own FEC.
\param cr LoRa coding rate denominator to be set.
\param longInterleave Enable long interleaver when set to true.
Note that with long interleaver enabled, CR 4/7 is not possible, there are packet length restrictions,
and it is not compatible with SX127x radios.
\returns \ref status_codes
*/
int16_t setCodingRate(uint8_t cr);
int16_t setCodingRate(uint8_t cr, bool longInterleave = false);
/*!
\brief Sets LoRa sync word.

Wyświetl plik

@ -105,7 +105,7 @@ int16_t SX126x::setSpreadingFactor(uint8_t sf) {
return(setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
}
int16_t SX126x::setCodingRate(uint8_t cr) {
int16_t SX126x::setCodingRate(uint8_t cr, bool longInterleave) {
// check active modem
if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
return(RADIOLIB_ERR_WRONG_MODEM);
@ -113,8 +113,26 @@ int16_t SX126x::setCodingRate(uint8_t cr) {
RADIOLIB_CHECK_RANGE(cr, 4, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
if(longInterleave) {
switch(cr) {
case 4:
this->codingRate = 0;
break;
case 5:
case 6:
this->codingRate = cr;
break;
case 8:
this->codingRate = cr - 1;
break;
default:
return(RADIOLIB_ERR_INVALID_CODING_RATE);
}
} else {
this->codingRate = cr - 4;
}
// update modulation parameters
this->codingRate = cr - 4;
return(setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
}

Wyświetl plik

@ -230,6 +230,9 @@
#define RADIOLIB_SX126X_LORA_CR_4_6 0x02 // 7 0 4/6
#define RADIOLIB_SX126X_LORA_CR_4_7 0x03 // 7 0 4/7
#define RADIOLIB_SX126X_LORA_CR_4_8 0x04 // 7 0 4/8
#define RADIOLIB_SX126X_LORA_CR_4_5_LI 0x05 // 7 0 4/5, long interleaver
#define RADIOLIB_SX126X_LORA_CR_4_6_LI 0x06 // 7 0 4/6, long interleaver
#define RADIOLIB_SX126X_LORA_CR_4_8_LI 0x07 // 7 0 4/8, long interleaver
#define RADIOLIB_SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_OFF 0x00 // 7 0 LoRa low data rate optimization: disabled
#define RADIOLIB_SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_ON 0x01 // 7 0 enabled

Wyświetl plik

@ -315,7 +315,12 @@ int16_t SX128x::reset(bool verify) {
int16_t SX128x::transmit(const uint8_t* data, size_t len, uint8_t addr) {
// check packet length
if(len > RADIOLIB_SX128X_MAX_PACKET_LENGTH) {
if(this->codingRateLoRa == RADIOLIB_SX128X_LORA_CR_4_8_LI && this->crcLoRa == RADIOLIB_SX128X_LORA_CRC_ON) {
// Long Interleaver at CR 4/8 supports up to 253 bytes if CRC is enabled
if(len > RADIOLIB_SX128X_MAX_PACKET_LENGTH - 2) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
} else if(len > RADIOLIB_SX128X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}

Wyświetl plik

@ -253,7 +253,7 @@
#define RADIOLIB_SX128X_LORA_CR_4_8 0x04 // 7 0 4/8
#define RADIOLIB_SX128X_LORA_CR_4_5_LI 0x05 // 7 0 4/5, long interleaving
#define RADIOLIB_SX128X_LORA_CR_4_6_LI 0x06 // 7 0 4/6, long interleaving
#define RADIOLIB_SX128X_LORA_CR_4_7_LI 0x07 // 7 0 4/7, long interleaving
#define RADIOLIB_SX128X_LORA_CR_4_8_LI 0x07 // 7 0 4/8, long interleaving
//RADIOLIB_SX128X_CMD_SET_PACKET_PARAMS
#define RADIOLIB_SX128X_GFSK_FLRC_SYNC_WORD_OFF 0x00 // 7 0 GFSK/FLRC sync word used: none