mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Fix ESP32 LoRaWanBridge OTAA
This commit is contained in:
parent
48aa621975
commit
03cf7dc460
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user