Fix ESP32 LoRaWanBridge OTAA

This commit is contained in:
Theo Arends 2024-03-26 17:02:44 +01:00
parent 48aa621975
commit 03cf7dc460
4 changed files with 77 additions and 39 deletions

View File

@ -26,10 +26,24 @@
* - Lora_DI1
\*********************************************************************************************/
//#define USE_LORA_SX126X_DEBUG
#include <RadioLib.h>
SX1262 LoRaRadio = nullptr; // Select LoRa support
void LoraOnReceiveSx126x(void) {
bool LoraSx126xBusy(void) {
// This is not consistently implemented in the used library
uint32_t timeout;
SetNextTimeInterval(timeout, 100);
while ((1 == digitalRead(Pin(GPIO_LORA_BUSY))) && !TimeReached(timeout)) {
delay(0);
}
return TimeReached(timeout);
}
/*********************************************************************************************/
void LoraSx126xOnInterrupt(void) {
// This is called after EVERY type of enabled interrupt so chk for valid receivedFlag in LoraAvailableSx126x()
if (!Lora.sendFlag && !Lora.receivedFlag && !Lora.receive_time) {
Lora.receive_time = millis();
@ -37,17 +51,34 @@ void LoraOnReceiveSx126x(void) {
Lora.receivedFlag = true; // we got a packet, set the flag
}
bool LoraAvailableSx126x(void) {
if (Lora.receivedFlag && Lora.sendFlag) {
bool LoraSx126xAvailable(void) {
if (Lora.sendFlag) {
Lora.receivedFlag = false; // Reset receive flag as it was caused by send interrupt
uint32_t time = millis();
int state = LoRaRadio.startReceive(); // Put module back to listen mode
Lora.sendFlag = false;
LoRaRadio.startReceive(); // Put module back to listen mode
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("S6X: Receive restarted"));
if (state != RADIOLIB_ERR_NONE) {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("S6X: Rcvd (%d) restarted (%d)"), time, state);
}
}
else if (Lora.receivedFlag) {
uint32_t irq_stat = LoRaRadio.getIrqStatus();
#ifdef USE_LORA_SX126X_DEBUG
if (irq_stat != 0) {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("S6X: Flag (%d) irq %04X"), millis(), irq_stat);
}
#endif // USE_LORA_SX126X_DEBUG
if (0 == (irq_stat & RADIOLIB_SX126X_IRQ_RX_DONE)) {
Lora.receivedFlag = false; // Reset receive flag
}
}
return (Lora.receivedFlag); // Check if the receive flag is set
}
int LoraReceiveSx126x(char* data) {
int LoraSx126xReceive(char* data) {
Lora.receivedFlag = false; // Reset flag
int packet_size = LoRaRadio.getPacketLength();
int state = LoRaRadio.readData((uint8_t*)data, TAS_LORA_MAX_PACKET_LENGTH -1);
@ -66,19 +97,28 @@ int LoraReceiveSx126x(char* data) {
return packet_size;
}
bool LoraSendSx126x(uint8_t* data, uint32_t len, bool invert) {
Lora.sendFlag = true; // Use this flag as LoRaRadio.transmit enable send interrupt
bool LoraSx126xSend(uint8_t* data, uint32_t len, bool invert) {
int state1 = RADIOLIB_ERR_NONE;
int state2 = RADIOLIB_ERR_NONE;
if (invert) {
LoRaRadio.invertIQ(true);
LoRaRadio.standby();
state1 = LoRaRadio.invertIQ(true);
LoraSx126xBusy();
}
int state = LoRaRadio.transmit(data, len);
Lora.sendFlag = true; // Use this flag as LoRaRadio.transmit enable send interrupt
if (invert) {
LoRaRadio.invertIQ(false);
LoraSx126xBusy();
state2 = LoRaRadio.invertIQ(false);
LoRaRadio.standby();
}
if (state != RADIOLIB_ERR_NONE || state1 != RADIOLIB_ERR_NONE || state2 != RADIOLIB_ERR_NONE) {
AddLog(LOG_LEVEL_DEBUG, PSTR("S6X: Send error %d %d %d"), state1, state, state2);
}
return (RADIOLIB_ERR_NONE == state);
}
bool LoraConfigSx126x(void) {
bool LoraSx126xConfig(void) {
LoRaRadio.setCodingRate(LoraSettings.coding_rate);
LoRaRadio.setSyncWord(LoraSettings.sync_word);
LoRaRadio.setPreambleLength(LoraSettings.preamble_length);
@ -97,11 +137,11 @@ bool LoraConfigSx126x(void) {
return true;
}
bool LoraInitSx126x(void) {
bool LoraSx126xInit(void) {
LoRaRadio = new Module(Pin(GPIO_LORA_CS), Pin(GPIO_LORA_DI1), Pin(GPIO_LORA_RST), Pin(GPIO_LORA_BUSY));
if (RADIOLIB_ERR_NONE == LoRaRadio.begin(LoraSettings.frequency)) {
LoraConfigSx126x();
LoRaRadio.setDio1Action(LoraOnReceiveSx126x);
LoraSx126xConfig();
LoRaRadio.setDio1Action(LoraSx126xOnInterrupt);
if (RADIOLIB_ERR_NONE == LoRaRadio.startReceive()) {
return true;
}

View File

@ -29,7 +29,7 @@
#include <LoRa.h> // extern LoRaClass LoRa;
void LoraOnReceiveSx127x(int packet_size) {
void LoraSx127xOnReceive(int packet_size) {
// This function is called when a complete packet is received by the module
#ifdef USE_LORA_DEBUG
// AddLog(LOG_LEVEL_DEBUG, PSTR("S7X: Packet size %d"), packet_size);
@ -41,11 +41,11 @@ void LoraOnReceiveSx127x(int packet_size) {
Lora.packet_size = packet_size; // we got a packet, set the flag
}
bool LoraAvailableSx127x(void) {
bool LoraSx127xAvailable(void) {
return (Lora.packet_size > 0); // check if the flag is set
}
int LoraReceiveSx127x(char* data) {
int LoraSx127xReceive(char* data) {
int packet_size = 0;
while (LoRa.available()) { // read packet up to LORA_MAX_PACKET_LENGTH
char sdata = LoRa.read();
@ -59,7 +59,7 @@ int LoraReceiveSx127x(char* data) {
return packet_size;
}
bool LoraSendSx127x(uint8_t* data, uint32_t len, bool invert) {
bool LoraSx127xSend(uint8_t* data, uint32_t len, bool invert) {
if (invert) {
LoRa.enableInvertIQ(); // active invert I and Q signals
}
@ -73,7 +73,7 @@ bool LoraSendSx127x(uint8_t* data, uint32_t len, bool invert) {
return true;
}
bool LoraConfigSx127x(void) {
bool LoraSx127xConfig(void) {
LoRa.setFrequency(LoraSettings.frequency * 1000 * 1000);
LoRa.setSignalBandwidth(LoraSettings.bandwidth * 1000);
LoRa.setSpreadingFactor(LoraSettings.spreading_factor);
@ -98,11 +98,11 @@ bool LoraConfigSx127x(void) {
return true;
}
bool LoraInitSx127x(void) {
bool LoraSx127xInit(void) {
LoRa.setPins(Pin(GPIO_LORA_CS), Pin(GPIO_LORA_RST), Pin(GPIO_LORA_DI0));
if (LoRa.begin(LoraSettings.frequency * 1000 * 1000)) {
LoraConfigSx127x();
LoRa.onReceive(LoraOnReceiveSx127x);
LoraSx127xConfig();
LoRa.onReceive(LoraSx127xOnReceive);
LoRa.receive();
return true;
}

View File

@ -18,8 +18,8 @@
* which makes the use of single fixed frequency and spreadingfactor hardware like
* SX127x (LiliGo T3, M5 LoRa868 or RFM95W) or SX126x (LiLiGo T3S3) a challenge.
* This driver uses one fixed frequency and spreadingfactor trying to tell the End-Device to do
* the same. In some cases the End-Device needs to be (serial) configured to use a single
* channel and fixed datarate.
* the same using Over The Air Activation (OTAA). In some cases the End-Device needs to be
* (serial) configured to use a single channel and fixed datarate.
*
* To be able to do this:
* - Tasmota needs a filesystem to store persistent data (#define USE_UFILESYS)
@ -152,21 +152,18 @@ void LoraWanTickerSend(void) {
if (1 == Lorawan.send_buffer_step) {
Lorawan.rx = true; // Always send during RX1
Lora.receive_time = 0; // Reset receive timer
LoraWan_Send.attach_ms(TAS_LORAWAN_RECEIVE_DELAY2, LoraWanTickerSend); // Retry after 1000 ms
LoraWan_Send.once_ms(TAS_LORAWAN_RECEIVE_DELAY2, LoraWanTickerSend); // Retry after 1000 ms
}
if (Lorawan.rx) { // If received in RX1 do not resend in RX2
LoraSend(Lorawan.send_buffer, Lorawan.send_buffer_len, true);
}
if (Lorawan.send_buffer_step <= 0) {
LoraWan_Send.detach();
}
}
void LoraWanSendResponse(uint8_t* buffer, size_t len, uint32_t lorawan_delay) {
memcpy(Lorawan.send_buffer, buffer, sizeof(Lorawan.send_buffer));
Lorawan.send_buffer_len = len;
Lorawan.send_buffer_step = 2;
LoraWan_Send.attach_ms(lorawan_delay - TimePassedSince(Lora.receive_time), LoraWanTickerSend);
LoraWan_Send.once_ms(lorawan_delay - TimePassedSince(Lora.receive_time), LoraWanTickerSend);
}
/*-------------------------------------------------------------------------------------------*/

View File

@ -252,6 +252,7 @@ void LoraInit(void) {
#endif // ESP8266
#ifdef ESP32
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
// SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
#endif // ESP32
#ifdef USE_LORAWAN_BRIDGE
@ -266,11 +267,11 @@ void LoraInit(void) {
#ifdef USE_LORA_SX127X
else if (PinUsed(GPIO_LORA_DI0)) {
// SX1276, RFM95W
if (LoraInitSx127x()) {
Lora.Config = &LoraConfigSx127x;
Lora.Available = &LoraAvailableSx127x;
Lora.Receive = &LoraReceiveSx127x;
Lora.Send = &LoraSendSx127x;
if (LoraSx127xInit()) {
Lora.Config = &LoraSx127xConfig;
Lora.Available = &LoraSx127xAvailable;
Lora.Receive = &LoraSx127xReceive;
Lora.Send = &LoraSx127xSend;
strcpy_P(hardware, PSTR("SX127x"));
Lora.present = true;
}
@ -279,11 +280,11 @@ void LoraInit(void) {
#ifdef USE_LORA_SX126X
else if (PinUsed(GPIO_LORA_DI1) && PinUsed(GPIO_LORA_BUSY)) {
// SX1262, LilyGoT3S3
if (LoraInitSx126x()) {
Lora.Config = &LoraConfigSx126x;
Lora.Available = &LoraAvailableSx126x;
Lora.Receive = &LoraReceiveSx126x;
Lora.Send = &LoraSendSx126x;
if (LoraSx126xInit()) {
Lora.Config = &LoraSx126xConfig;
Lora.Available = &LoraSx126xAvailable;
Lora.Receive = &LoraSx126xReceive;
Lora.Send = &LoraSx126xSend;
strcpy_P(hardware, PSTR("SX126x"));
Lora.present = true;
}