Skip to content

Commit 8426fdd

Browse files
committed
workaround for LR1110 shift issue
it seems that if the LR1110 radio hears a packet corrupted in a specific way, it'll report a packet of 0 length and with the header error IRQ set. every packet received afterwards will then be shifted to the right by 4 bytes on top of the radio's reported offset. this can occur multiple times with the shift increasing by 4 bytes each time. thus, this patch will read from an additional offset after hearing the trigger packet. transmitting seems to reset the shift - unsure exactly what operation resets it but standby() is called after tx so patch assumes shift is 0 after standby(). more investigation may be needed here.
1 parent 93c0180 commit 8426fdd

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ monitor_speed = 115200
1818
lib_deps =
1919
SPI
2020
Wire
21-
jgromes/RadioLib @ ^7.1.2
21+
jgromes/RadioLib @ ^7.3.0
2222
rweather/Crypto @ ^0.4.0
2323
adafruit/RTClib @ ^2.1.3
2424
melopero/Melopero RV3028 @ ^1.1.0

src/helpers/radiolib/CustomLR1110.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,74 @@ class CustomLR1110 : public LR1110 {
99
public:
1010
CustomLR1110(Module *mod) : LR1110(mod) { }
1111

12+
uint8_t shiftCount = 0;
13+
14+
int16_t standby() override {
15+
// tx resets the shift, standby is called on tx completion
16+
// this might not actually be what resets it, but it seems to work
17+
// more investigation needed
18+
this->shiftCount = 0;
19+
return LR1110::standby();
20+
}
21+
22+
size_t getPacketLength(bool update) override {
23+
size_t len = LR1110::getPacketLength(update);
24+
if (len == 0) {
25+
uint32_t irq = getIrqStatus();
26+
if (irq & RADIOLIB_LR11X0_IRQ_HEADER_ERR) {
27+
Serial.println(F("got possible bug packet"));
28+
this->shiftCount += 4; // uint8 will loop around to 0 at 256, perfect as rx buffer is 256 bytes
29+
} else {
30+
Serial.println(F("got zero-length packet without header err irq"));
31+
}
32+
}
33+
return len;
34+
}
35+
36+
int16_t readData(uint8_t *data, size_t len) override {
37+
// check active modem
38+
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
39+
int16_t state = getPacketType(&modem);
40+
RADIOLIB_ASSERT(state);
41+
if((modem != RADIOLIB_LR11X0_PACKET_TYPE_LORA) &&
42+
(modem != RADIOLIB_LR11X0_PACKET_TYPE_GFSK)) {
43+
return(RADIOLIB_ERR_WRONG_MODEM);
44+
}
45+
46+
// check integrity CRC
47+
uint32_t irq = getIrqStatus();
48+
int16_t crcState = RADIOLIB_ERR_NONE;
49+
// Report CRC mismatch when there's a payload CRC error, or a header error and no valid header (to avoid false alarm from previous packet)
50+
if((irq & RADIOLIB_LR11X0_IRQ_CRC_ERR) || ((irq & RADIOLIB_LR11X0_IRQ_HEADER_ERR) && !(irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID))) {
51+
crcState = RADIOLIB_ERR_CRC_MISMATCH;
52+
}
53+
54+
// get packet length
55+
// the offset is needed since LR11x0 seems to move the buffer base by 4 bytes on every packet
56+
uint8_t offset = 0;
57+
size_t length = LR1110::getPacketLength(true, &offset);
58+
if((len != 0) && (len < length)) {
59+
// user requested less data than we got, only return what was requested
60+
length = len;
61+
}
62+
63+
// read packet data
64+
state = readBuffer8(data, length, (uint8_t)(offset + this->shiftCount)); // add shiftCount to offset - only change from radiolib
65+
RADIOLIB_ASSERT(state);
66+
67+
// clear the Rx buffer
68+
state = clearRxBuffer();
69+
RADIOLIB_ASSERT(state);
70+
71+
// clear interrupt flags
72+
state = clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
73+
74+
// check if CRC failed - this is done after reading data to give user the option to keep them
75+
RADIOLIB_ASSERT(crcState);
76+
77+
return(state);
78+
}
79+
1280
RadioLibTime_t getTimeOnAir(size_t len) override {
1381
// calculate number of symbols
1482
float N_symbol = 0;

0 commit comments

Comments
 (0)