diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5eaf568b..e7d4cbe3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -104,6 +104,10 @@ jobs: run: echo "index-url=--additional-urls https://resource.heltec.cn/download/package_CubeCell_index.json" >> $GITHUB_OUTPUT - id: MegaCore:avr:1281 run: echo "index-url=--additional-urls https://mcudude.github.io/MegaCore/package_MCUdude_MegaCore_index.json" >> $GITHUB_OUTPUT + - id: teensy:avr:teensy41 + run: | + echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT + echo "index-url=--additional-urls https://www.pjrc.com/teensy/package_teensy_index.json" >> $GITHUB_OUTPUT - id: arduino:renesas_uno:minima run: | echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT diff --git a/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino b/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino index 7b199c3e..99c65225 100644 --- a/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino +++ b/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino @@ -64,7 +64,7 @@ void loop() { // Perform an uplink int state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload)); - debug((state != RADIOLIB_ERR_RX_TIMEOUT) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false); + debug((state != RADIOLIB_LORAWAN_NO_DOWNLINK) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false); // Wait until next uplink - observing legal & TTN FUP constraints delay(uplinkIntervalSeconds * 1000UL); diff --git a/examples/LoRaWAN/LoRaWAN_ABP/configABP.h b/examples/LoRaWAN/LoRaWAN_ABP/configABP.h index 5d8d29e1..a536ff14 100644 --- a/examples/LoRaWAN/LoRaWAN_ABP/configABP.h +++ b/examples/LoRaWAN/LoRaWAN_ABP/configABP.h @@ -3,10 +3,10 @@ #include -// How often to send an uplink - consider legal & FUP constraints - see notes +// how often to send an uplink - consider legal & FUP constraints - see notes const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds -// Device address - either a development address or one assigned +// device address - either a development address or one assigned // to the LoRaWAN Service Provider - TTN will generate one for you #ifndef RADIOLIB_LORAWAN_DEV_ADDR // Replace with your DevAddr #define RADIOLIB_LORAWAN_DEV_ADDR 0x------ @@ -25,11 +25,10 @@ const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds #define RADIOLIB_LORAWAN_APPS_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- #endif -// For the curious, the #ifndef blocks allow for automated testing &/or you can +// for the curious, the #ifndef blocks allow for automated testing &/or you can // put your EUI & keys in to your platformio.ini - see wiki for more tips - -// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500 +// regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500 const LoRaWANBand_t Region = EU868; const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0 @@ -99,20 +98,17 @@ const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0 #endif - -// Copy over the keys in to the something that will not compile if incorrectly formatted +// copy over the keys in to the something that will not compile if incorrectly formatted uint32_t devAddr = RADIOLIB_LORAWAN_DEV_ADDR; uint8_t NwkSKey[] = { RADIOLIB_LORAWAN_NWKS_KEY }; uint8_t SNwkSIntKey[] = { RADIOLIB_LORAWAN_SNWKSINT_KEY }; // Previously sNwkSIntKey uint8_t NwkSEncKey[] = { RADIOLIB_LORAWAN_NWKSENC_KEY }; // Previously fNwkSIntKey uint8_t AppSKey[] = { RADIOLIB_LORAWAN_APPS_KEY }; - -// Create the LoRaWAN node +// create the LoRaWAN node LoRaWANNode node(&radio, &Region, subBand); - -// Helper function to display any issues +// helper function to display any issues void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) { if (isFail) { Serial.print(message); @@ -123,7 +119,7 @@ void debug(bool isFail, const __FlashStringHelper* message, int state, bool Free } } -// Helper function to display a byte array +// helper function to display a byte array void arrayDump(uint8_t *buffer, uint16_t len) { for(uint16_t c = 0; c < len; c++) { char b = buffer[c]; @@ -133,5 +129,4 @@ void arrayDump(uint8_t *buffer, uint16_t len) { Serial.println(); } - #endif diff --git a/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino b/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino index 23d2ef75..ad49a261 100644 --- a/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino +++ b/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino @@ -122,9 +122,10 @@ void loop() { } else { state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), Port, downlinkPayload, &downlinkSize); } - debug((state != RADIOLIB_ERR_RX_TIMEOUT) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false); + debug((state != RADIOLIB_LORAWAN_NO_DOWNLINK) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false); - if(state == RADIOLIB_ERR_NONE) { + // Check if downlink was received + if(state != RADIOLIB_LORAWAN_NO_DOWNLINK) { // Did we get a downlink with data for us if (downlinkSize > 0) { Serial.println(F("Downlink data: ")); diff --git a/examples/LoRaWAN/LoRaWAN_Reference/config.h b/examples/LoRaWAN/LoRaWAN_Reference/config.h index b9c1bf71..cb681da2 100644 --- a/examples/LoRaWAN/LoRaWAN_Reference/config.h +++ b/examples/LoRaWAN/LoRaWAN_Reference/config.h @@ -3,14 +3,14 @@ #include -// How often to send an uplink - consider legal & FUP constraints - see notes +// how often to send an uplink - consider legal & FUP constraints - see notes const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds -// JoinEUI - previous versions of LoRaWAN called this AppEUI +// joinEUI - previous versions of LoRaWAN called this AppEUI // for development purposes you can use all zeros - see wiki for details #define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000 -// The Device EUI & two keys can be generated on the TTN console +// the Device EUI & two keys can be generated on the TTN console #ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI #define RADIOLIB_LORAWAN_DEV_EUI 0x--------------- #endif @@ -21,16 +21,13 @@ const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds #define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- #endif -// For the curious, the #ifndef blocks allow for automated testing &/or you can +// for the curious, the #ifndef blocks allow for automated testing &/or you can // put your EUI & keys in to your platformio.ini - see wiki for more tips - - -// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500 +// regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500 const LoRaWANBand_t Region = EU868; const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0 - // ============================================================================ // Below is to support the sketch - only make changes if the notes say so ... @@ -96,18 +93,16 @@ const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0 #endif - -// Copy over the EUI's & keys in to the something that will not compile if incorrectly formatted +// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI; uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI; uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY }; uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY }; -// Create the LoRaWAN node +// create the LoRaWAN node LoRaWANNode node(&radio, &Region, subBand); - -// Helper function to display any issues +// helper function to display any issues void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) { if (isFail) { Serial.print(message); @@ -118,7 +113,7 @@ void debug(bool isFail, const __FlashStringHelper* message, int state, bool Free } } -// Helper function to display a byte array +// helper function to display a byte array void arrayDump(uint8_t *buffer, uint16_t len) { for(uint16_t c = 0; c < len; c++) { char b = buffer[c]; @@ -128,5 +123,4 @@ void arrayDump(uint8_t *buffer, uint16_t len) { Serial.println(); } - #endif diff --git a/examples/LoRaWAN/LoRaWAN_Starter/LoRaWAN_Starter.ino b/examples/LoRaWAN/LoRaWAN_Starter/LoRaWAN_Starter.ino index 72c65096..0914c1c0 100644 --- a/examples/LoRaWAN/LoRaWAN_Starter/LoRaWAN_Starter.ino +++ b/examples/LoRaWAN/LoRaWAN_Starter/LoRaWAN_Starter.ino @@ -57,7 +57,7 @@ void loop() { // Perform an uplink int state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload)); - debug((state != RADIOLIB_ERR_RX_TIMEOUT) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false); + debug((state != RADIOLIB_LORAWAN_NO_DOWNLINK) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false); Serial.print(F("Uplink complete, next in ")); Serial.print(uplinkIntervalSeconds); diff --git a/examples/LoRaWAN/LoRaWAN_Starter/config.h b/examples/LoRaWAN/LoRaWAN_Starter/config.h index b9c1bf71..cb681da2 100644 --- a/examples/LoRaWAN/LoRaWAN_Starter/config.h +++ b/examples/LoRaWAN/LoRaWAN_Starter/config.h @@ -3,14 +3,14 @@ #include -// How often to send an uplink - consider legal & FUP constraints - see notes +// how often to send an uplink - consider legal & FUP constraints - see notes const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds -// JoinEUI - previous versions of LoRaWAN called this AppEUI +// joinEUI - previous versions of LoRaWAN called this AppEUI // for development purposes you can use all zeros - see wiki for details #define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000 -// The Device EUI & two keys can be generated on the TTN console +// the Device EUI & two keys can be generated on the TTN console #ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI #define RADIOLIB_LORAWAN_DEV_EUI 0x--------------- #endif @@ -21,16 +21,13 @@ const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds #define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- #endif -// For the curious, the #ifndef blocks allow for automated testing &/or you can +// for the curious, the #ifndef blocks allow for automated testing &/or you can // put your EUI & keys in to your platformio.ini - see wiki for more tips - - -// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500 +// regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500 const LoRaWANBand_t Region = EU868; const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0 - // ============================================================================ // Below is to support the sketch - only make changes if the notes say so ... @@ -96,18 +93,16 @@ const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0 #endif - -// Copy over the EUI's & keys in to the something that will not compile if incorrectly formatted +// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI; uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI; uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY }; uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY }; -// Create the LoRaWAN node +// create the LoRaWAN node LoRaWANNode node(&radio, &Region, subBand); - -// Helper function to display any issues +// helper function to display any issues void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) { if (isFail) { Serial.print(message); @@ -118,7 +113,7 @@ void debug(bool isFail, const __FlashStringHelper* message, int state, bool Free } } -// Helper function to display a byte array +// helper function to display a byte array void arrayDump(uint8_t *buffer, uint16_t len) { for(uint16_t c = 0; c < len; c++) { char b = buffer[c]; @@ -128,5 +123,4 @@ void arrayDump(uint8_t *buffer, uint16_t len) { Serial.println(); } - #endif diff --git a/examples/LoRaWAN/README.md b/examples/LoRaWAN/README.md index a269810b..8a44860f 100644 --- a/examples/LoRaWAN/README.md +++ b/examples/LoRaWAN/README.md @@ -1,18 +1,20 @@ # LoRaWAN examples RadioLib LoRaWAN v1.1 examples. -* [LoRaWAN_Starter](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Starter): this is the recommended entry point for new users. Please read the `notes` that come with this example to learn more about LoRaWAN and how to use it in RadioLib! -* [LoRaWAN_Reference](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Reference): this sketch showcases most of the available API for LoRaWAN in RadioLib. Be frightened by the possibilities! It is recommended you have read all the `notes` for the Starter sketch first, as well as the [Learn section on The Things Network](https://www.thethingsnetwork.org/docs/lorawan/)! +* [LoRaWAN_Starter](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Starter): this is the recommended entry point for new users. Please read the [`notes`](https://github.com/jgromes/RadioLib/blob/master/examples/LoRaWAN/LoRaWAN_Starter/notes.md) that come with this example to learn more about LoRaWAN and how to use it in RadioLib! +* [LoRaWAN_Reference](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Reference): this sketch showcases most of the available API for LoRaWAN in RadioLib. Be frightened by the possibilities! It is recommended you have read all the [`notes`](https://github.com/jgromes/RadioLib/blob/master/examples/LoRaWAN/LoRaWAN_Starter/notes.md) for the Starter sketch first, as well as the [Learn section on The Things Network](https://www.thethingsnetwork.org/docs/lorawan/)! * [LoRaWAN_ABP](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_ABP): if you wish to use ABP instead of OTAA (but why?), this example shows how you can do this using RadioLib. --- -All three of these examples do not fully comply with LoRaWAN v1.1: for that, persistent storage is necessary. As the implementation of persistent storage differs between different platforms, these are not given here, but in a separate repository, see below: +> [!WARNING] +> These examples do not fully comply with LoRaWAN v1.1: for that, persistent storage is necessary. As the implementation of persistent storage differs between different platforms, these are not given here, but in a separate repository, see below: ## RadioLib persistence In [this repository](https://github.com/radiolib-org/radiolib-persistence), examples are provided that do comply with the required persistence of certain parameters for LoRaWAN v1.1. Examples are (or will become) available for some of the most popular platforms. **These examples assume you have successfully used the Starter sketch and understood (most of) the accompanying notes!** Currently, examples are available for the following platforms: * [LoRaWAN for ESP32](https://github.com/radiolib-org/radiolib-persistence/tree/main/examples/LoRaWAN_ESP32) +* [LoRaWAN for ESP8266](https://github.com/radiolib-org/radiolib-persistence/tree/main/examples/LoRaWAN_ESP8266) -_This list is last updated for RadioLib 6.5.0_ +_This list is last updated at 30/03/2024._ diff --git a/idf_component.yml b/idf_component.yml index 09f82ad9..572ca4d8 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -1,4 +1,4 @@ -version: "6.4.2" +version: "6.5.0" description: "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN)." tags: "radio, communication, morse, cc1101, aprs, sx1276, sx1278, sx1272, rtty, ax25, afsk, nrf24, rfm96, sx1231, rfm96, rfm98, sstv, sx1278, sx1272, sx1276, sx1280, sx1281, sx1282, sx1261, sx1262, sx1268, si4432, rfm22, llcc68, pager, pocsag, lorawan" url: "https://github.com/jgromes/RadioLib" diff --git a/keywords.txt b/keywords.txt index 48efe632..d9d59507 100644 --- a/keywords.txt +++ b/keywords.txt @@ -134,6 +134,7 @@ getSNR KEYWORD2 getDataRate KEYWORD2 setBitRate KEYWORD2 setRxBandwidth KEYWORD2 +autoSetRxBandwidth KEYWORD2 setAFCBandwidth KEYWORD2 setAFC KEYWORD2 setAFCAGCTrigger KEYWORD2 @@ -436,4 +437,5 @@ RADIOLIB_ERR_N_FCNT_DOWN_INVALID LITERAL1 RADIOLIB_ERR_A_FCNT_DOWN_INVALID LITERAL1 RADIOLIB_ERR_DATA_RATE_INVALID LITERAL1 RADIOLIB_ERR_DWELL_TIME_EXCEEDED LITERAL1 -RADIOLIB_ERR_CHECKSUM_MISMATCH LITERAL1 \ No newline at end of file +RADIOLIB_ERR_CHECKSUM_MISMATCH LITERAL1 +RADIOLIB_LORAWAN_NO_DOWNLINK LITERAL1 diff --git a/library.json b/library.json index 2927c2f6..07583852 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "RadioLib", - "version": "6.4.2", + "version": "6.5.0", "description": "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN).", "keywords": "radio, communication, morse, cc1101, aprs, sx1276, sx1278, sx1272, rtty, ax25, afsk, nrf24, rfm96, sx1231, rfm96, rfm98, sstv, sx1278, sx1272, sx1276, sx1280, sx1281, sx1282, sx1261, sx1262, sx1268, si4432, rfm22, llcc68, pager, pocsag, lorawan", "homepage": "https://github.com/jgromes/RadioLib", diff --git a/library.properties b/library.properties index 9fd734b1..0b435dfc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=RadioLib -version=6.4.2 +version=6.5.0 author=Jan Gromes maintainer=Jan Gromes sentence=Universal wireless communication library diff --git a/src/ArduinoHal.h b/src/ArduinoHal.h index 00074c1d..2fa8b5d6 100644 --- a/src/ArduinoHal.h +++ b/src/ArduinoHal.h @@ -60,7 +60,7 @@ class ArduinoHal : public RadioLibHal { uint32_t pinToInterrupt(uint32_t pin) override; #if !RADIOLIB_GODMODE - private: + protected: #endif SPIClass* spi = NULL; SPISettings spiSettings = RADIOLIB_DEFAULT_SPI_SETTINGS; diff --git a/src/BuildOpt.h b/src/BuildOpt.h index 5653a1ef..9b25d3fe 100644 --- a/src/BuildOpt.h +++ b/src/BuildOpt.h @@ -557,8 +557,8 @@ // version definitions #define RADIOLIB_VERSION_MAJOR 6 -#define RADIOLIB_VERSION_MINOR 4 -#define RADIOLIB_VERSION_PATCH 2 +#define RADIOLIB_VERSION_MINOR 5 +#define RADIOLIB_VERSION_PATCH 0 #define RADIOLIB_VERSION_EXTRA 0 #define RADIOLIB_VERSION (((RADIOLIB_VERSION_MAJOR) << 24) | ((RADIOLIB_VERSION_MINOR) << 16) | ((RADIOLIB_VERSION_PATCH) << 8) | (RADIOLIB_VERSION_EXTRA)) diff --git a/src/TypeDef.h b/src/TypeDef.h index 818d99d5..6cb67247 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -558,6 +558,11 @@ */ #define RADIOLIB_ERR_CHECKSUM_MISMATCH (-1115) +/*! + \brief No downlink was received - most likely none was sent from the server. +*/ +#define RADIOLIB_LORAWAN_NO_DOWNLINK (-1116) + /*! \} */ diff --git a/src/modules/CC1101/CC1101.cpp b/src/modules/CC1101/CC1101.cpp index 16bd25ee..af7f1df9 100644 --- a/src/modules/CC1101/CC1101.cpp +++ b/src/modules/CC1101/CC1101.cpp @@ -100,29 +100,29 @@ void CC1101::reset() { int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) { // calculate timeout (5ms + 500 % of expected time-on-air) - uint32_t timeout = 5000000 + (uint32_t)((((float)(len * 8)) / (this->bitRate * 1000.0)) * 5000000.0); + uint32_t timeout = 5 + (uint32_t)((((float)(len * 8)) / this->bitRate) * 5); // start transmission int16_t state = startTransmit(data, len, addr); RADIOLIB_ASSERT(state); // wait for transmission start or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getGpio())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } } // wait for transmission end or timeout - start = this->mod->hal->micros(); + start = this->mod->hal->millis(); while(this->mod->hal->digitalRead(this->mod->getGpio())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } @@ -133,18 +133,18 @@ int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) { int16_t CC1101::receive(uint8_t* data, size_t len) { // calculate timeout (500 ms + 400 full max-length packets at current bit rate) - uint32_t timeout = 500000 + (1.0/(this->bitRate*1000.0))*(RADIOLIB_CC1101_MAX_PACKET_LENGTH*400.0); + uint32_t timeout = 500 + (1.0/(this->bitRate))*(RADIOLIB_CC1101_MAX_PACKET_LENGTH*400.0); // start reception int16_t state = startReceive(); RADIOLIB_ASSERT(state); // wait for packet start or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { standby(); SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); return(RADIOLIB_ERR_RX_TIMEOUT); @@ -152,11 +152,11 @@ int16_t CC1101::receive(uint8_t* data, size_t len) { } // wait for packet end or timeout - start = this->mod->hal->micros(); + start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { standby(); SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); return(RADIOLIB_ERR_RX_TIMEOUT); @@ -489,6 +489,24 @@ int16_t CC1101::setRxBandwidth(float rxBw) { return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH); } +int16_t CC1101::autoSetRxBandwidth() { + // Uncertainty ~ +/- 40ppm for a cheap CC1101 + // Uncertainty * 2 for both transmitter and receiver + float uncertainty = ((this->frequency) * 40 * 2); + uncertainty = (uncertainty/1000); //Since bitrate is in kBit + float minbw = ((this->bitRate) + uncertainty); + + int possibles[16] = {58, 68, 81, 102, 116, 135, 162, 203, 232, 270, 325, 406, 464, 541, 650, 812}; + + for (int i = 0; i < 16; i++) { + if (possibles[i] > minbw) { + int16_t state = setRxBandwidth(possibles[i]); + return(state); + } + } + return(RADIOLIB_ERR_UNKNOWN); + } + int16_t CC1101::setFrequencyDeviation(float freqDev) { // set frequency deviation to lowest available setting (required for digimodes) float newFreqDev = freqDev; diff --git a/src/modules/CC1101/CC1101.h b/src/modules/CC1101/CC1101.h index bb979116..69b8e4eb 100644 --- a/src/modules/CC1101/CC1101.h +++ b/src/modules/CC1101/CC1101.h @@ -745,6 +745,14 @@ class CC1101: public PhysicalLayer { */ int16_t setRxBandwidth(float rxBw); + /*! + \brief calculates and sets Rx bandwidth based on the freq, baud and freq uncertainty. + Reimplement of atlas0fd00m's (RfCat) CalculatePktChanBw function. + Modified for worse ppm with the CC1101, and adjusted for the supportted CC1101 bw. + \returns \ref status_codes + */ + int16_t autoSetRxBandwidth(); + /*! \brief Sets frequency deviation. Allowed values range from 1.587 to 380.8 kHz. \param freqDev Frequency deviation to be set in kHz. diff --git a/src/modules/RF69/RF69.cpp b/src/modules/RF69/RF69.cpp index a934898e..84080f38 100644 --- a/src/modules/RF69/RF69.cpp +++ b/src/modules/RF69/RF69.cpp @@ -100,18 +100,18 @@ void RF69::reset() { int16_t RF69::transmit(uint8_t* data, size_t len, uint8_t addr) { // calculate timeout (5ms + 500 % of expected time-on-air) - uint32_t timeout = 5000000 + (uint32_t)((((float)(len * 8)) / (this->bitRate * 1000.0)) * 5000000.0); + uint32_t timeout = 5 + (uint32_t)((((float)(len * 8)) / this->bitRate) * 5); // start transmission int16_t state = startTransmit(data, len, addr); RADIOLIB_ASSERT(state); // wait for transmission end or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } @@ -122,18 +122,18 @@ int16_t RF69::transmit(uint8_t* data, size_t len, uint8_t addr) { int16_t RF69::receive(uint8_t* data, size_t len) { // calculate timeout (500 ms + 400 full 64-byte packets at current bit rate) - uint32_t timeout = 500000 + (1.0/(this->bitRate*1000.0))*(RADIOLIB_RF69_MAX_PACKET_LENGTH*400.0); + uint32_t timeout = 500 + (1.0/(this->bitRate))*(RADIOLIB_RF69_MAX_PACKET_LENGTH*400.0); // start reception int16_t state = startReceive(); RADIOLIB_ASSERT(state); // wait for packet reception or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { standby(); clearIRQFlags(); return(RADIOLIB_ERR_RX_TIMEOUT); diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 161a5245..2c029e54 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -231,41 +231,27 @@ int16_t SX126x::transmit(uint8_t* data, size_t len, uint8_t addr) { return(RADIOLIB_ERR_PACKET_TOO_LONG); } - uint32_t timeout = 0; - - // get currently active modem - uint8_t modem = getPacketType(); - if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) { - // calculate timeout (150% of expected time-on-air) - timeout = (getTimeOnAir(len) * 3) / 2; - - } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) { - // calculate timeout (500% of expected time-on-air) - timeout = getTimeOnAir(len) * 5; - - } else { - return(RADIOLIB_ERR_UNKNOWN); - } - - RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout); + // calculate timeout in ms (500% of expected time-on-air) + uint32_t timeout = (getTimeOnAir(len) * 5) / 1000; + RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout); // start transmission state = startTransmit(data, len, addr); RADIOLIB_ASSERT(state); // wait for packet transmission or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } } - uint32_t elapsed = this->mod->hal->micros() - start; // update data rate - this->dataRateMeasured = (len*8.0)/((float)elapsed/1000000.0); + uint32_t elapsed = this->mod->hal->millis() - start; + this->dataRateMeasured = (len*8.0)/((float)elapsed/1000.0); return(finishTransmit()); } @@ -282,7 +268,8 @@ int16_t SX126x::receive(uint8_t* data, size_t len) { if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) { // calculate timeout (100 LoRa symbols, the default for SX127x series) float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz; - timeout = (uint32_t)(symbolLength * 100.0 * 1000.0); + timeout = (uint32_t)(symbolLength * 100.0); + } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) { // calculate timeout (500 % of expected time-one-air) size_t maxLen = len; @@ -290,26 +277,27 @@ int16_t SX126x::receive(uint8_t* data, size_t len) { maxLen = 0xFF; } float brBps = ((float)(RADIOLIB_SX126X_CRYSTAL_FREQ) * 1000000.0 * 32.0) / (float)this->bitRate; - timeout = (uint32_t)(((maxLen * 8.0) / brBps) * 1000000.0 * 5.0); + timeout = (uint32_t)(((maxLen * 8.0) / brBps) * 1000.0 * 5.0); } else { return(RADIOLIB_ERR_UNKNOWN); + } - RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout); + RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout); // start reception - uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625); + uint32_t timeoutValue = (uint32_t)(((float)timeout * 1000.0) / 15.625); state = startReceive(timeoutValue); RADIOLIB_ASSERT(state); // wait for packet reception or timeout bool softTimeout = false; - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); // safety check, the timeout should be done by the radio - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { softTimeout = true; break; } diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 7606f001..98d78394 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -149,13 +149,14 @@ int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) { int16_t modem = getActiveModem(); uint32_t start = 0; uint32_t timeout = 0; + uint32_t toa = getTimeOnAir(len); if(modem == RADIOLIB_SX127X_LORA) { - // calculate timeout (150 % of expected time-on-air) - timeout = getTimeOnAir(len) * 1.5; + // calculate timeout in ms (150 % of expected time-on-air) + timeout = (toa * 1.5) / 1000; } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - // calculate timeout (5ms + 500 % of expected time-on-air) - timeout = 5000 + getTimeOnAir(len) * 5; + // calculate timeout in ms (5ms + 500 % of expected time-on-air) + timeout = 5 + (toa * 5) / 1000; } else { return(RADIOLIB_ERR_UNKNOWN); @@ -163,22 +164,23 @@ int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) { } // start transmission + RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout); state = startTransmit(data, len, addr); RADIOLIB_ASSERT(state); // wait for packet transmission or timeout - start = this->mod->hal->micros(); + start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } } // update data rate - uint32_t elapsed = this->mod->hal->micros() - start; - this->dataRate = (len*8.0)/((float)elapsed/1000000.0); + uint32_t elapsed = this->mod->hal->millis() - start; + this->dataRate = (len*8.0)/((float)elapsed/1000.0); return(finishTransmit()); } @@ -198,17 +200,17 @@ int16_t SX127x::receive(uint8_t* data, size_t len) { uint32_t timeout = 0; if(this->mod->getGpio() == RADIOLIB_NC) { float symbolLength = (float) (uint32_t(1) << this->spreadingFactor) / (float) this->bandwidth; - timeout = (uint32_t)(symbolLength * 100.0 * 1000.0); + timeout = (uint32_t)(symbolLength * 100.0); } // wait for packet reception or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); if(this->mod->getGpio() == RADIOLIB_NC) { // no GPIO pin provided, use software timeout - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { clearIRQFlags(); return(RADIOLIB_ERR_RX_TIMEOUT); } @@ -223,18 +225,18 @@ int16_t SX127x::receive(uint8_t* data, size_t len) { } } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - // calculate timeout (500 % of expected time-on-air) - uint32_t timeout = getTimeOnAir(len) * 5; + // calculate timeout in ms (500 % of expected time-on-air) + uint32_t timeout = (getTimeOnAir(len) * 5) / 1000; // set mode to receive state = startReceive(len, RADIOLIB_SX127X_RX); RADIOLIB_ASSERT(state); // wait for packet reception or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { clearIRQFlags(); return(RADIOLIB_ERR_RX_TIMEOUT); } @@ -1252,31 +1254,30 @@ uint32_t SX127x::getTimeOnAir(size_t len) { // get number of symbols float n_sym = getNumSymbols(len); - // Get time-on-air in us + // get time-on-air in us return ceil((double)symbolLength * (double)n_sym) * 1000; } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - // Get number of bits preamble + // get number of bits preamble float n_pre = (float) ((this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB_FSK) << 8) | this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB_FSK)) * 8; - //Get the number of bits of the sync word + // get the number of bits of the sync word float n_syncWord = (float) (this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, 2, 0) + 1) * 8; - //Get CRC bits + // get CRC bits float crc = (this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 4, 4) == RADIOLIB_SX127X_CRC_ON) * 16; if (this->packetLengthConfig == RADIOLIB_SX127X_PACKET_FIXED) { - //If Packet size fixed -> len = fixed packet length + // if packet size fixed -> len = fixed packet length len = this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH_FSK); } else { - //if packet variable -> Add 1 extra byte for payload length + // if packet variable -> Add 1 extra byte for payload length len += 1; } - // Calculate time-on-air in us {[(length in bytes) * (8 bits / 1 byte)] / [(Bit Rate in kbps) * (1000 bps / 1 kbps)]} * (1000000 us in 1 sec) - return (uint32_t) (((crc + n_syncWord + n_pre + (float) (len * 8)) / (this->bitRate * 1000.0)) * 1000000.0); - } else { - return(RADIOLIB_ERR_UNKNOWN); + // calculate time-on-air in us {[(length in bytes) * (8 bits / 1 byte)] / [(Bit Rate in kbps) * (1000 bps / 1 kbps)]} * (1000000 us in 1 sec) + return((uint32_t) (((crc + n_syncWord + n_pre + (float) (len * 8)) / (this->bitRate * 1000.0)) * 1000000.0)); } - + + return(RADIOLIB_ERR_UNKNOWN); } uint32_t SX127x::calculateRxTimeout(uint32_t timeoutUs) { diff --git a/src/modules/SX128x/SX128x.cpp b/src/modules/SX128x/SX128x.cpp index 55b18dd9..2df75594 100644 --- a/src/modules/SX128x/SX128x.cpp +++ b/src/modules/SX128x/SX128x.cpp @@ -305,20 +305,19 @@ int16_t SX128x::transmit(uint8_t* data, size_t len, uint8_t addr) { int16_t state = standby(); RADIOLIB_ASSERT(state); - // calculate timeout (500% of expected time-on-air) - uint32_t timeout = getTimeOnAir(len) * 5; - - RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout); + // calculate timeout in ms (500% of expected time-on-air) + uint32_t timeout = (getTimeOnAir(len) * 5) / 1000; + RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout); // start transmission state = startTransmit(data, len, addr); RADIOLIB_ASSERT(state); // wait for packet transmission or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } @@ -340,8 +339,7 @@ int16_t SX128x::receive(uint8_t* data, size_t len) { // calculate timeout (1000% of expected time-on-air) uint32_t timeout = getTimeOnAir(len) * 10; - - RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout); + RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout); // start reception uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625); @@ -350,11 +348,11 @@ int16_t SX128x::receive(uint8_t* data, size_t len) { // wait for packet reception or timeout bool softTimeout = false; - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(!this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); // safety check, the timeout should be done by the radio - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { softTimeout = true; break; } diff --git a/src/modules/Si443x/Si443x.cpp b/src/modules/Si443x/Si443x.cpp index 541f3eb7..dcd63751 100644 --- a/src/modules/Si443x/Si443x.cpp +++ b/src/modules/Si443x/Si443x.cpp @@ -73,17 +73,17 @@ void Si443x::reset() { int16_t Si443x::transmit(uint8_t* data, size_t len, uint8_t addr) { // calculate timeout (5ms + 500 % of expected time-on-air) - uint32_t timeout = 5000000 + (uint32_t)((((float)(len * 8)) / (this->bitRate * 1000.0)) * 5000000.0); + uint32_t timeout = 5 + (uint32_t)((((float)(len * 8)) / this->bitRate) * 5); // start transmission int16_t state = startTransmit(data, len, addr); RADIOLIB_ASSERT(state); // wait for transmission end or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } @@ -94,16 +94,16 @@ int16_t Si443x::transmit(uint8_t* data, size_t len, uint8_t addr) { int16_t Si443x::receive(uint8_t* data, size_t len) { // calculate timeout (500 ms + 400 full 64-byte packets at current bit rate) - uint32_t timeout = 500000 + (1.0/(this->bitRate*1000.0))*(RADIOLIB_SI443X_MAX_PACKET_LENGTH*400.0); + uint32_t timeout = 500 + (1.0/(this->bitRate))*(RADIOLIB_SI443X_MAX_PACKET_LENGTH*400.0); // start reception int16_t state = startReceive(); RADIOLIB_ASSERT(state); // wait for packet reception or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(this->mod->hal->digitalRead(this->mod->getIrq())) { - if(this->mod->hal->micros() - start > timeout) { + if(this->mod->hal->millis() - start > timeout) { standby(); clearIRQFlags(); return(RADIOLIB_ERR_RX_TIMEOUT); diff --git a/src/modules/nRF24/nRF24.cpp b/src/modules/nRF24/nRF24.cpp index a5429884..40678b8c 100644 --- a/src/modules/nRF24/nRF24.cpp +++ b/src/modules/nRF24/nRF24.cpp @@ -88,7 +88,7 @@ int16_t nRF24::transmit(uint8_t* data, size_t len, uint8_t addr) { RADIOLIB_ASSERT(state); // wait until transmission is finished - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); @@ -98,8 +98,8 @@ int16_t nRF24::transmit(uint8_t* data, size_t len, uint8_t addr) { return(RADIOLIB_ERR_ACK_NOT_RECEIVED); } - // check timeout: 15 retries * 4ms (max Tx time as per datasheet) - if(this->mod->hal->micros() - start >= 60000) { + // check timeout: 15 retries * 4ms (max Tx time as per datasheet) + 10 ms + if(this->mod->hal->millis() - start >= ((15 * 4) + 10)) { finishTransmit(); return(RADIOLIB_ERR_TX_TIMEOUT); } @@ -114,12 +114,12 @@ int16_t nRF24::receive(uint8_t* data, size_t len) { RADIOLIB_ASSERT(state); // wait for Rx_DataReady or timeout - uint32_t start = this->mod->hal->micros(); + uint32_t start = this->mod->hal->millis(); while(this->mod->hal->digitalRead(this->mod->getIrq())) { this->mod->hal->yield(); - // check timeout: 15 retries * 4ms (max Tx time as per datasheet) - if(this->mod->hal->micros() - start >= 60000) { + // check timeout: 15 retries * 4ms (max Tx time as per datasheet) + 10 ms + if(this->mod->hal->millis() - start >= ((15 * 4) + 10)) { standby(); clearIRQ(); return(RADIOLIB_ERR_RX_TIMEOUT); diff --git a/src/protocols/LoRaWAN/LoRaWAN.cpp b/src/protocols/LoRaWAN/LoRaWAN.cpp index 0e7692c3..a29aaf1b 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.cpp +++ b/src/protocols/LoRaWAN/LoRaWAN.cpp @@ -1226,7 +1226,7 @@ int16_t LoRaWANNode::downlinkCommon() { this->phyLayer->invertIQ(false); } - return(RADIOLIB_ERR_RX_TIMEOUT); + return(RADIOLIB_LORAWAN_NO_DOWNLINK); } // wait for the DIO to fire indicating a downlink is received