From 24815c6cdcae30005d4da41b280bfcb046572152 Mon Sep 17 00:00:00 2001 From: lewisxhe Date: Mon, 13 Jan 2025 10:28:08 +0800 Subject: [PATCH] RadioLib update to v7.1.2 --- .../.github/ISSUE_TEMPLATE/bug_report.md | 4 +- .../.github/ISSUE_TEMPLATE/feature_request.md | 4 +- .../ISSUE_TEMPLATE/module-not-working.md | 2 +- .../.github/ISSUE_TEMPLATE/regular-issue.md | 2 +- lib/RadioLib/.github/workflows/main.yml | 84 +++++-- lib/RadioLib/.github/workflows/release.yml | 37 +++ lib/RadioLib/.github/workflows/unit-test.yml | 27 +++ lib/RadioLib/README.md | 14 +- .../CC1101_Receive_Interrupt.ino | 30 +-- .../CC1101_Transmit_Address.ino | 4 +- .../CC1101_Transmit_Blocking.ino | 4 +- .../CC1101_Transmit_Interrupt.ino | 34 +-- ...0_Channel_Activity_Detection_Interrupt.ino | 30 +-- .../LR11x0_LR_FHSS_Modem.ino | 3 +- .../LR11x0_Receive_Interrupt.ino | 30 +-- .../LR11x0_Transmit_Interrupt.ino | 30 +-- .../LR11x0_WiFi_Scan_Interrupt.ino | 28 +-- .../LoRaWAN_Reference/LoRaWAN_Reference.ino | 2 +- .../examples/LoRaWAN/LoRaWAN_Starter/notes.md | 2 +- lib/RadioLib/examples/LoRaWAN/README.md | 14 +- .../NonArduino/ESP-IDF/main}/EspHal.h | 2 +- .../examples/NonArduino/ESP-IDF/main/main.cpp | 2 +- .../examples/NonArduino/Tock/CMakeLists.txt | 28 ++- .../examples/NonArduino/Tock/README.md | 2 +- .../examples/NonArduino/Tock/build.sh | 4 +- .../examples/NonArduino/Tock/main.cpp | 6 +- .../RF69_Receive_Interrupt.ino | 30 +-- .../RF69_Transmit_Interrupt.ino | 30 +-- ...x_Channel_Activity_Detection_Interrupt.ino | 24 +- .../STM32WLx_Receive_Interrupt.ino | 24 +- .../STM32WLx_Transmit_Interrupt.ino | 24 +- ...x_Channel_Activity_Detection_Interrupt.ino | 30 +-- ...26x_Channel_Activity_Detection_Receive.ino | 35 +-- .../SX126x_FSK_Modem/SX126x_FSK_Modem.ino | 29 --- .../SX126x_LR_FHSS_Modem.ino | 3 +- .../SX126x_Receive_Interrupt.ino | 30 +-- .../SX126x_Transmit_Interrupt.ino | 30 +-- ...x_Channel_Activity_Detection_Interrupt.ino | 60 ++--- ...27x_Channel_Activity_Detection_Receive.ino | 66 ++--- .../SX127x_Receive_Direct.ino | 12 +- .../SX127x_Receive_Interrupt.ino | 30 +-- .../SX127x_Transmit_Interrupt.ino | 30 +-- ...x_Channel_Activity_Detection_Interrupt.ino | 30 +-- .../SX128x_Receive_Interrupt.ino | 30 +-- .../SX128x_Transmit_Interrupt.ino | 30 +-- .../Si443x_Receive_Interrupt.ino | 30 +-- .../Si443x_Transmit_Interrupt.ino | 30 +-- .../nRF24_Receive_Interrupt.ino | 30 +-- .../nRF24_Transmit_Interrupt.ino | 30 +-- lib/RadioLib/idf_component.yml | 2 +- lib/RadioLib/keywords.txt | 2 + lib/RadioLib/library.json | 2 +- lib/RadioLib/library.properties | 2 +- lib/RadioLib/src/BuildOpt.h | 13 +- lib/RadioLib/src/Module.cpp | 10 +- lib/RadioLib/src/Module.h | 12 +- lib/RadioLib/src/RadioLib.h | 8 +- lib/RadioLib/src/hal/Tock/libtockHal.h | 225 ------------------ lib/RadioLib/src/modules/CC1101/CC1101.cpp | 192 +++++++-------- lib/RadioLib/src/modules/CC1101/CC1101.h | 24 +- lib/RadioLib/src/modules/LLCC68/LLCC68.cpp | 13 +- lib/RadioLib/src/modules/LLCC68/LLCC68.h | 1 + lib/RadioLib/src/modules/LR11x0/LR1110.cpp | 6 +- lib/RadioLib/src/modules/LR11x0/LR1120.cpp | 6 +- lib/RadioLib/src/modules/LR11x0/LR11x0.cpp | 68 +++--- lib/RadioLib/src/modules/LR11x0/LR11x0.h | 11 +- lib/RadioLib/src/modules/RF69/RF69.cpp | 4 + lib/RadioLib/src/modules/RF69/RF69.h | 8 + lib/RadioLib/src/modules/SX126x/SX1261.cpp | 16 +- lib/RadioLib/src/modules/SX126x/SX1261.h | 2 +- lib/RadioLib/src/modules/SX126x/SX1262.cpp | 6 +- lib/RadioLib/src/modules/SX126x/SX1268.cpp | 6 +- lib/RadioLib/src/modules/SX126x/SX126x.cpp | 122 ++++------ lib/RadioLib/src/modules/SX126x/SX126x.h | 11 +- lib/RadioLib/src/modules/SX127x/SX1272.cpp | 33 +-- lib/RadioLib/src/modules/SX127x/SX1272.h | 1 - lib/RadioLib/src/modules/SX127x/SX1273.cpp | 4 +- lib/RadioLib/src/modules/SX127x/SX1276.cpp | 4 +- lib/RadioLib/src/modules/SX127x/SX1277.cpp | 4 +- lib/RadioLib/src/modules/SX127x/SX1278.cpp | 33 +-- lib/RadioLib/src/modules/SX127x/SX1278.h | 1 - lib/RadioLib/src/modules/SX127x/SX1279.cpp | 4 +- lib/RadioLib/src/modules/SX127x/SX127x.cpp | 45 +++- lib/RadioLib/src/modules/SX127x/SX127x.h | 10 + lib/RadioLib/src/modules/SX128x/SX128x.cpp | 23 +- lib/RadioLib/src/modules/nRF24/nRF24.cpp | 38 +-- .../src/protocols/LoRaWAN/LoRaWAN.cpp | 185 +++++++------- lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.h | 49 ++-- .../src/protocols/LoRaWAN/LoRaWANBands.cpp | 95 ++------ lib/RadioLib/src/protocols/Pager/Pager.cpp | 11 +- .../protocols/PhysicalLayer/PhysicalLayer.h | 6 +- lib/RadioLib/src/utils/Utils.cpp | 2 +- lib/RadioLib/src/utils/Utils.h | 2 +- 93 files changed, 1143 insertions(+), 1305 deletions(-) create mode 100644 lib/RadioLib/.github/workflows/release.yml create mode 100644 lib/RadioLib/.github/workflows/unit-test.yml rename lib/RadioLib/{src/hal/ESP-IDF => examples/NonArduino/ESP-IDF/main}/EspHal.h (98%) delete mode 100644 lib/RadioLib/src/hal/Tock/libtockHal.h diff --git a/lib/RadioLib/.github/ISSUE_TEMPLATE/bug_report.md b/lib/RadioLib/.github/ISSUE_TEMPLATE/bug_report.md index 5ef9564..486e056 100644 --- a/lib/RadioLib/.github/ISSUE_TEMPLATE/bug_report.md +++ b/lib/RadioLib/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,8 +7,8 @@ assignees: '' --- -**IMPORTANT: Check the wiki** -Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there. +**IMPORTANT: Check the docs** +Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). **Describe the bug** A clear and concise description of what the bug is. When applicable, please include [debug mode output](https://github.com/jgromes/RadioLib/wiki/Debug-mode) **using the appropriate debug mode**. diff --git a/lib/RadioLib/.github/ISSUE_TEMPLATE/feature_request.md b/lib/RadioLib/.github/ISSUE_TEMPLATE/feature_request.md index ec5c496..a01ef16 100644 --- a/lib/RadioLib/.github/ISSUE_TEMPLATE/feature_request.md +++ b/lib/RadioLib/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,8 +7,8 @@ assignees: '' --- -**IMPORTANT: Check the wiki** -Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there. +**IMPORTANT: Check the docs** +Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] diff --git a/lib/RadioLib/.github/ISSUE_TEMPLATE/module-not-working.md b/lib/RadioLib/.github/ISSUE_TEMPLATE/module-not-working.md index d6d8f35..be93f67 100644 --- a/lib/RadioLib/.github/ISSUE_TEMPLATE/module-not-working.md +++ b/lib/RadioLib/.github/ISSUE_TEMPLATE/module-not-working.md @@ -9,7 +9,7 @@ assignees: '' **IMPORTANT: Before submitting an issue, please check the following:** 1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored. -2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there. +2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). 3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases). 4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib! 5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html). diff --git a/lib/RadioLib/.github/ISSUE_TEMPLATE/regular-issue.md b/lib/RadioLib/.github/ISSUE_TEMPLATE/regular-issue.md index c55b36a..3e1b8d0 100644 --- a/lib/RadioLib/.github/ISSUE_TEMPLATE/regular-issue.md +++ b/lib/RadioLib/.github/ISSUE_TEMPLATE/regular-issue.md @@ -9,7 +9,7 @@ assignees: '' **IMPORTANT: Before submitting an issue, please check the following:** 1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored. -2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there. +2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). 3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases). 4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib! 5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html). diff --git a/lib/RadioLib/.github/workflows/main.yml b/lib/RadioLib/.github/workflows/main.yml index 06c8d6f..22383d8 100644 --- a/lib/RadioLib/.github/workflows/main.yml +++ b/lib/RadioLib/.github/workflows/main.yml @@ -36,6 +36,7 @@ on: - MegaCore:avr:1281 - teensy:avr:teensy41 - arduino:renesas_uno:minima + - SiliconLabs:silabs:xg24explorerkit jobs: build: @@ -89,7 +90,7 @@ jobs: - id: STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1 run: | # Do *not* skip STM32WL examples - echo "skip-pattern='LR11x0_Firmware_Update'" >> $GITHUB_OUTPUT + echo "skip-pattern=(LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT - id: stm32duino:STM32F1:mapleMini run: | @@ -118,6 +119,9 @@ jobs: - id: arduino:renesas_uno:minima run: | echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT + - id: SiliconLabs:silabs:xg24explorerkit + run: | + echo "index-url=--additional-urls https://siliconlabs.github.io/arduino/package_arduinosilabs_index.json" >> $GITHUB_OUTPUT runs-on: ubuntu-latest name: ${{ matrix.id }} @@ -176,28 +180,62 @@ jobs: if: ${{ env.run-build == 'true' }} run: | - for example in $(find $PWD/examples -name '*.ino' | sort); do - # check whether to skip this sketch - if [ ! -z '${{ steps.prep.outputs.skip-pattern }}' ] && [[ ${example} =~ ${{ steps.prep.outputs.skip-pattern }} ]]; then - # skip sketch - echo -e "\n\033[1;33mSkipped ${example##*/} (matched with ${{ steps.prep.outputs.skip-pattern }})\033[0m"; - else - # apply special flags for LoRaWAN - if [[ ${example} =~ "LoRaWAN" ]]; then - flags="-DRADIOLIB_LORAWAN_DEV_ADDR=0 -DRADIOLIB_LORAWAN_FNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_SNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_NWKSENC_KEY=0 -DRADIOLIB_LORAWAN_APPS_KEY=0 -DRADIOLIB_LORAWAN_APP_KEY=0 -DRADIOLIB_LORAWAN_NWK_KEY=0 -DRADIOLIB_LORAWAN_DEV_EUI=0 -DARDUINO_TTGO_LORA32_V1" - fi + cd $PWD/extras/test/ci + ./build_examples.sh ${{ matrix.id }} "${{ steps.prep.outputs.skip-pattern }}" ${{ steps.prep.outputs.options }} + + - name: Parse sizes + if: ${{ env.run-build == 'true' }} + run: + | + cd $PWD/extras/test/ci + ./parse_size.sh ${{ matrix.id }} + + - name: Extract short commit hash + id: short-hash + run: echo "::set-output name=short_sha::$(git rev-parse --short HEAD)" + + - name: Upload size report as artifact + uses: actions/upload-artifact@v3 + with: + name: size-file-${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }} + path: extras/test/ci/size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv - # build sketch - echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m"; - arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn ${{ matrix.id }}${{ steps.prep.outputs.options }} --build-property compiler.cpp.extra_flags="$flags" $example --warnings=${{ steps.prep.outputs.warnings }} - if [ $? -ne 0 ]; then - echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n"; - exit 1; - else - echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n"; - fi - fi - done + metrics: + runs-on: ubuntu-latest + needs: build + steps: + - name: Set up SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.ACTIONS_METRICS_DEPLOY_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan github.com >> ~/.ssh/known_hosts + + - name: Clone artifact repo + run: + | + cd $PWD/.. + git clone git@github.com:radiolib-org/artifacts.git + cd artifacts + git config --global user.name "${{ github.actor }}" + git config --global user.email "${{ github.actor }}@users.noreply.github.com" + + - name: Download size artifacts + uses: actions/download-artifact@v3 + with: + path: aggregated-sizes + + - name: Push size files + run: + | + ls -R aggregated-sizes + mkdir -p $PWD/../artifacts/radiolib-ci/l0 + cp aggregated-sizes/*/size_*.csv $PWD/../artifacts/radiolib-ci/l0/. + cd $PWD/../artifacts/radiolib-ci + git add . + COMMIT_URL="https://github.com/jgromes/RadioLib/commit/$GITHUB_SHA" + git commit -m "Push artifacts from $COMMIT_URL" + git push origin main esp-build: runs-on: ubuntu-latest @@ -247,7 +285,7 @@ jobs: run: | cd $PWD/examples/NonArduino/Tock git clone https://github.com/tock/libtock-c.git - cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../ + cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh rpi-build: diff --git a/lib/RadioLib/.github/workflows/release.yml b/lib/RadioLib/.github/workflows/release.yml new file mode 100644 index 0000000..c8ce82d --- /dev/null +++ b/lib/RadioLib/.github/workflows/release.yml @@ -0,0 +1,37 @@ +name: "Release" + +on: workflow_dispatch + +jobs: + release: + name: Release RadioLib update + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Checkout latest tag + run: git checkout $(git describe --tags $(git rev-list --tags --max-count=1)) + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install PlatformIO and ESP-IDF + run: | + pip install --upgrade platformio + pip install --upgrade idf-component-manager + + - name: PlatformIO publish + env: + PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }} + run: pio pkg publish --no-interactive + + - name: ESP-IDF publish + env: + IDF_COMPONENT_API_TOKEN: ${{ secrets.IDF_COMPONENT_API_TOKEN }} + run: compote component upload --name RadioLib --namespace jgromes diff --git a/lib/RadioLib/.github/workflows/unit-test.yml b/lib/RadioLib/.github/workflows/unit-test.yml new file mode 100644 index 0000000..58a7d72 --- /dev/null +++ b/lib/RadioLib/.github/workflows/unit-test.yml @@ -0,0 +1,27 @@ +name: "Unit test" + +on: + push: + branches: [master] + pull_request: + branches: [master] + workflow_dispatch: + +jobs: + unit-test: + name: Build and run unit test + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libboost-all-dev libfmt-dev + + - name: Run unit test + run: | + cd extras/test/unit + ./test.sh diff --git a/lib/RadioLib/README.md b/lib/RadioLib/README.md index c608e2d..92ffe44 100644 --- a/lib/RadioLib/README.md +++ b/lib/RadioLib/README.md @@ -4,8 +4,6 @@ ## Universal wireless communication library for embedded devices -## See the [Wiki](https://github.com/jgromes/RadioLib/wiki) and [FAQ](https://github.com/jgromes/RadioLib/wiki/Frequently-Asked-Questions) for further information. See the [GitHub Pages](https://jgromes.github.io/RadioLib) for detailed and up-to-date API reference. - RadioLib allows its users to integrate all sorts of different wireless communication modules, protocols and even digital modes into a single consistent system. Want to add a Bluetooth interface to your LoRa network? Sure thing! Do you just want to go really old-school and play around with radio teletype, slow-scan TV, or even Hellschreiber using nothing but a cheap radio module? Why not! @@ -13,6 +11,13 @@ RadioLib natively supports Arduino, but can run in non-Arduino environments as w RadioLib was originally created as a driver for [__RadioShield__](https://github.com/jgromes/RadioShield), but it can be used to control as many different wireless modules as you like - or at least as many as your microcontroller can handle! +### Quick links: +* [__Wiki__](https://github.com/jgromes/RadioLib/wiki) - contains useful general information on using this library +* [__FAQ__](https://github.com/jgromes/RadioLib/wiki/Frequently-Asked-Questions) - frequently asked questions, and answers +* [__API Reference__](https://jgromes.github.io/RadioLib) - full API reference, automatically generated from the source code +* [__Status Code Decoder__](https://radiolib-org.github.io/status_decoder/decode.html) - decoder for status codes returned by RadioLib methods +* [__Debug Log Decoder__](https://radiolib-org.github.io/debug_decoder/decode.html) - decoder for RadioLib SPI debug logs + ### Supported modules: * __CC1101__ FSK radio module * __LLCC68__ LoRa module @@ -43,7 +48,7 @@ SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0 and SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x * [__POCSAG__](https://www.sigidwiki.com/wiki/POCSAG) using 2-FSK for modules: SX127x, RFM9x, RF69, SX1231, CC1101, nRF24L01, RFM2x and Si443x -* [__LoRaWAN__](https://lora-alliance.org/) using LoRa for modules: +* [__LoRaWAN__](https://lora-alliance.org/) using LoRa and FSK for modules: SX127x, RFM9x, SX126x, LR11x0 and SX128x ### Supported Arduino platforms: @@ -89,4 +94,7 @@ SX127x, RFM9x, SX126x, LR11x0 and SX128x * __PJRC__ * [__Teensy__](https://github.com/PaulStoffregen/cores) - Teensy 2.x, 3.x and 4.x boards +* __Silicon Labs__ + * [__EFR32__](https://github.com/SiliconLabs/arduino) - Silicon Labs xG24, xG27 and other boards + The list above is by no means exhaustive - RadioLib code is independent of the used platform! Compilation of all examples is tested for all platforms officially supported prior to releasing new version. In addition, RadioLib includes an internal hardware abstraction layer, which allows it to be easily ported even to non-Arduino environments. diff --git a/lib/RadioLib/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino b/lib/RadioLib/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino index 1a6528d..9f9a188 100644 --- a/lib/RadioLib/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino @@ -37,6 +37,21 @@ CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -76,21 +91,6 @@ void setup() { // radio.readData(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino b/lib/RadioLib/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino index 37bc21f..89fef51 100644 --- a/lib/RadioLib/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino +++ b/lib/RadioLib/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino @@ -82,10 +82,10 @@ void setup() { void loop() { Serial.print(F("[CC1101] Transmitting packet ... ")); - // you can transmit C-string or Arduino string up to 63 characters long + // you can transmit C-string or Arduino string up to 64 characters long int state = radio.transmit("Hello World!"); - // you can also transmit byte array up to 63 bytes long + // you can also transmit byte array up to 64 bytes long /* byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; int state = radio.transmit(byteArr, 8); diff --git a/lib/RadioLib/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino b/lib/RadioLib/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino index 52f4fb9..3f45061 100644 --- a/lib/RadioLib/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino +++ b/lib/RadioLib/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino @@ -57,11 +57,11 @@ int count = 0; void loop() { Serial.print(F("[CC1101] Transmitting packet ... ")); - // you can transmit C-string or Arduino string up to 63 characters long + // you can transmit C-string or Arduino string up to 64 characters long String str = "Hello World! #" + String(count++); int state = radio.transmit(str); - // you can also transmit byte array up to 63 bytes long + // you can also transmit byte array up to 64 bytes long /* byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; int state = radio.transmit(byteArr, 8); diff --git a/lib/RadioLib/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino b/lib/RadioLib/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino index 049c970..e1d8862 100644 --- a/lib/RadioLib/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino @@ -36,6 +36,21 @@ Radio radio = new RadioModule(); // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -69,21 +84,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; @@ -119,11 +119,11 @@ void loop() { Serial.print(F("[CC1101] Sending another packet ... ")); // you can transmit C-string or Arduino string up to - // 256 characters long + // 64 characters long String str = "Hello World! #" + String(count++); transmissionState = radio.startTransmit(str); - // you can also transmit byte array up to 256 bytes long + // you can also transmit byte array up to 64 bytes long /* byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; diff --git a/lib/RadioLib/examples/LR11x0/LR11x0_Channel_Activity_Detection_Interrupt/LR11x0_Channel_Activity_Detection_Interrupt.ino b/lib/RadioLib/examples/LR11x0/LR11x0_Channel_Activity_Detection_Interrupt/LR11x0_Channel_Activity_Detection_Interrupt.ino index e7e295c..7de03b2 100644 --- a/lib/RadioLib/examples/LR11x0/LR11x0_Channel_Activity_Detection_Interrupt/LR11x0_Channel_Activity_Detection_Interrupt.ino +++ b/lib/RadioLib/examples/LR11x0/LR11x0_Channel_Activity_Detection_Interrupt/LR11x0_Channel_Activity_Detection_Interrupt.ino @@ -57,6 +57,21 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { END_OF_MODE_TABLE, }; +// flag to indicate that a packet was detected or CAD timed out +volatile bool scanFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // something happened, set the flag + scanFlag = true; +} + void setup() { Serial.begin(9600); @@ -89,21 +104,6 @@ void setup() { } } -// flag to indicate that a packet was detected or CAD timed out -volatile bool scanFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // something happened, set the flag - scanFlag = true; -} - void loop() { // check if the flag is set if(scanFlag) { diff --git a/lib/RadioLib/examples/LR11x0/LR11x0_LR_FHSS_Modem/LR11x0_LR_FHSS_Modem.ino b/lib/RadioLib/examples/LR11x0/LR11x0_LR_FHSS_Modem/LR11x0_LR_FHSS_Modem.ino index a7de634..f1c7c19 100644 --- a/lib/RadioLib/examples/LR11x0/LR11x0_LR_FHSS_Modem/LR11x0_LR_FHSS_Modem.ino +++ b/lib/RadioLib/examples/LR11x0/LR11x0_LR_FHSS_Modem/LR11x0_LR_FHSS_Modem.ino @@ -62,7 +62,8 @@ void setup() { 3, // header count 0x13A); // hopping sequence seed state = radio.setOutputPower(10.0); - state = radio.setSyncWord(0x12345678); + uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67}; + state = radio.setSyncWord(syncWord, 4); if (state != RADIOLIB_ERR_NONE) { Serial.print(F("Unable to set configuration, code ")); Serial.println(state); diff --git a/lib/RadioLib/examples/LR11x0/LR11x0_Receive_Interrupt/LR11x0_Receive_Interrupt.ino b/lib/RadioLib/examples/LR11x0/LR11x0_Receive_Interrupt/LR11x0_Receive_Interrupt.ino index 372c208..3b1d607 100644 --- a/lib/RadioLib/examples/LR11x0/LR11x0_Receive_Interrupt/LR11x0_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/LR11x0/LR11x0_Receive_Interrupt/LR11x0_Receive_Interrupt.ino @@ -63,6 +63,21 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { END_OF_MODE_TABLE, }; +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -105,21 +120,6 @@ void setup() { // radio.scanChannel(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/LR11x0/LR11x0_Transmit_Interrupt/LR11x0_Transmit_Interrupt.ino b/lib/RadioLib/examples/LR11x0/LR11x0_Transmit_Interrupt/LR11x0_Transmit_Interrupt.ino index 8e40eff..3086a9a 100644 --- a/lib/RadioLib/examples/LR11x0/LR11x0_Transmit_Interrupt/LR11x0_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/LR11x0/LR11x0_Transmit_Interrupt/LR11x0_Transmit_Interrupt.ino @@ -62,6 +62,21 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -98,21 +113,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/examples/LR11x0/LR11x0_WiFi_Scan_Interrupt/LR11x0_WiFi_Scan_Interrupt.ino b/lib/RadioLib/examples/LR11x0/LR11x0_WiFi_Scan_Interrupt/LR11x0_WiFi_Scan_Interrupt.ino index 38872f2..21d90f2 100644 --- a/lib/RadioLib/examples/LR11x0/LR11x0_WiFi_Scan_Interrupt/LR11x0_WiFi_Scan_Interrupt.ino +++ b/lib/RadioLib/examples/LR11x0/LR11x0_WiFi_Scan_Interrupt/LR11x0_WiFi_Scan_Interrupt.ino @@ -60,6 +60,20 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { END_OF_MODE_TABLE, }; +// flag to indicate that a scan was completed +volatile bool scanFlag = false; + +// this function is called when a scan is completed +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // scan is complete, set the flag + scanFlag = true; +} + void setup() { Serial.begin(9600); @@ -92,20 +106,6 @@ void setup() { } } -// flag to indicate that a scan was completed -volatile bool scanFlag = false; - -// this function is called when a scan is completed -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // scan is complete, set the flag - scanFlag = true; -} - void loop() { // check if the flag is set if(scanFlag) { diff --git a/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino b/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino index 28b2946..87d7f1e 100644 --- a/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino +++ b/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino @@ -68,7 +68,7 @@ void setup() { // Manages uplink intervals to the TTN Fair Use Policy node.setDutyCycle(true, 1250); - // Enable the dwell time limits - 400ms is the limit for the US + // Update dwell time limits - 400ms is the limit for the US node.setDwellTime(true, 400); Serial.println(F("Ready!\n")); diff --git a/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Starter/notes.md b/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Starter/notes.md index e68949e..49a37f8 100644 --- a/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Starter/notes.md +++ b/lib/RadioLib/examples/LoRaWAN/LoRaWAN_Starter/notes.md @@ -52,7 +52,7 @@ You are making your own device using a third party LoRaWAN stack so there will n Choose the Frequency plan appropriate for your region. Consider that almost all countries have laws relating to what frequencies you use so don't get creative. For Europe please use the recommended option. For other regions use the entry marked 'used by TTN'. -Choose LoRaWAN 1.1.0 - the last one in the list - the latest specfication. RadioLib uses RP001 Regional Parameters 1.1 revision A. +Choose LoRaWAN 1.1.0 - the last one in the list - the latest specfication. RadioLib uses RP001 Regional Parameters 1.1 revision B. At this point you will be asked for your JoinEUI. As this is a DIY device and we are using RadioLib, you can use all zero's as recommended by The LoRa Alliance TR007 Technical Recommendations document. Once you've put in all zeros and clicked confirm you will be asked for a DevEUI, AppKey and NwkKey. It is preferable to have the console generate them so they are properly formatted. diff --git a/lib/RadioLib/examples/LoRaWAN/README.md b/lib/RadioLib/examples/LoRaWAN/README.md index f4754c1..d2a7325 100644 --- a/lib/RadioLib/examples/LoRaWAN/README.md +++ b/lib/RadioLib/examples/LoRaWAN/README.md @@ -6,17 +6,17 @@ RadioLib LoRaWAN examples. * [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. ## LoRaWAN versions & regional parameters -RadioLib implements both LoRaWAN v1.1 and v1.0.4. Confusingly, v1.0.4 is newer than v1.1, but v1.1 includes more security checks and as such **LoRaWAN v1.1 is preferred**. -The catch is in the Regional Parameters: as v1.0.4 is newer, it is more up to date regarding local laws & regulations. Therefore, RadioLib implements 1.0.4 as baseline and 1.1 as fallback, but **Regional Parameters v1.0.4 is preferred**. -_Note: the CN500 band is implemented as specified in RP v1.1, as the RP v1.0.4 version is much too complex._ +RadioLib implements both LoRaWAN Specification 1.1 and 1.0.4. Confusingly, 1.0.4 is newer than 1.1, but 1.1 includes more security checks and as such **LoRaWAN 1.1 is preferred**. +The catch is in the Regional Parameters: as RP002 1.0.4 is newer than RP001 1.1, it is more up to date regarding local laws & regulations. Therefore, RadioLib implements 1.0.4 as baseline and 1.1 (revision B) as fallback, and as such **RP002 Regional Parameters 1.0.4 is preferred**. +_Note: the CN500 band is implemented as specified in RP001 1.1 revision B, as the RP002 1.0.4 version is much too complex._ -To activate a LoRaWAN v1.1 session, supply all the required keys: +To activate a LoRaWAN 1.1 session, supply all the required keys: ```cpp node.beginOTAA(joinEUI, devEUI, nwkKey, appKey); node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey); ``` -To activate a LoRaWAN v1.0.4 session, set the keys that are not available to `NULL`: +To activate a LoRaWAN 1.0.4 session, set the keys that are not available to `NULL`: ```cpp node.beginOTAA(joinEUI, devEUI, NULL, appKey); node.beginABP(devAddr, NULL, NULL, nwkSEncKey, appSKey); @@ -26,9 +26,9 @@ The device doesn't need to know the Regional Parameters version - that is of imp ## LoRaWAN persistence > [!WARNING] -> These examples do not actually comply with LoRaWAN v1.0.4/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: +> These examples do not actually comply with LoRaWAN 1.0.4/1.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: -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!** +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 1.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) diff --git a/lib/RadioLib/src/hal/ESP-IDF/EspHal.h b/lib/RadioLib/examples/NonArduino/ESP-IDF/main/EspHal.h similarity index 98% rename from lib/RadioLib/src/hal/ESP-IDF/EspHal.h rename to lib/RadioLib/examples/NonArduino/ESP-IDF/main/EspHal.h index 340adbd..3f7cd12 100644 --- a/lib/RadioLib/src/hal/ESP-IDF/EspHal.h +++ b/lib/RadioLib/examples/NonArduino/ESP-IDF/main/EspHal.h @@ -7,7 +7,7 @@ // this example only works on ESP32 and is unlikely to work on ESP32S2/S3 etc. // if you need high portability, you should probably use Arduino anyway ... #if CONFIG_IDF_TARGET_ESP32 == 0 - #error Target is not ESP32! + #error This example HAL only supports ESP32 targets. Support for ESP32S2/S3 etc. can be added by adjusting this file to user needs. #endif // include all the dependencies diff --git a/lib/RadioLib/examples/NonArduino/ESP-IDF/main/main.cpp b/lib/RadioLib/examples/NonArduino/ESP-IDF/main/main.cpp index 45e6f75..9a2272b 100644 --- a/lib/RadioLib/examples/NonArduino/ESP-IDF/main/main.cpp +++ b/lib/RadioLib/examples/NonArduino/ESP-IDF/main/main.cpp @@ -17,7 +17,7 @@ #include // include the hardware abstraction layer -#include "hal/ESP-IDF/EspHal.h" +#include "EspHal.h" // create a new instance of the HAL class EspHal* hal = new EspHal(5, 19, 27); diff --git a/lib/RadioLib/examples/NonArduino/Tock/CMakeLists.txt b/lib/RadioLib/examples/NonArduino/Tock/CMakeLists.txt index 42d6d67..661968f 100644 --- a/lib/RadioLib/examples/NonArduino/Tock/CMakeLists.txt +++ b/lib/RadioLib/examples/NonArduino/Tock/CMakeLists.txt @@ -50,7 +50,21 @@ add_executable(${PROJECT_NAME} main.cpp) # The build system for libtock-c is a bit odd and the version of libraries # built changes based on compiler version. if (RISCV_BUILD) - if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") + if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0") + target_link_libraries(${PROJECT_NAME} PUBLIC + RadioLib + $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a + $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/lib/gcc/riscv64-unknown-elf/14.1.0/rv32i/ilp32/libgcc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a + ) + + target_include_directories(RadioLib AFTER PUBLIC + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/include/ + ) + elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") target_link_libraries(${PROJECT_NAME} PUBLIC RadioLib $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a @@ -80,7 +94,17 @@ if (RISCV_BUILD) ) endif() else() - if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") + if (EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0") + target_link_libraries(${PROJECT_NAME} PUBLIC + RadioLib + $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a + $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/lib/gcc/arm-none-eabi/14.1.0/libgcc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/arm-none-eabi/lib/libstdc++.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libc.a + $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libm.a + ) + elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0") target_link_libraries(${PROJECT_NAME} PUBLIC RadioLib $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a diff --git a/lib/RadioLib/examples/NonArduino/Tock/README.md b/lib/RadioLib/examples/NonArduino/Tock/README.md index cae7f38..8022a30 100644 --- a/lib/RadioLib/examples/NonArduino/Tock/README.md +++ b/lib/RadioLib/examples/NonArduino/Tock/README.md @@ -23,7 +23,7 @@ The RadioLib example can be built with: $ git clone https://github.com/jgromes/RadioLib.git $ cd RadioLib/examples/NonArduino/Tock/ $ git clone https://github.com/tock/libtock-c.git -$ cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../ +$ cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../ $ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh ``` diff --git a/lib/RadioLib/examples/NonArduino/Tock/build.sh b/lib/RadioLib/examples/NonArduino/Tock/build.sh index cb91a4a..2ac538e 100644 --- a/lib/RadioLib/examples/NonArduino/Tock/build.sh +++ b/lib/RadioLib/examples/NonArduino/Tock/build.sh @@ -3,9 +3,9 @@ set -e rm -rf ./build-* -cd libtock-c/examples/cxx_hello +pushd ${LIBTOCK_C_DIRECTORY}/examples/cxx_hello make -j4 -cd ../../../ +popd mkdir -p build-arm cd build-arm diff --git a/lib/RadioLib/examples/NonArduino/Tock/main.cpp b/lib/RadioLib/examples/NonArduino/Tock/main.cpp index e716d50..e0db219 100644 --- a/lib/RadioLib/examples/NonArduino/Tock/main.cpp +++ b/lib/RadioLib/examples/NonArduino/Tock/main.cpp @@ -28,14 +28,14 @@ #include // include the hardware abstraction layer -#include "hal/Tock/libtockHal.h" +#include "RadioLib/libtockHal.h" // the entry point for the program int main(void) { printf("[SX1261] Initialising Radio ... \r\n"); // create a new instance of the HAL class - TockHal* hal = new TockHal(); + TockRadioLibHal* hal = new TockRadioLibHal(); // now we can create the radio module // pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE @@ -43,7 +43,7 @@ int main(void) { // DIO1 pin: 2 // NRST pin: 4 // BUSY pin: 1 - Module* tock_module = new Module(hal, RADIO_NSS, RADIO_DIO_1, RADIO_RESET, RADIO_BUSY); + Module* tock_module = new Module(hal, RADIOLIB_RADIO_NSS, RADIOLIB_RADIO_DIO_1, RADIOLIB_RADIO_RESET, RADIOLIB_RADIO_BUSY); SX1262* radio = new SX1262(tock_module); // Setup the radio diff --git a/lib/RadioLib/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino b/lib/RadioLib/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino index 4678525..e596a28 100644 --- a/lib/RadioLib/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino @@ -29,6 +29,21 @@ RF69 radio = new Module(10, 2, 3); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -68,21 +83,6 @@ void setup() { // radio.readData(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino b/lib/RadioLib/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino index c4de787..58a3f07 100644 --- a/lib/RadioLib/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino @@ -35,6 +35,21 @@ Radio radio = new RadioModule(); // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -85,21 +100,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino b/lib/RadioLib/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino index 1a0e390..b5a67e6 100644 --- a/lib/RadioLib/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino +++ b/lib/RadioLib/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino @@ -33,6 +33,18 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { END_OF_MODE_TABLE, }; +// flag to indicate that a packet was detected or CAD timed out +volatile bool scanFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) { + // something happened, set the flag + scanFlag = true; +} + void setup() { Serial.begin(9600); @@ -66,18 +78,6 @@ void setup() { } } -// flag to indicate that a packet was detected or CAD timed out -volatile bool scanFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -void setFlag(void) { - // something happened, set the flag - scanFlag = true; -} - void loop() { // check if the flag is set if(scanFlag) { diff --git a/lib/RadioLib/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino b/lib/RadioLib/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino index fe203f2..dc62255 100644 --- a/lib/RadioLib/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino @@ -43,6 +43,18 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { END_OF_MODE_TABLE, }; +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -97,18 +109,6 @@ void setup() { // radio.scanChannel(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino b/lib/RadioLib/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino index aed1c12..736be3b 100644 --- a/lib/RadioLib/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino @@ -38,6 +38,18 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -85,18 +97,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Interrupt/SX126x_Channel_Activity_Detection_Interrupt.ino b/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Interrupt/SX126x_Channel_Activity_Detection_Interrupt.ino index c47b4b2..d47b58d 100644 --- a/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Interrupt/SX126x_Channel_Activity_Detection_Interrupt.ino +++ b/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Interrupt/SX126x_Channel_Activity_Detection_Interrupt.ino @@ -33,6 +33,21 @@ SX1262 radio = new Module(10, 2, 3, 9); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was detected or CAD timed out +volatile bool scanFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // something happened, set the flag + scanFlag = true; +} + void setup() { Serial.begin(9600); @@ -62,21 +77,6 @@ void setup() { } } -// flag to indicate that a packet was detected or CAD timed out -volatile bool scanFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // something happened, set the flag - scanFlag = true; -} - void loop() { // check if the flag is set if(scanFlag) { diff --git a/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Receive/SX126x_Channel_Activity_Detection_Receive.ino b/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Receive/SX126x_Channel_Activity_Detection_Receive.ino index ec89de0..85b204d 100644 --- a/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Receive/SX126x_Channel_Activity_Detection_Receive.ino +++ b/lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Receive/SX126x_Channel_Activity_Detection_Receive.ino @@ -35,6 +35,24 @@ SX1262 radio = new Module(10, 2, 3, 9); Radio radio = new RadioModule(); */ +// whether we are receiving, or scanning +bool receiving = false; + +// flag to indicate that a packet was detected or CAD timed out +volatile bool scanFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // something happened, set the flag + scanFlag = true; +} + void setup() { Serial.begin(9600); @@ -64,23 +82,6 @@ void setup() { } } -// flag to indicate that a packet was detected or CAD timed out -volatile bool scanFlag = false; - -bool receiving = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // something happened, set the flag - scanFlag = true; -} - void loop() { // check if the flag is set if(scanFlag) { diff --git a/lib/RadioLib/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino b/lib/RadioLib/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino index 9bffbee..cc8849d 100644 --- a/lib/RadioLib/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino +++ b/lib/RadioLib/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino @@ -126,33 +126,4 @@ void loop() { Serial.println(F("[SX1262] Failed to receive packet, code ")); Serial.println(state); } - - // FSK modem has built-in address filtering system - // it can be enabled by setting node address, broadcast - // address, or both - // - // to transmit packet to a particular address, - // use the following methods: - // - // radio.transmit("Hello World!", address); - // radio.startTransmit("Hello World!", address); - - // set node address to 0x02 - state = radio.setNodeAddress(0x02); - // set broadcast address to 0xFF - state = radio.setBroadcastAddress(0xFF); - if (state != RADIOLIB_ERR_NONE) { - Serial.println(F("[SX1262] Unable to set address filter, code ")); - Serial.println(state); - } - - // address filtering can also be disabled - // NOTE: calling this method will also erase previously set - // node and broadcast address - /* - state = radio.disableAddressFiltering(); - if (state != RADIOLIB_ERR_NONE) { - Serial.println(F("Unable to remove address filter, code ")); - } - */ } diff --git a/lib/RadioLib/examples/SX126x/SX126x_LR_FHSS_Modem/SX126x_LR_FHSS_Modem.ino b/lib/RadioLib/examples/SX126x/SX126x_LR_FHSS_Modem/SX126x_LR_FHSS_Modem.ino index 9b27944..44519d5 100644 --- a/lib/RadioLib/examples/SX126x/SX126x_LR_FHSS_Modem/SX126x_LR_FHSS_Modem.ino +++ b/lib/RadioLib/examples/SX126x/SX126x_LR_FHSS_Modem/SX126x_LR_FHSS_Modem.ino @@ -62,7 +62,8 @@ void setup() { 3, // header count 0x13A); // hopping sequence seed state = radio.setOutputPower(10.0); - state = radio.setSyncWord(0x12345678); + uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67}; + state = radio.setSyncWord(syncWord, 4); if (state != RADIOLIB_ERR_NONE) { Serial.print(F("Unable to set configuration, code ")); Serial.println(state); diff --git a/lib/RadioLib/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino b/lib/RadioLib/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino index 42e27f2..de1664b 100644 --- a/lib/RadioLib/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino @@ -39,6 +39,21 @@ SX1262 radio = new Module(10, 2, 3, 9); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -78,21 +93,6 @@ void setup() { // radio.scanChannel(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino b/lib/RadioLib/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino index 1acf3ee..fcc5c95 100644 --- a/lib/RadioLib/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino @@ -38,6 +38,21 @@ Radio radio = new RadioModule(); // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -71,21 +86,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Interrupt/SX127x_Channel_Activity_Detection_Interrupt.ino b/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Interrupt/SX127x_Channel_Activity_Detection_Interrupt.ino index 95070e0..4efbf4a 100644 --- a/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Interrupt/SX127x_Channel_Activity_Detection_Interrupt.ino +++ b/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Interrupt/SX127x_Channel_Activity_Detection_Interrupt.ino @@ -34,6 +34,36 @@ SX1278 radio = new Module(10, 2, 9, 3); Radio radio = new RadioModule(); */ +// flag to indicate that a preamble was not detected +volatile bool timeoutFlag = false; + +// flag to indicate that a preamble was detected +volatile bool detectedFlag = false; + +// this function is called when no preamble +// is detected within timeout period +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlagTimeout(void) { + // we timed out, set the flag + timeoutFlag = true; +} + +// this function is called when LoRa preamble +// is detected within timeout period +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlagDetected(void) { + // we got a preamble, set the flag + detectedFlag = true; +} + void setup() { // Serial port speed must be high enough for this example Serial.begin(115200); @@ -68,36 +98,6 @@ void setup() { } } -// flag to indicate that a preamble was not detected -volatile bool timeoutFlag = false; - -// flag to indicate that a preamble was detected -volatile bool detectedFlag = false; - -// this function is called when no preamble -// is detected within timeout period -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlagTimeout(void) { - // we timed out, set the flag - timeoutFlag = true; -} - -// this function is called when LoRa preamble -// is detected within timeout period -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlagDetected(void) { - // we got a preamble, set the flag - detectedFlag = true; -} - void loop() { // check if we need to restart channel activity detection if(detectedFlag || timeoutFlag) { diff --git a/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino b/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino index 9b03d2e..0e5670e 100644 --- a/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino +++ b/lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino @@ -39,6 +39,39 @@ SX1278 radio = new Module(10, 2, 9, 3); Radio radio = new RadioModule(); */ +// flag to indicate that a preamble was not detected +volatile bool timeoutFlag = false; + +// flag to indicate that a preamble was detected +volatile bool detectedFlag = false; + +// flag to indicate if we are currently receiving +bool receiving = false; + +// this function is called when no preamble +// is detected within timeout period +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlagTimeout(void) { + // we timed out, set the flag + timeoutFlag = true; +} + +// this function is called when LoRa preamble +// is detected within timeout period +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlagDetected(void) { + // we got a preamble, set the flag + detectedFlag = true; +} + void setup() { // Serial port speed must be high enough for this example Serial.begin(115200); @@ -74,39 +107,6 @@ void setup() { } } -// flag to indicate that a preamble was not detected -volatile bool timeoutFlag = false; - -// flag to indicate that a preamble was detected -volatile bool detectedFlag = false; - -// flag to indicate if we are currently receiving -bool receiving = false; - -// this function is called when no preamble -// is detected within timeout period -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlagTimeout(void) { - // we timed out, set the flag - timeoutFlag = true; -} - -// this function is called when LoRa preamble -// is detected within timeout period -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlagDetected(void) { - // we got a preamble, set the flag - detectedFlag = true; -} - void loop() { // check if we need to restart channel activity detection if(detectedFlag || timeoutFlag) { diff --git a/lib/RadioLib/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino b/lib/RadioLib/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino index f41493b..ff9c443 100644 --- a/lib/RadioLib/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino +++ b/lib/RadioLib/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino @@ -32,6 +32,12 @@ const int pin = 5; Radio radio = new RadioModule(); */ +// this function is called when a new bit is received +void readBit(void) { + // read the data bit + radio.readBit(pin); +} + void setup() { Serial.begin(9600); @@ -59,12 +65,6 @@ void setup() { radio.receiveDirect(); } -// this function is called when a new bit is received -void readBit(void) { - // read the data bit - radio.readBit(pin); -} - void loop() { // we expect the packet to contain the string "Hello World!", // a length byte and 2 CRC bytes, that's 15 bytes in total diff --git a/lib/RadioLib/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino b/lib/RadioLib/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino index 451e419..ebb0483 100644 --- a/lib/RadioLib/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino @@ -39,6 +39,21 @@ SX1278 radio = new Module(10, 2, 9, 3); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -78,21 +93,6 @@ void setup() { // radio.scanChannel(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino b/lib/RadioLib/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino index 22785d7..04385bc 100644 --- a/lib/RadioLib/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino @@ -38,6 +38,21 @@ Radio radio = new RadioModule(); // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -71,21 +86,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/examples/SX128x/SX128x_Channel_Activity_Detection_Interrupt/SX128x_Channel_Activity_Detection_Interrupt.ino b/lib/RadioLib/examples/SX128x/SX128x_Channel_Activity_Detection_Interrupt/SX128x_Channel_Activity_Detection_Interrupt.ino index 8a57e18..8e3ab59 100644 --- a/lib/RadioLib/examples/SX128x/SX128x_Channel_Activity_Detection_Interrupt/SX128x_Channel_Activity_Detection_Interrupt.ino +++ b/lib/RadioLib/examples/SX128x/SX128x_Channel_Activity_Detection_Interrupt/SX128x_Channel_Activity_Detection_Interrupt.ino @@ -31,6 +31,21 @@ SX1280 radio = new Module(10, 2, 3, 9); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was detected or CAD timed out +volatile bool scanFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // something happened, set the flag + scanFlag = true; +} + void setup() { Serial.begin(9600); @@ -60,21 +75,6 @@ void setup() { } } -// flag to indicate that a packet was detected or CAD timed out -volatile bool scanFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // something happened, set the flag - scanFlag = true; -} - void loop() { // check if the flag is set if(scanFlag) { diff --git a/lib/RadioLib/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino b/lib/RadioLib/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino index 0ca0406..984db24 100644 --- a/lib/RadioLib/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino @@ -39,6 +39,21 @@ SX1280 radio = new Module(10, 2, 3, 9); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -79,21 +94,6 @@ void setup() { // radio.scanChannel(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino b/lib/RadioLib/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino index 1c760d5..340efd1 100644 --- a/lib/RadioLib/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino @@ -38,6 +38,21 @@ Radio radio = new RadioModule(); // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -71,21 +86,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino b/lib/RadioLib/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino index 45f1817..63be2b4 100644 --- a/lib/RadioLib/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino @@ -31,6 +31,21 @@ Si4432 radio = new Module(10, 2, 9); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -70,21 +85,6 @@ void setup() { // radio.readData(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino b/lib/RadioLib/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino index 4450186..d2e433c 100644 --- a/lib/RadioLib/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino @@ -36,6 +36,21 @@ Radio radio = new RadioModule(); // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -69,21 +84,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino b/lib/RadioLib/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino index d081ff7..cb19db0 100644 --- a/lib/RadioLib/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino +++ b/lib/RadioLib/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino @@ -34,6 +34,21 @@ nRF24 radio = new Module(10, 2, 3); Radio radio = new RadioModule(); */ +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we got a packet, set the flag + receivedFlag = true; +} + void setup() { Serial.begin(9600); @@ -88,21 +103,6 @@ void setup() { // radio.readData(); } -// flag to indicate that a packet was received -volatile bool receivedFlag = false; - -// this function is called when a complete packet -// is received by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we got a packet, set the flag - receivedFlag = true; -} - void loop() { // check if the flag is set if(receivedFlag) { diff --git a/lib/RadioLib/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino b/lib/RadioLib/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino index 0751e51..9ee46c4 100644 --- a/lib/RadioLib/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino +++ b/lib/RadioLib/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino @@ -36,6 +36,21 @@ Radio radio = new RadioModule(); // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +#if defined(ESP8266) || defined(ESP32) + ICACHE_RAM_ATTR +#endif +void setFlag(void) { + // we sent a packet, set the flag + transmittedFlag = true; +} + void setup() { Serial.begin(9600); @@ -84,21 +99,6 @@ void setup() { */ } -// flag to indicate that a packet was sent -volatile bool transmittedFlag = false; - -// this function is called when a complete packet -// is transmitted by the module -// IMPORTANT: this function MUST be 'void' type -// and MUST NOT have any arguments! -#if defined(ESP8266) || defined(ESP32) - ICACHE_RAM_ATTR -#endif -void setFlag(void) { - // we sent a packet, set the flag - transmittedFlag = true; -} - // counter to keep track of transmitted packets int count = 0; diff --git a/lib/RadioLib/idf_component.yml b/lib/RadioLib/idf_component.yml index 9f175c3..e5199c4 100644 --- a/lib/RadioLib/idf_component.yml +++ b/lib/RadioLib/idf_component.yml @@ -1,4 +1,4 @@ -version: "7.1.0" +version: "7.1.2" 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 diff --git a/lib/RadioLib/keywords.txt b/lib/RadioLib/keywords.txt index 179b4e2..9457fcb 100644 --- a/lib/RadioLib/keywords.txt +++ b/lib/RadioLib/keywords.txt @@ -197,6 +197,7 @@ randomByte KEYWORD2 getPacketLength KEYWORD2 setFifoEmptyAction KEYWORD2 clearFifoEmptyAction KEYWORD2 +setFifoThreshold KEYWORD2 setFifoFullAction KEYWORD2 clearFifoFullAction KEYWORD2 fifoAdd KEYWORD2 @@ -221,6 +222,7 @@ setGdo2Action KEYWORD2 clearGdo0Action KEYWORD2 clearGdo2Action KEYWORD2 setCrcFiltering KEYWORD2 +beginFSK4 KEYWORD2 # SX126x-specific setTCXO KEYWORD2 diff --git a/lib/RadioLib/library.json b/lib/RadioLib/library.json index 9c27984..6182a0c 100644 --- a/lib/RadioLib/library.json +++ b/lib/RadioLib/library.json @@ -1,6 +1,6 @@ { "name": "RadioLib", - "version": "7.1.0", + "version": "7.1.2", "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, rf69, sx1231, rfm96, rfm98, sstv, sx1280, sx1281, sx1282, sx1261, sx1262, sx1268, si4432, rfm22, llcc68, pager, pocsag, lorawan, lr1110, lr1120, lr1121", "homepage": "https://github.com/jgromes/RadioLib", diff --git a/lib/RadioLib/library.properties b/lib/RadioLib/library.properties index 26e9ffe..f4a9586 100644 --- a/lib/RadioLib/library.properties +++ b/lib/RadioLib/library.properties @@ -1,5 +1,5 @@ name=RadioLib -version=7.1.0 +version=7.1.2 author=Jan Gromes maintainer=Jan Gromes sentence=Universal wireless communication library diff --git a/lib/RadioLib/src/BuildOpt.h b/lib/RadioLib/src/BuildOpt.h index 35ee448..d64f500 100644 --- a/lib/RadioLib/src/BuildOpt.h +++ b/lib/RadioLib/src/BuildOpt.h @@ -133,11 +133,9 @@ * RADIOLIB_DEFAULT_SPI - default SPIClass instance to use. * RADIOLIB_NONVOLATILE - macro to place variable into program storage (usually Flash). * RADIOLIB_NONVOLATILE_READ_BYTE - function/macro to read variables saved in program storage (usually Flash). - * RADIOLIB_TYPE_ALIAS - construct to create an alias for a type, usually vai the `using` keyword. + * RADIOLIB_TYPE_ALIAS - construct to create an alias for a type, usually via the `using` keyword. * RADIOLIB_TONE_UNSUPPORTED - some platforms do not have tone()/noTone(), which is required for AFSK. * - * In addition, some platforms may require RadioLib to disable specific drivers (such as ESP8266). - * * Users may also specify their own configuration by uncommenting the RADIOLIB_CUSTOM_ARDUINO, * and then specifying all platform parameters in the section below. This will override automatic * platform detection. @@ -365,6 +363,13 @@ #define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus) #define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus) +#elif defined(ARDUINO_ARCH_SILABS) + // Silicon Labs Arduino + #define RADIOLIB_PLATFORM "Arduino Silicon Labs" + #define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode) + #define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus) + #define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus) + #else // other Arduino platforms not covered by the above list - this may or may not work #define RADIOLIB_PLATFORM "Unknown Arduino" @@ -578,7 +583,7 @@ // version definitions #define RADIOLIB_VERSION_MAJOR 7 #define RADIOLIB_VERSION_MINOR 1 -#define RADIOLIB_VERSION_PATCH 0 +#define RADIOLIB_VERSION_PATCH 2 #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/lib/RadioLib/src/Module.cpp b/lib/RadioLib/src/Module.cpp index 7b3c59a..cd5ddc6 100644 --- a/lib/RadioLib/src/Module.cpp +++ b/lib/RadioLib/src/Module.cpp @@ -56,13 +56,21 @@ int16_t Module::SPIgetRegValue(uint32_t reg, uint8_t msb, uint8_t lsb) { return(maskedValue); } -int16_t Module::SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval, uint8_t checkMask) { +int16_t Module::SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval, uint8_t checkMask, bool force) { if((msb > 7) || (lsb > 7) || (lsb > msb)) { return(RADIOLIB_ERR_INVALID_BIT_RANGE); } + // read the current value uint8_t currentValue = SPIreadRegister(reg); uint8_t mask = ~((0b11111111 << (msb + 1)) | (0b11111111 >> (8 - lsb))); + + // check if we actually need to update the register + if((currentValue & mask) == (value & mask) && !force) { + return(RADIOLIB_ERR_NONE); + } + + // update the register uint8_t newValue = (currentValue & ~mask) | (value & mask); SPIwriteRegister(reg, newValue); diff --git a/lib/RadioLib/src/Module.h b/lib/RadioLib/src/Module.h index 946c42e..328a7f5 100644 --- a/lib/RadioLib/src/Module.h +++ b/lib/RadioLib/src/Module.h @@ -272,9 +272,10 @@ class Module { \param lsb Least significant bit of the register variable. Bits below this one will not be affected by the write operation. \param checkInterval Number of milliseconds between register writing and verification reading. Some registers need up to 10ms to process the change. \param checkMask Mask of bits to check, only bits set to 1 will be verified. + \param force Write new value even if the old value is the same. \returns \ref status_codes */ - int16_t SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0, uint8_t checkInterval = 2, uint8_t checkMask = 0xFF); + int16_t SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0, uint8_t checkInterval = 2, uint8_t checkMask = 0xFF, bool force = false); /*! \brief SPI burst read method. @@ -382,12 +383,9 @@ class Module { int16_t SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio); // pin number access methods - - /*! - \brief Access method to get the pin number of SPI chip select. - \returns Pin number of SPI chip select configured in the constructor. - */ - uint32_t getCs() const { return(csPin); } + // getCs is omitted on purpose, as it can interfere when accessing the SPI in a concurrent environment + // so it is considered to be part of the SPI pins and hence not accessible from outside + // see https://github.com/jgromes/RadioLib/discussions/1364 /*! \brief Access method to get the pin number of interrupt/GPIO. diff --git a/lib/RadioLib/src/RadioLib.h b/lib/RadioLib/src/RadioLib.h index bd6c959..adc6854 100644 --- a/lib/RadioLib/src/RadioLib.h +++ b/lib/RadioLib/src/RadioLib.h @@ -4,11 +4,15 @@ /*! \mainpage RadioLib Documentation - Universal wireless communication library for Arduino. + Universal wireless communication library for embedded devices. \par Currently Supported Wireless Modules and Protocols - CC1101 FSK module + - LLCC68 LoRa/FSK module + - LR11x0 LoRa/FSK/LR-FHSS module + - nRF24 FSK module - RF69 FSK module + - RFM2x FSK module - Si443x FSK module - SX126x LoRa/FSK module - SX127x LoRa/FSK module @@ -22,6 +26,8 @@ - Hellschreiber (HellClient) - 4-FSK (FSK4Client) - APRS (APRSClient) + - POCSAG (PagerClient) + - LoRaWAN (LoRaWANNode) \par Quick Links Documentation for most common methods can be found in its reference page (see the list above).\n diff --git a/lib/RadioLib/src/hal/Tock/libtockHal.h b/lib/RadioLib/src/hal/Tock/libtockHal.h deleted file mode 100644 index 7ae8bf2..0000000 --- a/lib/RadioLib/src/hal/Tock/libtockHal.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - RadioLib Non-Arduino Tock Library helper functions - - Licensed under the MIT License - - Copyright (c) 2023 Alistair Francis - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#ifndef TOCK_HAL_H -#define TOCK_HAL_H - -// include RadioLib -#include - -// include all the dependencies -#include "libtock/net/lora_phy.h" -#include "libtock/net/syscalls/lora_phy_syscalls.h" -#include "libtock-sync/net/lora_phy.h" -#include "libtock/peripherals/gpio.h" -#include "libtock-sync/services/alarm.h" -#include "libtock/kernel/read_only_state.h" - -#define RADIO_BUSY 1 -#define RADIO_DIO_1 2 -#define RADIO_DIO_3 3 -#define RADIO_RESET 4 -// Skip the chips select as Tock handles this for us -#define RADIO_NSS RADIOLIB_NC - -// define Arduino-style macros -#define PIN_LOW (0x0) -#define PIN_HIGH (0x1) -#define PIN_INPUT (0x01) -#define PIN_OUTPUT (0x03) -#define PIN_RISING (0x01) -#define PIN_FALLING (0x02) - -typedef void (*gpioIrqFn)(void); - -gpioIrqFn gpio_funcs[4] = { NULL, NULL, NULL, NULL}; -uint32_t frequency = 0; - -/* - * Get the the timer frequency in Hz. - */ -int alarm_internal_frequency(uint32_t* frequency) { - syscall_return_t rval = command(0x0, 1, 0, 0); - return tock_command_return_u32_to_returncode(rval, frequency); -} - -int alarm_internal_read(uint32_t* time) { - syscall_return_t rval = command(0x0, 2, 0, 0); - return tock_command_return_u32_to_returncode(rval, time); -} - -static void lora_phy_gpio_Callback (int gpioPin, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - void* userdata) -{ - gpioIrqFn fn = gpio_funcs[gpioPin - 1]; - - if (fn != NULL ) { - fn(); - } -} - -class TockHal : public RadioLibHal { - public: - // default constructor - initializes the base HAL and any needed private members - TockHal() - : RadioLibHal(PIN_INPUT, PIN_OUTPUT, PIN_LOW, PIN_HIGH, PIN_RISING, PIN_FALLING) { - } - - void init() override { - } - - void term() override { - } - - // GPIO-related methods (pinMode, digitalWrite etc.) should check - // RADIOLIB_NC as an alias for non-connected pins - void pinMode(uint32_t pin, uint32_t mode) override { - if(pin == RADIOLIB_NC) { - return; - } - - if (mode == PIN_OUTPUT) { - libtock_lora_phy_gpio_enable_output(pin); - } else if (mode == PIN_INPUT) { - libtock_lora_phy_gpio_enable_input(pin, libtock_pull_down); - } - } - - void digitalWrite(uint32_t pin, uint32_t value) override { - if(pin == RADIOLIB_NC) { - return; - } - - if (value) { - libtock_lora_phy_gpio_set(pin); - } else { - libtock_lora_phy_gpio_clear(pin); - } - } - - uint32_t digitalRead(uint32_t pin) override { - int value; - - if(pin == RADIOLIB_NC) { - return 0; - } - - libtock_lora_phy_gpio_read(pin, &value); - - return value; - } - - void attachInterrupt(uint32_t interruptNum, gpioIrqFn interruptCb, uint32_t mode) override { - if(interruptNum == RADIOLIB_NC) { - return; - } - - gpio_funcs[interruptNum - 1] = interruptCb; - libtock_lora_phy_gpio_command_interrupt_callback(lora_phy_gpio_Callback, NULL); - - // set GPIO as input and enable interrupts on it - libtock_lora_phy_gpio_enable_input(interruptNum, libtock_pull_down); - libtock_lora_phy_gpio_enable_interrupt(interruptNum, libtock_change); - } - - void detachInterrupt(uint32_t interruptNum) override { - if(interruptNum == RADIOLIB_NC) { - return; - } - - gpio_funcs[interruptNum - 1] = NULL; - libtock_lora_phy_gpio_disable_interrupt(interruptNum); - } - - void delay(unsigned long ms) override { -#if !defined(RADIOLIB_CLOCK_DRIFT_MS) - libtocksync_alarm_delay_ms(ms); -#else - libtocksync_alarm_delay_ms(ms * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS)); -#endif - } - - void delayMicroseconds(unsigned long us) override { -#if !defined(RADIOLIB_CLOCK_DRIFT_MS) - libtocksync_alarm_delay_ms(us / 1000); -#else - libtocksync_alarm_delay_ms((us * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS)) / 1000); -#endif - } - - unsigned long millis() override { - uint32_t now; - unsigned long ms; - - if (frequency == 0) { - alarm_internal_frequency(&frequency); - } - - alarm_internal_read(&now); - - ms = now / (frequency / 1000); - -#if !defined(RADIOLIB_CLOCK_DRIFT_MS) - return ms; -#else - return ms * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS); -#endif - } - - unsigned long micros() override { - return millis() / 1000; - } - - long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override { - return 0; - } - - void spiBegin() { - } - - void spiBeginTransaction() { - } - - void spiTransfer(uint8_t* out, size_t len, uint8_t* in) { - libtocksync_lora_phy_read_write(out, in, len); - } - - void spiEndTransaction() { - } - - void spiEnd() { - } - - void yield() { - ::yield_no_wait(); - } - - private: -}; - -#endif diff --git a/lib/RadioLib/src/modules/CC1101/CC1101.cpp b/lib/RadioLib/src/modules/CC1101/CC1101.cpp index f2ff50a..b91b949 100644 --- a/lib/RadioLib/src/modules/CC1101/CC1101.cpp +++ b/lib/RadioLib/src/modules/CC1101/CC1101.cpp @@ -7,94 +7,19 @@ CC1101::CC1101(Module* module) : PhysicalLayer(RADIOLIB_CC1101_FREQUENCY_STEP_SI } int16_t CC1101::begin(float freq, float br, float freqDev, float rxBw, int8_t pwr, uint8_t preambleLength) { - // set module properties - this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_CC1101_CMD_READ; - this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_CC1101_CMD_WRITE; - this->mod->init(); - this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput); + // set the modulation and execute the common part + this->modulation = RADIOLIB_CC1101_MOD_FORMAT_2_FSK; + return(this->beginCommon(freq, br, freqDev, rxBw, pwr, preambleLength)); +} - // try to find the CC1101 chip - uint8_t i = 0; - bool flagFound = false; - while((i < 10) && !flagFound) { - int16_t version = getChipVersion(); - if((version == RADIOLIB_CC1101_VERSION_CURRENT) || (version == RADIOLIB_CC1101_VERSION_LEGACY) || (version == RADIOLIB_CC1101_VERSION_CLONE)) { - flagFound = true; - } else { - RADIOLIB_DEBUG_BASIC_PRINTLN("CC1101 not found! (%d of 10 tries) RADIOLIB_CC1101_REG_VERSION == 0x%04X, expected 0x0004/0x0014", i + 1, version); - this->mod->hal->delay(10); - i++; - } - } - - if(!flagFound) { - RADIOLIB_DEBUG_BASIC_PRINTLN("No CC1101 found!"); - this->mod->term(); - return(RADIOLIB_ERR_CHIP_NOT_FOUND); - } else { - RADIOLIB_DEBUG_BASIC_PRINTLN("M\tCC1101"); - } - - // configure settings not accessible by API - int16_t state = config(); - RADIOLIB_ASSERT(state); - - // configure publicly accessible settings - state = setFrequency(freq); - RADIOLIB_ASSERT(state); - - // configure bitrate - state = setBitRate(br); - RADIOLIB_ASSERT(state); - - // configure default RX bandwidth - state = setRxBandwidth(rxBw); - RADIOLIB_ASSERT(state); - - // configure default frequency deviation - state = setFrequencyDeviation(freqDev); - RADIOLIB_ASSERT(state); - - // configure default TX output power - state = setOutputPower(pwr); - RADIOLIB_ASSERT(state); - - // set default packet length mode - state = variablePacketLengthMode(); - RADIOLIB_ASSERT(state); - - // configure default preamble length - state = setPreambleLength(preambleLength, preambleLength - 4); - RADIOLIB_ASSERT(state); - - // set default data shaping - state = setDataShaping(RADIOLIB_SHAPING_NONE); - RADIOLIB_ASSERT(state); - - // set default encoding - state = setEncoding(RADIOLIB_ENCODING_NRZ); - RADIOLIB_ASSERT(state); - - // set default sync word - uint8_t sw[RADIOLIB_CC1101_DEFAULT_SW_LEN] = RADIOLIB_CC1101_DEFAULT_SW; - state = setSyncWord(sw[0], sw[1], 0, false); - RADIOLIB_ASSERT(state); - - // flush FIFOs - SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); - SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); - - return(state); +int16_t CC1101::beginFSK4(float freq, float br, float freqDev, float rxBw, int8_t pwr, uint8_t preambleLength) { + // set the modulation and execute the common part + this->modulation = RADIOLIB_CC1101_MOD_FORMAT_4_FSK; + return(this->beginCommon(freq, br, freqDev, rxBw, pwr, preambleLength)); } void CC1101::reset() { - // this is the manual power-on-reset sequence - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow); - this->mod->hal->delayMicroseconds(5); - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelHigh); - this->mod->hal->delayMicroseconds(40); - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow); - this->mod->hal->delay(10); + // just send the command, the reset sequence as described in datasheet seems unnecessary in our usage SPIsendCommand(RADIOLIB_CC1101_CMD_RESET); } @@ -922,7 +847,7 @@ int16_t CC1101::setDataShaping(uint8_t sh) { // set data shaping switch(sh) { case RADIOLIB_SHAPING_NONE: - state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_2_FSK, 6, 4); + state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, this->modulation, 6, 4); break; case RADIOLIB_SHAPING_0_5: state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_GFSK, 6, 4); @@ -1006,6 +931,87 @@ int16_t CC1101::setDIOMapping(uint32_t pin, uint32_t value) { return(SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0 - pin, value)); } +int16_t CC1101::beginCommon(float freq, float br, float freqDev, float rxBw, int8_t pwr, uint8_t preambleLength) { + // set module properties + this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_CC1101_CMD_READ; + this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_CC1101_CMD_WRITE; + this->mod->init(); + this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput); + + // try to find the CC1101 chip + uint8_t i = 0; + bool flagFound = false; + while((i < 10) && !flagFound) { + int16_t version = getChipVersion(); + if((version == RADIOLIB_CC1101_VERSION_CURRENT) || (version == RADIOLIB_CC1101_VERSION_LEGACY) || (version == RADIOLIB_CC1101_VERSION_CLONE)) { + flagFound = true; + } else { + RADIOLIB_DEBUG_BASIC_PRINTLN("CC1101 not found! (%d of 10 tries) RADIOLIB_CC1101_REG_VERSION == 0x%04X, expected 0x0004/0x0014", i + 1, version); + this->mod->hal->delay(10); + i++; + } + } + + if(!flagFound) { + RADIOLIB_DEBUG_BASIC_PRINTLN("No CC1101 found!"); + this->mod->term(); + return(RADIOLIB_ERR_CHIP_NOT_FOUND); + } else { + RADIOLIB_DEBUG_BASIC_PRINTLN("M\tCC1101"); + } + + // configure settings not accessible by API + int16_t state = config(); + RADIOLIB_ASSERT(state); + + // configure publicly accessible settings + state = setFrequency(freq); + RADIOLIB_ASSERT(state); + + // configure bitrate + state = setBitRate(br); + RADIOLIB_ASSERT(state); + + // configure default RX bandwidth + state = setRxBandwidth(rxBw); + RADIOLIB_ASSERT(state); + + // configure default frequency deviation + state = setFrequencyDeviation(freqDev); + RADIOLIB_ASSERT(state); + + // configure default TX output power + state = setOutputPower(pwr); + RADIOLIB_ASSERT(state); + + // set default packet length mode + state = variablePacketLengthMode(); + RADIOLIB_ASSERT(state); + + // configure default preamble length + state = setPreambleLength(preambleLength, preambleLength - 4); + RADIOLIB_ASSERT(state); + + // set default data shaping + state = setDataShaping(RADIOLIB_SHAPING_NONE); + RADIOLIB_ASSERT(state); + + // set default encoding + state = setEncoding(RADIOLIB_ENCODING_NRZ); + RADIOLIB_ASSERT(state); + + // set default sync word + uint8_t sw[RADIOLIB_CC1101_DEFAULT_SW_LEN] = RADIOLIB_CC1101_DEFAULT_SW; + state = setSyncWord(sw[0], sw[1], 0, false); + RADIOLIB_ASSERT(state); + + // flush FIFOs + SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); + SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); + + return(state); +} + int16_t CC1101::config() { // Reset the radio. Registers may be dirty from previous usage. reset(); @@ -1154,21 +1160,7 @@ void CC1101::SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, size_t len) { } void CC1101::SPIsendCommand(uint8_t cmd) { - // pull NSS low - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow); - - // start transfer - this->mod->hal->spiBeginTransaction(); - - // send the command byte - uint8_t status = 0; - this->mod->hal->spiTransfer(&cmd, 1, &status); - - // stop transfer - this->mod->hal->spiEndTransaction(); - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelHigh); - RADIOLIB_DEBUG_SPI_PRINTLN("CMD\tW\t%02X\t%02X", cmd, status); - (void)status; + this->mod->SPItransferStream(&cmd, 1, true, NULL, NULL, 0, false); } #endif diff --git a/lib/RadioLib/src/modules/CC1101/CC1101.h b/lib/RadioLib/src/modules/CC1101/CC1101.h index cb5efe7..e1a71a4 100644 --- a/lib/RadioLib/src/modules/CC1101/CC1101.h +++ b/lib/RadioLib/src/modules/CC1101/CC1101.h @@ -8,7 +8,7 @@ // CC1101 physical layer properties #define RADIOLIB_CC1101_FREQUENCY_STEP_SIZE 396.7285156 -#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 63 +#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 64 #define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0 #define RADIOLIB_CC1101_DIV_EXPONENT 16 @@ -191,9 +191,6 @@ // RADIOLIB_CC1101_REG_SYNC0 #define RADIOLIB_CC1101_SYNC_WORD_LSB 0x91 // 7 0 sync word LSB -// RADIOLIB_CC1101_REG_PKTLEN -#define RADIOLIB_CC1101_PACKET_LENGTH 0xFF // 7 0 packet length in bytes - // RADIOLIB_CC1101_REG_PKTCTRL1 #define RADIOLIB_CC1101_PQT 0x00 // 7 5 preamble quality threshold #define RADIOLIB_CC1101_CRC_AUTOFLUSH_OFF 0b00000000 // 3 3 automatic Rx FIFO flush on CRC check fail: disabled (default) @@ -562,6 +559,24 @@ class CC1101: public PhysicalLayer { int8_t pwr = RADIOLIB_CC1101_DEFAULT_POWER, uint8_t preambleLength = RADIOLIB_CC1101_DEFAULT_PREAMBLELEN); + /*! + \brief Initialization method for 4-FSK modulation. + \param freq Carrier frequency in MHz. Defaults to 434 MHz. + \param br Bit rate to be used in kbps. Defaults to 4.8 kbps. + \param freqDev Frequency deviation from carrier frequency in kHz Defaults to 5.0 kHz. + \param rxBw Receiver bandwidth in kHz. Defaults to 135.0 kHz. + \param pwr Output power in dBm. Defaults to 10 dBm. + \param preambleLength Preamble Length in bits. Defaults to 16 bits. + \returns \ref status_codes + */ + int16_t beginFSK4( + float freq = RADIOLIB_CC1101_DEFAULT_FREQ, + float br = RADIOLIB_CC1101_DEFAULT_BR, + float freqDev = RADIOLIB_CC1101_DEFAULT_FREQDEV, + float rxBw = RADIOLIB_CC1101_DEFAULT_RXBW, + int8_t pwr = RADIOLIB_CC1101_DEFAULT_POWER, + uint8_t preambleLength = RADIOLIB_CC1101_DEFAULT_PREAMBLELEN); + /*! \brief Reset method - resets the chip using manual reset sequence (without RESET pin). */ @@ -1014,6 +1029,7 @@ class CC1101: public PhysicalLayer { int8_t power = RADIOLIB_CC1101_DEFAULT_POWER; + int16_t beginCommon(float freq, float br, float freqDev, float rxBw, int8_t pwr, uint8_t preambleLength); int16_t config(); int16_t transmitDirect(bool sync, uint32_t frf); int16_t receiveDirect(bool sync); diff --git a/lib/RadioLib/src/modules/LLCC68/LLCC68.cpp b/lib/RadioLib/src/modules/LLCC68/LLCC68.cpp index 18ce03d..834f5ed 100644 --- a/lib/RadioLib/src/modules/LLCC68/LLCC68.cpp +++ b/lib/RadioLib/src/modules/LLCC68/LLCC68.cpp @@ -9,6 +9,13 @@ LLCC68::LLCC68(Module* mod) : SX1262(mod) { int16_t LLCC68::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t pwr, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) { // execute common part int16_t state = SX126x::begin(cr, syncWord, preambleLength, tcxoVoltage, useRegulatorLDO); + if(state == RADIOLIB_ERR_CHIP_NOT_FOUND) { + // bit of a hack, but some LLCC68 chips report as "SX1261", try that + // for full discussion, see https://github.com/jgromes/RadioLib/issues/1329 + chipType = RADIOLIB_SX1261_CHIP_TYPE; + state = SX126x::begin(cr, syncWord, preambleLength, tcxoVoltage, useRegulatorLDO); + RADIOLIB_DEBUG_PRINTLN("LLCC68 version string not found, using SX1261 instead"); + } RADIOLIB_ASSERT(state); // configure publicly accessible settings @@ -118,13 +125,13 @@ int16_t LLCC68::checkDataRate(DataRate_t dr) { int16_t LLCC68::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; - case(ModemType_t::LRFHSS): { + case(ModemType_t::RADIOLIB_MODEM_LRFHSS): { return(this->beginLRFHSS()); } break; default: diff --git a/lib/RadioLib/src/modules/LLCC68/LLCC68.h b/lib/RadioLib/src/modules/LLCC68/LLCC68.h index a0b6d19..7809c56 100644 --- a/lib/RadioLib/src/modules/LLCC68/LLCC68.h +++ b/lib/RadioLib/src/modules/LLCC68/LLCC68.h @@ -7,6 +7,7 @@ #include "../../Module.h" #include "../SX126x/SX1262.h" +#include "../SX126x/SX1261.h" //RADIOLIB_SX126X_REG_VERSION_STRING #define RADIOLIB_LLCC68_CHIP_TYPE "LLCC68" diff --git a/lib/RadioLib/src/modules/LR11x0/LR1110.cpp b/lib/RadioLib/src/modules/LR11x0/LR1110.cpp index 26cbe2a..1fbc696 100644 --- a/lib/RadioLib/src/modules/LR11x0/LR1110.cpp +++ b/lib/RadioLib/src/modules/LR11x0/LR1110.cpp @@ -113,13 +113,13 @@ int16_t LR1110::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPo int16_t LR1110::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginGFSK()); } break; - case(ModemType_t::LRFHSS): { + case(ModemType_t::RADIOLIB_MODEM_LRFHSS): { return(this->beginLRFHSS()); } break; } diff --git a/lib/RadioLib/src/modules/LR11x0/LR1120.cpp b/lib/RadioLib/src/modules/LR11x0/LR1120.cpp index 61294b7..fb62782 100644 --- a/lib/RadioLib/src/modules/LR11x0/LR1120.cpp +++ b/lib/RadioLib/src/modules/LR11x0/LR1120.cpp @@ -133,13 +133,13 @@ int16_t LR1120::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPo int16_t LR1120::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginGFSK()); } break; - case(ModemType_t::LRFHSS): { + case(ModemType_t::RADIOLIB_MODEM_LRFHSS): { return(this->beginLRFHSS()); } break; } diff --git a/lib/RadioLib/src/modules/LR11x0/LR11x0.cpp b/lib/RadioLib/src/modules/LR11x0/LR11x0.cpp index c40ff58..f039bc4 100644 --- a/lib/RadioLib/src/modules/LR11x0/LR11x0.cpp +++ b/lib/RadioLib/src/modules/LR11x0/LR11x0.cpp @@ -110,7 +110,8 @@ int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, bool narrowGrid, float tcxoV state = setLrFhssConfig(bw, cr); RADIOLIB_ASSERT(state); - state = setSyncWord(0x12AD101B); + uint8_t syncWord[] = { 0x12, 0xAD, 0x10, 0x1B }; + state = setSyncWord(syncWord, 4); RADIOLIB_ASSERT(state); state = setRegulatorLDO(); @@ -128,6 +129,8 @@ int16_t LR11x0::beginGNSS(uint8_t constellations, float tcxoVoltage) { state = this->clearErrors(); RADIOLIB_ASSERT(state); + // set GNSS flag to reserve DIO11 for LF clock + this->gnss = true; state = this->configLfClock(RADIOLIB_LR11X0_LF_BUSY_RELEASE_DISABLED | RADIOLIB_LR11X0_LF_CLK_XOSC); RADIOLIB_ASSERT(state); @@ -353,10 +356,9 @@ int16_t LR11x0::standby(uint8_t mode, bool wakeup) { this->mod->setRfSwitchState(Module::MODE_IDLE); if(wakeup) { - // pull NSS low for a while to wake up - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow); - this->mod->hal->delay(1); - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelHigh); + // send a NOP command - this pulls the NSS low to exit the sleep mode, + // while preventing interference with possible other SPI transactions + (void)this->mod->SPIwriteStream((uint16_t)RADIOLIB_LR11X0_CMD_NOP, NULL, 0, false, false); } uint8_t buff[] = { mode }; @@ -758,20 +760,16 @@ int16_t LR11x0::setCodingRate(uint8_t cr, bool longInterleave) { return(setModulationParamsLoRa(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize)); } -int16_t LR11x0::setSyncWord(uint32_t syncWord) { +int16_t LR11x0::setSyncWord(uint8_t syncWord) { // check active modem uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE; int16_t state = getPacketType(&type); RADIOLIB_ASSERT(state); - if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) { - return(setLoRaSyncWord(syncWord & 0xFF)); - - } else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) { - return(lrFhssSetSyncWord(syncWord)); - + if(type != RADIOLIB_LR11X0_PACKET_TYPE_LORA) { + return(RADIOLIB_ERR_WRONG_MODEM); } - return(RADIOLIB_ERR_WRONG_MODEM); + return(setLoRaSyncWord(syncWord)); } int16_t LR11x0::setBitRate(float br) { @@ -885,27 +883,36 @@ int16_t LR11x0::setSyncWord(uint8_t* syncWord, size_t len) { uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE; int16_t state = getPacketType(&type); RADIOLIB_ASSERT(state); - if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) { + if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) { + // update sync word length + this->syncWordLength = len*8; + state = setPacketParamsGFSK(this->preambleLengthGFSK, this->preambleDetLength, this->syncWordLength, this->addrComp, this->packetType, RADIOLIB_LR11X0_MAX_PACKET_LENGTH, this->crcTypeGFSK, this->whitening); + RADIOLIB_ASSERT(state); + + // sync word is passed most-significant byte first + uint8_t fullSyncWord[RADIOLIB_LR11X0_GFSK_SYNC_WORD_LEN] = { 0 }; + memcpy(fullSyncWord, syncWord, len); + return(setGfskSyncWord(fullSyncWord)); + + } else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) { // with length set to 1 and LoRa modem active, assume it is the LoRa sync word if(len > 1) { return(RADIOLIB_ERR_INVALID_SYNC_WORD); } return(setSyncWord(syncWord[0])); - } else if(type != RADIOLIB_LR11X0_PACKET_TYPE_GFSK) { - return(RADIOLIB_ERR_WRONG_MODEM); + } else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) { + // with length set to 4 and LR-FHSS modem active, assume it is the LR-FHSS sync word + if(len != sizeof(uint32_t)) { + return(RADIOLIB_ERR_INVALID_SYNC_WORD); + } + uint32_t sync = 0; + memcpy(&sync, syncWord, sizeof(uint32_t)); + return(lrFhssSetSyncWord(sync)); } - // update sync word length - this->syncWordLength = len*8; - state = setPacketParamsGFSK(this->preambleLengthGFSK, this->preambleDetLength, this->syncWordLength, this->addrComp, this->packetType, RADIOLIB_LR11X0_MAX_PACKET_LENGTH, this->crcTypeGFSK, this->whitening); - RADIOLIB_ASSERT(state); - - // sync word is passed most-significant byte first - uint8_t fullSyncWord[RADIOLIB_LR11X0_GFSK_SYNC_WORD_LEN] = { 0 }; - memcpy(fullSyncWord, syncWord, len); - return(setGfskSyncWord(fullSyncWord)); + return(RADIOLIB_ERR_WRONG_MODEM); } int16_t LR11x0::setSyncBits(uint8_t *syncWord, uint8_t bitsLen) { @@ -2032,13 +2039,13 @@ int16_t LR11x0::getModem(ModemType_t* modem) { switch(packetType) { case(RADIOLIB_LR11X0_PACKET_TYPE_LORA): - *modem = ModemType_t::LoRa; + *modem = ModemType_t::RADIOLIB_MODEM_LORA; return(RADIOLIB_ERR_NONE); case(RADIOLIB_LR11X0_PACKET_TYPE_GFSK): - *modem = ModemType_t::FSK; + *modem = ModemType_t::RADIOLIB_MODEM_FSK; return(RADIOLIB_ERR_NONE); case(RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS): - *modem = ModemType_t::LRFHSS; + *modem = ModemType_t::RADIOLIB_MODEM_LRFHSS; return(RADIOLIB_ERR_NONE); } @@ -2060,6 +2067,7 @@ int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) { this->mod->spiConfig.stream = true; this->mod->spiConfig.parseStatusCb = SPIparseStatus; this->mod->spiConfig.checkStatusCb = SPIcheckStatus; + this->gnss = false; // try to find the LR11x0 chip - this will also reset the module at least once if(!LR11x0::findChip(this->chipType)) { @@ -2446,7 +2454,7 @@ int16_t LR11x0::setDioIrqParams(uint32_t irq1, uint32_t irq2) { } int16_t LR11x0::setDioIrqParams(uint32_t irq) { - return(setDioIrqParams(irq,irq)); + return(setDioIrqParams(irq, this->gnss ? 0 : irq)); } int16_t LR11x0::clearIrq(uint32_t irq) { @@ -2457,7 +2465,7 @@ int16_t LR11x0::clearIrq(uint32_t irq) { } int16_t LR11x0::configLfClock(uint8_t setup) { - return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CONFIG_LF_LOCK, true, &setup, 1)); + return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CONFIG_LF_CLOCK, true, &setup, 1)); } int16_t LR11x0::setTcxoMode(uint8_t tune, uint32_t delay) { diff --git a/lib/RadioLib/src/modules/LR11x0/LR11x0.h b/lib/RadioLib/src/modules/LR11x0/LR11x0.h index 974e8e3..42685a9 100644 --- a/lib/RadioLib/src/modules/LR11x0/LR11x0.h +++ b/lib/RadioLib/src/modules/LR11x0/LR11x0.h @@ -33,7 +33,7 @@ #define RADIOLIB_LR11X0_CMD_SET_DIO_AS_RF_SWITCH (0x0112) #define RADIOLIB_LR11X0_CMD_SET_DIO_IRQ_PARAMS (0x0113) #define RADIOLIB_LR11X0_CMD_CLEAR_IRQ (0x0114) -#define RADIOLIB_LR11X0_CMD_CONFIG_LF_LOCK (0x0116) +#define RADIOLIB_LR11X0_CMD_CONFIG_LF_CLOCK (0x0116) #define RADIOLIB_LR11X0_CMD_SET_TCXO_MODE (0x0117) #define RADIOLIB_LR11X0_CMD_REBOOT (0x0118) #define RADIOLIB_LR11X0_CMD_GET_VBAT (0x0119) @@ -281,7 +281,7 @@ #define RADIOLIB_LR11X0_IRQ_ALL (0x1BF80FFCUL) // 31 0 all interrupts #define RADIOLIB_LR11X0_IRQ_NONE (0x00UL << 0) // 31 0 no interrupts -// RADIOLIB_LR11X0_CMD_CONFIG_LF_LOCK +// RADIOLIB_LR11X0_CMD_CONFIG_LF_CLOCK #define RADIOLIB_LR11X0_LF_CLK_RC (0x00UL << 0) // 1 0 32.768 kHz source: RC oscillator #define RADIOLIB_LR11X0_LF_CLK_XOSC (0x01UL << 0) // 1 0 crystal oscillator #define RADIOLIB_LR11X0_LF_CLK_EXT (0x02UL << 0) // 1 0 external signal on DIO11 @@ -1176,11 +1176,11 @@ class LR11x0: public PhysicalLayer { int16_t setCodingRate(uint8_t cr, bool longInterleave = false); /*! - \brief Sets LoRa or LR-FHSS sync word. - \param syncWord LoRa or LR-FHSS sync word to be set. For LoRa, only 8 least significant bits will be used + \brief Sets LoRa sync word. + \param syncWord LoRa sync word to be set. \returns \ref status_codes */ - int16_t setSyncWord(uint32_t syncWord); + int16_t setSyncWord(uint8_t syncWord); /*! \brief Sets GFSK bit rate. Allowed values range from 0.6 to 300.0 kbps. @@ -1828,6 +1828,7 @@ class LR11x0: public PhysicalLayer { float dataRateMeasured = 0; uint8_t wifiScanMode = 0; + bool gnss = false; int16_t modSetup(float tcxoVoltage, uint8_t modem); static int16_t SPIparseStatus(uint8_t in); diff --git a/lib/RadioLib/src/modules/RF69/RF69.cpp b/lib/RadioLib/src/modules/RF69/RF69.cpp index 2bbfeb5..f87270b 100644 --- a/lib/RadioLib/src/modules/RF69/RF69.cpp +++ b/lib/RadioLib/src/modules/RF69/RF69.cpp @@ -321,6 +321,10 @@ void RF69::clearFifoEmptyAction() { clearDio1Action(); } +void RF69::setFifoThreshold(uint8_t threshold) { + this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, threshold, 6, 0); +} + void RF69::setFifoFullAction(void (*func)(void)) { // set the interrupt this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_FIFO_THRESH, 6, 0); diff --git a/lib/RadioLib/src/modules/RF69/RF69.h b/lib/RadioLib/src/modules/RF69/RF69.h index a7a25e4..00ea43b 100644 --- a/lib/RadioLib/src/modules/RF69/RF69.h +++ b/lib/RadioLib/src/modules/RF69/RF69.h @@ -648,6 +648,14 @@ class RF69: public PhysicalLayer { */ void clearFifoEmptyAction(); + /*! + \brief Set FIFO threshold level. + Be aware that threshold is also set in setFifoFullAction method. + setFifoThreshold method must be called AFTER calling setFifoFullAction! + \param threshold Threshold level in bytes. + */ + void setFifoThreshold(uint8_t threshold); + /*! \brief Set interrupt service routine function to call when FIFO is full. \param func Pointer to interrupt service routine. diff --git a/lib/RadioLib/src/modules/SX126x/SX1261.cpp b/lib/RadioLib/src/modules/SX126x/SX1261.cpp index d6a90c3..89af5c8 100644 --- a/lib/RadioLib/src/modules/SX126x/SX1261.cpp +++ b/lib/RadioLib/src/modules/SX126x/SX1261.cpp @@ -16,11 +16,19 @@ int16_t SX1261::setOutputPower(int8_t power) { RADIOLIB_ASSERT(state); // set PA config - state = SX126x::setPaConfig(0x04, RADIOLIB_SX126X_PA_CONFIG_SX1261, 0x00); + uint8_t paDutyCycle = 0x04; + int8_t txPwr = power; + if(power == 15) { + // for 15 dBm, increase the duty cycle and lowe the power to set + // SX1261/2 datasheet, DS.SX1261-2.W.APP Rev. 2.1 page 78 + paDutyCycle = 0x06; + txPwr--; + } + state = SX126x::setPaConfig(paDutyCycle, RADIOLIB_SX126X_PA_CONFIG_SX1261, 0x00); RADIOLIB_ASSERT(state); // set output power with default 200us ramp - state = SX126x::setTxParams(power, RADIOLIB_SX126X_PA_RAMP_200U); + state = SX126x::setTxParams(txPwr, RADIOLIB_SX126X_PA_RAMP_200U); RADIOLIB_ASSERT(state); // restore OCP configuration @@ -29,9 +37,9 @@ int16_t SX1261::setOutputPower(int8_t power) { int16_t SX1261::checkOutputPower(int8_t power, int8_t* clipped) { if(clipped) { - *clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power)); + *clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(15, power)); } - RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER); + RADIOLIB_CHECK_RANGE(power, -17, 15, RADIOLIB_ERR_INVALID_OUTPUT_POWER); return(RADIOLIB_ERR_NONE); } diff --git a/lib/RadioLib/src/modules/SX126x/SX1261.h b/lib/RadioLib/src/modules/SX126x/SX1261.h index 196cc21..5c5e3be 100644 --- a/lib/RadioLib/src/modules/SX126x/SX1261.h +++ b/lib/RadioLib/src/modules/SX126x/SX1261.h @@ -28,7 +28,7 @@ class SX1261 : public SX1262 { SX1261(Module* mod); // cppcheck-suppress noExplicitConstructor /*! - \brief Sets output power. Allowed values are in range from -17 to 14 dBm. + \brief Sets output power. Allowed values are in range from -17 to 15 dBm. \param power Output power to be set in dBm. \returns \ref status_codes */ diff --git a/lib/RadioLib/src/modules/SX126x/SX1262.cpp b/lib/RadioLib/src/modules/SX126x/SX1262.cpp index 85253ab..426c2d0 100644 --- a/lib/RadioLib/src/modules/SX126x/SX1262.cpp +++ b/lib/RadioLib/src/modules/SX126x/SX1262.cpp @@ -116,13 +116,13 @@ int16_t SX1262::checkOutputPower(int8_t power, int8_t* clipped) { int16_t SX1262::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; - case(ModemType_t::LRFHSS): { + case(ModemType_t::RADIOLIB_MODEM_LRFHSS): { return(this->beginLRFHSS()); } break; default: diff --git a/lib/RadioLib/src/modules/SX126x/SX1268.cpp b/lib/RadioLib/src/modules/SX126x/SX1268.cpp index 6ae42ea..7de82a2 100644 --- a/lib/RadioLib/src/modules/SX126x/SX1268.cpp +++ b/lib/RadioLib/src/modules/SX126x/SX1268.cpp @@ -117,13 +117,13 @@ int16_t SX1268::checkOutputPower(int8_t power, int8_t* clipped) { int16_t SX1268::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; - case(ModemType_t::LRFHSS): { + case(ModemType_t::RADIOLIB_MODEM_LRFHSS): { return(this->beginLRFHSS()); } break; default: diff --git a/lib/RadioLib/src/modules/SX126x/SX126x.cpp b/lib/RadioLib/src/modules/SX126x/SX126x.cpp index 16062db..f14e0f8 100644 --- a/lib/RadioLib/src/modules/SX126x/SX126x.cpp +++ b/lib/RadioLib/src/modules/SX126x/SX126x.cpp @@ -74,7 +74,6 @@ int16_t SX126x::beginFSK(float br, float freqDev, float rxBw, uint16_t preambleL this->pulseShape = RADIOLIB_SX126X_GFSK_FILTER_GAUSS_0_5; this->crcTypeFSK = RADIOLIB_SX126X_GFSK_CRC_2_BYTE_INV; // CCITT CRC configuration this->preambleLengthFSK = preambleLength; - this->addrComp = RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF; // set module properties and perform initial setup int16_t state = this->modSetup(tcxoVoltage, useRegulatorLDO, RADIOLIB_SX126X_PACKET_TYPE_GFSK); @@ -203,8 +202,8 @@ int16_t SX126x::transmit(const uint8_t* data, size_t len, uint8_t addr) { return(RADIOLIB_ERR_PACKET_TOO_LONG); } - // calculate timeout in ms (500% of expected time-on-air) - RadioLibTime_t timeout = (getTimeOnAir(len) * 5) / 1000; + // calculate timeout in ms (5ms + 500 % of expected time-on-air) + RadioLibTime_t timeout = 5 + (getTimeOnAir(len) * 5) / 1000; RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout); // start transmission @@ -468,8 +467,10 @@ int16_t SX126x::standby(uint8_t mode, bool wakeup) { this->mod->setRfSwitchState(Module::MODE_IDLE); if(wakeup) { - // pull NSS low to wake up - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow); + // send a NOP command - this pulls the NSS low to exit the sleep mode, + // while preventing interference with possible other SPI transactions + // see https://github.com/jgromes/RadioLib/discussions/1364 + (void)this->mod->SPIwriteStream((uint16_t)RADIOLIB_SX126X_CMD_NOP, NULL, 0, false, false); } uint8_t data[] = { mode }; @@ -509,13 +510,15 @@ void SX126x::clearChannelScanAction() { } int16_t SX126x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) { + (void)addr; + // check packet length if(len > RADIOLIB_SX126X_MAX_PACKET_LENGTH) { return(RADIOLIB_ERR_PACKET_TOO_LONG); } // maximum packet length is decreased by 1 when address filtering is active - if((this->addrComp != RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF) && (len > RADIOLIB_SX126X_MAX_PACKET_LENGTH - 1)) { + if((RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF != RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF) && (len > RADIOLIB_SX126X_MAX_PACKET_LENGTH - 1)) { return(RADIOLIB_ERR_PACKET_TOO_LONG); } @@ -526,13 +529,7 @@ int16_t SX126x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) { state = setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, len, this->headerType, this->invertIQEnabled); } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) { - state = setPacketParamsFSK(this->preambleLengthFSK, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType, len); - - // address is taken from the register - if(this->addrComp != RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF) { - RADIOLIB_ASSERT(state); - state = writeRegister(RADIOLIB_SX126X_REG_NODE_ADDRESS, &addr, 1); - } + state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType, len); } else if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) { return(RADIOLIB_ERR_UNKNOWN); @@ -626,12 +623,6 @@ int16_t SX126x::finishTransmit() { int16_t state = clearIrqStatus(); RADIOLIB_ASSERT(state); - // restore the original node address - if(getPacketType() == RADIOLIB_SX126X_PACKET_TYPE_GFSK) { - state = writeRegister(RADIOLIB_SX126X_REG_NODE_ADDRESS, &this->nodeAddr, 1); - RADIOLIB_ASSERT(state); - } - // set mode to standby to disable transmitter/RF switch return(standby()); } @@ -641,7 +632,12 @@ int16_t SX126x::startReceive() { } int16_t SX126x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { - (void)len; + // in implicit header mode, use the provided length if it is nonzero + // otherwise we trust the user has previously set the payload length manually + if((this->headerType == RADIOLIB_SX126X_LORA_HEADER_IMPLICIT) && (len != 0)) { + this->implicitLen = len; + } + int16_t state = startReceiveCommon(timeout, irqFlags, irqMask); RADIOLIB_ASSERT(state); @@ -743,7 +739,7 @@ int16_t SX126x::startReceiveCommon(uint32_t timeout, RadioLibIrqFlags_t irqFlags if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) { state = setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, this->implicitLen, this->headerType, this->invertIQEnabled); } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) { - state = setPacketParamsFSK(this->preambleLengthFSK, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType); + state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType); } else { return(RADIOLIB_ERR_UNKNOWN); } @@ -968,12 +964,15 @@ int16_t SX126x::setPreambleLength(size_t preambleLength) { return(setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, this->implicitLen, this->headerType, this->invertIQEnabled)); } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) { this->preambleLengthFSK = preambleLength; - this->preambleDetLength = preambleLength >= 32 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_32 : - preambleLength >= 24 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_24 : - preambleLength >= 16 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_16 : - preambleLength > 0 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_8 : + // maximum preamble detector length is limited by sync word length + // for details, see the note in SX1261 datasheet, Rev 2.1, section 6.2.2.1, page 45 + uint8_t maxDetLen = RADIOLIB_MIN(this->syncWordLength, this->preambleLengthFSK); + this->preambleDetLength = maxDetLen >= 32 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_32 : + maxDetLen >= 24 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_24 : + maxDetLen >= 16 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_16 : + maxDetLen > 0 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_8 : RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_OFF; - return(setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType)); + return(setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType)); } return(RADIOLIB_ERR_UNKNOWN); @@ -1209,7 +1208,16 @@ int16_t SX126x::setSyncWord(uint8_t* syncWord, size_t len) { // update packet parameters this->syncWordLength = len * 8; - state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType); + + // maximum preamble detector length is limited by sync word length + // for details, see the note in SX1261 datasheet, Rev 2.1, section 6.2.2.1, page 45 + uint8_t maxDetLen = RADIOLIB_MIN(this->syncWordLength, this->preambleLengthFSK); + this->preambleDetLength = maxDetLen >= 32 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_32 : + maxDetLen >= 24 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_24 : + maxDetLen >= 16 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_16 : + maxDetLen > 0 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_8 : + RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_OFF; + state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType); return(state); @@ -1251,52 +1259,6 @@ int16_t SX126x::setSyncBits(uint8_t *syncWord, uint8_t bitsLen) { return(setSyncWord(syncWord, bytesLen)); } -int16_t SX126x::setNodeAddress(uint8_t addr) { - // check active modem - if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_GFSK) { - return(RADIOLIB_ERR_WRONG_MODEM); - } - - // enable address filtering (node only) - this->addrComp = RADIOLIB_SX126X_GFSK_ADDRESS_FILT_NODE; - int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType); - RADIOLIB_ASSERT(state); - - // set node address - this->nodeAddr = addr; - state = writeRegister(RADIOLIB_SX126X_REG_NODE_ADDRESS, &addr, 1); - - return(state); -} - -int16_t SX126x::setBroadcastAddress(uint8_t broadAddr) { - // check active modem - if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_GFSK) { - return(RADIOLIB_ERR_WRONG_MODEM); - } - - // enable address filtering (node and broadcast) - this->addrComp = RADIOLIB_SX126X_GFSK_ADDRESS_FILT_NODE_BROADCAST; - int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType); - RADIOLIB_ASSERT(state); - - // set broadcast address - state = writeRegister(RADIOLIB_SX126X_REG_BROADCAST_ADDRESS, &broadAddr, 1); - - return(state); -} - -int16_t SX126x::disableAddressFiltering() { - // check active modem - if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_GFSK) { - return(RADIOLIB_ERR_WRONG_MODEM); - } - - // disable address filtering - this->addrComp = RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF; - return(setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening)); -} - int16_t SX126x::setCRC(uint8_t len, uint16_t initial, uint16_t polynomial, bool inverted) { // check active modem uint8_t modem = getPacketType(); @@ -1325,7 +1287,7 @@ int16_t SX126x::setCRC(uint8_t len, uint16_t initial, uint16_t polynomial, bool return(RADIOLIB_ERR_INVALID_CRC_CONFIGURATION); } - int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType); + int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType); RADIOLIB_ASSERT(state); // write initial CRC value @@ -1367,7 +1329,7 @@ int16_t SX126x::setWhitening(bool enabled, uint16_t initial) { // disable whitening this->whitening = RADIOLIB_SX126X_GFSK_WHITENING_OFF; - state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType); + state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType); RADIOLIB_ASSERT(state); } else { @@ -1387,7 +1349,7 @@ int16_t SX126x::setWhitening(bool enabled, uint16_t initial) { state = writeRegister(RADIOLIB_SX126X_REG_WHITENING_INITIAL_MSB, data, 2); RADIOLIB_ASSERT(state); - state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType); + state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType); RADIOLIB_ASSERT(state); } return(state); @@ -1682,13 +1644,13 @@ int16_t SX126x::getModem(ModemType_t* modem) { uint8_t packetType = getPacketType(); switch(packetType) { case(RADIOLIB_SX126X_PACKET_TYPE_LORA): - *modem = ModemType_t::LoRa; + *modem = ModemType_t::RADIOLIB_MODEM_LORA; return(RADIOLIB_ERR_NONE); case(RADIOLIB_SX126X_PACKET_TYPE_GFSK): - *modem = ModemType_t::FSK; + *modem = ModemType_t::RADIOLIB_MODEM_FSK; return(RADIOLIB_ERR_NONE); case(RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS): - *modem = ModemType_t::LRFHSS; + *modem = ModemType_t::RADIOLIB_MODEM_LRFHSS; return(RADIOLIB_ERR_NONE); } @@ -2049,7 +2011,7 @@ int16_t SX126x::setPacketMode(uint8_t mode, uint8_t len) { } // set requested packet mode - int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, mode, len); + int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, mode, len); RADIOLIB_ASSERT(state); // update cached value diff --git a/lib/RadioLib/src/modules/SX126x/SX126x.h b/lib/RadioLib/src/modules/SX126x/SX126x.h index d1ca545..5fba5a3 100644 --- a/lib/RadioLib/src/modules/SX126x/SX126x.h +++ b/lib/RadioLib/src/modules/SX126x/SX126x.h @@ -823,6 +823,10 @@ class SX126x: public PhysicalLayer { /*! \brief Sets preamble length for LoRa or FSK modem. Allowed values range from 1 to 65535. \param preambleLength Preamble length to be set in symbols (LoRa) or bits (FSK). + NOTE: In FSK mode, sync word length limits the preamble detector length + (the number of preamble bits that must be detected to start receiving packet). + For details, see the note in SX1261 datasheet, Rev 2.1, section 6.2.2.1, page 45. + Preamble detector length is adjusted automatically each time this method is called. \returns \ref status_codes */ int16_t setPreambleLength(size_t preambleLength) override; @@ -887,6 +891,10 @@ class SX126x: public PhysicalLayer { Can also set LR-FHSS sync word, but its length must be 4 bytes. \param syncWord FSK sync word to be set. \param len FSK sync word length in bytes. + NOTE: In FSK mode, sync word length limits the preamble detector length + (the number of preamble bits that must be detected to start receiving packet). + For details, see the note in SX1261 datasheet, Rev 2.1, section 6.2.2.1, page 45. + Preamble detector length is adjusted automatically each time this method is called. \returns \ref status_codes */ int16_t setSyncWord(uint8_t* syncWord, size_t len) override; @@ -1278,10 +1286,9 @@ class SX126x: public PhysicalLayer { bool ldroAuto = true; uint32_t bitRate = 0, frequencyDev = 0; - uint8_t preambleDetLength = 0, rxBandwidth = 0, pulseShape = 0, crcTypeFSK = 0, syncWordLength = 0, addrComp = 0, whitening = 0, packetType = 0; + uint8_t preambleDetLength = 0, rxBandwidth = 0, pulseShape = 0, crcTypeFSK = 0, syncWordLength = 0, whitening = 0, packetType = 0; uint16_t preambleLengthFSK = 0; float rxBandwidthKhz = 0; - uint8_t nodeAddr = 0; float dataRateMeasured = 0; diff --git a/lib/RadioLib/src/modules/SX127x/SX1272.cpp b/lib/RadioLib/src/modules/SX127x/SX1272.cpp index ed61570..4b118d6 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1272.cpp +++ b/lib/RadioLib/src/modules/SX127x/SX1272.cpp @@ -497,11 +497,13 @@ int16_t SX1272::autoLDRO() { } int16_t SX1272::implicitHeader(size_t len) { - return(setHeaderType(RADIOLIB_SX1272_HEADER_IMPL_MODE, len)); + this->implicitHdr = true; + return(setHeaderType(RADIOLIB_SX1272_HEADER_IMPL_MODE, 2, len)); } int16_t SX1272::explicitHeader() { - return(setHeaderType(RADIOLIB_SX1272_HEADER_EXPL_MODE)); + this->implicitHdr = false; + return(setHeaderType(RADIOLIB_SX1272_HEADER_EXPL_MODE, 2)); } int16_t SX1272::setBandwidthRaw(uint8_t newBandwidth) { @@ -521,11 +523,13 @@ int16_t SX1272::setSpreadingFactorRaw(uint8_t newSpreadingFactor) { // write registers Module* mod = this->getMod(); if(newSpreadingFactor == RADIOLIB_SX127X_SF_6) { + this->implicitHdr = true; state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_HEADER_IMPL_MODE | (SX127x::crcEnabled ? RADIOLIB_SX1272_RX_CRC_MODE_ON : RADIOLIB_SX1272_RX_CRC_MODE_OFF), 2, 1); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, RADIOLIB_SX127X_SF_6 | RADIOLIB_SX127X_TX_MODE_SINGLE, 7, 3); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECT_OPTIMIZE, RADIOLIB_SX127X_DETECT_OPTIMIZE_SF_6, 2, 0); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECTION_THRESHOLD, RADIOLIB_SX127X_DETECTION_THRESHOLD_SF_6); } else { + this->implicitHdr = false; state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_HEADER_EXPL_MODE | (SX127x::crcEnabled ? RADIOLIB_SX1272_RX_CRC_MODE_ON : RADIOLIB_SX1272_RX_CRC_MODE_OFF), 2, 1); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, newSpreadingFactor | RADIOLIB_SX127X_TX_MODE_SINGLE, 7, 3); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECT_OPTIMIZE, RADIOLIB_SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0); @@ -544,27 +548,6 @@ int16_t SX1272::setCodingRateRaw(uint8_t newCodingRate) { return(state); } -int16_t SX1272::setHeaderType(uint8_t headerType, size_t len) { - // check active modem - if(getActiveModem() != RADIOLIB_SX127X_LORA) { - return(RADIOLIB_ERR_WRONG_MODEM); - } - - // set requested packet mode - Module* mod = this->getMod(); - int16_t state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, headerType, 2, 2); - RADIOLIB_ASSERT(state); - - // set length to register - state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len); - RADIOLIB_ASSERT(state); - - // update cached value - SX127x::packetLength = len; - - return(state); -} - int16_t SX1272::configFSK() { // configure common registers int16_t state = SX127x::configFSK(); @@ -587,10 +570,10 @@ void SX1272::errataFix(bool rx) { int16_t SX1272::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; default: diff --git a/lib/RadioLib/src/modules/SX127x/SX1272.h b/lib/RadioLib/src/modules/SX127x/SX1272.h index 2689969..337558e 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1272.h +++ b/lib/RadioLib/src/modules/SX127x/SX1272.h @@ -316,7 +316,6 @@ class SX1272: public SX127x { int16_t setBandwidthRaw(uint8_t newBandwidth); int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor); int16_t setCodingRateRaw(uint8_t newCodingRate); - int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF); int16_t configFSK(); void errataFix(bool rx) override; diff --git a/lib/RadioLib/src/modules/SX127x/SX1273.cpp b/lib/RadioLib/src/modules/SX127x/SX1273.cpp index 0efbbe9..6a3af96 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1273.cpp +++ b/lib/RadioLib/src/modules/SX127x/SX1273.cpp @@ -117,10 +117,10 @@ int16_t SX1273::checkDataRate(DataRate_t dr) { int16_t SX1273::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; default: diff --git a/lib/RadioLib/src/modules/SX127x/SX1276.cpp b/lib/RadioLib/src/modules/SX127x/SX1276.cpp index 8890c6c..062d11b 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1276.cpp +++ b/lib/RadioLib/src/modules/SX127x/SX1276.cpp @@ -81,10 +81,10 @@ int16_t SX1276::setFrequency(float freq) { int16_t SX1276::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; default: diff --git a/lib/RadioLib/src/modules/SX127x/SX1277.cpp b/lib/RadioLib/src/modules/SX127x/SX1277.cpp index c85a5fe..59729e8 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1277.cpp +++ b/lib/RadioLib/src/modules/SX127x/SX1277.cpp @@ -159,10 +159,10 @@ int16_t SX1277::checkDataRate(DataRate_t dr) { int16_t SX1277::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; default: diff --git a/lib/RadioLib/src/modules/SX127x/SX1278.cpp b/lib/RadioLib/src/modules/SX127x/SX1278.cpp index e53bfe3..df76e56 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1278.cpp +++ b/lib/RadioLib/src/modules/SX127x/SX1278.cpp @@ -535,11 +535,13 @@ int16_t SX1278::autoLDRO() { } int16_t SX1278::implicitHeader(size_t len) { - return(setHeaderType(RADIOLIB_SX1278_HEADER_IMPL_MODE, len)); + this->implicitHdr = true; + return(setHeaderType(RADIOLIB_SX1278_HEADER_IMPL_MODE, 0, len)); } int16_t SX1278::explicitHeader() { - return(setHeaderType(RADIOLIB_SX1278_HEADER_EXPL_MODE)); + this->implicitHdr = false; + return(setHeaderType(RADIOLIB_SX1278_HEADER_EXPL_MODE, 0)); } int16_t SX1278::setBandwidthRaw(uint8_t newBandwidth) { @@ -559,11 +561,13 @@ int16_t SX1278::setSpreadingFactorRaw(uint8_t newSpreadingFactor) { // write registers Module* mod = this->getMod(); if(newSpreadingFactor == RADIOLIB_SX127X_SF_6) { + this->implicitHdr = true; state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1278_HEADER_IMPL_MODE, 0, 0); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, RADIOLIB_SX127X_SF_6 | RADIOLIB_SX127X_TX_MODE_SINGLE, 7, 3); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECT_OPTIMIZE, RADIOLIB_SX127X_DETECT_OPTIMIZE_SF_6, 2, 0); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECTION_THRESHOLD, RADIOLIB_SX127X_DETECTION_THRESHOLD_SF_6); } else { + this->implicitHdr = false; state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1278_HEADER_EXPL_MODE, 0, 0); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, newSpreadingFactor | RADIOLIB_SX127X_TX_MODE_SINGLE, 7, 3); state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECT_OPTIMIZE, RADIOLIB_SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0); @@ -582,27 +586,6 @@ int16_t SX1278::setCodingRateRaw(uint8_t newCodingRate) { return(state); } -int16_t SX1278::setHeaderType(uint8_t headerType, size_t len) { - // check active modem - if(getActiveModem() != RADIOLIB_SX127X_LORA) { - return(RADIOLIB_ERR_WRONG_MODEM); - } - - // set requested packet mode - Module* mod = this->getMod(); - int16_t state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, headerType, 0, 0); - RADIOLIB_ASSERT(state); - - // set length to register - state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len); - RADIOLIB_ASSERT(state); - - // update cached value - SX127x::packetLength = len; - - return(state); -} - int16_t SX1278::configFSK() { // configure common registers int16_t state = SX127x::configFSK(); @@ -707,10 +690,10 @@ void SX1278::errataFix(bool rx) { int16_t SX1278::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; default: diff --git a/lib/RadioLib/src/modules/SX127x/SX1278.h b/lib/RadioLib/src/modules/SX127x/SX1278.h index feb1d09..1fadf64 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1278.h +++ b/lib/RadioLib/src/modules/SX127x/SX1278.h @@ -328,7 +328,6 @@ class SX1278: public SX127x { int16_t setBandwidthRaw(uint8_t newBandwidth); int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor); int16_t setCodingRateRaw(uint8_t newCodingRate); - int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF); int16_t configFSK(); void errataFix(bool rx) override; diff --git a/lib/RadioLib/src/modules/SX127x/SX1279.cpp b/lib/RadioLib/src/modules/SX127x/SX1279.cpp index 4babad0..a91273f 100644 --- a/lib/RadioLib/src/modules/SX127x/SX1279.cpp +++ b/lib/RadioLib/src/modules/SX127x/SX1279.cpp @@ -81,10 +81,10 @@ int16_t SX1279::setFrequency(float freq) { int16_t SX1279::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginFSK()); } break; default: diff --git a/lib/RadioLib/src/modules/SX127x/SX127x.cpp b/lib/RadioLib/src/modules/SX127x/SX127x.cpp index a8c6122..9774b3a 100644 --- a/lib/RadioLib/src/modules/SX127x/SX127x.cpp +++ b/lib/RadioLib/src/modules/SX127x/SX127x.cpp @@ -417,8 +417,9 @@ int16_t SX127x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, Radi state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 5, 4); } - // set expected packet length for SF6 - if(this->spreadingFactor == 6) { + // in implicit header mode, use the provided length if it is nonzero + // otherwise we trust the user has previously set the payload length manually + if((this->implicitHdr) && (len != 0)) { state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len); this->packetLength = len; } @@ -504,6 +505,10 @@ void SX127x::clearFifoEmptyAction() { clearDio1Action(); } +void SX127x::setFifoThreshold(uint8_t threshold) { + this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, threshold, 5, 0); +} + void SX127x::setFifoFullAction(void (*func)(void)) { // set the interrupt this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_FIFO_THRESH, 5, 0); @@ -1197,9 +1202,10 @@ int16_t SX127x::setFrequencyRaw(float newFreq) { uint32_t FRF = (newFreq * (uint32_t(1) << RADIOLIB_SX127X_DIV_EXPONENT)) / RADIOLIB_SX127X_CRYSTAL_FREQ; // write registers + // lsb needs to be written no matter what in order for the module to update the frequency state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_MSB, (FRF & 0xFF0000) >> 16); state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_MID, (FRF & 0x00FF00) >> 8); - state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_LSB, FRF & 0x0000FF); + state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_LSB, FRF & 0x0000FF, 7U, 0U, 2U, 0xFF, true); return(state); } @@ -1207,12 +1213,12 @@ size_t SX127x::getPacketLength(bool update) { int16_t modem = getActiveModem(); if(modem == RADIOLIB_SX127X_LORA) { - if(this->spreadingFactor != 6) { - // get packet length for SF7 - SF12 + if(!this->implicitHdr) { + // get packet length for explicit header mode return(this->mod->SPIreadRegister(RADIOLIB_SX127X_REG_RX_NB_BYTES)); } else { - // return the cached value for SF6 + // return the cached value for implicit header mode return(this->packetLength); } @@ -1320,7 +1326,7 @@ int16_t SX127x::setIrqFlags(uint32_t irq) { uint8_t usedPinFlags = 0; bool conflict = false; int16_t modem = getActiveModem(); - int16_t state; + int16_t state = RADIOLIB_ERR_NONE; for(uint8_t i = 0; i <= 31; i++) { // check if the bit is set uint32_t irqBit = irq & (1UL << i); @@ -1760,10 +1766,10 @@ int16_t SX127x::getModem(ModemType_t* modem) { int16_t packetType = getActiveModem(); switch(packetType) { case(RADIOLIB_SX127X_LORA): - *modem = ModemType_t::LoRa; + *modem = ModemType_t::RADIOLIB_MODEM_LORA; return(RADIOLIB_ERR_NONE); case(RADIOLIB_SX127X_FSK_OOK): - *modem = ModemType_t::FSK; + *modem = ModemType_t::RADIOLIB_MODEM_FSK; return(RADIOLIB_ERR_NONE); } @@ -1856,6 +1862,27 @@ float SX127x::getRSSI(bool packet, bool skipReceive, int16_t offset) { } } +int16_t SX127x::setHeaderType(uint8_t headerType, uint8_t bitIndex, size_t len) { + // check active modem + if(getActiveModem() != RADIOLIB_SX127X_LORA) { + return(RADIOLIB_ERR_WRONG_MODEM); + } + + // set requested packet mode + Module* mod = this->getMod(); + int16_t state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, headerType, bitIndex, bitIndex); + RADIOLIB_ASSERT(state); + + // set length to register + state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len); + RADIOLIB_ASSERT(state); + + // update cached value + SX127x::packetLength = len; + + return(state); +} + int16_t SX127x::setLowBatteryThreshold(int8_t level, uint32_t pin) { // check disable if(level < 0) { diff --git a/lib/RadioLib/src/modules/SX127x/SX127x.h b/lib/RadioLib/src/modules/SX127x/SX127x.h index c54a549..593f27e 100644 --- a/lib/RadioLib/src/modules/SX127x/SX127x.h +++ b/lib/RadioLib/src/modules/SX127x/SX127x.h @@ -761,6 +761,14 @@ class SX127x: public PhysicalLayer { */ void clearFifoEmptyAction(); + /*! + \brief Set FIFO threshold level. + Be aware that threshold is also set in setFifoFullAction method. + setFifoThreshold method must be called AFTER calling setFifoFullAction! + \param threshold Threshold level in bytes. + */ + void setFifoThreshold(uint8_t threshold); + /*! \brief Set interrupt service routine function to call when FIFO is full. \param func Pointer to interrupt service routine. @@ -1241,12 +1249,14 @@ class SX127x: public PhysicalLayer { uint8_t codingRate = 0; bool crcEnabled = false; bool ookEnabled = false; + bool implicitHdr = false; int16_t configFSK(); int16_t getActiveModem(); int16_t setFrequencyRaw(float newFreq); int16_t setBitRateCommon(float br, uint8_t fracRegAddr); float getRSSI(bool packet, bool skipReceive, int16_t offset); + int16_t setHeaderType(uint8_t headerType, uint8_t bitIndex, size_t len = 0xFF); #if !RADIOLIB_GODMODE private: diff --git a/lib/RadioLib/src/modules/SX128x/SX128x.cpp b/lib/RadioLib/src/modules/SX128x/SX128x.cpp index 7a5fc20..139fac5 100644 --- a/lib/RadioLib/src/modules/SX128x/SX128x.cpp +++ b/lib/RadioLib/src/modules/SX128x/SX128x.cpp @@ -327,8 +327,8 @@ int16_t SX128x::transmit(const uint8_t* data, size_t len, uint8_t addr) { int16_t state = standby(); RADIOLIB_ASSERT(state); - // calculate timeout in ms (500% of expected time-on-air) - RadioLibTime_t timeout = (getTimeOnAir(len) * 5) / 1000; + // calculate timeout in ms (5ms + 500 % of expected time-on-air) + RadioLibTime_t timeout = 5 + (getTimeOnAir(len) * 5) / 1000; RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout); // start transmission @@ -480,8 +480,9 @@ int16_t SX128x::standby(uint8_t mode, bool wakeup) { this->mod->setRfSwitchState(Module::MODE_IDLE); if(wakeup) { - // pull NSS low to wake up - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow); + // send a NOP command - this pulls the NSS low to exit the sleep mode, + // while preventing interference with possible other SPI transactions + (void)this->mod->SPIwriteStream((uint16_t)RADIOLIB_SX128X_CMD_NOP, NULL, 0, false, false); } uint8_t data[] = { mode }; @@ -589,7 +590,11 @@ int16_t SX128x::startReceive() { } int16_t SX128x::startReceive(uint16_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) { - (void)len; + // in implicit header mode, use the provided length if it is nonzero + // otherwise we trust the user has previously set the payload length manually + if((this->headerType == RADIOLIB_SX128X_LORA_HEADER_IMPLICIT) && (len != 0)) { + this->payloadLen = len; + } // check active modem if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) { @@ -858,10 +863,10 @@ int16_t SX128x::checkOutputPower(int8_t pwr, int8_t* clipped) { int16_t SX128x::setModem(ModemType_t modem) { switch(modem) { - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { return(this->begin()); } break; - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { return(this->beginGFSK()); } break; default: @@ -875,10 +880,10 @@ int16_t SX128x::getModem(ModemType_t* modem) { uint8_t packetType = getPacketType(); switch(packetType) { case(RADIOLIB_SX128X_PACKET_TYPE_LORA): - *modem = ModemType_t::LoRa; + *modem = ModemType_t::RADIOLIB_MODEM_LORA; return(RADIOLIB_ERR_NONE); case(RADIOLIB_SX128X_PACKET_TYPE_GFSK): - *modem = ModemType_t::FSK; + *modem = ModemType_t::RADIOLIB_MODEM_FSK; return(RADIOLIB_ERR_NONE); } diff --git a/lib/RadioLib/src/modules/nRF24/nRF24.cpp b/lib/RadioLib/src/modules/nRF24/nRF24.cpp index deafef2..0218ddd 100644 --- a/lib/RadioLib/src/modules/nRF24/nRF24.cpp +++ b/lib/RadioLib/src/modules/nRF24/nRF24.cpp @@ -615,43 +615,7 @@ void nRF24::SPIwriteTxPayload(uint8_t* data, uint8_t numBytes) { } void nRF24::SPItransfer(uint8_t cmd, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes) { - // prepare the buffers - size_t buffLen = 1 + numBytes; - #if RADIOLIB_STATIC_ONLY - uint8_t buffOut[RADIOLIB_STATIC_ARRAY_SIZE]; - uint8_t buffIn[RADIOLIB_STATIC_ARRAY_SIZE]; - #else - uint8_t* buffOut = new uint8_t[buffLen]; - uint8_t* buffIn = new uint8_t[buffLen]; - #endif - uint8_t* buffOutPtr = buffOut; - - // copy the command - *(buffOutPtr++) = cmd; - - // copy the data - if(write) { - memcpy(buffOutPtr, dataOut, numBytes); - } else { - memset(buffOutPtr, 0x00, numBytes); - } - - // do the transfer - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow); - this->mod->hal->spiBeginTransaction(); - this->mod->hal->spiTransfer(buffOut, buffLen, buffIn); - this->mod->hal->spiEndTransaction(); - this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelHigh); - - // copy the data - if(!write) { - memcpy(dataIn, &buffIn[1], numBytes); - } - - #if !RADIOLIB_STATIC_ONLY - delete[] buffOut; - delete[] buffIn; - #endif + (void)this->mod->SPItransferStream(&cmd, 1, write, dataOut, dataIn, numBytes, false); } #endif diff --git a/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.cpp b/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.cpp index 6b4666a..07281be 100644 --- a/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.cpp +++ b/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.cpp @@ -12,13 +12,11 @@ LoRaWANNode::LoRaWANNode(PhysicalLayer* phy, const LoRaWANBand_t* band, uint8_t this->channels[RADIOLIB_LORAWAN_DIR_RX2] = this->band->rx2; this->txPowerMax = this->band->powerMax; this->subBand = subBand; - this->dwellTimeEnabledUp = this->dwellTimeUp != 0; - this->dwellTimeEnabledDn = this->dwellTimeDn != 0; memset(this->channelPlan, 0, sizeof(this->channelPlan)); } #if defined(RADIOLIB_BUILD_ARDUINO) -int16_t LoRaWANNode::sendReceive(String& strUp, uint8_t fPort, String& strDown, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) { +int16_t LoRaWANNode::sendReceive(const String& strUp, uint8_t fPort, String& strDown, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) { int16_t state = RADIOLIB_ERR_UNKNOWN; const char* dataUp = strUp.c_str(); @@ -28,7 +26,7 @@ int16_t LoRaWANNode::sendReceive(String& strUp, uint8_t fPort, String& strDown, size_t lenDown = 0; uint8_t dataDown[251]; - state = this->sendReceive((uint8_t*)dataUp, strlen(dataUp), fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown); + state = this->sendReceive((const uint8_t*)dataUp, strlen(dataUp), fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown); if(state == RADIOLIB_ERR_NONE) { // add null terminator @@ -55,7 +53,7 @@ int16_t LoRaWANNode::sendReceive(const char* strUp, uint8_t fPort, uint8_t* data return(this->sendReceive((uint8_t*)strUp, strlen(strUp), fPort, dataDown, lenDown, isConfirmed, eventUp, eventDown)); } -int16_t LoRaWANNode::sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) { +int16_t LoRaWANNode::sendReceive(const uint8_t* dataUp, size_t lenUp, uint8_t fPort, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) { // build a temporary buffer // LoRaWAN downlinks can have 250 bytes at most with 1 extra byte for NULL size_t lenDown = 0; @@ -64,7 +62,7 @@ int16_t LoRaWANNode::sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, b return(this->sendReceive(dataUp, lenUp, fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown)); } -int16_t LoRaWANNode::sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, uint8_t* dataDown, size_t* lenDown, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) { +int16_t LoRaWANNode::sendReceive(const uint8_t* dataUp, size_t lenUp, uint8_t fPort, uint8_t* dataDown, size_t* lenDown, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) { if(!dataUp || !dataDown || !lenDown) { return(RADIOLIB_ERR_NULL_POINTER); } @@ -241,7 +239,7 @@ uint8_t* LoRaWANNode::getBufferNonces() { return(this->bufferNonces); } -int16_t LoRaWANNode::setBufferNonces(uint8_t* persistentBuffer) { +int16_t LoRaWANNode::setBufferNonces(const uint8_t* persistentBuffer) { if(this->isActivated()) { RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Did not update buffer: session already active"); return(RADIOLIB_ERR_NONE); @@ -292,7 +290,8 @@ void LoRaWANNode::clearSession() { this->confFCntDown = RADIOLIB_LORAWAN_FCNT_NONE; this->adrFCnt = 0; - // reset number of retransmissions from ADR + // reset ADR state + this->txPowerSteps = 0; this->nbTrans = 1; // clear CSMA settings @@ -307,7 +306,7 @@ void LoRaWANNode::createSession(uint16_t lwMode, uint8_t initialDr) { // setup JoinRequest uplink/downlink frequencies and datarates if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) { - this->selectChannelPlanDyn(true); + this->selectChannelPlanDyn(); } else { this->selectChannelPlanFix(); } @@ -346,15 +345,9 @@ void LoRaWANNode::createSession(uint16_t lwMode, uint8_t initialDr) { } // if there is no (channel that allowed the) user-specified datarate, use a default datarate - // we use the floor of the average datarate of the first enabled channel if(initialDr == RADIOLIB_LORAWAN_DATA_RATE_UNUSED) { - for(int i = 0; i < RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS; i++) { - if(this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i].enabled) { - uint8_t drMin = this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i].drMin; - uint8_t drMax = this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i].drMax; - drUp = (drMin + drMax) / 2; - } - } + // use the specified datarate from the first channel (this is always defined) + drUp = this->channelPlan[RADIOLIB_LORAWAN_UPLINK][0].dr; } } @@ -464,7 +457,7 @@ uint8_t* LoRaWANNode::getBufferSession() { return(this->bufferSession); } -int16_t LoRaWANNode::setBufferSession(uint8_t* persistentBuffer) { +int16_t LoRaWANNode::setBufferSession(const uint8_t* persistentBuffer) { if(this->isActivated()) { RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Did not update buffer: session already active"); return(RADIOLIB_ERR_NONE); @@ -588,7 +581,7 @@ int16_t LoRaWANNode::setBufferSession(uint8_t* persistentBuffer) { return(state); } -int16_t LoRaWANNode::beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey) { +int16_t LoRaWANNode::beginOTAA(uint64_t joinEUI, uint64_t devEUI, const uint8_t* nwkKey, const uint8_t* appKey) { if(!appKey) { return(RADIOLIB_ERR_NULL_POINTER); } @@ -617,7 +610,7 @@ int16_t LoRaWANNode::beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKe return(RADIOLIB_ERR_NONE); } -int16_t LoRaWANNode::beginABP(uint32_t addr, uint8_t* fNwkSIntKey, uint8_t* sNwkSIntKey, uint8_t* nwkSEncKey, uint8_t* appSKey) { +int16_t LoRaWANNode::beginABP(uint32_t addr, const uint8_t* fNwkSIntKey, const uint8_t* sNwkSIntKey, const uint8_t* nwkSEncKey, const uint8_t* appSKey) { if(!nwkSEncKey || !appSKey) { return(RADIOLIB_ERR_NULL_POINTER); } @@ -723,7 +716,7 @@ int16_t LoRaWANNode::processJoinAccept(LoRaWANJoinEvent_t *joinEvent) { } } else { // for v1.0.4, the JoinNonce is simply a non-repeating value (we only check the last value) - if(joinNonceNew == this->joinNonce) { + if((this->joinNonce > 0) && (joinNonceNew == this->joinNonce)) { return(RADIOLIB_ERR_JOIN_NONCE_INVALID); } } @@ -767,7 +760,7 @@ int16_t LoRaWANNode::processJoinAccept(LoRaWANJoinEvent_t *joinEvent) { // in case of dynamic band, reset the channels to clear JoinRequest-specific channels if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) { - this->selectChannelPlanDyn(false); + this->selectChannelPlanDyn(); } uint8_t cOcts[5]; @@ -846,8 +839,10 @@ int16_t LoRaWANNode::processJoinAccept(LoRaWANJoinEvent_t *joinEvent) { this->bufferNonces[RADIOLIB_LORAWAN_NONCES_ACTIVE] = (uint8_t)true; // generate the signature of the Nonces buffer, and store it in the last two bytes of the Nonces buffer + // also store this signature in the Session buffer to make sure these buffers match uint16_t signature = LoRaWANNode::checkSum16(this->bufferNonces, RADIOLIB_LORAWAN_NONCES_BUF_SIZE - 2); LoRaWANNode::hton(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_SIGNATURE], signature); + LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE], signature); // store DevAddr and all keys LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_DEV_ADDR], this->devAddr); @@ -855,9 +850,6 @@ int16_t LoRaWANNode::processJoinAccept(LoRaWANJoinEvent_t *joinEvent) { memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NWK_SENC_KEY], this->nwkSEncKey, RADIOLIB_AES128_KEY_SIZE); memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY], this->fNwkSIntKey, RADIOLIB_AES128_KEY_SIZE); memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_SNWK_SINT_KEY], this->sNwkSIntKey, RADIOLIB_AES128_KEY_SIZE); - - // set the signature of the Nonces buffer in the Session buffer - LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE], signature); // store network parameters LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_HOMENET_ID], this->homeNetId); @@ -913,7 +905,7 @@ int16_t LoRaWANNode::activateOTAA(uint8_t joinDr, LoRaWANJoinEvent_t *joinEvent) RADIOLIB_ASSERT(state); // calculate JoinRequest time-on-air in milliseconds - if(this->dwellTimeEnabledUp) { + if(this->dwellTimeUp) { RadioLibTime_t toa = this->phyLayer->getTimeOnAir(RADIOLIB_LORAWAN_JOIN_REQUEST_LEN) / 1000; if(toa > this->dwellTimeUp) { RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Dwell time exceeded: ToA = %lu, max = %d", (unsigned long)toa, this->dwellTimeUp); @@ -982,8 +974,10 @@ int16_t LoRaWANNode::activateABP(uint8_t initialDr) { this->bufferNonces[RADIOLIB_LORAWAN_NONCES_ACTIVE] = (uint8_t)true; // generate the signature of the Nonces buffer, and store it in the last two bytes of the Nonces buffer + // also store this signature in the Session buffer to make sure these buffers match uint16_t signature = LoRaWANNode::checkSum16(this->bufferNonces, RADIOLIB_LORAWAN_NONCES_BUF_SIZE - 2); LoRaWANNode::hton(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_SIGNATURE], signature); + LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE], signature); // store DevAddr and all keys LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_DEV_ADDR], this->devAddr); @@ -992,9 +986,6 @@ int16_t LoRaWANNode::activateABP(uint8_t initialDr) { memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY], this->fNwkSIntKey, RADIOLIB_AES128_BLOCK_SIZE); memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_SNWK_SINT_KEY], this->sNwkSIntKey, RADIOLIB_AES128_BLOCK_SIZE); - // set the signature of the Nonces buffer in the Session buffer - LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE], signature); - // store network parameters LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_HOMENET_ID], this->homeNetId); LoRaWANNode::hton(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_VERSION], this->rev); @@ -1139,15 +1130,26 @@ void LoRaWANNode::adrBackoff() { } } - // try to decrease the datarate + // if datarate can be decreased, try it if(this->channels[RADIOLIB_LORAWAN_UPLINK].dr > 0) { - if(this->setDatarate(this->channels[RADIOLIB_LORAWAN_UPLINK].dr - 1) == RADIOLIB_ERR_NONE) { - return; + uint8_t oldDr = this->channels[RADIOLIB_LORAWAN_UPLINK].dr; + + if(this->setDatarate(oldDr - 1) == RADIOLIB_ERR_NONE) { + // if there is no dwell time limit, a lower datarate is OK + if(!this->dwellTimeUp) { + return; + } + // if there is a dwell time limit, check if this datarate allows an empty uplink + if(this->phyLayer->getTimeOnAir(13) / 1000 < this->dwellTimeUp) { + return; + } + // if the Time on Air of an empty uplink exceeded the dwell time, revert + this->setDatarate(oldDr); } } if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) { - this->selectChannelPlanDyn(false); // revert to default frequencies + this->selectChannelPlanDyn(); // revert to default frequencies } else { this->selectChannelPlanFix(); // go back to default selected subband } @@ -1159,7 +1161,7 @@ void LoRaWANNode::adrBackoff() { return; } -void LoRaWANNode::composeUplink(uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t fPort, bool isConfirmed) { +void LoRaWANNode::composeUplink(const uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t fPort, bool isConfirmed) { // set the packet fields if(isConfirmed) { out[RADIOLIB_LORAWAN_FHDR_LEN_START_OFFS] = RADIOLIB_LORAWAN_MHDR_MTYPE_CONF_DATA_UP; @@ -1175,10 +1177,18 @@ void LoRaWANNode::composeUplink(uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_ out[RADIOLIB_LORAWAN_FHDR_FCTRL_POS] |= RADIOLIB_LORAWAN_FCTRL_ADR_ENABLED; // AdrAckReq is set if no downlink has been received for >=Limit uplinks - // but it is unset once backoff has been completed (which is internally denoted by adrFCnt == FCNT_NONE) uint32_t adrLimit = 0x01 << this->adrLimitExp; - if(this->adrFCnt != RADIOLIB_LORAWAN_FCNT_NONE && (this->fCntUp - this->adrFCnt) >= adrLimit) { - out[RADIOLIB_LORAWAN_FHDR_FCTRL_POS] |= RADIOLIB_LORAWAN_FCTRL_ADR_ACK_REQ; + if(this->rev == 1) { + // AdrAckReq is unset once backoff has been completed + // (which is internally denoted by adrFCnt == FCNT_NONE) + if(this->adrFCnt != RADIOLIB_LORAWAN_FCNT_NONE && (this->fCntUp - this->adrFCnt) >= adrLimit) { + out[RADIOLIB_LORAWAN_FHDR_FCTRL_POS] |= RADIOLIB_LORAWAN_FCTRL_ADR_ACK_REQ; + } + } else { // rev == 0 + // AdrAckReq is always set, also when backoff has been completed + if(this->adrFCnt == RADIOLIB_LORAWAN_FCNT_NONE || (this->fCntUp - this->adrFCnt) >= adrLimit) { + out[RADIOLIB_LORAWAN_FHDR_FCTRL_POS] |= RADIOLIB_LORAWAN_FCTRL_ADR_ACK_REQ; + } } } @@ -1561,7 +1571,7 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e #if !RADIOLIB_STATIC_ONLY delete[] downlinkMsg; #endif - return(RADIOLIB_ERR_INVALID_PORT); + return(RADIOLIB_ERR_DOWNLINK_MALFORMED); } // get the frame counter @@ -1641,8 +1651,8 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e isConfirmedDown = true; } - // a downlink was received, so reset the ADR counter to the last uplink's fCnt - this->adrFCnt = this->getFCntUp(); + // a downlink was received, so restart the ADR counter with the next uplink + this->adrFCnt = this->getFCntUp() + 1; // if this downlink is on FPort 0, the FOptsLen is the length of the payload // in any other case, the payload (length) is user accessible @@ -1710,15 +1720,24 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e while(procLen < fOptsLen) { cid = *mPtr; // MAC id is the first byte + + // fetch length of MAC downlink payload state = this->getMacLen(cid, &fLen, RADIOLIB_LORAWAN_DOWNLINK, true); - RADIOLIB_ASSERT(state); + if(state != RADIOLIB_ERR_NONE) { + RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Unknown MAC CID %02x", cid); + RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Skipping remaining MAC commands"); + break; + } + + // already fetch length of MAC answer payload (if any) uint8_t fLenRe = 0; - state = this->getMacLen(cid, &fLenRe, RADIOLIB_LORAWAN_UPLINK, true); - RADIOLIB_ASSERT(state); + (void)this->getMacLen(cid, &fLenRe, RADIOLIB_LORAWAN_UPLINK, true); + // don't care about return value: the previous getMacLen() would have failed anyway if(procLen + fLen > fOptsLen) { - RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Incomplete MAC command %02x (%d bytes, expected %d)", cid, fOptsLen, fLen); - return(RADIOLIB_ERR_INVALID_CID); + RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Incomplete MAC command %02x (%d bytes, expected %d)", cid, fOptsLen - procLen, fLen); + RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Skipping remaining MAC commands"); + break; } bool reply = false; @@ -1929,7 +1948,6 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin // only acknowledge if the radio is able to operate at or below the requested power level if(state == RADIOLIB_ERR_NONE || (state == RADIOLIB_ERR_INVALID_OUTPUT_POWER && powerActual < power)) { pwrAck = 1; - this->txPowerSteps = macTxSteps; } else { RADIOLIB_DEBUG_PROTOCOL_PRINTLN("ADR failed to configure Tx power %d, code %d!", power, state); } @@ -1941,10 +1959,17 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin // if ACK not completely successful, revert and stop if(optOut[0] != 0x07) { - this->applyChannelMask(chMaskGrp0123, chMaskGrp45); - this->setAvailableChannels(chMaskActive); + // according to paragraph 4.3.1.1, if ADR is disabled, + // the ADR channel mask must be accepted even if drAck/pwrAck fails. + // therefore, only revert the channel mask if ADR is enabled. + if(this->adrEnabled) { + this->applyChannelMask(chMaskGrp0123, chMaskGrp45); + this->setAvailableChannels(chMaskActive); + } + // revert datarate this->channels[RADIOLIB_LORAWAN_UPLINK].dr = currentDr; - // Tx power was not modified + // Tx power was not actually modified + return(true); } @@ -2211,10 +2236,7 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin this->txPowerMax = eirpEncoding[maxEirpRaw]; RADIOLIB_DEBUG_PROTOCOL_PRINTLN("TxParamSetupReq: dlDwell = %d, ulDwell = %d, maxEirp = %d dBm", dlDwell, ulDwell, eirpEncoding[maxEirpRaw]); - this->dwellTimeEnabledUp = ulDwell ? true : false; this->dwellTimeUp = ulDwell ? RADIOLIB_LORAWAN_DWELL_TIME : 0; - - this->dwellTimeEnabledDn = dlDwell ? true : false; this->dwellTimeDn = dlDwell ? RADIOLIB_LORAWAN_DWELL_TIME : 0; memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_TX_PARAM_SETUP], optIn, lenIn); @@ -2699,11 +2721,13 @@ void LoRaWANNode::setDutyCycle(bool enable, RadioLibTime_t msPerHour) { } void LoRaWANNode::setDwellTime(bool enable, RadioLibTime_t msPerUplink) { - this->dwellTimeEnabledUp = enable; - if(msPerUplink == 0) { - this->dwellTimeUp = this->band->dwellTimeUp; - } else { + if(!enable) { + this->dwellTimeUp = 0; + + } else if(msPerUplink > 0) { this->dwellTimeUp = msPerUplink; + } else { //msPerUplink == 0 + this->dwellTimeUp = this->band->dwellTimeUp; } } @@ -2776,11 +2800,11 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir, // set modem-dependent functions switch(this->band->dataRates[chnl->dr] & RADIOLIB_LORAWAN_DATA_RATE_MODEM) { case(RADIOLIB_LORAWAN_DATA_RATE_LORA): - if(modem != ModemType_t::LoRa) { - state = this->phyLayer->setModem(ModemType_t::LoRa); + if(modem != ModemType_t::RADIOLIB_MODEM_LORA) { + state = this->phyLayer->setModem(ModemType_t::RADIOLIB_MODEM_LORA); RADIOLIB_ASSERT(state); } - modem = ModemType_t::LoRa; + modem = ModemType_t::RADIOLIB_MODEM_LORA; // downlink messages are sent with inverted IQ if(dir == RADIOLIB_LORAWAN_DOWNLINK) { state = this->phyLayer->invertIQ(true); @@ -2791,11 +2815,11 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir, break; case(RADIOLIB_LORAWAN_DATA_RATE_FSK): - if(modem != ModemType_t::FSK) { - state = this->phyLayer->setModem(ModemType_t::FSK); + if(modem != ModemType_t::RADIOLIB_MODEM_FSK) { + state = this->phyLayer->setModem(ModemType_t::RADIOLIB_MODEM_FSK); RADIOLIB_ASSERT(state); } - modem = ModemType_t::FSK; + modem = ModemType_t::RADIOLIB_MODEM_FSK; state = this->phyLayer->setDataShaping(RADIOLIB_SHAPING_1_0); RADIOLIB_ASSERT(state); state = this->phyLayer->setEncoding(RADIOLIB_ENCODING_WHITENING); @@ -2803,11 +2827,11 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir, break; case(RADIOLIB_LORAWAN_DATA_RATE_LR_FHSS): - if(modem != ModemType_t::LRFHSS) { - state = this->phyLayer->setModem(ModemType_t::LRFHSS); + if(modem != ModemType_t::RADIOLIB_MODEM_LRFHSS) { + state = this->phyLayer->setModem(ModemType_t::RADIOLIB_MODEM_LRFHSS); RADIOLIB_ASSERT(state); } - modem = ModemType_t::LRFHSS; + modem = ModemType_t::RADIOLIB_MODEM_LRFHSS; break; default: @@ -2836,7 +2860,7 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir, uint8_t syncWordLen = 0; size_t preLen = 0; switch(modem) { - case(ModemType_t::FSK): { + case(ModemType_t::RADIOLIB_MODEM_FSK): { preLen = 8*RADIOLIB_LORAWAN_GFSK_PREAMBLE_LEN; syncWord[0] = (uint8_t)(RADIOLIB_LORAWAN_GFSK_SYNC_WORD >> 16); syncWord[1] = (uint8_t)(RADIOLIB_LORAWAN_GFSK_SYNC_WORD >> 8); @@ -2846,7 +2870,7 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir, dr.fsk.bitRate, dr.fsk.freqDev); } break; - case(ModemType_t::LoRa): { + case(ModemType_t::RADIOLIB_MODEM_LORA): { preLen = RADIOLIB_LORAWAN_LORA_PREAMBLE_LEN; syncWord[0] = RADIOLIB_LORAWAN_LORA_SYNC_WORD; syncWordLen = 1; @@ -2854,7 +2878,7 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir, dr.lora.spreadingFactor, dr.lora.bandwidth, dr.lora.codingRate, dir ? 'D' : 'U'); } break; - case(ModemType_t::LRFHSS): { + case(ModemType_t::RADIOLIB_MODEM_LRFHSS): { syncWord[0] = (uint8_t)(RADIOLIB_LORAWAN_LR_FHSS_SYNC_WORD >> 24); syncWord[1] = (uint8_t)(RADIOLIB_LORAWAN_LR_FHSS_SYNC_WORD >> 16); syncWord[2] = (uint8_t)(RADIOLIB_LORAWAN_LR_FHSS_SYNC_WORD >> 8); @@ -2875,7 +2899,7 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir, if(pre) { preLen = pre; } - if(modem != ModemType_t::LRFHSS) { + if(modem != ModemType_t::RADIOLIB_MODEM_LRFHSS) { state = this->phyLayer->setPreambleLength(preLen); } return(state); @@ -2970,7 +2994,7 @@ void LoRaWANNode::getChannelPlanMask(uint64_t* chMaskGrp0123, uint32_t* chMaskGr } } -void LoRaWANNode::selectChannelPlanDyn(bool joinRequest) { +void LoRaWANNode::selectChannelPlanDyn() { RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Setting up dynamic channels"); size_t num = 0; @@ -2980,15 +3004,6 @@ void LoRaWANNode::selectChannelPlanDyn(bool joinRequest) { this->channelPlan[RADIOLIB_LORAWAN_DOWNLINK][num] = this->band->txFreqs[num]; } - // if we're about to send a JoinRequest, copy the JoinRequest channels to the next slots - if(joinRequest) { - size_t numJR = 0; - for(; numJR < 3 && this->band->txJoinReq[num].enabled; numJR++, num++) { - this->channelPlan[RADIOLIB_LORAWAN_UPLINK][num] = this->band->txFreqs[num]; - this->channelPlan[RADIOLIB_LORAWAN_DOWNLINK][num] = this->band->txFreqs[num]; - } - } - // clear all remaining channels for(; num < RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS; num++) { this->channelPlan[RADIOLIB_LORAWAN_UPLINK][num] = RADIOLIB_LORAWAN_CHANNEL_NONE; @@ -3115,7 +3130,7 @@ int16_t LoRaWANNode::selectChannels() { // if downlink dwelltime is enabled, datarate < 2 cannot be used, so clip to 2 // only in use on AS923_x bands - if(this->dwellTimeEnabledDn && rx1Dr < 2) { + if(this->dwellTimeDn && rx1Dr < 2) { rx1Dr = 2; } this->channels[RADIOLIB_LORAWAN_DOWNLINK].dr = rx1Dr; @@ -3267,7 +3282,7 @@ uint8_t LoRaWANNode::getMaxPayloadLen() { maxLen += 13; // mandatory FHDR is 12/13 bytes // if not limited by dwell-time, just return maximum - if(!this->dwellTimeEnabledUp) { + if(!this->dwellTimeUp) { // subtract FHDR (13 bytes) as well as any FOpts return(maxLen - 13 - this->fOptsUpLen); } @@ -3305,7 +3320,7 @@ int16_t LoRaWANNode::findDataRate(uint8_t dr, DataRate_t* dataRate) { switch(dataRateBand & RADIOLIB_LORAWAN_DATA_RATE_MODEM) { case(RADIOLIB_LORAWAN_DATA_RATE_LORA): - modemNew = ModemType_t::LoRa; + modemNew = ModemType_t::RADIOLIB_MODEM_LORA; dataRate->lora.spreadingFactor = ((dataRateBand & RADIOLIB_LORAWAN_DATA_RATE_SF) >> 3) + 7; switch(dataRateBand & RADIOLIB_LORAWAN_DATA_RATE_BW) { case(RADIOLIB_LORAWAN_DATA_RATE_BW_125_KHZ): @@ -3323,12 +3338,12 @@ int16_t LoRaWANNode::findDataRate(uint8_t dr, DataRate_t* dataRate) { dataRate->lora.codingRate = 5; break; case(RADIOLIB_LORAWAN_DATA_RATE_FSK): - modemNew = ModemType_t::FSK; + modemNew = ModemType_t::RADIOLIB_MODEM_FSK; dataRate->fsk.bitRate = 50; dataRate->fsk.freqDev = 25; break; case(RADIOLIB_LORAWAN_DATA_RATE_LR_FHSS): - modemNew = ModemType_t::LRFHSS; + modemNew = ModemType_t::RADIOLIB_MODEM_LRFHSS; switch(dataRateBand & RADIOLIB_LORAWAN_DATA_RATE_BW) { case(RADIOLIB_LORAWAN_DATA_RATE_BW_137_KHZ): dataRate->lrFhss.bw = 0x02; // specific encoding @@ -3416,7 +3431,7 @@ void LoRaWANNode::processAES(const uint8_t* in, size_t len, uint8_t* key, uint8_ } } -int16_t LoRaWANNode::checkBufferCommon(uint8_t *buffer, uint16_t size) { +int16_t LoRaWANNode::checkBufferCommon(const uint8_t *buffer, uint16_t size) { // check if there are actually values in the buffer size_t i = 0; for(; i < size; i++) { diff --git a/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.h b/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.h index cc9c364..90a51ab 100644 --- a/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.h +++ b/lib/RadioLib/src/protocols/LoRaWAN/LoRaWAN.h @@ -232,7 +232,7 @@ struct LoRaWANMacCommand_t { #define RADIOLIB_LORAWAN_MAC_COMMAND_NONE { .cid = 0, .lenDn = 0, .lenUp = 0, .persist = false, .user = false } constexpr LoRaWANMacCommand_t MacTable[RADIOLIB_LORAWAN_NUM_MAC_COMMANDS] = { - { RADIOLIB_LORAWAN_MAC_RESET, 1, 1, false, false }, + { RADIOLIB_LORAWAN_MAC_RESET, 1, 1, true, false }, { RADIOLIB_LORAWAN_MAC_LINK_CHECK, 2, 0, false, true }, { RADIOLIB_LORAWAN_MAC_LINK_ADR, 4, 1, false, false }, { RADIOLIB_LORAWAN_MAC_DUTY_CYCLE, 1, 0, false, false }, @@ -242,7 +242,7 @@ constexpr LoRaWANMacCommand_t MacTable[RADIOLIB_LORAWAN_NUM_MAC_COMMANDS] = { { RADIOLIB_LORAWAN_MAC_RX_TIMING_SETUP, 1, 0, true, false }, { RADIOLIB_LORAWAN_MAC_TX_PARAM_SETUP, 1, 0, true, false }, { RADIOLIB_LORAWAN_MAC_DL_CHANNEL, 4, 1, true, false }, - { RADIOLIB_LORAWAN_MAC_REKEY, 1, 1, false, false }, + { RADIOLIB_LORAWAN_MAC_REKEY, 1, 1, true, false }, { RADIOLIB_LORAWAN_MAC_ADR_PARAM_SETUP, 1, 0, false, false }, { RADIOLIB_LORAWAN_MAC_DEVICE_TIME, 5, 0, false, true }, { RADIOLIB_LORAWAN_MAC_FORCE_REJOIN, 2, 0, false, false }, @@ -273,8 +273,8 @@ enum LoRaWANSchemeSession_t { RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY = RADIOLIB_LORAWAN_SESSION_APP_SKEY + RADIOLIB_AES128_KEY_SIZE, // 16 bytes RADIOLIB_LORAWAN_SESSION_SNWK_SINT_KEY = RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY + RADIOLIB_AES128_KEY_SIZE, // 16 bytes RADIOLIB_LORAWAN_SESSION_DEV_ADDR = RADIOLIB_LORAWAN_SESSION_SNWK_SINT_KEY + RADIOLIB_AES128_KEY_SIZE, // 4 bytes - RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE = RADIOLIB_LORAWAN_SESSION_DEV_ADDR + sizeof(uint32_t), // 2 bytes - RADIOLIB_LORAWAN_SESSION_FCNT_UP = RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE + 2, // 4 bytes + RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE = RADIOLIB_LORAWAN_SESSION_DEV_ADDR + sizeof(uint32_t), // 2 bytes + RADIOLIB_LORAWAN_SESSION_FCNT_UP = RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE + sizeof(uint16_t), // 4 bytes RADIOLIB_LORAWAN_SESSION_N_FCNT_DOWN = RADIOLIB_LORAWAN_SESSION_FCNT_UP + sizeof(uint32_t), // 4 bytes RADIOLIB_LORAWAN_SESSION_A_FCNT_DOWN = RADIOLIB_LORAWAN_SESSION_N_FCNT_DOWN + sizeof(uint32_t), // 4 bytes RADIOLIB_LORAWAN_SESSION_ADR_FCNT = RADIOLIB_LORAWAN_SESSION_A_FCNT_DOWN + sizeof(uint32_t), // 4 bytes @@ -291,11 +291,7 @@ enum LoRaWANSchemeSession_t { RADIOLIB_LORAWAN_SESSION_TX_PARAM_SETUP = RADIOLIB_LORAWAN_SESSION_RX_TIMING_SETUP + 1, // 1 byte RADIOLIB_LORAWAN_SESSION_ADR_PARAM_SETUP = RADIOLIB_LORAWAN_SESSION_TX_PARAM_SETUP + 1, // 1 byte RADIOLIB_LORAWAN_SESSION_REJOIN_PARAM_SETUP = RADIOLIB_LORAWAN_SESSION_ADR_PARAM_SETUP + 1, // 1 byte - RADIOLIB_LORAWAN_SESSION_BEACON_FREQ = RADIOLIB_LORAWAN_SESSION_REJOIN_PARAM_SETUP + 1, // 3 bytes - RADIOLIB_LORAWAN_SESSION_PING_SLOT_CHANNEL = RADIOLIB_LORAWAN_SESSION_BEACON_FREQ + 3, // 4 bytes - RADIOLIB_LORAWAN_SESSION_PERIODICITY = RADIOLIB_LORAWAN_SESSION_PING_SLOT_CHANNEL + 4, // 1 byte - RADIOLIB_LORAWAN_SESSION_LAST_TIME = RADIOLIB_LORAWAN_SESSION_PERIODICITY + 1, // 4 bytes - RADIOLIB_LORAWAN_SESSION_UL_CHANNELS = RADIOLIB_LORAWAN_SESSION_LAST_TIME + 4, // 16*5 bytes + RADIOLIB_LORAWAN_SESSION_UL_CHANNELS = RADIOLIB_LORAWAN_SESSION_REJOIN_PARAM_SETUP + 1, // 16*5 bytes RADIOLIB_LORAWAN_SESSION_DL_CHANNELS = RADIOLIB_LORAWAN_SESSION_UL_CHANNELS + RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS*5, // 16*4 bytes RADIOLIB_LORAWAN_SESSION_AVAILABLE_CHANNELS = RADIOLIB_LORAWAN_SESSION_DL_CHANNELS + RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS*4, // 2 bytes RADIOLIB_LORAWAN_SESSION_MAC_QUEUE = RADIOLIB_LORAWAN_SESSION_AVAILABLE_CHANNELS + sizeof(uint16_t), // 15 bytes @@ -405,9 +401,6 @@ struct LoRaWANBand_t { /*! \brief A set of default uplink (TX) channels for dynamic bands */ LoRaWANChannel_t txFreqs[3]; - /*! \brief A set of possible extra channels for the Join-Request message for dynamic bands */ - LoRaWANChannel_t txJoinReq[3]; - /*! \brief The number of TX channel spans for fixed bands */ uint8_t numTxSpans; @@ -548,7 +541,7 @@ class LoRaWANNode { \param persistentBuffer Buffer that should match the internal format (previously extracted using getBufferNonces) \returns \ref status_codes */ - int16_t setBufferNonces(uint8_t* persistentBuffer); + int16_t setBufferNonces(const uint8_t* persistentBuffer); /*! \brief Clear an active session, so that the device will have to rejoin the network. @@ -566,7 +559,7 @@ class LoRaWANNode { \param persistentBuffer Buffer that should match the internal format (previously extracted using getBufferSession) \returns \ref status_codes */ - int16_t setBufferSession(uint8_t* persistentBuffer); + int16_t setBufferSession(const uint8_t* persistentBuffer); /*! \brief Set the device credentials and activation configuration @@ -576,7 +569,7 @@ class LoRaWANNode { \param appKey Pointer to the application AES-128 key. \returns \ref status_codes */ - int16_t beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey); + int16_t beginOTAA(uint64_t joinEUI, uint64_t devEUI, const uint8_t* nwkKey, const uint8_t* appKey); /*! \brief Set the device credentials and activation configuration @@ -588,7 +581,7 @@ class LoRaWANNode { \param appSKey Pointer to the application session AES-128 key. \returns \ref status_codes */ - int16_t beginABP(uint32_t addr, uint8_t* fNwkSIntKey, uint8_t* sNwkSIntKey, uint8_t* nwkSEncKey, uint8_t* appSKey); + int16_t beginABP(uint32_t addr, const uint8_t* fNwkSIntKey, const uint8_t* sNwkSIntKey, const uint8_t* nwkSEncKey, const uint8_t* appSKey); /*! \brief Join network by restoring OTAA session or performing over-the-air activation. By this procedure, @@ -622,7 +615,7 @@ class LoRaWANNode { (fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user. \returns Window number > 0 if downlink was received, 0 is no downlink was received, otherwise \ref status_codes */ - virtual int16_t sendReceive(String& strUp, uint8_t fPort, String& strDown, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL); + virtual int16_t sendReceive(const String& strUp, uint8_t fPort, String& strDown, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL); #endif /*! @@ -665,7 +658,7 @@ class LoRaWANNode { (fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user. \returns Window number > 0 if downlink was received, 0 is no downlink was received, otherwise \ref status_codes */ - virtual int16_t sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort = 1, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL); + virtual int16_t sendReceive(const uint8_t* dataUp, size_t lenUp, uint8_t fPort = 1, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL); /*! \brief Send a message to the server and wait for a downlink during Rx1 and/or Rx2 window. @@ -681,7 +674,7 @@ class LoRaWANNode { (fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user. \returns Window number > 0 if downlink was received, 0 is no downlink was received, otherwise \ref status_codes */ - virtual int16_t sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, uint8_t* dataDown, size_t* lenDown, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL); + virtual int16_t sendReceive(const uint8_t* dataUp, size_t lenUp, uint8_t fPort, uint8_t* dataDown, size_t* lenDown, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL); /*! \brief Add a MAC command to the uplink queue. @@ -750,10 +743,10 @@ class LoRaWANNode { void setDutyCycle(bool enable = true, RadioLibTime_t msPerHour = 0); /*! - \brief Toggle adherence to dwellTime limits to on or off. + \brief Set or disable uplink dwell time limitation; enabled by default if mandatory. \param enable Whether to adhere to dwellTime limits or not (default true). \param msPerUplink The maximum allowed Time-on-Air per uplink in milliseconds - (default 0 = maximum allowed for configured band). + (default 0 = band default value); make sure you follow regulations/law! */ void setDwellTime(bool enable, RadioLibTime_t msPerUplink = 0); @@ -920,9 +913,7 @@ class LoRaWANNode { uint32_t dutyCycle = 0; // dwell time is set upon initialization and activated in regions that impose this - bool dwellTimeEnabledUp = false; uint16_t dwellTimeUp = 0; - bool dwellTimeEnabledDn = false; uint16_t dwellTimeDn = 0; RadioLibTime_t tUplink = 0; // scheduled uplink transmission time (internal clock) @@ -1002,7 +993,7 @@ class LoRaWANNode { void adrBackoff(); // create an encrypted uplink buffer, composing metadata, user data and MAC data - void composeUplink(uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t fPort, bool isConfirmed); + void composeUplink(const uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t fPort, bool isConfirmed); // generate and set the MIC of an uplink buffer (depends on selected channels) void micUplink(uint8_t* inOut, uint8_t lenInOut); @@ -1071,7 +1062,7 @@ class LoRaWANNode { // setup uplink/downlink channel data rates and frequencies // for dynamic channels, there is a small set of predefined channels // in case of JoinRequest, add some optional extra frequencies - void selectChannelPlanDyn(bool joinRequest = false); + void selectChannelPlanDyn(); // setup uplink/downlink channel data rates and frequencies // for fixed bands, we only allow one sub-band at a time to be selected @@ -1112,11 +1103,11 @@ class LoRaWANNode { static uint16_t checkSum16(const uint8_t *key, uint16_t keyLen); // check the integrity of a buffer using a 16-bit checksum located in the last two bytes of the buffer - static int16_t checkBufferCommon(uint8_t *buffer, uint16_t size); + static int16_t checkBufferCommon(const uint8_t *buffer, uint16_t size); // network-to-host conversion method - takes data from network packet and converts it to the host endians template - static T ntoh(uint8_t* buff, size_t size = 0); + static T ntoh(const uint8_t* buff, size_t size = 0); // host-to-network conversion method - takes data from host variable and and converts it to network packet endians template @@ -1124,8 +1115,8 @@ class LoRaWANNode { }; template -T LoRaWANNode::ntoh(uint8_t* buff, size_t size) { - uint8_t* buffPtr = buff; +T LoRaWANNode::ntoh(const uint8_t* buff, size_t size) { + const uint8_t* buffPtr = buff; size_t targetSize = sizeof(T); if(size != 0) { targetSize = size; diff --git a/lib/RadioLib/src/protocols/LoRaWAN/LoRaWANBands.cpp b/lib/RadioLib/src/protocols/LoRaWAN/LoRaWANBands.cpp index d29126a..398de51 100644 --- a/lib/RadioLib/src/protocols/LoRaWAN/LoRaWANBands.cpp +++ b/lib/RadioLib/src/protocols/LoRaWAN/LoRaWANBands.cpp @@ -30,14 +30,9 @@ const LoRaWANBand_t EU868 = { .dwellTimeDn = 0, .txParamSupported = false, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 8681000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 8683000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 2, .freq = 8685000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE + { .enabled = true, .idx = 0, .freq = 8681000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 8683000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 2, .freq = 8685000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, }, .numTxSpans = 0, .txSpans = { @@ -107,11 +102,6 @@ const LoRaWANBand_t US915 = { RADIOLIB_LORAWAN_CHANNEL_NONE, RADIOLIB_LORAWAN_CHANNEL_NONE }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE - }, .numTxSpans = 2, .txSpans = { { @@ -197,14 +187,9 @@ const LoRaWANBand_t EU433 = { .dwellTimeDn = 0, .txParamSupported = false, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 4331750, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 4333750, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 2, .freq = 4335750, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE + { .enabled = true, .idx = 0, .freq = 4331750, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 4333750, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 2, .freq = 4335750, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, }, .numTxSpans = 0, .txSpans = { @@ -274,11 +259,6 @@ const LoRaWANBand_t AU915 = { RADIOLIB_LORAWAN_CHANNEL_NONE, RADIOLIB_LORAWAN_CHANNEL_NONE }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE - }, .numTxSpans = 2, .txSpans = { { @@ -368,11 +348,6 @@ const LoRaWANBand_t CN500 = { RADIOLIB_LORAWAN_CHANNEL_NONE, RADIOLIB_LORAWAN_CHANNEL_NONE }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE - }, .numTxSpans = 1, .txSpans = { { @@ -451,13 +426,8 @@ const LoRaWANBand_t AS923 = { .dwellTimeDn = RADIOLIB_LORAWAN_DWELL_TIME, .txParamSupported = true, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 9232000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 9234000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - RADIOLIB_LORAWAN_CHANNEL_NONE - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, + { .enabled = true, .idx = 0, .freq = 9232000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 9234000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, RADIOLIB_LORAWAN_CHANNEL_NONE }, .numTxSpans = 0, @@ -524,13 +494,8 @@ const LoRaWANBand_t AS923_2 = { .dwellTimeDn = RADIOLIB_LORAWAN_DWELL_TIME, .txParamSupported = true, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 9214000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 9216000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - RADIOLIB_LORAWAN_CHANNEL_NONE - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, + { .enabled = true, .idx = 0, .freq = 9214000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 9216000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, RADIOLIB_LORAWAN_CHANNEL_NONE }, .numTxSpans = 0, @@ -597,13 +562,8 @@ const LoRaWANBand_t AS923_3 = { .dwellTimeDn = RADIOLIB_LORAWAN_DWELL_TIME, .txParamSupported = true, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 9166000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 9168000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - RADIOLIB_LORAWAN_CHANNEL_NONE - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, + { .enabled = true, .idx = 0, .freq = 9166000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 9168000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, RADIOLIB_LORAWAN_CHANNEL_NONE }, .numTxSpans = 0, @@ -670,13 +630,8 @@ const LoRaWANBand_t AS923_4 = { .dwellTimeDn = RADIOLIB_LORAWAN_DWELL_TIME, .txParamSupported = true, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 9173000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 9175000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - RADIOLIB_LORAWAN_CHANNEL_NONE - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, + { .enabled = true, .idx = 0, .freq = 9173000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 9175000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, RADIOLIB_LORAWAN_CHANNEL_NONE }, .numTxSpans = 0, @@ -743,14 +698,9 @@ const LoRaWANBand_t KR920 = { .dwellTimeDn = 0, .txParamSupported = false, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 9221000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 9223000, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 2, .freq = 9225000, .drMin = 0, .drMax = 5, .dr = 5, .available = true } - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE + { .enabled = true, .idx = 0, .freq = 9221000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 9223000, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 2, .freq = 9225000, .drMin = 0, .drMax = 5, .dr = 3, .available = true } }, .numTxSpans = 0, .txSpans = { @@ -816,14 +766,9 @@ const LoRaWANBand_t IN865 = { .dwellTimeDn = 0, .txParamSupported = false, .txFreqs = { - { .enabled = true, .idx = 0, .freq = 8650625, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 1, .freq = 8654025, .drMin = 0, .drMax = 5, .dr = 5, .available = true }, - { .enabled = true, .idx = 2, .freq = 8659850, .drMin = 0, .drMax = 5, .dr = 5, .available = true } - }, - .txJoinReq = { - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE, - RADIOLIB_LORAWAN_CHANNEL_NONE + { .enabled = true, .idx = 0, .freq = 8650625, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 1, .freq = 8654025, .drMin = 0, .drMax = 5, .dr = 3, .available = true }, + { .enabled = true, .idx = 2, .freq = 8659850, .drMin = 0, .drMax = 5, .dr = 3, .available = true } }, .numTxSpans = 0, .txSpans = { diff --git a/lib/RadioLib/src/protocols/Pager/Pager.cpp b/lib/RadioLib/src/protocols/Pager/Pager.cpp index 9d56ea4..f286395 100644 --- a/lib/RadioLib/src/protocols/Pager/Pager.cpp +++ b/lib/RadioLib/src/protocols/Pager/Pager.cpp @@ -93,7 +93,7 @@ int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t } // Automatically set function bits based on given encoding - if (function == RADIOLIB_PAGER_FUNC_AUTO) { + if(function == RADIOLIB_PAGER_FUNC_AUTO) { if(encoding == RADIOLIB_PAGER_BCD) { function = RADIOLIB_PAGER_FUNC_BITS_NUMERIC; @@ -101,14 +101,14 @@ int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t function = RADIOLIB_PAGER_FUNC_BITS_ALPHA; } else { - return(RADIOLIB_ERR_INVALID_ENCODING); + return(RADIOLIB_ERR_INVALID_ENCODING); } if(len == 0) { function = RADIOLIB_PAGER_FUNC_BITS_TONE; } } - if (function > RADIOLIB_PAGER_FUNC_BITS_ALPHA) { + if(function > RADIOLIB_PAGER_FUNC_BITS_ALPHA) { return(RADIOLIB_ERR_INVALID_FUNCTION); } @@ -168,7 +168,7 @@ int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t uint8_t blockPos = RADIOLIB_PAGER_PREAMBLE_LENGTH + 1 + framePos + 1 + i; // check if we need to skip a frame sync marker - if(((blockPos - (RADIOLIB_PAGER_PREAMBLE_LENGTH + 1)) % RADIOLIB_PAGER_BATCH_LEN) == 0) { + if(((blockPos - RADIOLIB_PAGER_PREAMBLE_LENGTH) % (RADIOLIB_PAGER_BATCH_LEN + 1)) == 0) { blockPos++; i++; } @@ -323,7 +323,7 @@ int16_t PagerClient::readData(String& str, size_t len, uint32_t* addr) { state = readData(data, &length, addr); if(state == RADIOLIB_ERR_NONE) { - // check tone-only tramsissions + // check tone-only transmissions if(length == 0) { length = 6; strncpy((char*)data, "", length + 1); @@ -497,6 +497,7 @@ bool PagerClient::addressMatched(uint32_t addr) { void PagerClient::write(uint32_t* data, size_t len) { // write code words from buffer for(size_t i = 0; i < len; i++) { + RADIOLIB_DEBUG_PROTOCOL_PRINTLN("POCSAG W\t%lu\t%08lX", (long unsigned int)i, (long unsigned int)data[i]); PagerClient::write(data[i]); } } diff --git a/lib/RadioLib/src/protocols/PhysicalLayer/PhysicalLayer.h b/lib/RadioLib/src/protocols/PhysicalLayer/PhysicalLayer.h index c546799..a8f66ce 100644 --- a/lib/RadioLib/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/lib/RadioLib/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -135,9 +135,9 @@ union ChannelScanConfig_t { \brief Type of modem, used by setModem. */ enum ModemType_t { - FSK = 0, - LoRa, - LRFHSS, + RADIOLIB_MODEM_FSK = 0, + RADIOLIB_MODEM_LORA, + RADIOLIB_MODEM_LRFHSS, }; /*! diff --git a/lib/RadioLib/src/utils/Utils.cpp b/lib/RadioLib/src/utils/Utils.cpp index c2f12a6..4111818 100644 --- a/lib/RadioLib/src/utils/Utils.cpp +++ b/lib/RadioLib/src/utils/Utils.cpp @@ -13,7 +13,7 @@ uint32_t rlb_reflect(uint32_t in, uint8_t bits) { return(res); } -void rlb_hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset, uint8_t width, bool be) { +void rlb_hexdump(const char* level, const uint8_t* data, size_t len, uint32_t offset, uint8_t width, bool be) { #if RADIOLIB_DEBUG size_t rem_len = len; for(size_t i = 0; i < len; i+=16) { diff --git a/lib/RadioLib/src/utils/Utils.h b/lib/RadioLib/src/utils/Utils.h index 638f2b6..b8c4ac6 100644 --- a/lib/RadioLib/src/utils/Utils.h +++ b/lib/RadioLib/src/utils/Utils.h @@ -33,7 +33,7 @@ uint32_t rlb_reflect(uint32_t in, uint8_t bits); \param width Word width (1 for uint8_t, 2 for uint16_t, 4 for uint32_t). \param be Print multi-byte data as big endian. Defaults to false. */ -void rlb_hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset = 0, uint8_t width = 1, bool be = false); +void rlb_hexdump(const char* level, const uint8_t* data, size_t len, uint32_t offset = 0, uint8_t width = 1, bool be = false); #if RADIOLIB_DEBUG && defined(RADIOLIB_BUILD_ARDUINO) size_t rlb_printf(const char* format, ...);