Compare commits
No commits in common. "master" and "7.1.0" have entirely different histories.
160 changed files with 3033 additions and 4212 deletions
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -7,8 +7,8 @@ assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**IMPORTANT: Check the docs**
|
**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/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html).
|
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.
|
||||||
|
|
||||||
**Describe the bug**
|
**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**.
|
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**.
|
||||||
|
|
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -7,8 +7,8 @@ assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**IMPORTANT: Check the docs**
|
**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/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html).
|
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.
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
**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 [...]
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
2
.github/ISSUE_TEMPLATE/module-not-working.md
vendored
2
.github/ISSUE_TEMPLATE/module-not-working.md
vendored
|
@ -9,7 +9,7 @@ assignees: ''
|
||||||
|
|
||||||
**IMPORTANT: Before submitting an issue, please check the following:**
|
**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.
|
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/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html).
|
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.
|
||||||
3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases).
|
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!
|
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).
|
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).
|
||||||
|
|
2
.github/ISSUE_TEMPLATE/regular-issue.md
vendored
2
.github/ISSUE_TEMPLATE/regular-issue.md
vendored
|
@ -9,7 +9,7 @@ assignees: ''
|
||||||
|
|
||||||
**IMPORTANT: Before submitting an issue, please check the following:**
|
**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.
|
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/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html).
|
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.
|
||||||
3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases).
|
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!
|
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).
|
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).
|
||||||
|
|
94
.github/workflows/main.yml
vendored
94
.github/workflows/main.yml
vendored
|
@ -36,7 +36,6 @@ on:
|
||||||
- MegaCore:avr:1281
|
- MegaCore:avr:1281
|
||||||
- teensy:avr:teensy41
|
- teensy:avr:teensy41
|
||||||
- arduino:renesas_uno:minima
|
- arduino:renesas_uno:minima
|
||||||
- SiliconLabs:silabs:xg24explorerkit
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
@ -83,16 +82,14 @@ jobs:
|
||||||
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
||||||
echo "options=':xtal=80,ResetMethod=ck,CrystalFreq=26,FlashFreq=40,FlashMode=qio,eesz=512K'" >> $GITHUB_OUTPUT
|
echo "options=':xtal=80,ResetMethod=ck,CrystalFreq=26,FlashFreq=40,FlashMode=qio,eesz=512K'" >> $GITHUB_OUTPUT
|
||||||
echo "index-url=--additional-urls http://arduino.esp8266.com/stable/package_esp8266com_index.json" >> $GITHUB_OUTPUT
|
echo "index-url=--additional-urls http://arduino.esp8266.com/stable/package_esp8266com_index.json" >> $GITHUB_OUTPUT
|
||||||
- id: STMicroelectronics:stm32:GenF3
|
- id: STMicroelectronics:stm32:GenF3:pnum=BLACKPILL_F303CC
|
||||||
run: |
|
run: |
|
||||||
echo "options=':pnum=BLACKPILL_F303CC'" >> $GITHUB_OUTPUT
|
|
||||||
echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
|
echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
|
||||||
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
||||||
- id: STMicroelectronics:stm32:Nucleo_64
|
- id: STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1
|
||||||
run: |
|
run: |
|
||||||
echo "options=':pnum=NUCLEO_WL55JC1'" >> $GITHUB_OUTPUT
|
|
||||||
# Do *not* skip STM32WL examples
|
# 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
|
echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
|
||||||
- id: stm32duino:STM32F1:mapleMini
|
- id: stm32duino:STM32F1:mapleMini
|
||||||
run: |
|
run: |
|
||||||
|
@ -121,9 +118,6 @@ jobs:
|
||||||
- id: arduino:renesas_uno:minima
|
- id: arduino:renesas_uno:minima
|
||||||
run: |
|
run: |
|
||||||
echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
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
|
runs-on: ubuntu-latest
|
||||||
name: ${{ matrix.id }}
|
name: ${{ matrix.id }}
|
||||||
|
@ -182,64 +176,28 @@ jobs:
|
||||||
if: ${{ env.run-build == 'true' }}
|
if: ${{ env.run-build == 'true' }}
|
||||||
run:
|
run:
|
||||||
|
|
|
|
||||||
cd $PWD/extras/test/ci
|
for example in $(find $PWD/examples -name '*.ino' | sort); do
|
||||||
./build_examples.sh ${{ matrix.id }} "${{ steps.prep.outputs.skip-pattern }}" ${{ steps.prep.outputs.options }}
|
# 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
|
||||||
|
|
||||||
- name: Extract short commit hash
|
# build sketch
|
||||||
id: short-hash
|
echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m";
|
||||||
run: echo "::set-output name=short_sha::$(git rev-parse --short HEAD)"
|
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
|
||||||
- name: Parse sizes
|
echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n";
|
||||||
if: ${{ env.run-build == 'true' }}
|
exit 1;
|
||||||
run:
|
else
|
||||||
|
|
echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n";
|
||||||
cd $PWD/extras/test/ci
|
fi
|
||||||
./parse_size.sh ${{ matrix.id }}
|
fi
|
||||||
cat size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv
|
done
|
||||||
|
|
||||||
- name: Upload size report as artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
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
|
|
||||||
|
|
||||||
metrics:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: build
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
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@v4
|
|
||||||
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:
|
esp-build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -289,11 +247,10 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
cd $PWD/examples/NonArduino/Tock
|
cd $PWD/examples/NonArduino/Tock
|
||||||
git clone https://github.com/tock/libtock-c.git
|
git clone https://github.com/tock/libtock-c.git
|
||||||
cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../
|
cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../
|
||||||
LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
||||||
|
|
||||||
rpi-build:
|
rpi-build:
|
||||||
if: false # self-hosted runner temporarily disabled
|
|
||||||
runs-on: [self-hosted, ARM64]
|
runs-on: [self-hosted, ARM64]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
@ -325,7 +282,6 @@ jobs:
|
||||||
./build.sh
|
./build.sh
|
||||||
|
|
||||||
rpi-test:
|
rpi-test:
|
||||||
if: false # self-hosted runner temporarily disabled
|
|
||||||
needs: rpi-build
|
needs: rpi-build
|
||||||
runs-on: [self-hosted, ARM64]
|
runs-on: [self-hosted, ARM64]
|
||||||
steps:
|
steps:
|
||||||
|
|
37
.github/workflows/release.yml
vendored
37
.github/workflows/release.yml
vendored
|
@ -1,37 +0,0 @@
|
||||||
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
|
|
48
.github/workflows/unit-test.yml
vendored
48
.github/workflows/unit-test.yml
vendored
|
@ -1,48 +0,0 @@
|
||||||
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-22.04
|
|
||||||
|
|
||||||
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 lcov
|
|
||||||
|
|
||||||
- name: Run unit test
|
|
||||||
run: |
|
|
||||||
cd extras/test/unit
|
|
||||||
./test.sh
|
|
||||||
|
|
||||||
- name: Measure test coverage
|
|
||||||
run: |
|
|
||||||
cd extras/test/unit
|
|
||||||
./coverage.sh
|
|
||||||
|
|
||||||
- name: Upload coverage report as artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: coverage_report
|
|
||||||
path: extras/test/unit/lcov.report
|
|
||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
uses: peaceiris/actions-gh-pages@v3
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
publish_branch: gh-pages
|
|
||||||
publish_dir: extras/test/unit/lcov.report
|
|
||||||
destination_dir: coverage
|
|
||||||
keep_files: true
|
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -11,6 +11,13 @@
|
||||||
# Jetbrain IDEs
|
# Jetbrain IDEs
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
|
# Debug decoder
|
||||||
|
extras/decoder/log.txt
|
||||||
|
extras/decoder/out.txt
|
||||||
|
|
||||||
|
# Spectrum scan
|
||||||
|
extras/SX126x_Spectrum_Scan/out/*
|
||||||
|
|
||||||
# PlatformIO
|
# PlatformIO
|
||||||
.pio*
|
.pio*
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ target_include_directories(RadioLib
|
||||||
set_property(TARGET RadioLib PROPERTY CXX_STANDARD 20)
|
set_property(TARGET RadioLib PROPERTY CXX_STANDARD 20)
|
||||||
|
|
||||||
# enable most warnings
|
# enable most warnings
|
||||||
target_compile_options(RadioLib PRIVATE -Wall -Wextra -Wpedantic -Wdouble-promotion)
|
target_compile_options(RadioLib PRIVATE -Wall -Wextra)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
|
14
README.md
14
README.md
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
## Universal wireless communication library for embedded devices
|
## 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.
|
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!
|
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!
|
||||||
|
|
||||||
|
@ -11,13 +13,6 @@ 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!
|
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:
|
### Supported modules:
|
||||||
* __CC1101__ FSK radio module
|
* __CC1101__ FSK radio module
|
||||||
* __LLCC68__ LoRa module
|
* __LLCC68__ LoRa module
|
||||||
|
@ -48,7 +43,7 @@ SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0 and
|
||||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
|
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
|
||||||
* [__POCSAG__](https://www.sigidwiki.com/wiki/POCSAG) using 2-FSK for modules:
|
* [__POCSAG__](https://www.sigidwiki.com/wiki/POCSAG) using 2-FSK for modules:
|
||||||
SX127x, RFM9x, RF69, SX1231, CC1101, nRF24L01, RFM2x and Si443x
|
SX127x, RFM9x, RF69, SX1231, CC1101, nRF24L01, RFM2x and Si443x
|
||||||
* [__LoRaWAN__](https://lora-alliance.org/) using LoRa and FSK for modules:
|
* [__LoRaWAN__](https://lora-alliance.org/) using LoRa for modules:
|
||||||
SX127x, RFM9x, SX126x, LR11x0 and SX128x
|
SX127x, RFM9x, SX126x, LR11x0 and SX128x
|
||||||
|
|
||||||
### Supported Arduino platforms:
|
### Supported Arduino platforms:
|
||||||
|
@ -94,7 +89,4 @@ SX127x, RFM9x, SX126x, LR11x0 and SX128x
|
||||||
* __PJRC__
|
* __PJRC__
|
||||||
* [__Teensy__](https://github.com/PaulStoffregen/cores) - Teensy 2.x, 3.x and 4.x boards
|
* [__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.
|
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.
|
||||||
|
|
|
@ -37,21 +37,6 @@ CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -91,6 +76,21 @@ void setup() {
|
||||||
// radio.readData();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -82,11 +82,10 @@ void setup() {
|
||||||
void loop() {
|
void loop() {
|
||||||
Serial.print(F("[CC1101] Transmitting packet ... "));
|
Serial.print(F("[CC1101] Transmitting packet ... "));
|
||||||
|
|
||||||
// you can transmit C-string or Arduino string up to 255 characters long
|
// you can transmit C-string or Arduino string up to 63 characters long
|
||||||
int state = radio.transmit("Hello World!");
|
int state = radio.transmit("Hello World!");
|
||||||
|
|
||||||
// you can also transmit byte array up to 255 bytes long
|
// you can also transmit byte array up to 63 bytes long
|
||||||
// With some limitations see here: https://github.com/jgromes/RadioLib/discussions/1138
|
|
||||||
/*
|
/*
|
||||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||||
int state = radio.transmit(byteArr, 8);
|
int state = radio.transmit(byteArr, 8);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
RadioLib CC1101 Blocking Transmit Example
|
RadioLib CC1101 Blocking Transmit Example
|
||||||
|
|
||||||
This example transmits packets using CC1101 FSK radio module.
|
This example transmits packets using CC1101 FSK radio module.
|
||||||
Each packet contains up to 255 bytes of data with some limitations (https://github.com/jgromes/RadioLib/discussions/1138), in the form of:
|
Each packet contains up to 64 bytes of data, in the form of:
|
||||||
- Arduino String
|
- Arduino String
|
||||||
- null-terminated char array (C-string)
|
- null-terminated char array (C-string)
|
||||||
- arbitrary binary data (byte array)
|
- arbitrary binary data (byte array)
|
||||||
|
@ -57,11 +57,11 @@ int count = 0;
|
||||||
void loop() {
|
void loop() {
|
||||||
Serial.print(F("[CC1101] Transmitting packet ... "));
|
Serial.print(F("[CC1101] Transmitting packet ... "));
|
||||||
|
|
||||||
// you can transmit C-string or Arduino string up to 255 characters long
|
// you can transmit C-string or Arduino string up to 63 characters long
|
||||||
String str = "Hello World! #" + String(count++);
|
String str = "Hello World! #" + String(count++);
|
||||||
int state = radio.transmit(str);
|
int state = radio.transmit(str);
|
||||||
|
|
||||||
// you can also transmit byte array up to 255 bytes long with some limitations; https://github.com/jgromes/RadioLib/discussions/1138
|
// you can also transmit byte array up to 63 bytes long
|
||||||
/*
|
/*
|
||||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||||
int state = radio.transmit(byteArr, 8);
|
int state = radio.transmit(byteArr, 8);
|
||||||
|
@ -72,7 +72,7 @@ void loop() {
|
||||||
Serial.println(F("success!"));
|
Serial.println(F("success!"));
|
||||||
|
|
||||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||||
// the supplied packet was longer than 255 bytes
|
// the supplied packet was longer than 64 bytes
|
||||||
Serial.println(F("too long!"));
|
Serial.println(F("too long!"));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
This example transmits packets using CC1101 FSK radio module.
|
This example transmits packets using CC1101 FSK radio module.
|
||||||
Once a packet is transmitted, an interrupt is triggered.
|
Once a packet is transmitted, an interrupt is triggered.
|
||||||
Each packet contains up to 255 bytes of data with some limitations (https://github.com/jgromes/RadioLib/discussions/1138), in the form of:
|
Each packet contains up to 64 bytes of data, in the form of:
|
||||||
- Arduino String
|
- Arduino String
|
||||||
- null-terminated char array (C-string)
|
- null-terminated char array (C-string)
|
||||||
- arbitrary binary data (byte array)
|
- arbitrary binary data (byte array)
|
||||||
|
@ -36,21 +36,6 @@ Radio radio = new RadioModule();
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -73,12 +58,10 @@ void setup() {
|
||||||
Serial.print(F("[CC1101] Sending first packet ... "));
|
Serial.print(F("[CC1101] Sending first packet ... "));
|
||||||
|
|
||||||
// you can transmit C-string or Arduino string up to
|
// you can transmit C-string or Arduino string up to
|
||||||
// 255 characters long
|
// 64 characters long
|
||||||
transmissionState = radio.startTransmit("Hello World!");
|
transmissionState = radio.startTransmit("Hello World!");
|
||||||
|
|
||||||
// you can also transmit byte array up to 255 bytes long
|
// you can also transmit byte array up to 64 bytes long
|
||||||
// When transmitting more than 64 bytes startTransmit blocks to refill the FIFO.
|
|
||||||
// Blocking ceases once the last bytes have been placed in the FIFO
|
|
||||||
/*
|
/*
|
||||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
||||||
0x78, 0xAB, 0xCD, 0xEF};
|
0x78, 0xAB, 0xCD, 0xEF};
|
||||||
|
@ -86,6 +69,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
@ -121,11 +119,11 @@ void loop() {
|
||||||
Serial.print(F("[CC1101] Sending another packet ... "));
|
Serial.print(F("[CC1101] Sending another packet ... "));
|
||||||
|
|
||||||
// you can transmit C-string or Arduino string up to
|
// you can transmit C-string or Arduino string up to
|
||||||
// 255 characters long
|
// 256 characters long
|
||||||
String str = "Hello World! #" + String(count++);
|
String str = "Hello World! #" + String(count++);
|
||||||
transmissionState = radio.startTransmit(str);
|
transmissionState = radio.startTransmit(str);
|
||||||
|
|
||||||
// you can also transmit byte array up to 255 bytes long with limitations https://github.com/jgromes/RadioLib/discussions/1138
|
// you can also transmit byte array up to 256 bytes long
|
||||||
/*
|
/*
|
||||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||||
0x89, 0xAB, 0xCD, 0xEF};
|
0x89, 0xAB, 0xCD, 0xEF};
|
||||||
|
|
|
@ -57,21 +57,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||||
END_OF_MODE_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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -104,6 +89,21 @@ 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(scanFlag) {
|
if(scanFlag) {
|
||||||
|
|
|
@ -62,8 +62,7 @@ void setup() {
|
||||||
3, // header count
|
3, // header count
|
||||||
0x13A); // hopping sequence seed
|
0x13A); // hopping sequence seed
|
||||||
state = radio.setOutputPower(10.0);
|
state = radio.setOutputPower(10.0);
|
||||||
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67};
|
state = radio.setSyncWord(0x12345678);
|
||||||
state = radio.setSyncWord(syncWord, 4);
|
|
||||||
if (state != RADIOLIB_ERR_NONE) {
|
if (state != RADIOLIB_ERR_NONE) {
|
||||||
Serial.print(F("Unable to set configuration, code "));
|
Serial.print(F("Unable to set configuration, code "));
|
||||||
Serial.println(state);
|
Serial.println(state);
|
||||||
|
|
|
@ -63,21 +63,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||||
END_OF_MODE_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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -120,6 +105,21 @@ void setup() {
|
||||||
// radio.scanChannel();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -62,21 +62,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -113,6 +98,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -60,20 +60,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||||
END_OF_MODE_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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -106,6 +92,20 @@ 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(scanFlag) {
|
if(scanFlag) {
|
||||||
|
|
|
@ -41,11 +41,9 @@ const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
||||||
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
||||||
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
||||||
|
|
||||||
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN470
|
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
|
||||||
const LoRaWANBand_t Region = EU868;
|
const LoRaWANBand_t Region = EU868;
|
||||||
|
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
||||||
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
|
|
||||||
const uint8_t subBand = 0;
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Below is to support the sketch - only make changes if the notes say so ...
|
// Below is to support the sketch - only make changes if the notes say so ...
|
||||||
|
|
|
@ -48,9 +48,6 @@ void setup() {
|
||||||
// Override the default join rate
|
// Override the default join rate
|
||||||
uint8_t joinDR = 4;
|
uint8_t joinDR = 4;
|
||||||
|
|
||||||
// Optionally provide a custom sleep function - see config.h
|
|
||||||
//node.setSleepFunction(customDelay);
|
|
||||||
|
|
||||||
// Setup the OTAA session information
|
// Setup the OTAA session information
|
||||||
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||||
|
|
||||||
|
@ -71,7 +68,7 @@ void setup() {
|
||||||
// Manages uplink intervals to the TTN Fair Use Policy
|
// Manages uplink intervals to the TTN Fair Use Policy
|
||||||
node.setDutyCycle(true, 1250);
|
node.setDutyCycle(true, 1250);
|
||||||
|
|
||||||
// Update dwell time limits - 400ms is the limit for the US
|
// Enable the dwell time limits - 400ms is the limit for the US
|
||||||
node.setDwellTime(true, 400);
|
node.setDwellTime(true, 400);
|
||||||
|
|
||||||
Serial.println(F("Ready!\n"));
|
Serial.println(F("Ready!\n"));
|
||||||
|
|
|
@ -37,11 +37,9 @@ const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
||||||
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
||||||
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
||||||
|
|
||||||
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN470
|
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
|
||||||
const LoRaWANBand_t Region = EU868;
|
const LoRaWANBand_t Region = EU868;
|
||||||
|
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
||||||
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
|
|
||||||
const uint8_t subBand = 0;
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Below is to support the sketch - only make changes if the notes say so ...
|
// Below is to support the sketch - only make changes if the notes say so ...
|
||||||
|
@ -144,19 +142,4 @@ void arrayDump(uint8_t *buffer, uint16_t len) {
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom delay function:
|
|
||||||
// Communication over LoRaWAN includes a lot of delays.
|
|
||||||
// By default, RadioLib will use the Arduino delay() function,
|
|
||||||
// which will waste a lot of power. However, you can put your
|
|
||||||
// microcontroller to sleep instead by customizing the function below,
|
|
||||||
// and providing it to RadioLib via "node.setSleepFunction".
|
|
||||||
// NOTE: You ahve to ensure that this function is timed precisely, and
|
|
||||||
// does actually wait for the amount of time specified!
|
|
||||||
// Failure to do so will result in missed downlinks or failed join!
|
|
||||||
void customDelay(RadioLibTime_t ms) {
|
|
||||||
// this is just an example, so we use the Arduino delay() function,
|
|
||||||
// but you can put your microcontroller to sleep here
|
|
||||||
::delay(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,11 +37,9 @@ const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
||||||
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
||||||
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
||||||
|
|
||||||
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN470
|
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
|
||||||
const LoRaWANBand_t Region = EU868;
|
const LoRaWANBand_t Region = EU868;
|
||||||
|
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
||||||
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
|
|
||||||
const uint8_t subBand = 0;
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Below is to support the sketch - only make changes if the notes say so ...
|
// Below is to support the sketch - only make changes if the notes say so ...
|
||||||
|
|
|
@ -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 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 B.
|
Choose LoRaWAN 1.1.0 - the last one in the list - the latest specfication. RadioLib uses RP001 Regional Parameters 1.1 revision A.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
|
|
@ -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_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
|
## LoRaWAN versions & regional parameters
|
||||||
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**.
|
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 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**.
|
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 CN470 band is implemented as specified in RP001 1.1 revision B, as the RP002 1.0.4 version is much too complex._
|
_Note: the CN500 band is implemented as specified in RP v1.1, as the RP v1.0.4 version is much too complex._
|
||||||
|
|
||||||
To activate a LoRaWAN 1.1 session, supply all the required keys:
|
To activate a LoRaWAN v1.1 session, supply all the required keys:
|
||||||
```cpp
|
```cpp
|
||||||
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||||
node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey);
|
node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey);
|
||||||
```
|
```
|
||||||
|
|
||||||
To activate a LoRaWAN 1.0.4 session, set the keys that are not available to `NULL`:
|
To activate a LoRaWAN v1.0.4 session, set the keys that are not available to `NULL`:
|
||||||
```cpp
|
```cpp
|
||||||
node.beginOTAA(joinEUI, devEUI, NULL, appKey);
|
node.beginOTAA(joinEUI, devEUI, NULL, appKey);
|
||||||
node.beginABP(devAddr, NULL, NULL, nwkSEncKey, appSKey);
|
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
|
## LoRaWAN persistence
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> 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:
|
> 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:
|
||||||
|
|
||||||
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!**
|
In [this repository](https://github.com/radiolib-org/radiolib-persistence), examples are provided that do comply with the required persistence of certain parameters for LoRaWAN v1.1. Examples are (or will become) available for some of the most popular platforms. **These examples assume you have successfully used the Starter sketch and understood (most of) the accompanying notes!**
|
||||||
Currently, examples are available for the following platforms:
|
Currently, examples are available for the following platforms:
|
||||||
|
|
||||||
* [LoRaWAN for ESP32](https://github.com/radiolib-org/radiolib-persistence/tree/main/examples/LoRaWAN_ESP32)
|
* [LoRaWAN for ESP32](https://github.com/radiolib-org/radiolib-persistence/tree/main/examples/LoRaWAN_ESP32)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <RadioLib.h>
|
#include <RadioLib.h>
|
||||||
|
|
||||||
// include the hardware abstraction layer
|
// include the hardware abstraction layer
|
||||||
#include "EspHal.h"
|
#include "hal/ESP-IDF/EspHal.h"
|
||||||
|
|
||||||
// create a new instance of the HAL class
|
// create a new instance of the HAL class
|
||||||
EspHal* hal = new EspHal(5, 19, 27);
|
EspHal* hal = new EspHal(5, 19, 27);
|
||||||
|
|
|
@ -50,21 +50,7 @@ add_executable(${PROJECT_NAME} main.cpp)
|
||||||
# The build system for libtock-c is a bit odd and the version of libraries
|
# The build system for libtock-c is a bit odd and the version of libraries
|
||||||
# built changes based on compiler version.
|
# built changes based on compiler version.
|
||||||
if (RISCV_BUILD)
|
if (RISCV_BUILD)
|
||||||
if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0")
|
if(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
|
|
||||||
$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
|
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||||
RadioLib
|
RadioLib
|
||||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
||||||
|
@ -94,17 +80,7 @@ if (RISCV_BUILD)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
if (EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0")
|
if(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
|
|
||||||
$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
|
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||||
RadioLib
|
RadioLib
|
||||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
||||||
|
|
|
@ -23,7 +23,7 @@ The RadioLib example can be built with:
|
||||||
$ git clone https://github.com/jgromes/RadioLib.git
|
$ git clone https://github.com/jgromes/RadioLib.git
|
||||||
$ cd RadioLib/examples/NonArduino/Tock/
|
$ cd RadioLib/examples/NonArduino/Tock/
|
||||||
$ git clone https://github.com/tock/libtock-c.git
|
$ git clone https://github.com/tock/libtock-c.git
|
||||||
$ cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../
|
$ cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../
|
||||||
$ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
$ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ set -e
|
||||||
|
|
||||||
rm -rf ./build-*
|
rm -rf ./build-*
|
||||||
|
|
||||||
pushd ${LIBTOCK_C_DIRECTORY}/examples/cxx_hello
|
cd libtock-c/examples/cxx_hello
|
||||||
make -j4
|
make -j4
|
||||||
popd
|
cd ../../../
|
||||||
|
|
||||||
mkdir -p build-arm
|
mkdir -p build-arm
|
||||||
cd build-arm
|
cd build-arm
|
||||||
|
|
|
@ -28,14 +28,14 @@
|
||||||
#include <RadioLib.h>
|
#include <RadioLib.h>
|
||||||
|
|
||||||
// include the hardware abstraction layer
|
// include the hardware abstraction layer
|
||||||
#include "RadioLib/libtockHal.h"
|
#include "hal/Tock/libtockHal.h"
|
||||||
|
|
||||||
// the entry point for the program
|
// the entry point for the program
|
||||||
int main(void) {
|
int main(void) {
|
||||||
printf("[SX1261] Initialising Radio ... \r\n");
|
printf("[SX1261] Initialising Radio ... \r\n");
|
||||||
|
|
||||||
// create a new instance of the HAL class
|
// create a new instance of the HAL class
|
||||||
TockRadioLibHal* hal = new TockRadioLibHal();
|
TockHal* hal = new TockHal();
|
||||||
|
|
||||||
// now we can create the radio module
|
// now we can create the radio module
|
||||||
// pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE
|
// pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE
|
||||||
|
@ -43,7 +43,7 @@ int main(void) {
|
||||||
// DIO1 pin: 2
|
// DIO1 pin: 2
|
||||||
// NRST pin: 4
|
// NRST pin: 4
|
||||||
// BUSY pin: 1
|
// BUSY pin: 1
|
||||||
Module* tock_module = new Module(hal, RADIOLIB_RADIO_NSS, RADIOLIB_RADIO_DIO_1, RADIOLIB_RADIO_RESET, RADIOLIB_RADIO_BUSY);
|
Module* tock_module = new Module(hal, RADIO_NSS, RADIO_DIO_1, RADIO_RESET, RADIO_BUSY);
|
||||||
SX1262* radio = new SX1262(tock_module);
|
SX1262* radio = new SX1262(tock_module);
|
||||||
|
|
||||||
// Setup the radio
|
// Setup the radio
|
||||||
|
|
|
@ -29,21 +29,6 @@ RF69 radio = new Module(10, 2, 3);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -83,6 +68,21 @@ void setup() {
|
||||||
// radio.readData();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -35,21 +35,6 @@ Radio radio = new RadioModule();
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -100,6 +85,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -33,18 +33,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||||
END_OF_MODE_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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -78,6 +66,18 @@ 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(scanFlag) {
|
if(scanFlag) {
|
||||||
|
|
|
@ -43,18 +43,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||||
END_OF_MODE_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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -109,6 +97,18 @@ void setup() {
|
||||||
// radio.scanChannel();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -38,18 +38,6 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -97,6 +85,18 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -33,21 +33,6 @@ SX1262 radio = new Module(10, 2, 3, 9);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -77,6 +62,21 @@ 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(scanFlag) {
|
if(scanFlag) {
|
||||||
|
|
|
@ -35,24 +35,6 @@ SX1262 radio = new Module(10, 2, 3, 9);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -82,6 +64,23 @@ 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(scanFlag) {
|
if(scanFlag) {
|
||||||
|
|
|
@ -126,4 +126,33 @@ void loop() {
|
||||||
Serial.println(F("[SX1262] Failed to receive packet, code "));
|
Serial.println(F("[SX1262] Failed to receive packet, code "));
|
||||||
Serial.println(state);
|
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 "));
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
RadioLib SX126x LR-FHSS Modem Example
|
||||||
|
|
||||||
|
This example shows how to use LR-FHSS modem in SX126x chips.
|
||||||
|
This modem can only transmit data, and is not able to receive.
|
||||||
|
|
||||||
|
NOTE: The sketch below is just a guide on how to use
|
||||||
|
LR-FHSS modem, so this code should not be run directly!
|
||||||
|
Instead, modify the other examples to use LR-FHSS
|
||||||
|
modem and use the appropriate configuration
|
||||||
|
methods.
|
||||||
|
|
||||||
|
For default module settings, see the wiki page
|
||||||
|
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lr-fhss-modem
|
||||||
|
|
||||||
|
For full API reference, see the GitHub Pages
|
||||||
|
https://jgromes.github.io/RadioLib/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// include the library
|
||||||
|
#include <RadioLib.h>
|
||||||
|
|
||||||
|
// SX1262 has the following connections:
|
||||||
|
// NSS pin: 10
|
||||||
|
// IRQ pin: 2
|
||||||
|
// NRST pin: 3
|
||||||
|
// BUSY pin: 9
|
||||||
|
SX1262 radio = new Module(10, 2, 3, 9);
|
||||||
|
|
||||||
|
// or detect the pinout automatically using RadioBoards
|
||||||
|
// https://github.com/radiolib-org/RadioBoards
|
||||||
|
/*
|
||||||
|
#define RADIO_BOARD_AUTO
|
||||||
|
#include <RadioBoards.h>
|
||||||
|
Radio radio = new RadioModule();
|
||||||
|
*/
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
// initialize SX1262 with default settings
|
||||||
|
Serial.print(F("[SX1262] Initializing ... "));
|
||||||
|
int state = radio.beginLRFHSS();
|
||||||
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
|
Serial.println(F("success!"));
|
||||||
|
} else {
|
||||||
|
Serial.print(F("failed, code "));
|
||||||
|
Serial.println(state);
|
||||||
|
while (true) { delay(10); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// if needed, you can switch between any of the modems
|
||||||
|
//
|
||||||
|
// radio.begin() start LoRa modem (and disable LR-FHSS)
|
||||||
|
// radio.beginLRFHSS() start LR-FHSS modem (and disable LoRa)
|
||||||
|
|
||||||
|
// the following settings can also
|
||||||
|
// be modified at run-time
|
||||||
|
state = radio.setFrequency(433.5);
|
||||||
|
state = radio.setLrFhssConfig(RADIOLIB_SX126X_LR_FHSS_BW_1523_4, // bandwidth
|
||||||
|
RADIOLIB_SX126X_LR_FHSS_CR_1_2, // coding rate
|
||||||
|
3, // header count
|
||||||
|
0x13A); // hopping sequence seed
|
||||||
|
state = radio.setOutputPower(10.0);
|
||||||
|
state = radio.setSyncWord(0x12345678);
|
||||||
|
if (state != RADIOLIB_ERR_NONE) {
|
||||||
|
Serial.print(F("Unable to set configuration, code "));
|
||||||
|
Serial.println(state);
|
||||||
|
while (true) { delay(10); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#warning "This sketch is just an API guide! Read the note at line 6."
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// LR-FHSS modem can only transmit!
|
||||||
|
// transmit LR-FHSS packet
|
||||||
|
int state = radio.transmit("Hello World!");
|
||||||
|
/*
|
||||||
|
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||||
|
0x89, 0xAB, 0xCD, 0xEF};
|
||||||
|
int state = radio.transmit(byteArr, 8);
|
||||||
|
*/
|
||||||
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
|
Serial.println(F("[SX1262] Packet transmitted successfully!"));
|
||||||
|
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||||
|
Serial.println(F("[SX1262] Packet too long!"));
|
||||||
|
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||||
|
Serial.println(F("[SX1262] Timed out while transmitting!"));
|
||||||
|
} else {
|
||||||
|
Serial.println(F("[SX1262] Failed to transmit packet, code "));
|
||||||
|
Serial.println(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
RadioLib SX126x LR-FHSS Modem Example
|
|
||||||
|
|
||||||
This example shows how to use LR-FHSS modem in SX126x chips.
|
|
||||||
This modem can only transmit data, and is not able to receive.
|
|
||||||
|
|
||||||
This example transmits packets using SX1262 LoRa radio module.
|
|
||||||
Each packet contains up to 256 bytes of data, in the form of:
|
|
||||||
- Arduino String
|
|
||||||
- null-terminated char array (C-string)
|
|
||||||
- arbitrary binary data (byte array)
|
|
||||||
|
|
||||||
Other modules from SX126x family can also be used.
|
|
||||||
|
|
||||||
Using blocking transmit is not recommended, as it will lead
|
|
||||||
to inefficient use of processor time!
|
|
||||||
Instead, interrupt transmit is recommended.
|
|
||||||
|
|
||||||
For default module settings, see the wiki page
|
|
||||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lr-fhss-modem
|
|
||||||
|
|
||||||
For full API reference, see the GitHub Pages
|
|
||||||
https://jgromes.github.io/RadioLib/
|
|
||||||
*/
|
|
||||||
|
|
||||||
// include the library
|
|
||||||
#include <RadioLib.h>
|
|
||||||
|
|
||||||
// SX1262 has the following connections:
|
|
||||||
// NSS pin: 10
|
|
||||||
// IRQ pin: 2
|
|
||||||
// NRST pin: 3
|
|
||||||
// BUSY pin: 9
|
|
||||||
SX1262 radio = new Module(10, 2, 3, 9);
|
|
||||||
|
|
||||||
// or detect the pinout automatically using RadioBoards
|
|
||||||
// https://github.com/radiolib-org/RadioBoards
|
|
||||||
/*
|
|
||||||
#define RADIO_BOARD_AUTO
|
|
||||||
#include <RadioBoards.h>
|
|
||||||
Radio radio = new RadioModule();
|
|
||||||
*/
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// initialize SX1262 with default settings
|
|
||||||
Serial.print(F("[SX1262] Initializing ... "));
|
|
||||||
int state = radio.beginLRFHSS();
|
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
|
||||||
Serial.println(F("success!"));
|
|
||||||
} else {
|
|
||||||
Serial.print(F("failed, code "));
|
|
||||||
Serial.println(state);
|
|
||||||
while (true) { delay(10); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// some modules have an external RF switch
|
|
||||||
// controlled via two pins (RX enable, TX enable)
|
|
||||||
// to enable automatic control of the switch,
|
|
||||||
// call the following method
|
|
||||||
// RX enable: 4
|
|
||||||
// TX enable: 5
|
|
||||||
/*
|
|
||||||
radio.setRfSwitchPins(4, 5);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// counter to keep track of transmitted packets
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
// LR-FHSS modem can only transmit!
|
|
||||||
Serial.print(F("[SX1262] Transmitting packet ... "));
|
|
||||||
|
|
||||||
// you can transmit C-string or Arduino string up to
|
|
||||||
// 256 characters long
|
|
||||||
String str = "Hello World! #" + String(count++);
|
|
||||||
int state = radio.transmit(str);
|
|
||||||
|
|
||||||
// you can also transmit byte array up to 256 bytes long
|
|
||||||
/*
|
|
||||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};
|
|
||||||
int state = radio.transmit(byteArr, 8);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
|
||||||
// the packet was successfully transmitted
|
|
||||||
Serial.println(F("success!"));
|
|
||||||
|
|
||||||
// print measured data rate
|
|
||||||
Serial.print(F("[SX1262] Datarate:\t"));
|
|
||||||
Serial.print(radio.getDataRate());
|
|
||||||
Serial.println(F(" bps"));
|
|
||||||
|
|
||||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
|
||||||
// the supplied packet was longer than 256 bytes
|
|
||||||
Serial.println(F("too long!"));
|
|
||||||
|
|
||||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
|
||||||
// timeout occurred while transmitting packet
|
|
||||||
Serial.println(F("timeout!"));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// some other error occurred
|
|
||||||
Serial.print(F("failed, code "));
|
|
||||||
Serial.println(state);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for a second before transmitting again
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
|
@ -1,151 +0,0 @@
|
||||||
/*
|
|
||||||
RadioLib SX126x LR-FHSS Transmit with Interrupts Example
|
|
||||||
|
|
||||||
This example shows how to use LR-FHSS modem in SX126x chips.
|
|
||||||
This modem can only transmit data, and is not able to receive.
|
|
||||||
|
|
||||||
This example transmits packets using SX1262 LoRa radio module.
|
|
||||||
Each packet contains up to 256 bytes of data, in the form of:
|
|
||||||
- Arduino String
|
|
||||||
- null-terminated char array (C-string)
|
|
||||||
- arbitrary binary data (byte array)
|
|
||||||
|
|
||||||
Other modules from SX126x family can also be used.
|
|
||||||
|
|
||||||
For default module settings, see the wiki page
|
|
||||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lr-fhss-modem
|
|
||||||
|
|
||||||
For full API reference, see the GitHub Pages
|
|
||||||
https://jgromes.github.io/RadioLib/
|
|
||||||
*/
|
|
||||||
|
|
||||||
// include the library
|
|
||||||
#include <RadioLib.h>
|
|
||||||
|
|
||||||
// SX1262 has the following connections:
|
|
||||||
// NSS pin: 10
|
|
||||||
// IRQ pin: 2
|
|
||||||
// NRST pin: 3
|
|
||||||
// BUSY pin: 9
|
|
||||||
SX1262 radio = new Module(10, 2, 3, 9);
|
|
||||||
|
|
||||||
// or detect the pinout automatically using RadioBoards
|
|
||||||
// https://github.com/radiolib-org/RadioBoards
|
|
||||||
/*
|
|
||||||
#define RADIO_BOARD_AUTO
|
|
||||||
#include <RadioBoards.h>
|
|
||||||
Radio radio = new RadioModule();
|
|
||||||
*/
|
|
||||||
|
|
||||||
// save transmission state between loops
|
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
|
||||||
|
|
||||||
// flag to indicate that a packet was sent
|
|
||||||
// or a frequency hop is needed
|
|
||||||
volatile bool flag = 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 or need to hop, set the flag
|
|
||||||
flag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
// initialize SX1262 with default settings
|
|
||||||
Serial.print(F("[SX1262] Initializing ... "));
|
|
||||||
int state = radio.beginLRFHSS();
|
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
|
||||||
Serial.println(F("success!"));
|
|
||||||
} else {
|
|
||||||
Serial.print(F("failed, code "));
|
|
||||||
Serial.println(state);
|
|
||||||
while (true) { delay(10); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the function that will be called
|
|
||||||
// when packet transmission is finished
|
|
||||||
radio.setPacketSentAction(setFlag);
|
|
||||||
|
|
||||||
// start transmitting the first packet
|
|
||||||
Serial.print(F("[SX1262] Sending first packet ... "));
|
|
||||||
|
|
||||||
// you can transmit C-string or Arduino string up to
|
|
||||||
// 256 characters long
|
|
||||||
transmissionState = radio.startTransmit("Hello World!");
|
|
||||||
|
|
||||||
// you can also transmit byte array up to 256 bytes long
|
|
||||||
/*
|
|
||||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
|
||||||
0x89, 0xAB, 0xCD, 0xEF};
|
|
||||||
state = radio.startTransmit(byteArr, 8);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// counter to keep track of transmitted packets
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
// LR-FHSS modem can only transmit!
|
|
||||||
|
|
||||||
// check if the previous transmission finished
|
|
||||||
if(flag) {
|
|
||||||
// reset flag
|
|
||||||
flag = false;
|
|
||||||
|
|
||||||
// check if this was caused by hopping or transmission finished
|
|
||||||
if(radio.getIrqFlags() & RADIOLIB_SX126X_IRQ_LR_FHSS_HOP) {
|
|
||||||
radio.hopLRFHSS();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (transmissionState == RADIOLIB_ERR_NONE) {
|
|
||||||
// packet was successfully sent
|
|
||||||
Serial.println(F("transmission finished!"));
|
|
||||||
|
|
||||||
// NOTE: when using interrupt-driven transmit method,
|
|
||||||
// it is not possible to automatically measure
|
|
||||||
// transmission data rate using getDataRate()
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Serial.print(F("failed, code "));
|
|
||||||
Serial.println(transmissionState);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up after transmission is finished
|
|
||||||
// this will ensure transmitter is disabled,
|
|
||||||
// RF switch is powered down etc.
|
|
||||||
radio.finishTransmit();
|
|
||||||
|
|
||||||
// wait a second before transmitting again
|
|
||||||
delay(1000);
|
|
||||||
|
|
||||||
// send another one
|
|
||||||
Serial.print(F("[SX1262] Sending another packet ... "));
|
|
||||||
|
|
||||||
// you can transmit C-string or Arduino string up to
|
|
||||||
// 256 characters long
|
|
||||||
String str = "Hello World! #" + String(count++);
|
|
||||||
transmissionState = radio.startTransmit(str);
|
|
||||||
|
|
||||||
// you can also transmit byte array up to 256 bytes long
|
|
||||||
/*
|
|
||||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
|
||||||
0x89, 0xAB, 0xCD, 0xEF};
|
|
||||||
transmissionState = radio.startTransmit(byteArr, 8);
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -39,21 +39,6 @@ SX1262 radio = new Module(10, 2, 3, 9);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -93,6 +78,21 @@ void setup() {
|
||||||
// radio.scanChannel();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -38,21 +38,6 @@ Radio radio = new RadioModule();
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -86,6 +71,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -34,36 +34,6 @@ SX1278 radio = new Module(10, 2, 9, 3);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
// Serial port speed must be high enough for this example
|
// Serial port speed must be high enough for this example
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
@ -98,6 +68,36 @@ 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() {
|
void loop() {
|
||||||
// check if we need to restart channel activity detection
|
// check if we need to restart channel activity detection
|
||||||
if(detectedFlag || timeoutFlag) {
|
if(detectedFlag || timeoutFlag) {
|
||||||
|
|
|
@ -39,39 +39,6 @@ SX1278 radio = new Module(10, 2, 9, 3);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
// Serial port speed must be high enough for this example
|
// Serial port speed must be high enough for this example
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
@ -107,6 +74,39 @@ 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() {
|
void loop() {
|
||||||
// check if we need to restart channel activity detection
|
// check if we need to restart channel activity detection
|
||||||
if(detectedFlag || timeoutFlag) {
|
if(detectedFlag || timeoutFlag) {
|
||||||
|
|
|
@ -32,12 +32,6 @@ const int pin = 5;
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -65,6 +59,12 @@ void setup() {
|
||||||
radio.receiveDirect();
|
radio.receiveDirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this function is called when a new bit is received
|
||||||
|
void readBit(void) {
|
||||||
|
// read the data bit
|
||||||
|
radio.readBit(pin);
|
||||||
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
// we expect the packet to contain the string "Hello World!",
|
// we expect the packet to contain the string "Hello World!",
|
||||||
// a length byte and 2 CRC bytes, that's 15 bytes in total
|
// a length byte and 2 CRC bytes, that's 15 bytes in total
|
||||||
|
|
|
@ -39,21 +39,6 @@ SX1278 radio = new Module(10, 2, 9, 3);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -93,6 +78,21 @@ void setup() {
|
||||||
// radio.scanChannel();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -38,21 +38,6 @@ Radio radio = new RadioModule();
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -86,6 +71,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -31,21 +31,6 @@ SX1280 radio = new Module(10, 2, 3, 9);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -75,6 +60,21 @@ 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(scanFlag) {
|
if(scanFlag) {
|
||||||
|
|
|
@ -39,21 +39,6 @@ SX1280 radio = new Module(10, 2, 3, 9);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -94,6 +79,21 @@ void setup() {
|
||||||
// radio.scanChannel();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -38,21 +38,6 @@ Radio radio = new RadioModule();
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -86,6 +71,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -31,21 +31,6 @@ Si4432 radio = new Module(10, 2, 9);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -85,6 +70,21 @@ void setup() {
|
||||||
// radio.readData();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -36,21 +36,6 @@ Radio radio = new RadioModule();
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -84,6 +69,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -34,21 +34,6 @@ nRF24 radio = new Module(10, 2, 3);
|
||||||
Radio radio = new RadioModule();
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -103,6 +88,21 @@ void setup() {
|
||||||
// radio.readData();
|
// 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() {
|
void loop() {
|
||||||
// check if the flag is set
|
// check if the flag is set
|
||||||
if(receivedFlag) {
|
if(receivedFlag) {
|
||||||
|
|
|
@ -36,21 +36,6 @@ Radio radio = new RadioModule();
|
||||||
// save transmission state between loops
|
// save transmission state between loops
|
||||||
int transmissionState = RADIOLIB_ERR_NONE;
|
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() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
@ -99,6 +84,21 @@ 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
|
// counter to keep track of transmitted packets
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
2
extras/SX126x_Spectrum_Scan/out/.gitignore
vendored
2
extras/SX126x_Spectrum_Scan/out/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
# all output pictures
|
|
||||||
*.png
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [[ $# -lt 1 ]]; then
|
|
||||||
echo "Usage: $0 <path to check>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
path=$1
|
|
||||||
|
|
||||||
cppcheck --version
|
|
||||||
cppcheck $path --enable=all \
|
|
||||||
--force \
|
|
||||||
--inline-suppr \
|
|
||||||
--suppress=ConfigurationNotChecked \
|
|
||||||
--suppress=unusedFunction \
|
|
||||||
--suppress=missingIncludeSystem \
|
|
||||||
--suppress=missingInclude \
|
|
||||||
--quiet
|
|
|
@ -2,14 +2,7 @@
|
||||||
|
|
||||||
file=cppcheck.txt
|
file=cppcheck.txt
|
||||||
cppcheck --version
|
cppcheck --version
|
||||||
cppcheck src --enable=all \
|
cppcheck src --enable=all --force --inline-suppr --suppress=ConfigurationNotChecked --suppress=unusedFunction --quiet >> $file 2>&1
|
||||||
--force \
|
|
||||||
--inline-suppr \
|
|
||||||
--suppress=ConfigurationNotChecked \
|
|
||||||
--suppress=unusedFunction \
|
|
||||||
--suppress=missingIncludeSystem \
|
|
||||||
--suppress=missingInclude \
|
|
||||||
--quiet >> $file 2>&1
|
|
||||||
echo "Cppcheck finished with exit code $?"
|
echo "Cppcheck finished with exit code $?"
|
||||||
|
|
||||||
error=$(grep ": error:" $file | wc -l)
|
error=$(grep ": error:" $file | wc -l)
|
||||||
|
|
111
extras/decoder/DebugDecoder.py
Normal file
111
extras/decoder/DebugDecoder.py
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
import re, sys, argparse
|
||||||
|
from pathlib import Path
|
||||||
|
from argparse import RawTextHelpFormatter
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
TODO list:
|
||||||
|
1. Parse macro values (the names of bits in all registers in header file)
|
||||||
|
2. Failed SPI write handling
|
||||||
|
3. SX126x/SX128x handling
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def get_macro_name(value, macros):
|
||||||
|
for macro in macros:
|
||||||
|
if macro[1] == value:
|
||||||
|
return macro[0]
|
||||||
|
return 'UNKNOWN_VALUE'
|
||||||
|
|
||||||
|
|
||||||
|
def get_macro_value(value):
|
||||||
|
return ' 0x{0:02X}\n'.format(int(value, 16))
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
|
||||||
|
RadioLib debug output decoder script. Turns RadioLib Serial dumps into readable text.
|
||||||
|
|
||||||
|
Step-by-step guid on how to use the decoder:
|
||||||
|
1. Uncomment lines 312 (#define RADIOLIB_DEBUG) and 313 (#define RADIOLIB_VERBOSE) in RadioLib/src/BuildOpt.h
|
||||||
|
2. Recompile and upload the failing Arduino sketch
|
||||||
|
3. Open Arduino IDE Serial Monitor and enable timestamps
|
||||||
|
4. Copy the Serial output and save it into a .txt file
|
||||||
|
5. Run this script
|
||||||
|
|
||||||
|
Output will be saved in the file specified by --out and printed to the terminal
|
||||||
|
''')
|
||||||
|
parser.add_argument('file', metavar='file', type=str, help='Text file of the debug output')
|
||||||
|
parser.add_argument('--out', metavar='out', default='./out.txt', type=str, help='Where to save the decoded file (defaults to ./out.txt)')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# open the log file
|
||||||
|
log = open(args.file, 'r').readlines()
|
||||||
|
|
||||||
|
# find modules that are in use
|
||||||
|
used_modules = []
|
||||||
|
pattern_module = re.compile('(([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?.[0-9]{3} -> )?M\t')
|
||||||
|
for entry in log:
|
||||||
|
m = pattern_module.search(entry)
|
||||||
|
if m != None:
|
||||||
|
used_modules.append(entry[m.end():].rstrip())
|
||||||
|
|
||||||
|
# get paths to all relevant header files
|
||||||
|
header_files = []
|
||||||
|
for path in Path('../../src').rglob('*.h'):
|
||||||
|
for module in used_modules:
|
||||||
|
if module in path.name:
|
||||||
|
header_files.append(path)
|
||||||
|
|
||||||
|
# extract names of address macros from the header files
|
||||||
|
macro_addresses = []
|
||||||
|
pattern_define = re.compile('#define \w* +\w*(\n| +\/\/){1}')
|
||||||
|
for path in header_files:
|
||||||
|
file = open(path, 'r').readlines()
|
||||||
|
for line in file:
|
||||||
|
m = pattern_define.search(line)
|
||||||
|
if m != None:
|
||||||
|
s = re.split(' +', m.group().rstrip())
|
||||||
|
if (s.__len__() > 1) and ('_REG' in s[1]):
|
||||||
|
macro_addresses.append([s[1], int(s[2], 0)])
|
||||||
|
|
||||||
|
'''
|
||||||
|
# extract names of value macros for each adddress macro
|
||||||
|
macro_values = []
|
||||||
|
for path in header_files:
|
||||||
|
file = open(path, 'r').readlines()
|
||||||
|
for line in file:
|
||||||
|
for module in used_modules:
|
||||||
|
pattern_addr_macro = re.compile('\/\/ SI443X_REG_\w+'.format(module.capitalize()))
|
||||||
|
'''
|
||||||
|
|
||||||
|
# parse every line in the log file
|
||||||
|
out = []
|
||||||
|
pattern_debug = re.compile('(([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?.[0-9]{3} -> )?[RWM]\t.+')
|
||||||
|
for entry in log:
|
||||||
|
m = pattern_debug.search(entry)
|
||||||
|
if m != None:
|
||||||
|
s = re.split('( |\t)+', entry.rstrip())
|
||||||
|
cmd_len = int((s.__len__() - 7)/2)
|
||||||
|
new_entry = s[0] + s[1] + s[2] + s[3]
|
||||||
|
if s[4] == 'W':
|
||||||
|
macro_address = int(s[6], 16)
|
||||||
|
new_entry += 'write {0:>2} 0x{1:02X} {2}\n'.format(cmd_len, macro_address, get_macro_name(macro_address, macro_addresses))
|
||||||
|
for i in range(cmd_len):
|
||||||
|
new_entry += get_macro_value(s[8 + 2*i]);
|
||||||
|
elif s[4] == 'R':
|
||||||
|
macro_address = int(s[6], 16)
|
||||||
|
new_entry += 'read {0:>2} 0x{1:02X} {2}\n'.format(cmd_len, macro_address, get_macro_name(macro_address, macro_addresses))
|
||||||
|
for i in range(cmd_len):
|
||||||
|
new_entry += get_macro_value(s[8 + 2*i]);
|
||||||
|
elif s[4] == 'M':
|
||||||
|
new_entry += 'module {}\n'.format(s[6])
|
||||||
|
out.append(new_entry)
|
||||||
|
else:
|
||||||
|
out.append(entry)
|
||||||
|
|
||||||
|
# write the output file
|
||||||
|
out_file = open(args.out, 'w')
|
||||||
|
for line in out:
|
||||||
|
print(line, end='')
|
||||||
|
out_file.write(line)
|
||||||
|
out_file.close()
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
board=$1
|
|
||||||
sketch=$2
|
|
||||||
flags=$3
|
|
||||||
warnings="all"
|
|
||||||
|
|
||||||
arduino-cli compile \
|
|
||||||
--libraries ../../../../ \
|
|
||||||
--fqbn $board \
|
|
||||||
--build-property compiler.cpp.extra_flags="$flags" \
|
|
||||||
--warnings=$warnings \
|
|
||||||
$sketch --export-binaries
|
|
|
@ -1,41 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#board=arduino:avr:mega
|
|
||||||
board="$1"
|
|
||||||
#skip="(STM32WL|LR11x0_Firmware_Update|NonArduino)"
|
|
||||||
skip="$2"
|
|
||||||
#options=""
|
|
||||||
options="$3"
|
|
||||||
|
|
||||||
# file for saving the compiled binary size reports
|
|
||||||
size_file="size_$board.txt"
|
|
||||||
rm -f $size_file
|
|
||||||
|
|
||||||
path="../../../examples"
|
|
||||||
for example in $(find $path -name '*.ino' | sort); do
|
|
||||||
# check whether to skip this sketch
|
|
||||||
if [ ! -z '$skip' ] && [[ ${example} =~ ${skip} ]]; then
|
|
||||||
# skip sketch
|
|
||||||
echo -e "\n\033[1;33mSkipped ${example##*/} (matched with $skip)\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
|
|
||||||
|
|
||||||
# build sketch
|
|
||||||
echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m";
|
|
||||||
board_opts=$board$options
|
|
||||||
./build_arduino.sh $board_opts $example "$flags"
|
|
||||||
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";
|
|
||||||
dir="$(dirname -- "$example")"
|
|
||||||
file="$(basename -- "$example")"
|
|
||||||
size="$(size $dir/build/*/$file.elf)"
|
|
||||||
echo $size >> $size_file
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
board=$1
|
|
||||||
hash=$(git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
in_file="size_$board.txt"
|
|
||||||
out_file="size_${hash}_${board//:/-}.csv"
|
|
||||||
rm -f $out_file
|
|
||||||
|
|
||||||
# write the header
|
|
||||||
echo "text,data,bss,dec,hex,filename" > "$out_file"
|
|
||||||
|
|
||||||
# convert to CSV
|
|
||||||
awk 'NR > 1 {
|
|
||||||
split($12, path_parts, "/");
|
|
||||||
filename_with_ext = path_parts[length(path_parts)];
|
|
||||||
split(filename_with_ext, filename_parts, ".");
|
|
||||||
filename = filename_parts[1];
|
|
||||||
print $7 "," $8 "," $9 "," $10 "," $11 "," filename
|
|
||||||
}' "$in_file" >> "$out_file"
|
|
||||||
|
|
||||||
# remove input file
|
|
||||||
rm -f $in_file
|
|
||||||
|
|
2
extras/test/unit/.gitignore
vendored
2
extras/test/unit/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
build/
|
|
||||||
lcov*
|
|
|
@ -1,30 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.13)
|
|
||||||
|
|
||||||
project(radiolib-unittest)
|
|
||||||
|
|
||||||
# add RadioLib sources
|
|
||||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
|
|
||||||
|
|
||||||
# add test sources
|
|
||||||
file(GLOB_RECURSE TEST_SOURCES
|
|
||||||
"tests/main.cpp"
|
|
||||||
"tests/TestModule.cpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
# create the executable
|
|
||||||
add_executable(${PROJECT_NAME} ${TEST_SOURCES})
|
|
||||||
|
|
||||||
# include directories
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC include)
|
|
||||||
|
|
||||||
# link RadioLib
|
|
||||||
target_link_libraries(${PROJECT_NAME} RadioLib fmt gcov)
|
|
||||||
|
|
||||||
# set target properties and options
|
|
||||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
|
||||||
set(BUILD_FLAGS -Wall -Wextra -fprofile-arcs -ftest-coverage -O0)
|
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE ${BUILD_FLAGS})
|
|
||||||
target_compile_options(RadioLib PRIVATE ${BUILD_FLAGS})
|
|
||||||
|
|
||||||
# set RadioLib debug
|
|
||||||
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI RADIOLIB_DEBUG_PROTOCOL)
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
filename="lcov"
|
|
||||||
rm -rf $filename.*
|
|
||||||
lcov --capture --directory build --output-file "${filename}.info"
|
|
||||||
|
|
||||||
# filter out boost and C++ standard library
|
|
||||||
lcov --remove "${filename}.info" "/usr/*/boost/*" "/usr/include/c++/*" --output-file "${filename}.info"
|
|
||||||
|
|
||||||
# generate HTML
|
|
||||||
genhtml "${filename}.info" --output-directory "${filename}.report"
|
|
|
@ -1,71 +0,0 @@
|
||||||
#ifndef HARDWARE_EMULATION_HPP
|
|
||||||
#define HARDWARE_EMULATION_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// value that is returned by the emualted radio class when performing SPI transfer to it
|
|
||||||
#define EMULATED_RADIO_SPI_RETURN (0xFF)
|
|
||||||
|
|
||||||
// pin indexes
|
|
||||||
#define EMULATED_RADIO_NSS_PIN (1)
|
|
||||||
#define EMULATED_RADIO_IRQ_PIN (2)
|
|
||||||
#define EMULATED_RADIO_RST_PIN (3)
|
|
||||||
#define EMULATED_RADIO_GPIO_PIN (4)
|
|
||||||
|
|
||||||
enum PinFunction_t {
|
|
||||||
PIN_UNASSIGNED = 0,
|
|
||||||
PIN_CS,
|
|
||||||
PIN_IRQ,
|
|
||||||
PIN_RST,
|
|
||||||
PIN_GPIO,
|
|
||||||
};
|
|
||||||
|
|
||||||
// structure for emulating GPIO pins
|
|
||||||
struct EmulatedPin_t {
|
|
||||||
uint32_t mode;
|
|
||||||
uint32_t value;
|
|
||||||
bool event;
|
|
||||||
PinFunction_t func;
|
|
||||||
};
|
|
||||||
|
|
||||||
// structure for emulating SPI registers
|
|
||||||
struct EmulatedRegister_t {
|
|
||||||
uint8_t value;
|
|
||||||
uint8_t readOnlyBitFlags;
|
|
||||||
bool bufferAccess;
|
|
||||||
};
|
|
||||||
|
|
||||||
// base class for emulated radio modules (SX126x etc.)
|
|
||||||
class EmulatedRadio {
|
|
||||||
public:
|
|
||||||
void connect(EmulatedPin_t* csPin, EmulatedPin_t* irqPin, EmulatedPin_t* rstPin, EmulatedPin_t* gpioPin) {
|
|
||||||
this->cs = csPin;
|
|
||||||
this->cs->func = PIN_CS;
|
|
||||||
this->irq = irqPin;
|
|
||||||
this->irq->func = PIN_IRQ;
|
|
||||||
this->rst = rstPin;
|
|
||||||
this->rst->func = PIN_RST;
|
|
||||||
this->gpio = gpioPin;
|
|
||||||
this->gpio->func = PIN_GPIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual uint8_t HandleSPI(uint8_t b) {
|
|
||||||
(void)b;
|
|
||||||
// handle the SPI input and generate output here
|
|
||||||
return(EMULATED_RADIO_SPI_RETURN);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void HandleGPIO() {
|
|
||||||
// handle discrete GPIO signals here (e.g. reset state machine on NSS falling edge)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// pointers to emulated GPIO pins
|
|
||||||
// this is done via pointers so that the same GPIO entity is shared, like with a real hardware
|
|
||||||
EmulatedPin_t* cs;
|
|
||||||
EmulatedPin_t* irq;
|
|
||||||
EmulatedPin_t* rst;
|
|
||||||
EmulatedPin_t* gpio;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,269 +0,0 @@
|
||||||
#ifndef TEST_HAL_HPP
|
|
||||||
#define TEST_HAL_HPP
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
#include <RadioLib.h>
|
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
|
||||||
#include <boost/format.hpp>
|
|
||||||
|
|
||||||
#if defined(TEST_HAL_LOG)
|
|
||||||
#define HAL_LOG(...) BOOST_TEST_MESSAGE(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define HAL_LOG(...) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "HardwareEmulation.hpp"
|
|
||||||
|
|
||||||
#define TEST_HAL_INPUT (0)
|
|
||||||
#define TEST_HAL_OUTPUT (1)
|
|
||||||
#define TEST_HAL_LOW (0)
|
|
||||||
#define TEST_HAL_HIGH (1)
|
|
||||||
#define TEST_HAL_RISING (0)
|
|
||||||
#define TEST_HAL_FALLING (1)
|
|
||||||
|
|
||||||
// number of emulated GPIO pins
|
|
||||||
#define TEST_HAL_NUM_GPIO_PINS (32)
|
|
||||||
|
|
||||||
#define TEST_HAL_SPI_LOG_LENGTH (512)
|
|
||||||
|
|
||||||
class TestHal : public RadioLibHal {
|
|
||||||
public:
|
|
||||||
TestHal() : RadioLibHal(TEST_HAL_INPUT, TEST_HAL_OUTPUT, TEST_HAL_LOW, TEST_HAL_HIGH, TEST_HAL_RISING, TEST_HAL_FALLING) { }
|
|
||||||
|
|
||||||
void init() override {
|
|
||||||
HAL_LOG("TestHal::init()");
|
|
||||||
|
|
||||||
// save program start timestamp
|
|
||||||
start = std::chrono::high_resolution_clock::now();
|
|
||||||
|
|
||||||
// init emulated GPIO
|
|
||||||
for(int i = 0; i < TEST_HAL_NUM_GPIO_PINS; i++) {
|
|
||||||
this->gpio[i].mode = 0;
|
|
||||||
this->gpio[i].value = 0;
|
|
||||||
this->gpio[i].event = false;
|
|
||||||
this->gpio[i].func = PIN_UNASSIGNED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// wipe history log
|
|
||||||
this->spiLogWipe();
|
|
||||||
}
|
|
||||||
|
|
||||||
void term() override {
|
|
||||||
HAL_LOG("TestHal::term()");
|
|
||||||
}
|
|
||||||
|
|
||||||
void pinMode(uint32_t pin, uint32_t mode) override {
|
|
||||||
HAL_LOG("TestHal::pinMode(pin=" << pin << ", mode=" << mode << " [" << ((mode == TEST_HAL_INPUT) ? "INPUT" : "OUTPUT") << "])");
|
|
||||||
|
|
||||||
// check the range
|
|
||||||
BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
|
|
||||||
|
|
||||||
// check known modes
|
|
||||||
BOOST_ASSERT_MSG(((mode == TEST_HAL_INPUT) || (mode == TEST_HAL_OUTPUT)), "Invalid pin mode");
|
|
||||||
|
|
||||||
// set mode
|
|
||||||
this->gpio[pin].mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void digitalWrite(uint32_t pin, uint32_t value) override {
|
|
||||||
HAL_LOG("TestHal::digitalWrite(pin=" << pin << ", value=" << value << " [" << ((value == TEST_HAL_LOW) ? "LOW" : "HIGH") << "])");
|
|
||||||
|
|
||||||
// check the range
|
|
||||||
BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
|
|
||||||
|
|
||||||
// check it is output
|
|
||||||
BOOST_ASSERT_MSG(this->gpio[pin].mode == TEST_HAL_OUTPUT, "GPIO is not output!");
|
|
||||||
|
|
||||||
// check known values
|
|
||||||
BOOST_ASSERT_MSG(((value == TEST_HAL_LOW) || (value == TEST_HAL_HIGH)), "Invalid output value");
|
|
||||||
|
|
||||||
// set value
|
|
||||||
this->gpio[pin].value = value;
|
|
||||||
this->gpio[pin].event = true;
|
|
||||||
if(radio) {
|
|
||||||
this->radio->HandleGPIO();
|
|
||||||
}
|
|
||||||
this->gpio[pin].event = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t digitalRead(uint32_t pin) override {
|
|
||||||
HAL_LOG("TestHal::digitalRead(pin=" << pin << ")");
|
|
||||||
|
|
||||||
// check the range
|
|
||||||
BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
|
|
||||||
|
|
||||||
// check it is input
|
|
||||||
BOOST_ASSERT_MSG(this->gpio[pin].mode == TEST_HAL_INPUT, "GPIO is not input");
|
|
||||||
|
|
||||||
// read the value
|
|
||||||
uint32_t value = this->gpio[pin].value;
|
|
||||||
HAL_LOG("TestHal::digitalRead(pin=" << pin << ")=" << value << " [" << ((value == TEST_HAL_LOW) ? "LOW" : "HIGH") << "]");
|
|
||||||
return(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
|
|
||||||
HAL_LOG("TestHal::attachInterrupt(interruptNum=" << interruptNum << ", interruptCb=" << interruptCb << ", mode=" << mode << ")");
|
|
||||||
|
|
||||||
// TODO implement
|
|
||||||
(void)interruptNum;
|
|
||||||
(void)interruptCb;
|
|
||||||
(void)mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void detachInterrupt(uint32_t interruptNum) override {
|
|
||||||
HAL_LOG("TestHal::detachInterrupt(interruptNum=" << interruptNum << ")");
|
|
||||||
|
|
||||||
// TODO implement
|
|
||||||
(void)interruptNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void delay(unsigned long ms) override {
|
|
||||||
HAL_LOG("TestHal::delay(ms=" << ms << ")");
|
|
||||||
const auto start = std::chrono::high_resolution_clock::now();
|
|
||||||
|
|
||||||
// sleep_for is sufficient for ms-precision sleep
|
|
||||||
std::this_thread::sleep_for(std::chrono::duration<unsigned long, std::milli>(ms));
|
|
||||||
|
|
||||||
// measure and print
|
|
||||||
const auto end = std::chrono::high_resolution_clock::now();
|
|
||||||
const std::chrono::duration<double, std::milli> elapsed = end - start;
|
|
||||||
HAL_LOG("TestHal::delay(ms=" << ms << ")=" << elapsed.count() << "ms");
|
|
||||||
}
|
|
||||||
|
|
||||||
void delayMicroseconds(unsigned long us) override {
|
|
||||||
HAL_LOG("TestHal::delayMicroseconds(us=" << us << ")");
|
|
||||||
const auto start = std::chrono::high_resolution_clock::now();
|
|
||||||
|
|
||||||
// busy wait is needed for microseconds precision
|
|
||||||
const auto len = std::chrono::microseconds(us);
|
|
||||||
while(std::chrono::high_resolution_clock::now() - start < len);
|
|
||||||
|
|
||||||
// measure and print
|
|
||||||
const auto end = std::chrono::high_resolution_clock::now();
|
|
||||||
const std::chrono::duration<double, std::micro> elapsed = end - start;
|
|
||||||
HAL_LOG("TestHal::delayMicroseconds(us=" << us << ")=" << elapsed.count() << "us");
|
|
||||||
}
|
|
||||||
|
|
||||||
void yield() override {
|
|
||||||
HAL_LOG("TestHal::yield()");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long millis() override {
|
|
||||||
HAL_LOG("TestHal::millis()");
|
|
||||||
std::chrono::time_point now = std::chrono::high_resolution_clock::now();
|
|
||||||
auto res = std::chrono::duration_cast<std::chrono::milliseconds>(now - this->start);
|
|
||||||
HAL_LOG("TestHal::millis()=" << res.count());
|
|
||||||
return(res.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long micros() override {
|
|
||||||
HAL_LOG("TestHal::micros()");
|
|
||||||
std::chrono::time_point now = std::chrono::high_resolution_clock::now();
|
|
||||||
auto res = std::chrono::duration_cast<std::chrono::microseconds>(now - this->start);
|
|
||||||
HAL_LOG("TestHal::micros()=" << res.count());
|
|
||||||
return(res.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
|
|
||||||
HAL_LOG("TestHal::pulseIn(pin=" << pin << ", state=" << state << ", timeout=" << timeout << ")");
|
|
||||||
|
|
||||||
// TODO implement
|
|
||||||
(void)pin;
|
|
||||||
(void)state;
|
|
||||||
(void)timeout;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void spiBegin() {
|
|
||||||
HAL_LOG("TestHal::spiBegin()");
|
|
||||||
}
|
|
||||||
|
|
||||||
void spiBeginTransaction() {
|
|
||||||
HAL_LOG("TestHal::spiBeginTransaction()");
|
|
||||||
}
|
|
||||||
|
|
||||||
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
|
|
||||||
HAL_LOG("TestHal::spiTransfer(len=" << len << ")");
|
|
||||||
|
|
||||||
for(size_t i = 0; i < len; i++) {
|
|
||||||
// append to log
|
|
||||||
(*this->spiLogPtr++) = out[i];
|
|
||||||
|
|
||||||
// process the SPI byte
|
|
||||||
in[i] = this->radio->HandleSPI(out[i]);
|
|
||||||
|
|
||||||
// artificial delay to emulate SPI running at a finite speed
|
|
||||||
// this is added because timeouts are based on time duration,
|
|
||||||
// so we need to make sure some time actually elapses
|
|
||||||
this->delayMicroseconds(100);
|
|
||||||
|
|
||||||
// output debug
|
|
||||||
HAL_LOG(fmt::format("out={:#02x}, in={:#02x}", out[i], in[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void spiEndTransaction() {
|
|
||||||
HAL_LOG("TestHal::spiEndTransaction()");
|
|
||||||
}
|
|
||||||
|
|
||||||
void spiEnd() {
|
|
||||||
HAL_LOG("TestHal::spiEnd()");
|
|
||||||
}
|
|
||||||
|
|
||||||
void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) {
|
|
||||||
HAL_LOG("TestHal::tone(pin=" << pin << ", frequency=" << frequency << ", duration=" << duration << ")");
|
|
||||||
|
|
||||||
// TODO implement
|
|
||||||
(void)pin;
|
|
||||||
(void)frequency;
|
|
||||||
(void)duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void noTone(uint32_t pin) {
|
|
||||||
HAL_LOG("TestHal::noTone(pin=" << pin << ")");
|
|
||||||
|
|
||||||
// TODO implement
|
|
||||||
(void)pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// method to compare buffer to the internal SPI log, for verifying SPI transactions
|
|
||||||
int spiLogMemcmp(const void* in, size_t n) {
|
|
||||||
int ret = memcmp(this->spiLog, in, n);
|
|
||||||
this->spiLogWipe();
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void spiLogWipe() {
|
|
||||||
memset(this->spiLog, 0x00, TEST_HAL_SPI_LOG_LENGTH);
|
|
||||||
this->spiLogPtr = this->spiLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
// method that "connects" the emualted radio hardware to this HAL
|
|
||||||
void connectRadio(EmulatedRadio* r) {
|
|
||||||
this->radio = r;
|
|
||||||
this->radio->connect(&this->gpio[EMULATED_RADIO_NSS_PIN],
|
|
||||||
&this->gpio[EMULATED_RADIO_IRQ_PIN],
|
|
||||||
&this->gpio[EMULATED_RADIO_RST_PIN],
|
|
||||||
&this->gpio[EMULATED_RADIO_GPIO_PIN]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// array of emulated GPIO pins
|
|
||||||
EmulatedPin_t gpio[TEST_HAL_NUM_GPIO_PINS];
|
|
||||||
|
|
||||||
// start time point
|
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> start;
|
|
||||||
|
|
||||||
// emulated radio hardware
|
|
||||||
EmulatedRadio* radio;
|
|
||||||
|
|
||||||
// SPI history log
|
|
||||||
uint8_t spiLog[TEST_HAL_SPI_LOG_LENGTH];
|
|
||||||
uint8_t* spiLogPtr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# build the test binary
|
|
||||||
rm -rf build
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake -G "CodeBlocks - Unix Makefiles" ..
|
|
||||||
make -j4
|
|
||||||
|
|
||||||
# run it
|
|
||||||
cd ..
|
|
||||||
./build/radiolib-unittest --log_level=message
|
|
|
@ -1,229 +0,0 @@
|
||||||
// boost test header
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
// mock HAL
|
|
||||||
#include "TestHal.hpp"
|
|
||||||
|
|
||||||
// testing fixture
|
|
||||||
struct ModuleFixture {
|
|
||||||
TestHal* hal = nullptr;
|
|
||||||
Module* mod = nullptr;
|
|
||||||
EmulatedRadio* radioHardware = nullptr;
|
|
||||||
|
|
||||||
ModuleFixture() {
|
|
||||||
BOOST_TEST_MESSAGE("--- Module fixture setup ---");
|
|
||||||
hal = new TestHal();
|
|
||||||
radioHardware = new EmulatedRadio();
|
|
||||||
hal->connectRadio(radioHardware);
|
|
||||||
|
|
||||||
mod = new Module(hal, EMULATED_RADIO_NSS_PIN, EMULATED_RADIO_IRQ_PIN, EMULATED_RADIO_RST_PIN, EMULATED_RADIO_GPIO_PIN);
|
|
||||||
mod->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
~ModuleFixture() {
|
|
||||||
BOOST_TEST_MESSAGE("--- Module fixture teardown ---");
|
|
||||||
mod->term();
|
|
||||||
delete[] mod;
|
|
||||||
delete[] hal;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_reg, ModuleFixture)
|
|
||||||
{
|
|
||||||
BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue register access ---");
|
|
||||||
int16_t ret;
|
|
||||||
|
|
||||||
// basic register read with default config
|
|
||||||
const uint8_t address = 0x12;
|
|
||||||
const uint8_t spiTxn[] = { address, 0x00 };
|
|
||||||
ret = mod->SPIgetRegValue(address);
|
|
||||||
|
|
||||||
// check return code, value and history log
|
|
||||||
BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
|
|
||||||
BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
|
|
||||||
// register read masking test
|
|
||||||
const uint8_t msb = 5;
|
|
||||||
const uint8_t lsb = 1;
|
|
||||||
const uint8_t maskedValue = 0x3E;
|
|
||||||
ret = mod->SPIgetRegValue(address, msb, lsb);
|
|
||||||
BOOST_TEST(ret == maskedValue);
|
|
||||||
|
|
||||||
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
|
|
||||||
ret = mod->SPIgetRegValue(address, lsb, msb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIgetRegValue(address, 10, lsb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIgetRegValue(address, msb, 10);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(Module_SPIsetRegValue_reg, ModuleFixture)
|
|
||||||
{
|
|
||||||
BOOST_TEST_MESSAGE("--- Test Module::SPIsetRegValue register access ---");
|
|
||||||
int16_t ret;
|
|
||||||
|
|
||||||
// basic register write with default config
|
|
||||||
const uint8_t address = 0x12;
|
|
||||||
const uint8_t value = 0xAB;
|
|
||||||
const uint8_t spiTxn[] = { address, 0x00, 0x80 | address, value };
|
|
||||||
ret = mod->SPIsetRegValue(address, value);
|
|
||||||
|
|
||||||
// check return code and history log
|
|
||||||
// this will return write error because the bare emulated radio has no internal logic
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
|
|
||||||
// register write masking test
|
|
||||||
const uint8_t msb = 5;
|
|
||||||
const uint8_t lsb = 1;
|
|
||||||
const uint8_t maskedValue = 0xEB;
|
|
||||||
const uint8_t spiTxn2[] = { address, 0x00, 0x80 | address, maskedValue };
|
|
||||||
ret = mod->SPIsetRegValue(address, value, msb, lsb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn2, sizeof(spiTxn2)) == 0);
|
|
||||||
|
|
||||||
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
|
|
||||||
ret = mod->SPIsetRegValue(address, value, lsb, msb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 10, lsb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIsetRegValue(address, value, msb, 10);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
|
|
||||||
// check interval test
|
|
||||||
const uint8_t interval = 200;
|
|
||||||
const unsigned long start = hal->micros();
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 7, 0, interval);
|
|
||||||
const unsigned long stop = hal->micros();
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
const unsigned long elapsed = stop - start;
|
|
||||||
BOOST_TEST(elapsed >= (unsigned long)interval*1000UL);
|
|
||||||
|
|
||||||
// disabled check mask test
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_NONE);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
|
|
||||||
// forced write test
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0xFF, true);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_stream, ModuleFixture)
|
|
||||||
{
|
|
||||||
BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue stream access ---");
|
|
||||||
int16_t ret;
|
|
||||||
|
|
||||||
// change settings to stream type
|
|
||||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_16;
|
|
||||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
|
|
||||||
mod->spiConfig.statusPos = 1;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_SX126X_CMD_READ_REGISTER;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_SX126X_CMD_WRITE_REGISTER;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_SX126X_CMD_NOP;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_SX126X_CMD_GET_STATUS;
|
|
||||||
mod->spiConfig.stream = true;
|
|
||||||
|
|
||||||
// basic register read
|
|
||||||
const uint8_t address = 0x12;
|
|
||||||
const uint8_t spiTxn[] = { RADIOLIB_SX126X_CMD_READ_REGISTER, 0x00, address, 0x00, 0x00 };
|
|
||||||
ret = mod->SPIgetRegValue(address);
|
|
||||||
|
|
||||||
// check return code, value and history log
|
|
||||||
BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
|
|
||||||
BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
|
|
||||||
// register read masking test
|
|
||||||
const uint8_t msb = 5;
|
|
||||||
const uint8_t lsb = 1;
|
|
||||||
const uint8_t maskedValue = 0x3E;
|
|
||||||
ret = mod->SPIgetRegValue(address, msb, lsb);
|
|
||||||
BOOST_TEST(ret == maskedValue);
|
|
||||||
|
|
||||||
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
|
|
||||||
ret = mod->SPIgetRegValue(address, lsb, msb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIgetRegValue(address, 10, lsb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIgetRegValue(address, msb, 10);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(Module_SPIsetRegValue_stream, ModuleFixture)
|
|
||||||
{
|
|
||||||
BOOST_TEST_MESSAGE("--- Test Module::SPIsetRegValue stream access ---");
|
|
||||||
int16_t ret;
|
|
||||||
|
|
||||||
// change settings to stream type
|
|
||||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_16;
|
|
||||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
|
|
||||||
mod->spiConfig.statusPos = 1;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_SX126X_CMD_READ_REGISTER;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_SX126X_CMD_WRITE_REGISTER;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_SX126X_CMD_NOP;
|
|
||||||
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_SX126X_CMD_GET_STATUS;
|
|
||||||
mod->spiConfig.stream = true;
|
|
||||||
|
|
||||||
// basic register write with default config
|
|
||||||
const uint8_t address = 0x12;
|
|
||||||
const uint8_t value = 0xAB;
|
|
||||||
const uint8_t spiTxn[] = {
|
|
||||||
RADIOLIB_SX126X_CMD_READ_REGISTER, 0x00, address, 0x00, 0x00,
|
|
||||||
RADIOLIB_SX126X_CMD_WRITE_REGISTER, 0x00, address, value,
|
|
||||||
};
|
|
||||||
ret = mod->SPIsetRegValue(address, value);
|
|
||||||
|
|
||||||
// check return code and history log
|
|
||||||
// this will return write error because the bare emulated radio has no internal logic
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
|
|
||||||
// register write masking test
|
|
||||||
const uint8_t msb = 5;
|
|
||||||
const uint8_t lsb = 1;
|
|
||||||
const uint8_t maskedValue = 0xEB;
|
|
||||||
const uint8_t spiTxn2[] = {
|
|
||||||
RADIOLIB_SX126X_CMD_READ_REGISTER, 0x00, address, 0x00, 0x00,
|
|
||||||
RADIOLIB_SX126X_CMD_WRITE_REGISTER, 0x00, address, maskedValue,
|
|
||||||
};
|
|
||||||
ret = mod->SPIsetRegValue(address, value, msb, lsb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn2, sizeof(spiTxn2)) == 0);
|
|
||||||
|
|
||||||
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
|
|
||||||
ret = mod->SPIsetRegValue(address, value, lsb, msb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 10, lsb);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
ret = mod->SPIsetRegValue(address, value, msb, 10);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
|
|
||||||
|
|
||||||
// check interval test
|
|
||||||
const uint8_t interval = 200;
|
|
||||||
const unsigned long start = hal->micros();
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 7, 0, interval);
|
|
||||||
const unsigned long stop = hal->micros();
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
const unsigned long elapsed = stop - start;
|
|
||||||
BOOST_TEST(elapsed >= (unsigned long)interval*1000UL);
|
|
||||||
|
|
||||||
// disabled check mask test
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_NONE);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
|
|
||||||
// forced write test
|
|
||||||
ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0xFF, true);
|
|
||||||
BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
|
|
||||||
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
|
|
@ -1,5 +0,0 @@
|
||||||
#define BOOST_TEST_MODULE "RadioLib Unit test"
|
|
||||||
#include <boost/test/included/unit_test.hpp>
|
|
||||||
|
|
||||||
// intentionally left blank, boost.test creates its own entrypoint
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: "17.0.3"
|
version: "7.1.0"
|
||||||
description: "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN)."
|
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:
|
tags:
|
||||||
- radio
|
- radio
|
||||||
|
@ -33,8 +33,8 @@ tags:
|
||||||
- lr1110
|
- lr1110
|
||||||
- lr1120
|
- lr1120
|
||||||
- lr1121
|
- lr1121
|
||||||
url: "https://git.cheetah.cat/forks/RadioLibSmol"
|
url: "https://github.com/jgromes/RadioLib"
|
||||||
repository: "https://git.cheetah.cat/forks/RadioLibSmol.git"
|
repository: "https://github.com/jgromes/RadioLib.git"
|
||||||
license: "MIT"
|
license: "MIT"
|
||||||
dependencies:
|
dependencies:
|
||||||
# Required IDF version
|
# Required IDF version
|
||||||
|
|
|
@ -86,7 +86,7 @@ EU868 KEYWORD1
|
||||||
US915 KEYWORD1
|
US915 KEYWORD1
|
||||||
EU433 KEYWORD1
|
EU433 KEYWORD1
|
||||||
AU915 KEYWORD1
|
AU915 KEYWORD1
|
||||||
CN470 KEYWORD1
|
CN500 KEYWORD1
|
||||||
AS923 KEYWORD1
|
AS923 KEYWORD1
|
||||||
AS923_2 KEYWORD1
|
AS923_2 KEYWORD1
|
||||||
AS923_3 KEYWORD1
|
AS923_3 KEYWORD1
|
||||||
|
@ -197,7 +197,6 @@ randomByte KEYWORD2
|
||||||
getPacketLength KEYWORD2
|
getPacketLength KEYWORD2
|
||||||
setFifoEmptyAction KEYWORD2
|
setFifoEmptyAction KEYWORD2
|
||||||
clearFifoEmptyAction KEYWORD2
|
clearFifoEmptyAction KEYWORD2
|
||||||
setFifoThreshold KEYWORD2
|
|
||||||
setFifoFullAction KEYWORD2
|
setFifoFullAction KEYWORD2
|
||||||
clearFifoFullAction KEYWORD2
|
clearFifoFullAction KEYWORD2
|
||||||
fifoAdd KEYWORD2
|
fifoAdd KEYWORD2
|
||||||
|
@ -222,7 +221,6 @@ setGdo2Action KEYWORD2
|
||||||
clearGdo0Action KEYWORD2
|
clearGdo0Action KEYWORD2
|
||||||
clearGdo2Action KEYWORD2
|
clearGdo2Action KEYWORD2
|
||||||
setCrcFiltering KEYWORD2
|
setCrcFiltering KEYWORD2
|
||||||
beginFSK4 KEYWORD2
|
|
||||||
|
|
||||||
# SX126x-specific
|
# SX126x-specific
|
||||||
setTCXO KEYWORD2
|
setTCXO KEYWORD2
|
||||||
|
@ -246,7 +244,6 @@ spectralScanAbort KEYWORD2
|
||||||
spectralScanGetStatus KEYWORD2
|
spectralScanGetStatus KEYWORD2
|
||||||
spectralScanGetResult KEYWORD2
|
spectralScanGetResult KEYWORD2
|
||||||
setPaRampTime KEYWORD2
|
setPaRampTime KEYWORD2
|
||||||
hopLRFHSS KEYWORD2
|
|
||||||
|
|
||||||
# nRF24
|
# nRF24
|
||||||
setIrqAction KEYWORD2
|
setIrqAction KEYWORD2
|
||||||
|
@ -343,8 +340,6 @@ setDataRate KEYWORD2
|
||||||
checkDataRate KEYWORD2
|
checkDataRate KEYWORD2
|
||||||
setModem KEYWORD2
|
setModem KEYWORD2
|
||||||
getModem KEYWORD2
|
getModem KEYWORD2
|
||||||
stageMode KEYWORD2
|
|
||||||
launchMode KEYWORD2
|
|
||||||
|
|
||||||
# LoRaWAN
|
# LoRaWAN
|
||||||
getBufferNonces KEYWORD2
|
getBufferNonces KEYWORD2
|
||||||
|
@ -379,7 +374,6 @@ getLastToA KEYWORD2
|
||||||
dutyCycleInterval KEYWORD2
|
dutyCycleInterval KEYWORD2
|
||||||
timeUntilUplink KEYWORD2
|
timeUntilUplink KEYWORD2
|
||||||
getMaxPayloadLen KEYWORD2
|
getMaxPayloadLen KEYWORD2
|
||||||
setSleepFunction KEYWORD2
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "RadioLib",
|
"name": "RadioLib",
|
||||||
"version": "17.0.3",
|
"version": "7.1.0",
|
||||||
"description": "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN).",
|
"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",
|
"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",
|
"homepage": "https://github.com/jgromes/RadioLib",
|
||||||
"repository":
|
"repository":
|
||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.cheetah.cat/forks/RadioLibSmol.git"
|
"url": "https://github.com/jgromes/RadioLib.git"
|
||||||
},
|
},
|
||||||
"authors":
|
"authors":
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
name=RadioLib
|
name=RadioLib
|
||||||
version=17.0.3
|
version=7.1.0
|
||||||
author=Jan Gromes <gromes.jan@gmail.com>
|
author=Jan Gromes <gromes.jan@gmail.com>
|
||||||
maintainer=Jan Gromes <gromes.jan@gmail.com>
|
maintainer=Jan Gromes <gromes.jan@gmail.com>
|
||||||
sentence=Universal wireless communication library
|
sentence=Universal wireless communication library
|
||||||
paragraph=User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, LR1110 and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN).
|
paragraph=User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, LR1110 and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN).
|
||||||
category=Communication
|
category=Communication
|
||||||
url=https://git.cheetah.cat/forks/RadioLibSmol
|
url=https://github.com/jgromes/RadioLib
|
||||||
architectures=*
|
architectures=*
|
||||||
includes=RadioLib.h
|
includes=RadioLib.h
|
||||||
|
|
127
src/BuildOpt.h
127
src/BuildOpt.h
|
@ -29,11 +29,7 @@
|
||||||
// set which output port should be used for debug output
|
// set which output port should be used for debug output
|
||||||
// may be Serial port (on Arduino) or file like stdout or stderr (on generic platforms)
|
// may be Serial port (on Arduino) or file like stdout or stderr (on generic platforms)
|
||||||
#if !defined(RADIOLIB_DEBUG_PORT)
|
#if !defined(RADIOLIB_DEBUG_PORT)
|
||||||
#if ARDUINO >= 100
|
#define RADIOLIB_DEBUG_PORT Serial
|
||||||
#define RADIOLIB_DEBUG_PORT Serial
|
|
||||||
#else
|
|
||||||
#define RADIOLIB_DEBUG_PORT stdout
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -118,10 +114,6 @@
|
||||||
//#define RADIOLIB_CLOCK_DRIFT_MS (0)
|
//#define RADIOLIB_CLOCK_DRIFT_MS (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(RADIOLIB_LINE_FEED)
|
|
||||||
#define RADIOLIB_LINE_FEED "\r\n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARDUINO >= 100
|
#if ARDUINO >= 100
|
||||||
// Arduino build
|
// Arduino build
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
@ -141,9 +133,11 @@
|
||||||
* RADIOLIB_DEFAULT_SPI - default SPIClass instance to use.
|
* RADIOLIB_DEFAULT_SPI - default SPIClass instance to use.
|
||||||
* RADIOLIB_NONVOLATILE - macro to place variable into program storage (usually Flash).
|
* 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_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 via the `using` keyword.
|
* RADIOLIB_TYPE_ALIAS - construct to create an alias for a type, usually vai the `using` keyword.
|
||||||
* RADIOLIB_TONE_UNSUPPORTED - some platforms do not have tone()/noTone(), which is required for AFSK.
|
* 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,
|
* 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
|
* and then specifying all platform parameters in the section below. This will override automatic
|
||||||
* platform detection.
|
* platform detection.
|
||||||
|
@ -268,24 +262,20 @@
|
||||||
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
||||||
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_MBED)
|
|
||||||
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
|
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
|
||||||
#define RADIOLIB_TONE_UNSUPPORTED
|
#define RADIOLIB_TONE_UNSUPPORTED
|
||||||
#define RADIOLIB_MBED_TONE_OVERRIDE
|
#define RADIOLIB_MBED_TONE_OVERRIDE
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_PORTENTA_H7)
|
#elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
|
||||||
// Arduino Portenta H7
|
// Arduino Portenta H7
|
||||||
#define RADIOLIB_PLATFORM "Portenta H7"
|
#define RADIOLIB_PLATFORM "Portenta H7"
|
||||||
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
|
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
|
||||||
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
||||||
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_MBED)
|
|
||||||
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
|
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
|
||||||
#define RADIOLIB_TONE_UNSUPPORTED
|
#define RADIOLIB_TONE_UNSUPPORTED
|
||||||
#define RADIOLIB_MBED_TONE_OVERRIDE
|
#define RADIOLIB_MBED_TONE_OVERRIDE
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(__STM32F4__) || defined(__STM32F1__)
|
#elif defined(__STM32F4__) || defined(__STM32F1__)
|
||||||
// Arduino STM32 core by Roger Clark (https://github.com/rogerclarkmelbourne/Arduino_STM32)
|
// Arduino STM32 core by Roger Clark (https://github.com/rogerclarkmelbourne/Arduino_STM32)
|
||||||
|
@ -375,13 +365,6 @@
|
||||||
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
||||||
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_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
|
#else
|
||||||
// other Arduino platforms not covered by the above list - this may or may not work
|
// other Arduino platforms not covered by the above list - this may or may not work
|
||||||
#define RADIOLIB_PLATFORM "Unknown Arduino"
|
#define RADIOLIB_PLATFORM "Unknown Arduino"
|
||||||
|
@ -441,10 +424,14 @@
|
||||||
|
|
||||||
#define RADIOLIB_NC (0xFFFFFFFF)
|
#define RADIOLIB_NC (0xFFFFFFFF)
|
||||||
#define RADIOLIB_NONVOLATILE
|
#define RADIOLIB_NONVOLATILE
|
||||||
#define RADIOLIB_NONVOLATILE_READ_BYTE(addr) (*(reinterpret_cast<uint8_t *>(reinterpret_cast<void *>(addr))))
|
#define RADIOLIB_NONVOLATILE_READ_BYTE(addr) (*((uint8_t *)(void *)(addr)))
|
||||||
#define RADIOLIB_NONVOLATILE_READ_DWORD(addr) (*(reinterpret_cast<uint32_t *>(reinterpret_cast<void *>(addr))))
|
#define RADIOLIB_NONVOLATILE_READ_DWORD(addr) (*((uint32_t *)(void *)(addr)))
|
||||||
#define RADIOLIB_TYPE_ALIAS(type, alias) using alias = type;
|
#define RADIOLIB_TYPE_ALIAS(type, alias) using alias = type;
|
||||||
|
|
||||||
|
#if !defined(RADIOLIB_DEBUG_PORT)
|
||||||
|
#define RADIOLIB_DEBUG_PORT stdout
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEC 10
|
#define DEC 10
|
||||||
#define HEX 16
|
#define HEX 16
|
||||||
#define OCT 8
|
#define OCT 8
|
||||||
|
@ -473,20 +460,23 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RADIOLIB_DEBUG
|
#if RADIOLIB_DEBUG
|
||||||
#if !defined(RADIOLIB_DEBUG_PRINT)
|
|
||||||
#define RADIOLIB_DEBUG_PRINT(M, ...) rlb_printf(false, M, ##__VA_ARGS__)
|
|
||||||
#define RADIOLIB_DEBUG_PRINT_LVL(LEVEL, M, ...) rlb_printf(true, LEVEL "" M, ##__VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(RADIOLIB_DEBUG_PRINTLN)
|
|
||||||
#define RADIOLIB_DEBUG_PRINTLN(M, ...) rlb_printf(false, M RADIOLIB_LINE_FEED, ##__VA_ARGS__)
|
|
||||||
#define RADIOLIB_DEBUG_PRINTLN_LVL(LEVEL, M, ...) rlb_printf(true, LEVEL "" M RADIOLIB_LINE_FEED, ##__VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// some Arduino platforms do not support printf("%f"), so it has to be done this way
|
|
||||||
#if defined(RADIOLIB_BUILD_ARDUINO)
|
#if defined(RADIOLIB_BUILD_ARDUINO)
|
||||||
|
#define RADIOLIB_DEBUG_PRINT(...) rlb_printf(__VA_ARGS__)
|
||||||
|
#define RADIOLIB_DEBUG_PRINTLN(M, ...) rlb_printf(M "\n", ##__VA_ARGS__)
|
||||||
|
#define RADIOLIB_DEBUG_PRINT_LVL(LEVEL, M, ...) rlb_printf(LEVEL "" M, ##__VA_ARGS__)
|
||||||
|
#define RADIOLIB_DEBUG_PRINTLN_LVL(LEVEL, M, ...) rlb_printf(LEVEL "" M "\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
// some platforms do not support printf("%f"), so it has to be done this way
|
||||||
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL); RADIOLIB_DEBUG_PORT.print(VAL, DECIMALS)
|
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL); RADIOLIB_DEBUG_PORT.print(VAL, DECIMALS)
|
||||||
#else
|
#else
|
||||||
|
#if !defined(RADIOLIB_DEBUG_PRINT)
|
||||||
|
#define RADIOLIB_DEBUG_PRINT(...) fprintf(RADIOLIB_DEBUG_PORT, __VA_ARGS__)
|
||||||
|
#define RADIOLIB_DEBUG_PRINT_LVL(LEVEL, M, ...) fprintf(RADIOLIB_DEBUG_PORT, LEVEL "" M, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
#if !defined(RADIOLIB_DEBUG_PRINTLN)
|
||||||
|
#define RADIOLIB_DEBUG_PRINTLN(M, ...) fprintf(RADIOLIB_DEBUG_PORT, M "\n", ##__VA_ARGS__)
|
||||||
|
#define RADIOLIB_DEBUG_PRINTLN_LVL(LEVEL, M, ...) fprintf(RADIOLIB_DEBUG_PORT, LEVEL "" M "\n", ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL "%.3f", VAL)
|
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL "%.3f", VAL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -494,74 +484,63 @@
|
||||||
#else
|
#else
|
||||||
#define RADIOLIB_DEBUG_PRINT(...) {}
|
#define RADIOLIB_DEBUG_PRINT(...) {}
|
||||||
#define RADIOLIB_DEBUG_PRINTLN(...) {}
|
#define RADIOLIB_DEBUG_PRINTLN(...) {}
|
||||||
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) {}
|
#define RADIOLIB_DEBUG_PRINT_FLOAT(VAL, DECIMALS) {}
|
||||||
#define RADIOLIB_DEBUG_HEXDUMP(...) {}
|
#define RADIOLIB_DEBUG_HEXDUMP(...) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RADIOLIB_DEBUG_TAG ": "
|
|
||||||
#define RADIOLIB_DEBUG_TAG_BASIC "RLB_DBG" RADIOLIB_DEBUG_TAG
|
|
||||||
#define RADIOLIB_DEBUG_TAG_PROTOCOL "RLB_PRO" RADIOLIB_DEBUG_TAG
|
|
||||||
#define RADIOLIB_DEBUG_TAG_SPI "RLB_SPI" RADIOLIB_DEBUG_TAG
|
|
||||||
|
|
||||||
#if RADIOLIB_DEBUG_BASIC
|
#if RADIOLIB_DEBUG_BASIC
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_BASIC_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_DBG: ", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT_LVL("", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_DBG: ", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_DBG: ", __VA_ARGS__);
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT(__VA_ARGS__)
|
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_DBG: ", __VA_ARGS__);
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN(__VA_ARGS__)
|
|
||||||
#else
|
#else
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINT(...) {}
|
#define RADIOLIB_DEBUG_BASIC_PRINT(...) {}
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) {}
|
|
||||||
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) {}
|
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) {}
|
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) {}
|
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) {}
|
||||||
#define RADIOLIB_DEBUG_BASIC_PRINTLN_NOTAG(...) {}
|
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) {}
|
||||||
|
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) {}
|
||||||
|
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RADIOLIB_DEBUG_PROTOCOL
|
#if RADIOLIB_DEBUG_PROTOCOL
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL(RADIOLIB_DEBUG_TAG_PROTOCOL, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_PRO: ", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL(RADIOLIB_DEBUG_TAG_PROTOCOL, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_PRO: ", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP(RADIOLIB_DEBUG_TAG_PROTOCOL, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_PRO: ", __VA_ARGS__);
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT(RADIOLIB_DEBUG_TAG_PROTOCOL, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_PRO: ", __VA_ARGS__);
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT(__VA_ARGS__)
|
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN(__VA_ARGS__)
|
|
||||||
#else
|
#else
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) {}
|
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) {}
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) {}
|
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) {}
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) {}
|
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) {}
|
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) {}
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_NOTAG(...) {}
|
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) {}
|
||||||
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN_NOTAG(...) {}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RADIOLIB_DEBUG_SPI
|
#if RADIOLIB_DEBUG_SPI
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_SPI_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_SPI: ", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT_LVL("", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_SPI: ", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
|
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN_LVL("", __VA_ARGS__)
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT(__VA_ARGS__)
|
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_SPI: ", __VA_ARGS__);
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN(__VA_ARGS__)
|
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_SPI: ", __VA_ARGS__);
|
||||||
#else
|
#else
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINT(...) {}
|
#define RADIOLIB_DEBUG_SPI_PRINT(...) {}
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) {}
|
|
||||||
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) {}
|
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) {}
|
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) {}
|
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) {}
|
||||||
|
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) {}
|
||||||
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) {}
|
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) {}
|
||||||
|
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) {}
|
||||||
|
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// debug info strings
|
// debug info strings
|
||||||
#define RADIOLIB_VALUE_TO_STRING(x) #x
|
#define RADIOLIB_VALUE_TO_STRING(x) #x
|
||||||
#define RADIOLIB_VALUE(x) RADIOLIB_VALUE_TO_STRING(x)
|
#define RADIOLIB_VALUE(x) RADIOLIB_VALUE_TO_STRING(x)
|
||||||
|
|
||||||
#define RADIOLIB_INFO "\r\nRadioLib Info\nVersion: \"" \
|
#define RADIOLIB_INFO "\nRadioLib Info\nVersion: \"" \
|
||||||
RADIOLIB_VALUE(RADIOLIB_VERSION_MAJOR) "." \
|
RADIOLIB_VALUE(RADIOLIB_VERSION_MAJOR) "." \
|
||||||
RADIOLIB_VALUE(RADIOLIB_VERSION_MINOR) "." \
|
RADIOLIB_VALUE(RADIOLIB_VERSION_MINOR) "." \
|
||||||
RADIOLIB_VALUE(RADIOLIB_VERSION_PATCH) "." \
|
RADIOLIB_VALUE(RADIOLIB_VERSION_PATCH) "." \
|
||||||
RADIOLIB_VALUE(RADIOLIB_VERSION_EXTRA) "\"\r\n" \
|
RADIOLIB_VALUE(RADIOLIB_VERSION_EXTRA) "\"\n" \
|
||||||
"Platform: " RADIOLIB_VALUE(RADIOLIB_PLATFORM) "\r\n" \
|
"Platform: " RADIOLIB_VALUE(RADIOLIB_PLATFORM) "\n" \
|
||||||
RADIOLIB_VALUE(__DATE__) " " RADIOLIB_VALUE(__TIME__)
|
"Compiled: " RADIOLIB_VALUE(__DATE__) " " RADIOLIB_VALUE(__TIME__)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief A simple assert macro, will return on error.
|
\brief A simple assert macro, will return on error.
|
||||||
|
@ -599,7 +578,7 @@
|
||||||
// version definitions
|
// version definitions
|
||||||
#define RADIOLIB_VERSION_MAJOR 7
|
#define RADIOLIB_VERSION_MAJOR 7
|
||||||
#define RADIOLIB_VERSION_MINOR 1
|
#define RADIOLIB_VERSION_MINOR 1
|
||||||
#define RADIOLIB_VERSION_PATCH 2
|
#define RADIOLIB_VERSION_PATCH 0
|
||||||
#define RADIOLIB_VERSION_EXTRA 0
|
#define RADIOLIB_VERSION_EXTRA 0
|
||||||
|
|
||||||
#define RADIOLIB_VERSION (((RADIOLIB_VERSION_MAJOR) << 24) | ((RADIOLIB_VERSION_MINOR) << 16) | ((RADIOLIB_VERSION_PATCH) << 8) | (RADIOLIB_VERSION_EXTRA))
|
#define RADIOLIB_VERSION (((RADIOLIB_VERSION_MAJOR) << 24) | ((RADIOLIB_VERSION_MINOR) << 16) | ((RADIOLIB_VERSION_PATCH) << 8) | (RADIOLIB_VERSION_EXTRA))
|
||||||
|
|
12
src/Hal.cpp
12
src/Hal.cpp
|
@ -1,18 +1,12 @@
|
||||||
#include "Hal.h"
|
#include "Hal.h"
|
||||||
|
|
||||||
static RadioLibHal* rlb_timestamp_hal = nullptr;
|
|
||||||
|
|
||||||
RadioLibHal::RadioLibHal(const uint32_t input, const uint32_t output, const uint32_t low, const uint32_t high, const uint32_t rising, const uint32_t falling)
|
RadioLibHal::RadioLibHal(const uint32_t input, const uint32_t output, const uint32_t low, const uint32_t high, const uint32_t rising, const uint32_t falling)
|
||||||
: GpioModeInput(input),
|
: GpioModeInput(input),
|
||||||
GpioModeOutput(output),
|
GpioModeOutput(output),
|
||||||
GpioLevelLow(low),
|
GpioLevelLow(low),
|
||||||
GpioLevelHigh(high),
|
GpioLevelHigh(high),
|
||||||
GpioInterruptRising(rising),
|
GpioInterruptRising(rising),
|
||||||
GpioInterruptFalling(falling) {
|
GpioInterruptFalling(falling) {}
|
||||||
if(!rlb_timestamp_hal) {
|
|
||||||
rlb_timestamp_hal = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RadioLibHal::init() {
|
void RadioLibHal::init() {
|
||||||
|
|
||||||
|
@ -39,7 +33,3 @@ void RadioLibHal::yield() {
|
||||||
uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) {
|
uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) {
|
||||||
return(pin);
|
return(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
RadioLibTime_t rlb_time_us() {
|
|
||||||
return(rlb_timestamp_hal == nullptr ? 0 : rlb_timestamp_hal->micros());
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
|
|
||||||
#include "BuildOpt.h"
|
#include "BuildOpt.h"
|
||||||
|
|
||||||
/*! \brief Global-scope function that returns timestamp since start (in microseconds). */
|
|
||||||
RadioLibTime_t rlb_time_us();
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class RadioLibHal
|
\class RadioLibHal
|
||||||
\brief Hardware abstraction library base interface.
|
\brief Hardware abstraction library base interface.
|
||||||
|
|
|
@ -25,7 +25,7 @@ Module::Module(const Module& mod) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Module& Module::operator=(const Module& mod) {
|
Module& Module::operator=(const Module& mod) {
|
||||||
memcpy(reinterpret_cast<void*>(&(const_cast<Module&>(mod)).spiConfig), &this->spiConfig, sizeof(SPIConfig_t));
|
memcpy((void*)&mod.spiConfig, &this->spiConfig, sizeof(SPIConfig_t));
|
||||||
this->csPin = mod.csPin;
|
this->csPin = mod.csPin;
|
||||||
this->irqPin = mod.irqPin;
|
this->irqPin = mod.irqPin;
|
||||||
this->rstPin = mod.rstPin;
|
this->rstPin = mod.rstPin;
|
||||||
|
@ -56,21 +56,13 @@ int16_t Module::SPIgetRegValue(uint32_t reg, uint8_t msb, uint8_t lsb) {
|
||||||
return(maskedValue);
|
return(maskedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Module::SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval, uint8_t checkMask, bool force) {
|
int16_t Module::SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval, uint8_t checkMask) {
|
||||||
if((msb > 7) || (lsb > 7) || (lsb > msb)) {
|
if((msb > 7) || (lsb > 7) || (lsb > msb)) {
|
||||||
return(RADIOLIB_ERR_INVALID_BIT_RANGE);
|
return(RADIOLIB_ERR_INVALID_BIT_RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the current value
|
|
||||||
uint8_t currentValue = SPIreadRegister(reg);
|
uint8_t currentValue = SPIreadRegister(reg);
|
||||||
uint8_t mask = ~((0b11111111 << (msb + 1)) | (0b11111111 >> (8 - lsb)));
|
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);
|
uint8_t newValue = (currentValue & ~mask) | (value & mask);
|
||||||
SPIwriteRegister(reg, newValue);
|
SPIwriteRegister(reg, newValue);
|
||||||
|
|
||||||
|
@ -142,7 +134,7 @@ uint8_t Module::SPIreadRegister(uint32_t reg) {
|
||||||
return(resp);
|
return(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::SPIwriteRegisterBurst(uint32_t reg, const uint8_t* data, size_t numBytes) {
|
void Module::SPIwriteRegisterBurst(uint32_t reg, uint8_t* data, size_t numBytes) {
|
||||||
if(!spiConfig.stream) {
|
if(!spiConfig.stream) {
|
||||||
SPItransfer(spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE], reg, data, NULL, numBytes);
|
SPItransfer(spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE], reg, data, NULL, numBytes);
|
||||||
} else {
|
} else {
|
||||||
|
@ -174,7 +166,7 @@ void Module::SPIwriteRegister(uint32_t reg, uint8_t data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes) {
|
void Module::SPItransfer(uint16_t cmd, uint32_t reg, uint8_t* dataOut, uint8_t* dataIn, size_t numBytes) {
|
||||||
// prepare the buffers
|
// prepare the buffers
|
||||||
size_t buffLen = this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8 + numBytes;
|
size_t buffLen = this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8 + numBytes;
|
||||||
#if RADIOLIB_STATIC_ONLY
|
#if RADIOLIB_STATIC_ONLY
|
||||||
|
@ -216,7 +208,7 @@ void Module::SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uin
|
||||||
|
|
||||||
// print debug information
|
// print debug information
|
||||||
#if RADIOLIB_DEBUG_SPI
|
#if RADIOLIB_DEBUG_SPI
|
||||||
const uint8_t* debugBuffPtr = NULL;
|
uint8_t* debugBuffPtr = NULL;
|
||||||
if(cmd == spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE]) {
|
if(cmd == spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE]) {
|
||||||
RADIOLIB_DEBUG_SPI_PRINT("W\t%X\t", reg);
|
RADIOLIB_DEBUG_SPI_PRINT("W\t%X\t", reg);
|
||||||
debugBuffPtr = &buffOut[this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8];
|
debugBuffPtr = &buffOut[this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8];
|
||||||
|
@ -227,7 +219,7 @@ void Module::SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uin
|
||||||
for(size_t n = 0; n < numBytes; n++) {
|
for(size_t n = 0; n < numBytes; n++) {
|
||||||
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", debugBuffPtr[n]);
|
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", debugBuffPtr[n]);
|
||||||
}
|
}
|
||||||
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
|
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !RADIOLIB_STATIC_ONLY
|
#if !RADIOLIB_STATIC_ONLY
|
||||||
|
@ -245,7 +237,7 @@ int16_t Module::SPIreadStream(uint16_t cmd, uint8_t* data, size_t numBytes, bool
|
||||||
return(this->SPIreadStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, data, numBytes, waitForGpio, verify));
|
return(this->SPIreadStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, data, numBytes, waitForGpio, verify));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Module::SPIreadStream(const uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
|
int16_t Module::SPIreadStream(uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
|
||||||
// send the command
|
// send the command
|
||||||
int16_t state = this->SPItransferStream(cmd, cmdLen, false, NULL, data, numBytes, waitForGpio);
|
int16_t state = this->SPItransferStream(cmd, cmdLen, false, NULL, data, numBytes, waitForGpio);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
@ -264,7 +256,7 @@ int16_t Module::SPIreadStream(const uint8_t* cmd, uint8_t cmdLen, uint8_t* data,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Module::SPIwriteStream(uint16_t cmd, const uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
|
int16_t Module::SPIwriteStream(uint16_t cmd, uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
|
||||||
uint8_t cmdBuf[2];
|
uint8_t cmdBuf[2];
|
||||||
uint8_t* cmdPtr = cmdBuf;
|
uint8_t* cmdPtr = cmdBuf;
|
||||||
for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
|
for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
|
||||||
|
@ -273,7 +265,7 @@ int16_t Module::SPIwriteStream(uint16_t cmd, const uint8_t* data, size_t numByte
|
||||||
return(this->SPIwriteStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, data, numBytes, waitForGpio, verify));
|
return(this->SPIwriteStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, data, numBytes, waitForGpio, verify));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Module::SPIwriteStream(const uint8_t* cmd, uint8_t cmdLen, const uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
|
int16_t Module::SPIwriteStream(uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
|
||||||
// send the command
|
// send the command
|
||||||
int16_t state = this->SPItransferStream(cmd, cmdLen, true, data, NULL, numBytes, waitForGpio);
|
int16_t state = this->SPItransferStream(cmd, cmdLen, true, data, NULL, numBytes, waitForGpio);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
@ -315,9 +307,8 @@ int16_t Module::SPIcheckStream() {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio) {
|
int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio) {
|
||||||
// prepare the output buffer
|
// prepare the output buffer
|
||||||
int16_t state = RADIOLIB_ERR_NONE;
|
|
||||||
size_t buffLen = cmdLen + numBytes;
|
size_t buffLen = cmdLen + numBytes;
|
||||||
if(!write) {
|
if(!write) {
|
||||||
buffLen += (this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] / 8);
|
buffLen += (this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] / 8);
|
||||||
|
@ -349,9 +340,6 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
|
||||||
RadioLibTime_t start = this->hal->millis();
|
RadioLibTime_t start = this->hal->millis();
|
||||||
while(this->hal->digitalRead(this->gpioPin)) {
|
while(this->hal->digitalRead(this->gpioPin)) {
|
||||||
this->hal->yield();
|
this->hal->yield();
|
||||||
|
|
||||||
// this timeout check triggers a false positive from cppcheck
|
|
||||||
// cppcheck-suppress unsignedLessThanZero
|
|
||||||
if(this->hal->millis() - start >= this->spiConfig.timeout) {
|
if(this->hal->millis() - start >= this->spiConfig.timeout) {
|
||||||
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO pre-transfer timeout, is it connected?");
|
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO pre-transfer timeout, is it connected?");
|
||||||
#if !RADIOLIB_STATIC_ONLY
|
#if !RADIOLIB_STATIC_ONLY
|
||||||
|
@ -359,7 +347,6 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
|
||||||
#endif
|
#endif
|
||||||
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
|
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,23 +374,21 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
|
||||||
RadioLibTime_t start = this->hal->millis();
|
RadioLibTime_t start = this->hal->millis();
|
||||||
while(this->hal->digitalRead(this->gpioPin)) {
|
while(this->hal->digitalRead(this->gpioPin)) {
|
||||||
this->hal->yield();
|
this->hal->yield();
|
||||||
|
|
||||||
// this timeout check triggers a false positive from cppcheck
|
|
||||||
// cppcheck-suppress unsignedLessThanZero
|
|
||||||
if(this->hal->millis() - start >= this->spiConfig.timeout) {
|
if(this->hal->millis() - start >= this->spiConfig.timeout) {
|
||||||
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO post-transfer timeout, is it connected?");
|
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO post-transfer timeout, is it connected?");
|
||||||
|
#if !RADIOLIB_STATIC_ONLY
|
||||||
// do not return yet to display the debug output
|
delete[] buffOut;
|
||||||
state = RADIOLIB_ERR_SPI_CMD_TIMEOUT;
|
delete[] buffIn;
|
||||||
break;
|
#endif
|
||||||
|
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse status (only if GPIO did not timeout)
|
// parse status
|
||||||
if((state == RADIOLIB_ERR_NONE) && (this->spiConfig.parseStatusCb != nullptr) && (numBytes > 0)) {
|
int16_t state = RADIOLIB_ERR_NONE;
|
||||||
|
if((this->spiConfig.parseStatusCb != nullptr) && (numBytes > 0)) {
|
||||||
state = this->spiConfig.parseStatusCb(buffIn[this->spiConfig.statusPos]);
|
state = this->spiConfig.parseStatusCb(buffIn[this->spiConfig.statusPos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +411,7 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
|
||||||
for(; n < cmdLen; n++) {
|
for(; n < cmdLen; n++) {
|
||||||
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", cmd[n]);
|
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", cmd[n]);
|
||||||
}
|
}
|
||||||
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
|
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
|
||||||
|
|
||||||
// print data bytes
|
// print data bytes
|
||||||
RADIOLIB_DEBUG_SPI_PRINT("SI\t");
|
RADIOLIB_DEBUG_SPI_PRINT("SI\t");
|
||||||
|
@ -436,12 +421,12 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
|
||||||
for(; n < buffLen; n++) {
|
for(; n < buffLen; n++) {
|
||||||
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffOut[n]);
|
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffOut[n]);
|
||||||
}
|
}
|
||||||
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
|
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
|
||||||
RADIOLIB_DEBUG_SPI_PRINT("SO\t");
|
RADIOLIB_DEBUG_SPI_PRINT("SO\t");
|
||||||
for(n = 0; n < buffLen; n++) {
|
for(n = 0; n < buffLen; n++) {
|
||||||
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffIn[n]);
|
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffIn[n]);
|
||||||
}
|
}
|
||||||
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
|
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !RADIOLIB_STATIC_ONLY
|
#if !RADIOLIB_STATIC_ONLY
|
||||||
|
|
24
src/Module.h
24
src/Module.h
|
@ -272,10 +272,9 @@ class Module {
|
||||||
\param lsb Least significant bit of the register variable. Bits below this one will not be affected by the write operation.
|
\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 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 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
|
\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, bool force = false);
|
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);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief SPI burst read method.
|
\brief SPI burst read method.
|
||||||
|
@ -298,7 +297,7 @@ class Module {
|
||||||
\param data Pointer to array that holds the data that will be written.
|
\param data Pointer to array that holds the data that will be written.
|
||||||
\param numBytes Number of bytes that will be written.
|
\param numBytes Number of bytes that will be written.
|
||||||
*/
|
*/
|
||||||
void SPIwriteRegisterBurst(uint32_t reg, const uint8_t* data, size_t numBytes);
|
void SPIwriteRegisterBurst(uint32_t reg, uint8_t* data, size_t numBytes);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief SPI basic write method. Use of this method is reserved for special cases, SPIsetRegValue should be used instead.
|
\brief SPI basic write method. Use of this method is reserved for special cases, SPIsetRegValue should be used instead.
|
||||||
|
@ -315,7 +314,7 @@ class Module {
|
||||||
\param dataIn Data that was transferred from slave to master.
|
\param dataIn Data that was transferred from slave to master.
|
||||||
\param numBytes Number of bytes to transfer.
|
\param numBytes Number of bytes to transfer.
|
||||||
*/
|
*/
|
||||||
void SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes);
|
void SPItransfer(uint16_t cmd, uint32_t reg, uint8_t* dataOut, uint8_t* dataIn, size_t numBytes);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Method to check the result of last SPI stream transfer.
|
\brief Method to check the result of last SPI stream transfer.
|
||||||
|
@ -344,7 +343,7 @@ class Module {
|
||||||
\param verify Whether to verify the result of the transaction after it is finished.
|
\param verify Whether to verify the result of the transaction after it is finished.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t SPIreadStream(const uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
|
int16_t SPIreadStream(uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Method to perform a write transaction with SPI stream.
|
\brief Method to perform a write transaction with SPI stream.
|
||||||
|
@ -355,7 +354,7 @@ class Module {
|
||||||
\param verify Whether to verify the result of the transaction after it is finished.
|
\param verify Whether to verify the result of the transaction after it is finished.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t SPIwriteStream(uint16_t cmd, const uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
|
int16_t SPIwriteStream(uint16_t cmd, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Method to perform a write transaction with SPI stream.
|
\brief Method to perform a write transaction with SPI stream.
|
||||||
|
@ -367,7 +366,7 @@ class Module {
|
||||||
\param verify Whether to verify the result of the transaction after it is finished.
|
\param verify Whether to verify the result of the transaction after it is finished.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t SPIwriteStream(const uint8_t* cmd, uint8_t cmdLen, const uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
|
int16_t SPIwriteStream(uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief SPI single transfer method for modules with stream-type SPI interface (SX126x, SX128x etc.).
|
\brief SPI single transfer method for modules with stream-type SPI interface (SX126x, SX128x etc.).
|
||||||
|
@ -380,12 +379,15 @@ class Module {
|
||||||
\param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
|
\param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio);
|
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
|
// pin number access methods
|
||||||
// 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 SPI chip select.
|
||||||
|
\returns Pin number of SPI chip select configured in the constructor.
|
||||||
|
*/
|
||||||
|
uint32_t getCs() const { return(csPin); }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Access method to get the pin number of interrupt/GPIO.
|
\brief Access method to get the pin number of interrupt/GPIO.
|
||||||
|
|
|
@ -4,15 +4,24 @@
|
||||||
/*!
|
/*!
|
||||||
\mainpage RadioLib Documentation
|
\mainpage RadioLib Documentation
|
||||||
|
|
||||||
Universal wireless communication library for embedded devices.
|
Universal wireless communication library for Arduino.
|
||||||
|
|
||||||
\par Currently Supported Wireless Modules and Protocols
|
\par Currently Supported Wireless Modules and Protocols
|
||||||
|
- CC1101 FSK module
|
||||||
|
- RF69 FSK module
|
||||||
|
- Si443x FSK module
|
||||||
- SX126x LoRa/FSK module
|
- SX126x LoRa/FSK module
|
||||||
- SX127x LoRa/FSK module
|
- SX127x LoRa/FSK module
|
||||||
- SX128x LoRa/GFSK/BLE/FLRC module
|
- SX128x LoRa/GFSK/BLE/FLRC module
|
||||||
- SX1231 FSK module
|
- SX1231 FSK module
|
||||||
- PhysicalLayer protocols
|
- PhysicalLayer protocols
|
||||||
- POCSAG (PagerClient)
|
- RTTY (RTTYClient)
|
||||||
|
- Morse Code (MorseClient)
|
||||||
|
- AX.25 (AX25Client)
|
||||||
|
- SSTV (SSTVClient)
|
||||||
|
- Hellschreiber (HellClient)
|
||||||
|
- 4-FSK (FSK4Client)
|
||||||
|
- APRS (APRSClient)
|
||||||
|
|
||||||
\par Quick Links
|
\par Quick Links
|
||||||
Documentation for most common methods can be found in its reference page (see the list above).\n
|
Documentation for most common methods can be found in its reference page (see the list above).\n
|
||||||
|
@ -22,7 +31,6 @@
|
||||||
- PhysicalLayer - FSK and LoRa radio modules
|
- PhysicalLayer - FSK and LoRa radio modules
|
||||||
|
|
||||||
\see https://github.com/jgromes/RadioLib
|
\see https://github.com/jgromes/RadioLib
|
||||||
\see https://jgromes.github.io/RadioLib/coverage/src/index.html
|
|
||||||
|
|
||||||
\copyright Copyright (c) 2019 Jan Gromes
|
\copyright Copyright (c) 2019 Jan Gromes
|
||||||
*/
|
*/
|
||||||
|
@ -58,7 +66,18 @@
|
||||||
#warning "Low-end platform detected, stability issues are likely!"
|
#warning "Low-end platform detected, stability issues are likely!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "modules/CC1101/CC1101.h"
|
||||||
|
#include "modules/LLCC68/LLCC68.h"
|
||||||
|
#include "modules/LR11x0/LR1110.h"
|
||||||
|
#include "modules/LR11x0/LR1120.h"
|
||||||
|
#include "modules/LR11x0/LR1121.h"
|
||||||
|
#include "modules/nRF24/nRF24.h"
|
||||||
#include "modules/RF69/RF69.h"
|
#include "modules/RF69/RF69.h"
|
||||||
|
#include "modules/RFM2x/RFM22.h"
|
||||||
|
#include "modules/RFM2x/RFM23.h"
|
||||||
|
#include "modules/Si443x/Si4430.h"
|
||||||
|
#include "modules/Si443x/Si4431.h"
|
||||||
|
#include "modules/Si443x/Si4432.h"
|
||||||
#include "modules/SX123x/SX1231.h"
|
#include "modules/SX123x/SX1231.h"
|
||||||
#include "modules/SX123x/SX1233.h"
|
#include "modules/SX123x/SX1233.h"
|
||||||
#include "modules/SX126x/SX1261.h"
|
#include "modules/SX126x/SX1261.h"
|
||||||
|
@ -77,7 +96,19 @@
|
||||||
|
|
||||||
// physical layer protocols
|
// physical layer protocols
|
||||||
#include "protocols/PhysicalLayer/PhysicalLayer.h"
|
#include "protocols/PhysicalLayer/PhysicalLayer.h"
|
||||||
|
#include "protocols/AFSK/AFSK.h"
|
||||||
|
#include "protocols/AX25/AX25.h"
|
||||||
|
#include "protocols/Hellschreiber/Hellschreiber.h"
|
||||||
|
#include "protocols/Morse/Morse.h"
|
||||||
#include "protocols/Pager/Pager.h"
|
#include "protocols/Pager/Pager.h"
|
||||||
|
#include "protocols/RTTY/RTTY.h"
|
||||||
|
#include "protocols/SSTV/SSTV.h"
|
||||||
|
#include "protocols/FSK4/FSK4.h"
|
||||||
|
#include "protocols/APRS/APRS.h"
|
||||||
|
#include "protocols/ExternalRadio/ExternalRadio.h"
|
||||||
|
#include "protocols/Print/Print.h"
|
||||||
|
#include "protocols/BellModem/BellModem.h"
|
||||||
|
#include "protocols/LoRaWAN/LoRaWAN.h"
|
||||||
|
|
||||||
// utilities
|
// utilities
|
||||||
#include "utils/CRC.h"
|
#include "utils/CRC.h"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// this example only works on ESP32 and is unlikely to work on ESP32S2/S3 etc.
|
// 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 you need high portability, you should probably use Arduino anyway ...
|
||||||
#if CONFIG_IDF_TARGET_ESP32 == 0
|
#if CONFIG_IDF_TARGET_ESP32 == 0
|
||||||
#error This example HAL only supports ESP32 targets. Support for ESP32S2/S3 etc. can be added by adjusting this file to user needs.
|
#error Target is not ESP32!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// include all the dependencies
|
// include all the dependencies
|
225
src/hal/Tock/libtockHal.h
Normal file
225
src/hal/Tock/libtockHal.h
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
RadioLib Non-Arduino Tock Library helper functions
|
||||||
|
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
|
||||||
|
|
||||||
|
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 <RadioLib.h>
|
||||||
|
|
||||||
|
// 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
|
|
@ -2,26 +2,99 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#if !RADIOLIB_EXCLUDE_CC1101
|
#if !RADIOLIB_EXCLUDE_CC1101
|
||||||
|
|
||||||
CC1101::CC1101(Module* module) : PhysicalLayer() {
|
CC1101::CC1101(Module* module) : PhysicalLayer(RADIOLIB_CC1101_FREQUENCY_STEP_SIZE, RADIOLIB_CC1101_MAX_PACKET_LENGTH) {
|
||||||
this->freqStep = RADIOLIB_CC1101_FREQUENCY_STEP_SIZE;
|
|
||||||
this->maxPacketLength = RADIOLIB_CC1101_MAX_PACKET_LENGTH;
|
|
||||||
this->mod = module;
|
this->mod = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::begin(float freq, float br, float freqDev, float rxBw, int8_t pwr, uint8_t preambleLength) {
|
int16_t CC1101::begin(float freq, float br, float freqDev, float rxBw, int8_t pwr, uint8_t preambleLength) {
|
||||||
// set the modulation and execute the common part
|
// set module properties
|
||||||
this->modulation = RADIOLIB_CC1101_MOD_FORMAT_2_FSK;
|
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_CC1101_CMD_READ;
|
||||||
return(this->beginCommon(freq, br, freqDev, rxBw, pwr, preambleLength));
|
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);
|
||||||
|
|
||||||
int16_t CC1101::beginFSK4(float freq, float br, float freqDev, float rxBw, int8_t pwr, uint8_t preambleLength) {
|
// try to find the CC1101 chip
|
||||||
// set the modulation and execute the common part
|
uint8_t i = 0;
|
||||||
this->modulation = RADIOLIB_CC1101_MOD_FORMAT_4_FSK;
|
bool flagFound = false;
|
||||||
return(this->beginCommon(freq, br, freqDev, rxBw, pwr, preambleLength));
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CC1101::reset() {
|
void CC1101::reset() {
|
||||||
// just send the command, the reset sequence as described in datasheet seems unnecessary in our usage
|
// 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);
|
||||||
SPIsendCommand(RADIOLIB_CC1101_CMD_RESET);
|
SPIsendCommand(RADIOLIB_CC1101_CMD_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +133,7 @@ int16_t CC1101::transmit(const uint8_t* data, size_t len, uint8_t addr) {
|
||||||
|
|
||||||
int16_t CC1101::receive(uint8_t* data, size_t len) {
|
int16_t CC1101::receive(uint8_t* data, size_t len) {
|
||||||
// calculate timeout (500 ms + 400 full max-length packets at current bit rate)
|
// calculate timeout (500 ms + 400 full max-length packets at current bit rate)
|
||||||
RadioLibTime_t timeout = 500 + (1.0f/(this->bitRate))*(RADIOLIB_CC1101_MAX_PACKET_LENGTH*400.0f);
|
RadioLibTime_t timeout = 500 + (1.0/(this->bitRate))*(RADIOLIB_CC1101_MAX_PACKET_LENGTH*400.0);
|
||||||
|
|
||||||
// start reception
|
// start reception
|
||||||
int16_t state = startReceive();
|
int16_t state = startReceive();
|
||||||
|
@ -118,12 +191,6 @@ int16_t CC1101::standby(uint8_t mode) {
|
||||||
return(standby());
|
return(standby());
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::sleep() {
|
|
||||||
int16_t state =standby();
|
|
||||||
SPIsendCommand(RADIOLIB_CC1101_CMD_POWER_DOWN);
|
|
||||||
return(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t CC1101::transmitDirect(uint32_t frf) {
|
int16_t CC1101::transmitDirect(uint32_t frf) {
|
||||||
return transmitDirect(true, frf);
|
return transmitDirect(true, frf);
|
||||||
}
|
}
|
||||||
|
@ -238,50 +305,23 @@ int16_t CC1101::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
|
||||||
// flush Tx FIFO
|
// flush Tx FIFO
|
||||||
SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX);
|
SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX);
|
||||||
|
|
||||||
// Turn on freq oscilator
|
// set GDO0 mapping
|
||||||
SPIsendCommand(RADIOLIB_CC1101_CMD_FSTXON);
|
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED, 5, 0);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
// Check MARCSTATE and wait until ready to tx
|
|
||||||
// 724us is the longest time for calibrate per datasheet
|
|
||||||
// Needs a bit more time for reliability
|
|
||||||
RadioLibTime_t start = this->mod->hal->micros();
|
|
||||||
while(SPIgetRegValue(RADIOLIB_CC1101_REG_MARCSTATE, 4, 0) != 0x12) {
|
|
||||||
if(this->mod->hal->micros() - start > 800) {
|
|
||||||
standby();
|
|
||||||
return(RADIOLIB_ERR_TX_TIMEOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set GDO0 mapping only if we aren't refilling the FIFO
|
|
||||||
int16_t state = RADIOLIB_ERR_NONE;
|
|
||||||
if(len <= RADIOLIB_CC1101_FIFO_SIZE) {
|
|
||||||
state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED, 5, 0);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// data put on FIFO
|
|
||||||
uint8_t dataSent = 0;
|
|
||||||
|
|
||||||
// optionally write packet length
|
// optionally write packet length
|
||||||
if(this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) {
|
if(this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) {
|
||||||
if (len > RADIOLIB_CC1101_MAX_PACKET_LENGTH - 1) {
|
|
||||||
return(RADIOLIB_ERR_PACKET_TOO_LONG);
|
|
||||||
}
|
|
||||||
SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, len);
|
SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, len);
|
||||||
dataSent+= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check address filtering
|
// check address filtering
|
||||||
uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0);
|
uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0);
|
||||||
if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) {
|
if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) {
|
||||||
SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, addr);
|
SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, addr);
|
||||||
dataSent += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill the FIFO
|
// fill the FIFO
|
||||||
uint8_t initialWrite = RADIOLIB_MIN((uint8_t)len, (uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - dataSent));
|
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast<uint8_t*>(data), len);
|
||||||
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast<uint8_t*>(data), initialWrite);
|
|
||||||
dataSent += initialWrite;
|
|
||||||
|
|
||||||
// set RF switch (if present)
|
// set RF switch (if present)
|
||||||
this->mod->setRfSwitchState(Module::MODE_TX);
|
this->mod->setRfSwitchState(Module::MODE_TX);
|
||||||
|
@ -289,40 +329,11 @@ int16_t CC1101::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
|
||||||
// set mode to transmit
|
// set mode to transmit
|
||||||
SPIsendCommand(RADIOLIB_CC1101_CMD_TX);
|
SPIsendCommand(RADIOLIB_CC1101_CMD_TX);
|
||||||
|
|
||||||
// Keep feeding the FIFO until the packet is done
|
|
||||||
while (dataSent < len) {
|
|
||||||
uint8_t fifoBytes = 0;
|
|
||||||
uint8_t prevFifobytes = 0;
|
|
||||||
|
|
||||||
// Check number of bytes on FIFO twice due to the CC1101 errata. Block until two reads are equal.
|
|
||||||
do{
|
|
||||||
fifoBytes = SPIgetRegValue(RADIOLIB_CC1101_REG_TXBYTES, 6, 0);
|
|
||||||
prevFifobytes = SPIgetRegValue(RADIOLIB_CC1101_REG_TXBYTES, 6, 0);
|
|
||||||
} while (fifoBytes != prevFifobytes);
|
|
||||||
|
|
||||||
//If there is room add more data to the FIFO
|
|
||||||
if (fifoBytes < RADIOLIB_CC1101_FIFO_SIZE) {
|
|
||||||
uint8_t bytesToWrite = RADIOLIB_MIN((uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - fifoBytes), (uint8_t)(len - dataSent));
|
|
||||||
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast<uint8_t*>(&data[dataSent]), bytesToWrite);
|
|
||||||
dataSent += bytesToWrite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::finishTransmit() {
|
int16_t CC1101::finishTransmit() {
|
||||||
// set mode to standby to disable transmitter/RF switch
|
// set mode to standby to disable transmitter/RF switch
|
||||||
|
|
||||||
// Check MARCSTATE for Idle to let anything in the FIFO empty
|
|
||||||
// Timeout is 2x FIFO transmit time
|
|
||||||
RadioLibTime_t timeout = (1.0f/(this->bitRate))*(RADIOLIB_CC1101_FIFO_SIZE*2.0f);
|
|
||||||
RadioLibTime_t start = this->mod->hal->millis();
|
|
||||||
while(SPIgetRegValue(RADIOLIB_CC1101_REG_MARCSTATE, 4, 0) != 0x01) {
|
|
||||||
if(this->mod->hal->millis() - start > timeout) {
|
|
||||||
return(RADIOLIB_ERR_TX_TIMEOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t state = standby();
|
int16_t state = standby();
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
@ -418,9 +429,9 @@ int16_t CC1101::readData(uint8_t* data, size_t len) {
|
||||||
int16_t CC1101::setFrequency(float freq) {
|
int16_t CC1101::setFrequency(float freq) {
|
||||||
// check allowed frequency range
|
// check allowed frequency range
|
||||||
#if RADIOLIB_CHECK_PARAMS
|
#if RADIOLIB_CHECK_PARAMS
|
||||||
if(!(((freq >= 300.0f) && (freq <= 348.0f)) ||
|
if(!(((freq >= 300.0) && (freq <= 348.0)) ||
|
||||||
((freq >= 387.0f) && (freq <= 464.0f)) ||
|
((freq >= 387.0) && (freq <= 464.0)) ||
|
||||||
((freq >= 779.0f) && (freq <= 928.0f)))) {
|
((freq >= 779.0) && (freq <= 928.0)))) {
|
||||||
return(RADIOLIB_ERR_INVALID_FREQUENCY);
|
return(RADIOLIB_ERR_INVALID_FREQUENCY);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -430,7 +441,7 @@ int16_t CC1101::setFrequency(float freq) {
|
||||||
|
|
||||||
//set carrier frequency
|
//set carrier frequency
|
||||||
uint32_t base = 1;
|
uint32_t base = 1;
|
||||||
uint32_t FRF = (freq * (base << 16)) / 26.0f;
|
uint32_t FRF = (freq * (base << 16)) / 26.0;
|
||||||
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ2, (FRF & 0xFF0000) >> 16, 7, 0);
|
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ2, (FRF & 0xFF0000) >> 16, 7, 0);
|
||||||
state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ1, (FRF & 0x00FF00) >> 8, 7, 0);
|
state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ1, (FRF & 0x00FF00) >> 8, 7, 0);
|
||||||
state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ0, FRF & 0x0000FF, 7, 0);
|
state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ0, FRF & 0x0000FF, 7, 0);
|
||||||
|
@ -444,7 +455,7 @@ int16_t CC1101::setFrequency(float freq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::setBitRate(float br) {
|
int16_t CC1101::setBitRate(float br) {
|
||||||
RADIOLIB_CHECK_RANGE(br, 0.025f, 600.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
|
RADIOLIB_CHECK_RANGE(br, 0.025, 600.0, RADIOLIB_ERR_INVALID_BIT_RATE);
|
||||||
|
|
||||||
// set mode to standby
|
// set mode to standby
|
||||||
SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE);
|
SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE);
|
||||||
|
@ -452,7 +463,7 @@ int16_t CC1101::setBitRate(float br) {
|
||||||
// calculate exponent and mantissa values
|
// calculate exponent and mantissa values
|
||||||
uint8_t e = 0;
|
uint8_t e = 0;
|
||||||
uint8_t m = 0;
|
uint8_t m = 0;
|
||||||
getExpMant(br * 1000.0f, 256, 28, 14, e, m);
|
getExpMant(br * 1000.0, 256, 28, 14, e, m);
|
||||||
|
|
||||||
// set bit rate value
|
// set bit rate value
|
||||||
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, e, 3, 0);
|
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, e, 3, 0);
|
||||||
|
@ -473,7 +484,7 @@ int16_t CC1101::setBitRateTolerance(uint8_t brt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::setRxBandwidth(float rxBw) {
|
int16_t CC1101::setRxBandwidth(float rxBw) {
|
||||||
RADIOLIB_CHECK_RANGE(rxBw, 58.0f, 812.0f, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
|
RADIOLIB_CHECK_RANGE(rxBw, 58.0, 812.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
|
||||||
|
|
||||||
// set mode to standby
|
// set mode to standby
|
||||||
SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE);
|
SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE);
|
||||||
|
@ -481,8 +492,8 @@ int16_t CC1101::setRxBandwidth(float rxBw) {
|
||||||
// calculate exponent and mantissa values
|
// calculate exponent and mantissa values
|
||||||
for(int8_t e = 3; e >= 0; e--) {
|
for(int8_t e = 3; e >= 0; e--) {
|
||||||
for(int8_t m = 3; m >= 0; m --) {
|
for(int8_t m = 3; m >= 0; m --) {
|
||||||
float point = (RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0f)/(8 * (m + 4) * ((uint32_t)1 << e));
|
float point = (RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0)/(8 * (m + 4) * ((uint32_t)1 << e));
|
||||||
if(fabs((rxBw * 1000.0f - point) <= 1000.0f)) {
|
if(fabs((rxBw * 1000.0) - point) <= 1000) {
|
||||||
// set Rx channel filter bandwidth
|
// set Rx channel filter bandwidth
|
||||||
return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, (e << 6) | (m << 4), 7, 4));
|
return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, (e << 6) | (m << 4), 7, 4));
|
||||||
}
|
}
|
||||||
|
@ -494,33 +505,33 @@ int16_t CC1101::setRxBandwidth(float rxBw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::autoSetRxBandwidth() {
|
int16_t CC1101::autoSetRxBandwidth() {
|
||||||
// Uncertainty ~ +/- 40ppm for a cheap CC1101
|
// Uncertainty ~ +/- 40ppm for a cheap CC1101
|
||||||
// Uncertainty * 2 for both transmitter and receiver
|
// Uncertainty * 2 for both transmitter and receiver
|
||||||
float uncertainty = ((this->frequency) * 40 * 2);
|
float uncertainty = ((this->frequency) * 40 * 2);
|
||||||
uncertainty = (uncertainty/1000); //Since bitrate is in kBit
|
uncertainty = (uncertainty/1000); //Since bitrate is in kBit
|
||||||
float minbw = ((this->bitRate) + uncertainty);
|
float minbw = ((this->bitRate) + uncertainty);
|
||||||
|
|
||||||
const int options[16] = { 58, 68, 81, 102, 116, 135, 162, 203, 232, 270, 325, 406, 464, 541, 650, 812 };
|
int possibles[16] = {58, 68, 81, 102, 116, 135, 162, 203, 232, 270, 325, 406, 464, 541, 650, 812};
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if(options[i] > minbw) {
|
if (possibles[i] > minbw) {
|
||||||
return(setRxBandwidth(options[i]));
|
int16_t state = setRxBandwidth(possibles[i]);
|
||||||
|
return(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return(RADIOLIB_ERR_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(RADIOLIB_ERR_UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t CC1101::setFrequencyDeviation(float freqDev) {
|
int16_t CC1101::setFrequencyDeviation(float freqDev) {
|
||||||
// set frequency deviation to lowest available setting (required for digimodes)
|
// set frequency deviation to lowest available setting (required for digimodes)
|
||||||
float newFreqDev = freqDev;
|
float newFreqDev = freqDev;
|
||||||
if(freqDev < 0.0f) {
|
if(freqDev < 0.0) {
|
||||||
newFreqDev = 1.587f;
|
newFreqDev = 1.587;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check range unless 0 (special value)
|
// check range unless 0 (special value)
|
||||||
if (freqDev != 0) {
|
if (freqDev != 0) {
|
||||||
RADIOLIB_CHECK_RANGE(newFreqDev, 1.587f, 380.8f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
RADIOLIB_CHECK_RANGE(newFreqDev, 1.587, 380.8, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set mode to standby
|
// set mode to standby
|
||||||
|
@ -529,7 +540,7 @@ int16_t CC1101::setFrequencyDeviation(float freqDev) {
|
||||||
// calculate exponent and mantissa values
|
// calculate exponent and mantissa values
|
||||||
uint8_t e = 0;
|
uint8_t e = 0;
|
||||||
uint8_t m = 0;
|
uint8_t m = 0;
|
||||||
getExpMant(newFreqDev * 1000.0f, 8, 17, 7, e, m);
|
getExpMant(newFreqDev * 1000.0, 8, 17, 7, e, m);
|
||||||
|
|
||||||
// set frequency deviation value
|
// set frequency deviation value
|
||||||
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_DEVIATN, (e << 4), 6, 4);
|
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_DEVIATN, (e << 4), 6, 4);
|
||||||
|
@ -558,7 +569,7 @@ int16_t CC1101::getFrequencyDeviation(float *freqDev) {
|
||||||
//
|
//
|
||||||
// freqDev = (fXosc / 2^17) * (8 + m) * 2^e
|
// freqDev = (fXosc / 2^17) * (8 + m) * 2^e
|
||||||
//
|
//
|
||||||
*freqDev = (1000.0f / (uint32_t(1) << 17)) - (8 + m) * (uint32_t(1) << e);
|
*freqDev = (1000.0 / (uint32_t(1) << 17)) - (8 + m) * (uint32_t(1) << e);
|
||||||
|
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
@ -577,7 +588,7 @@ int16_t CC1101::setOutputPower(int8_t pwr) {
|
||||||
// PA_TABLE[0] is the power to be used when transmitting a 0 (no power)
|
// PA_TABLE[0] is the power to be used when transmitting a 0 (no power)
|
||||||
// PA_TABLE[1] is the power to be used when transmitting a 1 (full power)
|
// PA_TABLE[1] is the power to be used when transmitting a 1 (full power)
|
||||||
|
|
||||||
const uint8_t paValues[2] = { 0x00, powerRaw };
|
uint8_t paValues[2] = {0x00, powerRaw};
|
||||||
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_PATABLE, paValues, 2);
|
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_PATABLE, paValues, 2);
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
|
@ -622,13 +633,13 @@ int16_t CC1101::checkOutputPower(int8_t power, int8_t* clipped, uint8_t* raw) {
|
||||||
|
|
||||||
// round to the known frequency settings
|
// round to the known frequency settings
|
||||||
uint8_t f;
|
uint8_t f;
|
||||||
if(this->frequency < 374.0f) {
|
if(this->frequency < 374.0) {
|
||||||
// 315 MHz
|
// 315 MHz
|
||||||
f = 0;
|
f = 0;
|
||||||
} else if(this->frequency < 650.5f) {
|
} else if(this->frequency < 650.5) {
|
||||||
// 434 MHz
|
// 434 MHz
|
||||||
f = 1;
|
f = 1;
|
||||||
} else if(this->frequency < 891.5f) {
|
} else if(this->frequency < 891.5) {
|
||||||
// 868 MHz
|
// 868 MHz
|
||||||
f = 2;
|
f = 2;
|
||||||
} else {
|
} else {
|
||||||
|
@ -656,7 +667,7 @@ int16_t CC1101::checkOutputPower(int8_t power, int8_t* clipped, uint8_t* raw) {
|
||||||
return(RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
return(RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CC1101::setSyncWord(const uint8_t* syncWord, uint8_t len, uint8_t maxErrBits, bool requireCarrierSense) {
|
int16_t CC1101::setSyncWord(uint8_t* syncWord, uint8_t len, uint8_t maxErrBits, bool requireCarrierSense) {
|
||||||
if((maxErrBits > 1) || (len != 2)) {
|
if((maxErrBits > 1) || (len != 2)) {
|
||||||
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
||||||
}
|
}
|
||||||
|
@ -781,9 +792,9 @@ float CC1101::getRSSI() {
|
||||||
|
|
||||||
if(!this->directModeEnabled) {
|
if(!this->directModeEnabled) {
|
||||||
if(this->rawRSSI >= 128) {
|
if(this->rawRSSI >= 128) {
|
||||||
rssi = (((float)this->rawRSSI - 256.0f)/2.0f) - 74.0f;
|
rssi = (((float)this->rawRSSI - 256.0)/2.0) - 74.0;
|
||||||
} else {
|
} else {
|
||||||
rssi = (((float)this->rawRSSI)/2.0f) - 74.0f;
|
rssi = (((float)this->rawRSSI)/2.0) - 74.0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint8_t rawRssi = SPIreadRegister(RADIOLIB_CC1101_REG_RSSI);
|
uint8_t rawRssi = SPIreadRegister(RADIOLIB_CC1101_REG_RSSI);
|
||||||
|
@ -911,7 +922,7 @@ int16_t CC1101::setDataShaping(uint8_t sh) {
|
||||||
// set data shaping
|
// set data shaping
|
||||||
switch(sh) {
|
switch(sh) {
|
||||||
case RADIOLIB_SHAPING_NONE:
|
case RADIOLIB_SHAPING_NONE:
|
||||||
state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, this->modulation, 6, 4);
|
state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_2_FSK, 6, 4);
|
||||||
break;
|
break;
|
||||||
case RADIOLIB_SHAPING_0_5:
|
case RADIOLIB_SHAPING_0_5:
|
||||||
state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_GFSK, 6, 4);
|
state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_GFSK, 6, 4);
|
||||||
|
@ -995,87 +1006,6 @@ int16_t CC1101::setDIOMapping(uint32_t pin, uint32_t value) {
|
||||||
return(SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0 - pin, 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
|
|
||||||
const 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() {
|
int16_t CC1101::config() {
|
||||||
// Reset the radio. Registers may be dirty from previous usage.
|
// Reset the radio. Registers may be dirty from previous usage.
|
||||||
reset();
|
reset();
|
||||||
|
@ -1128,7 +1058,7 @@ int16_t CC1101::directMode(bool sync) {
|
||||||
|
|
||||||
void CC1101::getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant) {
|
void CC1101::getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant) {
|
||||||
// get table origin point (exp = 0, mant = 0)
|
// get table origin point (exp = 0, mant = 0)
|
||||||
float origin = (mantOffset * RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0f)/((uint32_t)1 << divExp);
|
float origin = (mantOffset * RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0)/((uint32_t)1 << divExp);
|
||||||
|
|
||||||
// iterate over possible exponent values
|
// iterate over possible exponent values
|
||||||
for(int8_t e = expMax; e >= 0; e--) {
|
for(int8_t e = expMax; e >= 0; e--) {
|
||||||
|
@ -1219,12 +1149,26 @@ void CC1101::SPIwriteRegister(uint8_t reg, uint8_t data) {
|
||||||
return(this->mod->SPIwriteRegister(reg, data));
|
return(this->mod->SPIwriteRegister(reg, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CC1101::SPIwriteRegisterBurst(uint8_t reg, const uint8_t* data, size_t len) {
|
void CC1101::SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, size_t len) {
|
||||||
this->mod->SPIwriteRegisterBurst(reg | RADIOLIB_CC1101_CMD_BURST, data, len);
|
this->mod->SPIwriteRegisterBurst(reg | RADIOLIB_CC1101_CMD_BURST, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CC1101::SPIsendCommand(uint8_t cmd) {
|
void CC1101::SPIsendCommand(uint8_t cmd) {
|
||||||
this->mod->SPItransferStream(&cmd, 1, true, NULL, NULL, 0, false);
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,9 +8,8 @@
|
||||||
|
|
||||||
// CC1101 physical layer properties
|
// CC1101 physical layer properties
|
||||||
#define RADIOLIB_CC1101_FREQUENCY_STEP_SIZE 396.7285156
|
#define RADIOLIB_CC1101_FREQUENCY_STEP_SIZE 396.7285156
|
||||||
#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 255
|
#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 63
|
||||||
#define RADIOLIB_CC1101_FIFO_SIZE 64
|
#define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0
|
||||||
#define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0f
|
|
||||||
#define RADIOLIB_CC1101_DIV_EXPONENT 16
|
#define RADIOLIB_CC1101_DIV_EXPONENT 16
|
||||||
|
|
||||||
// CC1101 SPI commands
|
// CC1101 SPI commands
|
||||||
|
@ -192,6 +191,9 @@
|
||||||
// RADIOLIB_CC1101_REG_SYNC0
|
// RADIOLIB_CC1101_REG_SYNC0
|
||||||
#define RADIOLIB_CC1101_SYNC_WORD_LSB 0x91 // 7 0 sync word LSB
|
#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
|
// RADIOLIB_CC1101_REG_PKTCTRL1
|
||||||
#define RADIOLIB_CC1101_PQT 0x00 // 7 5 preamble quality threshold
|
#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)
|
#define RADIOLIB_CC1101_CRC_AUTOFLUSH_OFF 0b00000000 // 3 3 automatic Rx FIFO flush on CRC check fail: disabled (default)
|
||||||
|
@ -560,24 +562,6 @@ class CC1101: public PhysicalLayer {
|
||||||
int8_t pwr = RADIOLIB_CC1101_DEFAULT_POWER,
|
int8_t pwr = RADIOLIB_CC1101_DEFAULT_POWER,
|
||||||
uint8_t preambleLength = RADIOLIB_CC1101_DEFAULT_PREAMBLELEN);
|
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).
|
\brief Reset method - resets the chip using manual reset sequence (without RESET pin).
|
||||||
*/
|
*/
|
||||||
|
@ -615,12 +599,6 @@ class CC1101: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
int16_t standby(uint8_t mode) override;
|
int16_t standby(uint8_t mode) override;
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Sets the module to sleep mode.
|
|
||||||
\returns \ref status_codes
|
|
||||||
*/
|
|
||||||
int16_t sleep() override;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Starts synchronous direct mode transmission.
|
\brief Starts synchronous direct mode transmission.
|
||||||
\param frf Raw RF frequency value. Defaults to 0, required for quick frequency shifts in RTTY.
|
\param frf Raw RF frequency value. Defaults to 0, required for quick frequency shifts in RTTY.
|
||||||
|
@ -702,10 +680,7 @@ class CC1101: public PhysicalLayer {
|
||||||
void clearPacketSentAction() override;
|
void clearPacketSentAction() override;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Interrupt-driven binary transmit method for packets less than 64 bytes.
|
\brief Interrupt-driven binary transmit method.
|
||||||
Method blocks for packets longer than 64 bytes up to a 255 byte limit, until
|
|
||||||
the last bytes are placed in the FIFO. Some limitations and issues apply; see discussion:
|
|
||||||
https://github.com/jgromes/RadioLib/discussions/1138
|
|
||||||
Overloads for string-based transmissions are implemented in PhysicalLayer.
|
Overloads for string-based transmissions are implemented in PhysicalLayer.
|
||||||
\param data Binary data to be sent.
|
\param data Binary data to be sent.
|
||||||
\param len Number of bytes to send.
|
\param len Number of bytes to send.
|
||||||
|
@ -843,7 +818,7 @@ class CC1101: public PhysicalLayer {
|
||||||
\param requireCarrierSense Require carrier sense above threshold in addition to sync word.
|
\param requireCarrierSense Require carrier sense above threshold in addition to sync word.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t setSyncWord(const uint8_t* syncWord, uint8_t len, uint8_t maxErrBits = 0, bool requireCarrierSense = false);
|
int16_t setSyncWord(uint8_t* syncWord, uint8_t len, uint8_t maxErrBits = 0, bool requireCarrierSense = false);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets preamble length.
|
\brief Sets preamble length.
|
||||||
|
@ -1013,7 +988,7 @@ class CC1101: public PhysicalLayer {
|
||||||
int16_t SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0, uint8_t checkInterval = 2);
|
int16_t SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0, uint8_t checkInterval = 2);
|
||||||
void SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes);
|
void SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes);
|
||||||
uint8_t SPIreadRegister(uint8_t reg);
|
uint8_t SPIreadRegister(uint8_t reg);
|
||||||
void SPIwriteRegisterBurst(uint8_t reg, const uint8_t* data, size_t len);
|
void SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, size_t len);
|
||||||
void SPIwriteRegister(uint8_t reg, uint8_t data);
|
void SPIwriteRegister(uint8_t reg, uint8_t data);
|
||||||
|
|
||||||
void SPIsendCommand(uint8_t cmd);
|
void SPIsendCommand(uint8_t cmd);
|
||||||
|
@ -1039,7 +1014,6 @@ class CC1101: public PhysicalLayer {
|
||||||
|
|
||||||
int8_t power = RADIOLIB_CC1101_DEFAULT_POWER;
|
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 config();
|
||||||
int16_t transmitDirect(bool sync, uint32_t frf);
|
int16_t transmitDirect(bool sync, uint32_t frf);
|
||||||
int16_t receiveDirect(bool sync);
|
int16_t receiveDirect(bool sync);
|
||||||
|
|
|
@ -9,13 +9,6 @@ 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) {
|
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
|
// execute common part
|
||||||
int16_t state = SX126x::begin(cr, syncWord, preambleLength, tcxoVoltage, useRegulatorLDO);
|
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);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// configure publicly accessible settings
|
// configure publicly accessible settings
|
||||||
|
@ -37,58 +30,8 @@ int16_t LLCC68::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LLCC68::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) {
|
|
||||||
// execute common part
|
|
||||||
int16_t state = SX126x::beginFSK(br, freqDev, rxBw, 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::beginFSK(br, freqDev, rxBw, preambleLength, tcxoVoltage, useRegulatorLDO);
|
|
||||||
RADIOLIB_DEBUG_PRINTLN("LLCC68 version string not found, using SX1261 instead");
|
|
||||||
}
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// configure publicly accessible settings
|
|
||||||
state = setFrequency(freq);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
state = SX126x::fixPaClamping();
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
state = setOutputPower(power);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
return(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t LLCC68::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, bool narrowGrid, int8_t power, float tcxoVoltage, bool useRegulatorLDO) {
|
|
||||||
// execute common part
|
|
||||||
int16_t state = SX126x::beginLRFHSS(bw, cr, narrowGrid, 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::beginLRFHSS(bw, cr, narrowGrid, tcxoVoltage, useRegulatorLDO);
|
|
||||||
RADIOLIB_DEBUG_PRINTLN("LLCC68 version string not found, using SX1261 instead");
|
|
||||||
}
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// configure publicly accessible settings
|
|
||||||
state = setFrequency(freq);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
state = SX126x::fixPaClamping();
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
state = setOutputPower(power);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
return(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t LLCC68::setBandwidth(float bw) {
|
int16_t LLCC68::setBandwidth(float bw) {
|
||||||
RADIOLIB_CHECK_RANGE(bw, 100.0f, 510.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
RADIOLIB_CHECK_RANGE(bw, 100.0, 510.0, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
||||||
return(SX1262::setBandwidth(bw));
|
return(SX1262::setBandwidth(bw));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,14 +88,14 @@ int16_t LLCC68::checkDataRate(DataRate_t dr) {
|
||||||
// select interpretation based on active modem
|
// select interpretation based on active modem
|
||||||
uint8_t modem = this->getPacketType();
|
uint8_t modem = this->getPacketType();
|
||||||
if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
|
if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
|
||||||
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
|
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
|
||||||
RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6, 200.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
|
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
|
||||||
RADIOLIB_CHECK_RANGE(dr.lora.bandwidth, 100.0f, 510.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
RADIOLIB_CHECK_RANGE(dr.lora.bandwidth, 100.0, 510.0, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
||||||
RADIOLIB_CHECK_RANGE(dr.lora.codingRate, 5, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
|
RADIOLIB_CHECK_RANGE(dr.lora.codingRate, 5, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
|
||||||
uint8_t bw_div2 = dr.lora.bandwidth / 2 + 0.01f;
|
uint8_t bw_div2 = dr.lora.bandwidth / 2 + 0.01;
|
||||||
switch (bw_div2) {
|
switch (bw_div2) {
|
||||||
case 62: // 125.0:
|
case 62: // 125.0:
|
||||||
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 5, 9, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
|
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 5, 9, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
|
||||||
|
@ -175,13 +118,13 @@ int16_t LLCC68::checkDataRate(DataRate_t dr) {
|
||||||
|
|
||||||
int16_t LLCC68::setModem(ModemType_t modem) {
|
int16_t LLCC68::setModem(ModemType_t modem) {
|
||||||
switch(modem) {
|
switch(modem) {
|
||||||
case(ModemType_t::RADIOLIB_MODEM_LORA): {
|
case(ModemType_t::LoRa): {
|
||||||
return(this->begin());
|
return(this->begin());
|
||||||
} break;
|
} break;
|
||||||
case(ModemType_t::RADIOLIB_MODEM_FSK): {
|
case(ModemType_t::FSK): {
|
||||||
return(this->beginFSK());
|
return(this->beginFSK());
|
||||||
} break;
|
} break;
|
||||||
case(ModemType_t::RADIOLIB_MODEM_LRFHSS): {
|
case(ModemType_t::LRFHSS): {
|
||||||
return(this->beginLRFHSS());
|
return(this->beginLRFHSS());
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#include "../../Module.h"
|
#include "../../Module.h"
|
||||||
#include "../SX126x/SX1262.h"
|
#include "../SX126x/SX1262.h"
|
||||||
#include "../SX126x/SX1261.h"
|
|
||||||
|
|
||||||
//RADIOLIB_SX126X_REG_VERSION_STRING
|
//RADIOLIB_SX126X_REG_VERSION_STRING
|
||||||
#define RADIOLIB_LLCC68_CHIP_TYPE "LLCC68"
|
#define RADIOLIB_LLCC68_CHIP_TYPE "LLCC68"
|
||||||
|
@ -39,38 +38,7 @@ class LLCC68: public SX1262 {
|
||||||
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
|
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX126X_SYNC_WORD_PRIVATE, int8_t power = 10, uint16_t preambleLength = 8, float tcxoVoltage = 0, bool useRegulatorLDO = false) override;
|
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX126X_SYNC_WORD_PRIVATE, int8_t pwr = 10, uint16_t preambleLength = 8, float tcxoVoltage = 0, bool useRegulatorLDO = false);
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Initialization method for FSK modem.
|
|
||||||
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
|
|
||||||
\param br FSK bit rate 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 156.2 kHz.
|
|
||||||
\param power Output power in dBm. Defaults to 10 dBm.
|
|
||||||
\param preambleLength FSK preamble length in bits. Defaults to 16 bits.
|
|
||||||
\param tcxoVoltage TCXO reference voltage to be set on DIO3. Defaults to 0 V (XTAL).
|
|
||||||
If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL.
|
|
||||||
To use XTAL, either set this value to 0, or set SX126x::XTAL to true.
|
|
||||||
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
|
|
||||||
\returns \ref status_codes
|
|
||||||
*/
|
|
||||||
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 156.2, int8_t power = 10, uint16_t preambleLength = 16, float tcxoVoltage = 0, bool useRegulatorLDO = false) override;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Initialization method for LR-FHSS modem. This modem only supports transmission!
|
|
||||||
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
|
|
||||||
\param bw LR-FHSS bandwidth, one of RADIOLIB_SX126X_LR_FHSS_BW_* values. Defaults to 722.66 kHz.
|
|
||||||
\param cr LR-FHSS coding rate, one of RADIOLIB_SX126X_LR_FHSS_CR_* values. Defaults to 2/3 coding rate.
|
|
||||||
\param narrowGrid Whether to use narrow (3.9 kHz) or wide (25.39 kHz) grid spacing. Defaults to true (narrow/non-FCC) grid.
|
|
||||||
\param power Output power in dBm. Defaults to 10 dBm.
|
|
||||||
\param tcxoVoltage TCXO reference voltage to be set. Defaults to 0 V (XTAL).
|
|
||||||
If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL.
|
|
||||||
To use XTAL, either set this value to 0, or set SX126x::XTAL to true.
|
|
||||||
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
|
|
||||||
\returns \ref status_codes
|
|
||||||
*/
|
|
||||||
int16_t beginLRFHSS(float freq = 434.0, uint8_t bw = RADIOLIB_SX126X_LR_FHSS_BW_722_66, uint8_t cr = RADIOLIB_SX126X_LR_FHSS_CR_2_3, bool narrowGrid = true, int8_t power = 10, float tcxoVoltage = 0, bool useRegulatorLDO = false) override;
|
|
||||||
|
|
||||||
// configuration methods
|
// configuration methods
|
||||||
|
|
||||||
|
@ -79,14 +47,14 @@ class LLCC68: public SX1262 {
|
||||||
\param bw LoRa bandwidth to be set in kHz.
|
\param bw LoRa bandwidth to be set in kHz.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t setBandwidth(float bw) override;
|
int16_t setBandwidth(float bw);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets LoRa spreading factor. Allowed values range from 5 to 11, depending on currently set spreading factor.
|
\brief Sets LoRa spreading factor. Allowed values range from 5 to 11, depending on currently set spreading factor.
|
||||||
\param sf LoRa spreading factor to be set.
|
\param sf LoRa spreading factor to be set.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t setSpreadingFactor(uint8_t sf) override;
|
int16_t setSpreadingFactor(uint8_t sf);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Set data.
|
\brief Set data.
|
||||||
|
|
|
@ -51,7 +51,7 @@ int16_t LR1110::setFrequency(float freq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR1110::setFrequency(float freq, bool skipCalibration, float band) {
|
int16_t LR1110::setFrequency(float freq, bool skipCalibration, float band) {
|
||||||
RADIOLIB_CHECK_RANGE(freq, 150.0f, 960.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
|
RADIOLIB_CHECK_RANGE(freq, 150.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY);
|
||||||
|
|
||||||
// check if we need to recalibrate image
|
// check if we need to recalibrate image
|
||||||
int16_t state;
|
int16_t state;
|
||||||
|
@ -113,13 +113,13 @@ int16_t LR1110::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPo
|
||||||
|
|
||||||
int16_t LR1110::setModem(ModemType_t modem) {
|
int16_t LR1110::setModem(ModemType_t modem) {
|
||||||
switch(modem) {
|
switch(modem) {
|
||||||
case(ModemType_t::RADIOLIB_MODEM_LORA): {
|
case(ModemType_t::LoRa): {
|
||||||
return(this->begin());
|
return(this->begin());
|
||||||
} break;
|
} break;
|
||||||
case(ModemType_t::RADIOLIB_MODEM_FSK): {
|
case(ModemType_t::FSK): {
|
||||||
return(this->beginGFSK());
|
return(this->beginGFSK());
|
||||||
} break;
|
} break;
|
||||||
case(ModemType_t::RADIOLIB_MODEM_LRFHSS): {
|
case(ModemType_t::LRFHSS): {
|
||||||
return(this->beginLRFHSS());
|
return(this->beginLRFHSS());
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ LR1120::LR1120(Module* mod) : LR11x0(mod) {
|
||||||
|
|
||||||
int16_t LR1120::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
|
int16_t LR1120::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
|
||||||
// execute common part
|
// execute common part
|
||||||
int16_t state = LR11x0::begin(bw, sf, cr, syncWord, preambleLength, tcxoVoltage, freq > 1000.0f);
|
int16_t state = LR11x0::begin(bw, sf, cr, syncWord, preambleLength, tcxoVoltage, freq > 1000.0);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// configure publicly accessible settings
|
// configure publicly accessible settings
|
||||||
|
@ -51,13 +51,11 @@ int16_t LR1120::setFrequency(float freq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR1120::setFrequency(float freq, bool skipCalibration, float band) {
|
int16_t LR1120::setFrequency(float freq, bool skipCalibration, float band) {
|
||||||
#if RADIOLIB_CHECK_PARAMS
|
if(!(((freq >= 150.0) && (freq <= 960.0)) ||
|
||||||
if(!(((freq >= 150.0f) && (freq <= 960.0f)) ||
|
((freq >= 1900.0) && (freq <= 2200.0)) ||
|
||||||
((freq >= 1900.0f) && (freq <= 2200.0f)) ||
|
((freq >= 2400.0) && (freq <= 2500.0)))) {
|
||||||
((freq >= 2400.0f) && (freq <= 2500.0f)))) {
|
|
||||||
return(RADIOLIB_ERR_INVALID_FREQUENCY);
|
return(RADIOLIB_ERR_INVALID_FREQUENCY);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// check if we need to recalibrate image
|
// check if we need to recalibrate image
|
||||||
int16_t state;
|
int16_t state;
|
||||||
|
@ -70,7 +68,7 @@ int16_t LR1120::setFrequency(float freq, bool skipCalibration, float band) {
|
||||||
state = LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f));
|
state = LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f));
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
this->freqMHz = freq;
|
this->freqMHz = freq;
|
||||||
this->highFreq = (freq > 1000.0f);
|
this->highFreq = (freq > 1000.0);
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,13 +133,13 @@ int16_t LR1120::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPo
|
||||||
|
|
||||||
int16_t LR1120::setModem(ModemType_t modem) {
|
int16_t LR1120::setModem(ModemType_t modem) {
|
||||||
switch(modem) {
|
switch(modem) {
|
||||||
case(ModemType_t::RADIOLIB_MODEM_LORA): {
|
case(ModemType_t::LoRa): {
|
||||||
return(this->begin());
|
return(this->begin());
|
||||||
} break;
|
} break;
|
||||||
case(ModemType_t::RADIOLIB_MODEM_FSK): {
|
case(ModemType_t::FSK): {
|
||||||
return(this->beginGFSK());
|
return(this->beginGFSK());
|
||||||
} break;
|
} break;
|
||||||
case(ModemType_t::RADIOLIB_MODEM_LRFHSS): {
|
case(ModemType_t::LRFHSS): {
|
||||||
return(this->beginLRFHSS());
|
return(this->beginLRFHSS());
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
|
|
||||||
#if !RADIOLIB_EXCLUDE_LR11X0
|
#if !RADIOLIB_EXCLUDE_LR11X0
|
||||||
|
|
||||||
LR11x0::LR11x0(Module* mod) : PhysicalLayer() {
|
LR11x0::LR11x0(Module* mod) : PhysicalLayer(RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE, RADIOLIB_LR11X0_MAX_PACKET_LENGTH) {
|
||||||
this->freqStep = RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE;
|
|
||||||
this->maxPacketLength = RADIOLIB_LR11X0_MAX_PACKET_LENGTH;
|
|
||||||
this->mod = mod;
|
this->mod = mod;
|
||||||
this->XTAL = false;
|
this->XTAL = false;
|
||||||
this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_LR11X0_IRQ_TX_DONE;
|
this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_LR11X0_IRQ_TX_DONE;
|
||||||
|
@ -112,8 +110,7 @@ int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, bool narrowGrid, float tcxoV
|
||||||
state = setLrFhssConfig(bw, cr);
|
state = setLrFhssConfig(bw, cr);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
uint8_t syncWord[] = { 0x12, 0xAD, 0x10, 0x1B };
|
state = setSyncWord(0x12AD101B);
|
||||||
state = setSyncWord(syncWord, 4);
|
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
state = setRegulatorLDO();
|
state = setRegulatorLDO();
|
||||||
|
@ -131,8 +128,6 @@ int16_t LR11x0::beginGNSS(uint8_t constellations, float tcxoVoltage) {
|
||||||
state = this->clearErrors();
|
state = this->clearErrors();
|
||||||
RADIOLIB_ASSERT(state);
|
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);
|
state = this->configLfClock(RADIOLIB_LR11X0_LF_BUSY_RELEASE_DISABLED | RADIOLIB_LR11X0_LF_CLK_XOSC);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
@ -221,7 +216,7 @@ int16_t LR11x0::transmit(const uint8_t* data, size_t len, uint8_t addr) {
|
||||||
RadioLibTime_t elapsed = this->mod->hal->micros() - start;
|
RadioLibTime_t elapsed = this->mod->hal->micros() - start;
|
||||||
|
|
||||||
// update data rate
|
// update data rate
|
||||||
this->dataRateMeasured = (len*8.0f)/((float)elapsed/1000000.0f);
|
this->dataRateMeasured = (len*8.0)/((float)elapsed/1000000.0);
|
||||||
|
|
||||||
return(finishTransmit());
|
return(finishTransmit());
|
||||||
}
|
}
|
||||||
|
@ -240,7 +235,7 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
|
||||||
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||||
// calculate timeout (100 LoRa symbols, the default for SX127x series)
|
// calculate timeout (100 LoRa symbols, the default for SX127x series)
|
||||||
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
|
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
|
||||||
timeout = (RadioLibTime_t)(symbolLength * 100.0f);
|
timeout = (RadioLibTime_t)(symbolLength * 100.0);
|
||||||
|
|
||||||
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||||
// calculate timeout (500 % of expected time-one-air)
|
// calculate timeout (500 % of expected time-one-air)
|
||||||
|
@ -248,8 +243,8 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
|
||||||
if(len == 0) {
|
if(len == 0) {
|
||||||
maxLen = 0xFF;
|
maxLen = 0xFF;
|
||||||
}
|
}
|
||||||
float brBps = ((float)(RADIOLIB_LR11X0_CRYSTAL_FREQ) * 1000000.0f * 32.0f) / (float)this->bitRate;
|
float brBps = ((float)(RADIOLIB_LR11X0_CRYSTAL_FREQ) * 1000000.0 * 32.0) / (float)this->bitRate;
|
||||||
timeout = (RadioLibTime_t)(((maxLen * 8.0f) / brBps) * 1000.0f * 5.0f);
|
timeout = (RadioLibTime_t)(((maxLen * 8.0) / brBps) * 1000.0 * 5.0);
|
||||||
|
|
||||||
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
||||||
// this modem cannot receive
|
// this modem cannot receive
|
||||||
|
@ -263,7 +258,7 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
|
||||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout);
|
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout);
|
||||||
|
|
||||||
// start reception
|
// start reception
|
||||||
uint32_t timeoutValue = (uint32_t)(((float)timeout * 1000.0f) / 30.52f);
|
uint32_t timeoutValue = (uint32_t)(((float)timeout * 1000.0) / 30.52);
|
||||||
state = startReceive(timeoutValue);
|
state = startReceive(timeoutValue);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
@ -289,7 +284,7 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
|
||||||
// check whether this was a timeout or not
|
// check whether this was a timeout or not
|
||||||
if((getIrqStatus() & RADIOLIB_LR11X0_IRQ_TIMEOUT) || softTimeout) {
|
if((getIrqStatus() & RADIOLIB_LR11X0_IRQ_TIMEOUT) || softTimeout) {
|
||||||
standby();
|
standby();
|
||||||
clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
return(RADIOLIB_ERR_RX_TIMEOUT);
|
return(RADIOLIB_ERR_RX_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +353,10 @@ int16_t LR11x0::standby(uint8_t mode, bool wakeup) {
|
||||||
this->mod->setRfSwitchState(Module::MODE_IDLE);
|
this->mod->setRfSwitchState(Module::MODE_IDLE);
|
||||||
|
|
||||||
if(wakeup) {
|
if(wakeup) {
|
||||||
// send a NOP command - this pulls the NSS low to exit the sleep mode,
|
// pull NSS low for a while to wake up
|
||||||
// while preventing interference with possible other SPI transactions
|
this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow);
|
||||||
(void)this->mod->SPIwriteStream((uint16_t)RADIOLIB_LR11X0_CMD_NOP, NULL, 0, false, false);
|
this->mod->hal->delay(1);
|
||||||
|
this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelHigh);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buff[] = { mode };
|
uint8_t buff[] = { mode };
|
||||||
|
@ -416,9 +412,76 @@ void LR11x0::clearPacketSentAction() {
|
||||||
this->clearIrqAction();
|
this->clearIrqAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t LR11x0::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
|
||||||
|
// suppress unused variable warning
|
||||||
|
(void)addr;
|
||||||
|
|
||||||
|
// check packet length
|
||||||
|
if(len > RADIOLIB_LR11X0_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_LR11X0_GFSK_ADDR_FILTER_DISABLED) && (len > RADIOLIB_LR11X0_MAX_PACKET_LENGTH - 1)) {
|
||||||
|
return(RADIOLIB_ERR_PACKET_TOO_LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set packet Length
|
||||||
|
int16_t state = RADIOLIB_ERR_NONE;
|
||||||
|
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||||
|
state = getPacketType(&modem);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||||
|
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, len, this->crcTypeLoRa, this->invertIQEnabled);
|
||||||
|
|
||||||
|
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||||
|
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->preambleDetLength, this->syncWordLength, this->addrComp, this->packetType, len, this->crcTypeGFSK, this->whitening);
|
||||||
|
|
||||||
|
} else if(modem != RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
||||||
|
return(RADIOLIB_ERR_UNKNOWN);
|
||||||
|
|
||||||
|
}
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// set DIO mapping
|
||||||
|
state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_TX_DONE | RADIOLIB_LR11X0_IRQ_TIMEOUT);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
||||||
|
// in LR-FHSS mode, the packet is built by the device
|
||||||
|
// TODO add configurable device offset
|
||||||
|
state = lrFhssBuildFrame(this->lrFhssHdrCount, this->lrFhssCr, this->lrFhssGrid, true, this->lrFhssBw, this->lrFhssHopSeq, 0, const_cast<uint8_t*>(data), len);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// write packet to buffer
|
||||||
|
state = writeBuffer8(const_cast<uint8_t*>(data), len);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear interrupt flags
|
||||||
|
state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// set RF switch (if present)
|
||||||
|
this->mod->setRfSwitchState(Module::MODE_TX);
|
||||||
|
|
||||||
|
// start transmission
|
||||||
|
state = setTx(RADIOLIB_LR11X0_TX_TIMEOUT_NONE);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// wait for BUSY to go low (= PA ramp up done)
|
||||||
|
while(this->mod->hal->digitalRead(this->mod->getGpio())) {
|
||||||
|
this->mod->hal->yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
return(state);
|
||||||
|
}
|
||||||
|
|
||||||
int16_t LR11x0::finishTransmit() {
|
int16_t LR11x0::finishTransmit() {
|
||||||
// clear interrupt flags
|
// clear interrupt flags
|
||||||
clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
|
|
||||||
// set mode to standby to disable transmitter/RF switch
|
// set mode to standby to disable transmitter/RF switch
|
||||||
return(standby());
|
return(standby());
|
||||||
|
@ -428,6 +491,46 @@ int16_t LR11x0::startReceive() {
|
||||||
return(this->startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0));
|
return(this->startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t LR11x0::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||||
|
(void)len;
|
||||||
|
|
||||||
|
// check active modem
|
||||||
|
int16_t state = RADIOLIB_ERR_NONE;
|
||||||
|
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||||
|
state = getPacketType(&modem);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
if((modem != RADIOLIB_LR11X0_PACKET_TYPE_LORA) &&
|
||||||
|
(modem != RADIOLIB_LR11X0_PACKET_TYPE_GFSK)) {
|
||||||
|
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set DIO mapping
|
||||||
|
uint32_t irq = irqMask;
|
||||||
|
if(timeout != RADIOLIB_LR11X0_RX_TIMEOUT_INF) {
|
||||||
|
irq |= (1UL << RADIOLIB_IRQ_TIMEOUT);
|
||||||
|
}
|
||||||
|
state = setDioIrqParams(getIrqMapped(irqFlags & irq));
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// clear interrupt flags
|
||||||
|
state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// set implicit mode and expected len if applicable
|
||||||
|
if((this->headerType == RADIOLIB_LR11X0_LORA_HEADER_IMPLICIT) && (modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA)) {
|
||||||
|
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->implicitLen, this->crcTypeLoRa, this->invertIQEnabled);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set RF switch (if present)
|
||||||
|
this->mod->setRfSwitchState(Module::MODE_RX);
|
||||||
|
|
||||||
|
// set mode to receive
|
||||||
|
state = setRx(timeout);
|
||||||
|
|
||||||
|
return(state);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t LR11x0::getIrqStatus() {
|
uint32_t LR11x0::getIrqStatus() {
|
||||||
// there is no dedicated "get IRQ" command, the IRQ bits are sent after the status bytes
|
// there is no dedicated "get IRQ" command, the IRQ bits are sent after the status bytes
|
||||||
uint8_t buff[6] = { 0 };
|
uint8_t buff[6] = { 0 };
|
||||||
|
@ -475,7 +578,7 @@ int16_t LR11x0::readData(uint8_t* data, size_t len) {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// clear interrupt flags
|
// clear interrupt flags
|
||||||
state = clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
|
|
||||||
// check if CRC failed - this is done after reading data to give user the option to keep them
|
// check if CRC failed - this is done after reading data to give user the option to keep them
|
||||||
RADIOLIB_ASSERT(crcState);
|
RADIOLIB_ASSERT(crcState);
|
||||||
|
@ -521,7 +624,7 @@ int16_t LR11x0::startChannelScan(const ChannelScanConfig_t &config) {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// clear interrupt flags
|
// clear interrupt flags
|
||||||
state = clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set mode to CAD
|
// set mode to CAD
|
||||||
|
@ -562,22 +665,22 @@ int16_t LR11x0::setBandwidth(float bw, bool high) {
|
||||||
|
|
||||||
// ensure byte conversion doesn't overflow
|
// ensure byte conversion doesn't overflow
|
||||||
if (high) {
|
if (high) {
|
||||||
RADIOLIB_CHECK_RANGE(bw, 203.125f, 815.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
RADIOLIB_CHECK_RANGE(bw, 203.125, 815.0, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
||||||
|
|
||||||
if(fabsf(bw - 203.125f) <= 0.001f) {
|
if(fabsf(bw - 203.125) <= 0.001) {
|
||||||
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_203_125;
|
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_203_125;
|
||||||
} else if(fabsf(bw - 406.25f) <= 0.001f) {
|
} else if(fabsf(bw - 406.25) <= 0.001) {
|
||||||
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_406_25;
|
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_406_25;
|
||||||
} else if(fabsf(bw - 812.5f) <= 0.001f) {
|
} else if(fabsf(bw - 812.5) <= 0.001) {
|
||||||
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_812_50;
|
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_812_50;
|
||||||
} else {
|
} else {
|
||||||
return(RADIOLIB_ERR_INVALID_BANDWIDTH);
|
return(RADIOLIB_ERR_INVALID_BANDWIDTH);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RADIOLIB_CHECK_RANGE(bw, 0.0f, 510.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
RADIOLIB_CHECK_RANGE(bw, 0.0, 510.0, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
||||||
|
|
||||||
// check allowed bandwidth values
|
// check allowed bandwidth values
|
||||||
uint8_t bw_div2 = bw / 2 + 0.01f;
|
uint8_t bw_div2 = bw / 2 + 0.01;
|
||||||
switch (bw_div2) {
|
switch (bw_div2) {
|
||||||
case 31: // 62.5:
|
case 31: // 62.5:
|
||||||
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_62_5;
|
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_62_5;
|
||||||
|
@ -655,20 +758,24 @@ int16_t LR11x0::setCodingRate(uint8_t cr, bool longInterleave) {
|
||||||
return(setModulationParamsLoRa(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
|
return(setModulationParamsLoRa(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::setSyncWord(uint8_t syncWord) {
|
int16_t LR11x0::setSyncWord(uint32_t syncWord) {
|
||||||
// check active modem
|
// check active modem
|
||||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||||
int16_t state = getPacketType(&type);
|
int16_t state = getPacketType(&type);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
if(type != RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
return(setLoRaSyncWord(syncWord & 0xFF));
|
||||||
|
|
||||||
|
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
||||||
|
return(lrFhssSetSyncWord(syncWord));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(setLoRaSyncWord(syncWord));
|
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::setBitRate(float br) {
|
int16_t LR11x0::setBitRate(float br) {
|
||||||
RADIOLIB_CHECK_RANGE(br, 0.6f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
|
RADIOLIB_CHECK_RANGE(br, 0.6, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
|
||||||
|
|
||||||
// check active modem
|
// check active modem
|
||||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||||
|
@ -680,7 +787,7 @@ int16_t LR11x0::setBitRate(float br) {
|
||||||
|
|
||||||
// set bit rate value
|
// set bit rate value
|
||||||
// TODO implement fractional bit rate configuration
|
// TODO implement fractional bit rate configuration
|
||||||
this->bitRate = br * 1000.0f;
|
this->bitRate = br * 1000.0;
|
||||||
return(setModulationParamsGFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
|
return(setModulationParamsGFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,12 +802,12 @@ int16_t LR11x0::setFrequencyDeviation(float freqDev) {
|
||||||
|
|
||||||
// set frequency deviation to lowest available setting (required for digimodes)
|
// set frequency deviation to lowest available setting (required for digimodes)
|
||||||
float newFreqDev = freqDev;
|
float newFreqDev = freqDev;
|
||||||
if(freqDev < 0.0f) {
|
if(freqDev < 0.0) {
|
||||||
newFreqDev = 0.6f;
|
newFreqDev = 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
RADIOLIB_CHECK_RANGE(newFreqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
RADIOLIB_CHECK_RANGE(newFreqDev, 0.6, 200.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
||||||
this->frequencyDev = newFreqDev * 1000.0f;
|
this->frequencyDev = newFreqDev * 1000.0;
|
||||||
return(setModulationParamsGFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
|
return(setModulationParamsGFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,47 +826,47 @@ int16_t LR11x0::setRxBandwidth(float rxBw) {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// check allowed receiver bandwidth values
|
// check allowed receiver bandwidth values
|
||||||
if(fabsf(rxBw - 4.8f) <= 0.001f) {
|
if(fabsf(rxBw - 4.8) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_4_8;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_4_8;
|
||||||
} else if(fabsf(rxBw - 5.8f) <= 0.001f) {
|
} else if(fabsf(rxBw - 5.8) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_5_8;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_5_8;
|
||||||
} else if(fabsf(rxBw - 7.3f) <= 0.001f) {
|
} else if(fabsf(rxBw - 7.3) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_7_3;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_7_3;
|
||||||
} else if(fabsf(rxBw - 9.7f) <= 0.001f) {
|
} else if(fabsf(rxBw - 9.7) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_9_7;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_9_7;
|
||||||
} else if(fabsf(rxBw - 11.7f) <= 0.001f) {
|
} else if(fabsf(rxBw - 11.7) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_11_7;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_11_7;
|
||||||
} else if(fabsf(rxBw - 14.6f) <= 0.001f) {
|
} else if(fabsf(rxBw - 14.6) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_14_6;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_14_6;
|
||||||
} else if(fabsf(rxBw - 19.5f) <= 0.001f) {
|
} else if(fabsf(rxBw - 19.5) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_19_5;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_19_5;
|
||||||
} else if(fabsf(rxBw - 23.4f) <= 0.001f) {
|
} else if(fabsf(rxBw - 23.4) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_23_4;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_23_4;
|
||||||
} else if(fabsf(rxBw - 29.3f) <= 0.001f) {
|
} else if(fabsf(rxBw - 29.3) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_29_3;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_29_3;
|
||||||
} else if(fabsf(rxBw - 39.0f) <= 0.001f) {
|
} else if(fabsf(rxBw - 39.0) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_39_0;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_39_0;
|
||||||
} else if(fabsf(rxBw - 46.9f) <= 0.001f) {
|
} else if(fabsf(rxBw - 46.9) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_46_9;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_46_9;
|
||||||
} else if(fabsf(rxBw - 58.6f) <= 0.001f) {
|
} else if(fabsf(rxBw - 58.6) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_58_6;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_58_6;
|
||||||
} else if(fabsf(rxBw - 78.2f) <= 0.001f) {
|
} else if(fabsf(rxBw - 78.2) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_78_2;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_78_2;
|
||||||
} else if(fabsf(rxBw - 93.8f) <= 0.001f) {
|
} else if(fabsf(rxBw - 93.8) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_93_8;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_93_8;
|
||||||
} else if(fabsf(rxBw - 117.3f) <= 0.001f) {
|
} else if(fabsf(rxBw - 117.3) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_117_3;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_117_3;
|
||||||
} else if(fabsf(rxBw - 156.2f) <= 0.001f) {
|
} else if(fabsf(rxBw - 156.2) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_156_2;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_156_2;
|
||||||
} else if(fabsf(rxBw - 187.2f) <= 0.001f) {
|
} else if(fabsf(rxBw - 187.2) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_187_2;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_187_2;
|
||||||
} else if(fabsf(rxBw - 234.3f) <= 0.001f) {
|
} else if(fabsf(rxBw - 234.3) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_234_3;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_234_3;
|
||||||
} else if(fabsf(rxBw - 312.0f) <= 0.001f) {
|
} else if(fabsf(rxBw - 312.0) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_312_0;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_312_0;
|
||||||
} else if(fabsf(rxBw - 373.6f) <= 0.001f) {
|
} else if(fabsf(rxBw - 373.6) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_373_6;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_373_6;
|
||||||
} else if(fabsf(rxBw - 467.0f) <= 0.001f) {
|
} else if(fabsf(rxBw - 467.0) <= 0.001) {
|
||||||
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_467_0;
|
this->rxBandwidth = RADIOLIB_LR11X0_GFSK_RX_BW_467_0;
|
||||||
} else {
|
} else {
|
||||||
return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
|
return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
|
||||||
|
@ -778,36 +885,27 @@ int16_t LR11x0::setSyncWord(uint8_t* syncWord, size_t len) {
|
||||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||||
int16_t state = getPacketType(&type);
|
int16_t state = getPacketType(&type);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||||
// 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
|
// with length set to 1 and LoRa modem active, assume it is the LoRa sync word
|
||||||
if(len > 1) {
|
if(len > 1) {
|
||||||
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
||||||
}
|
}
|
||||||
return(setSyncWord(syncWord[0]));
|
return(setSyncWord(syncWord[0]));
|
||||||
|
|
||||||
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
} else if(type != RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||||
// with length set to 4 and LR-FHSS modem active, assume it is the LR-FHSS sync word
|
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||||
if(len != sizeof(uint32_t)) {
|
|
||||||
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
|
||||||
}
|
|
||||||
uint32_t sync = 0;
|
|
||||||
memcpy(&sync, syncWord, sizeof(uint32_t));
|
|
||||||
return(lrFhssSetSyncWord(sync));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
// 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::setSyncBits(uint8_t *syncWord, uint8_t bitsLen) {
|
int16_t LR11x0::setSyncBits(uint8_t *syncWord, uint8_t bitsLen) {
|
||||||
|
@ -999,13 +1097,13 @@ int16_t LR11x0::checkDataRate(DataRate_t dr) {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||||
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
|
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
|
||||||
RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6, 200.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||||
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 5, 12, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
|
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 5, 12, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
|
||||||
RADIOLIB_CHECK_RANGE(dr.lora.bandwidth, 0.0f, 510.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
RADIOLIB_CHECK_RANGE(dr.lora.bandwidth, 0.0, 510.0, RADIOLIB_ERR_INVALID_BANDWIDTH);
|
||||||
RADIOLIB_CHECK_RANGE(dr.lora.codingRate, 5, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
|
RADIOLIB_CHECK_RANGE(dr.lora.codingRate, 5, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
|
@ -1053,28 +1151,28 @@ int16_t LR11x0::setTCXO(float voltage, uint32_t delay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check 0 V disable
|
// check 0 V disable
|
||||||
if(fabsf(voltage - 0.0f) <= 0.001f) {
|
if(fabsf(voltage - 0.0) <= 0.001) {
|
||||||
setTcxoMode(0, 0);
|
setTcxoMode(0, 0);
|
||||||
return(reset());
|
return(reset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check allowed voltage values
|
// check allowed voltage values
|
||||||
uint8_t tune = 0;
|
uint8_t tune = 0;
|
||||||
if(fabsf(voltage - 1.6f) <= 0.001f) {
|
if(fabsf(voltage - 1.6) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_1_6;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_1_6;
|
||||||
} else if(fabsf(voltage - 1.7f) <= 0.001f) {
|
} else if(fabsf(voltage - 1.7) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_1_7;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_1_7;
|
||||||
} else if(fabsf(voltage - 1.8f) <= 0.001f) {
|
} else if(fabsf(voltage - 1.8) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_1_8;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_1_8;
|
||||||
} else if(fabsf(voltage - 2.2f) <= 0.001f) {
|
} else if(fabsf(voltage - 2.2) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_2_2;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_2_2;
|
||||||
} else if(fabsf(voltage - 2.4f) <= 0.001f) {
|
} else if(fabsf(voltage - 2.4) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_2_4;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_2_4;
|
||||||
} else if(fabsf(voltage - 2.7f) <= 0.001f) {
|
} else if(fabsf(voltage - 2.7) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_2_7;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_2_7;
|
||||||
} else if(fabsf(voltage - 3.0f) <= 0.001f) {
|
} else if(fabsf(voltage - 3.0) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_3_0;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_3_0;
|
||||||
} else if(fabsf(voltage - 3.3f) <= 0.001f) {
|
} else if(fabsf(voltage - 3.3) <= 0.001) {
|
||||||
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_3_3;
|
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_3_3;
|
||||||
} else {
|
} else {
|
||||||
return(RADIOLIB_ERR_INVALID_TCXO_VOLTAGE);
|
return(RADIOLIB_ERR_INVALID_TCXO_VOLTAGE);
|
||||||
|
@ -1248,7 +1346,7 @@ RadioLibTime_t LR11x0::getTimeOnAir(size_t len) {
|
||||||
uint32_t N_symbolPreamble = (this->preambleLengthLoRa & 0x0F) * (uint32_t(1) << ((this->preambleLengthLoRa & 0xF0) >> 4));
|
uint32_t N_symbolPreamble = (this->preambleLengthLoRa & 0x0F) * (uint32_t(1) << ((this->preambleLengthLoRa & 0xF0) >> 4));
|
||||||
|
|
||||||
// calculate the number of symbols
|
// calculate the number of symbols
|
||||||
N_symbol = (float)N_symbolPreamble + coeff1 + 8.0f + ceilf((float)RADIOLIB_MAX((int16_t)(8 * len + N_bitCRC - coeff2 + N_symbolHeader), (int16_t)0) / (float)coeff3) * (float)(this->codingRate + 4);
|
N_symbol = (float)N_symbolPreamble + coeff1 + 8.0 + ceilf((float)RADIOLIB_MAX((int16_t)(8 * len + N_bitCRC - coeff2 + N_symbolHeader), (int16_t)0) / (float)coeff3) * (float)(this->codingRate + 4);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// long interleaving - abandon hope all ye who enter here
|
// long interleaving - abandon hope all ye who enter here
|
||||||
|
@ -1257,7 +1355,7 @@ RadioLibTime_t LR11x0::getTimeOnAir(size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get time-on-air in us
|
// get time-on-air in us
|
||||||
return(((uint32_t(1) << this->spreadingFactor) / this->bandwidthKhz) * N_symbol * 1000.0f);
|
return(((uint32_t(1) << this->spreadingFactor) / this->bandwidthKhz) * N_symbol * 1000.0);
|
||||||
|
|
||||||
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||||
return(((uint32_t)len * 8 * 1000000UL) / this->bitRate);
|
return(((uint32_t)len * 8 * 1000000UL) / this->bitRate);
|
||||||
|
@ -1314,7 +1412,7 @@ int16_t LR11x0::setIrqFlags(uint32_t irq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::clearIrqFlags(uint32_t irq) {
|
int16_t LR11x0::clearIrqFlags(uint32_t irq) {
|
||||||
return(this->clearIrqState(irq));
|
return(this->clearIrq(irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t LR11x0::randomByte() {
|
uint8_t LR11x0::randomByte() {
|
||||||
|
@ -1489,7 +1587,7 @@ void LR11x0::clearWiFiScanAction() {
|
||||||
|
|
||||||
int16_t LR11x0::getWifiScanResultsCount(uint8_t* count) {
|
int16_t LR11x0::getWifiScanResultsCount(uint8_t* count) {
|
||||||
// clear IRQ first, as this is likely to be called right after scan has finished
|
// clear IRQ first, as this is likely to be called right after scan has finished
|
||||||
int16_t state = clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
int16_t state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
uint8_t buff[1] = { 0 };
|
uint8_t buff[1] = { 0 };
|
||||||
|
@ -1660,7 +1758,7 @@ int16_t LR11x0::updateFirmware(const uint32_t* image, size_t size, bool nonvolat
|
||||||
uint32_t offset = i * maxLen;
|
uint32_t offset = i * maxLen;
|
||||||
uint32_t len = (i == (numWrites - 1)) ? rem : maxLen;
|
uint32_t len = (i == (numWrites - 1)) ? rem : maxLen;
|
||||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Writing chunk %d at offset %08lx (%u words)", (int)i, (unsigned long)offset, (unsigned int)len);
|
RADIOLIB_DEBUG_BASIC_PRINTLN("Writing chunk %d at offset %08lx (%u words)", (int)i, (unsigned long)offset, (unsigned int)len);
|
||||||
this->bootWriteFlashEncrypted(offset*sizeof(uint32_t), const_cast<uint32_t*>(&image[offset]), len, nonvolatile);
|
this->bootWriteFlashEncrypted(offset*sizeof(uint32_t), (uint32_t*)&image[offset], len, nonvolatile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// kick the device from bootloader
|
// kick the device from bootloader
|
||||||
|
@ -1706,7 +1804,7 @@ int16_t LR11x0::isGnssScanCapable() {
|
||||||
size_t len = sz > 32 ? 32 : sz/sizeof(uint32_t);
|
size_t len = sz > 32 ? 32 : sz/sizeof(uint32_t);
|
||||||
state = this->readRegMem32(addr, buff, len);
|
state = this->readRegMem32(addr, buff, len);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
RADIOLIB_DEBUG_HEXDUMP(NULL, reinterpret_cast<uint8_t*>(buff), len*sizeof(uint32_t), addr);
|
RADIOLIB_DEBUG_HEXDUMP(NULL, (uint8_t*)buff, len*sizeof(uint32_t), addr);
|
||||||
addr += len*sizeof(uint32_t);
|
addr += len*sizeof(uint32_t);
|
||||||
sz -= len*sizeof(uint32_t);
|
sz -= len*sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
@ -1765,7 +1863,7 @@ int16_t LR11x0::gnssScan(LR11x0GnssResult_t* res) {
|
||||||
|
|
||||||
// distinguish between GNSS-done and GNSS-abort outcomes and clear the flags
|
// distinguish between GNSS-done and GNSS-abort outcomes and clear the flags
|
||||||
uint32_t irq = this->getIrqStatus();
|
uint32_t irq = this->getIrqStatus();
|
||||||
this->clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
this->clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
if(irq & RADIOLIB_LR11X0_IRQ_GNSS_ABORT) {
|
if(irq & RADIOLIB_LR11X0_IRQ_GNSS_ABORT) {
|
||||||
return(RADIOLIB_ERR_RX_TIMEOUT);
|
return(RADIOLIB_ERR_RX_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
@ -1877,7 +1975,7 @@ int16_t LR11x0::updateGnssAlmanac(uint8_t constellation) {
|
||||||
|
|
||||||
// distinguish between GNSS-done and GNSS-abort outcomes and clear the flags
|
// distinguish between GNSS-done and GNSS-abort outcomes and clear the flags
|
||||||
uint32_t irq = this->getIrqStatus();
|
uint32_t irq = this->getIrqStatus();
|
||||||
this->clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
this->clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
if(irq & RADIOLIB_LR11X0_IRQ_GNSS_ABORT) {
|
if(irq & RADIOLIB_LR11X0_IRQ_GNSS_ABORT) {
|
||||||
state = RADIOLIB_ERR_RX_TIMEOUT;
|
state = RADIOLIB_ERR_RX_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -1928,143 +2026,25 @@ int16_t LR11x0::getGnssSatellites(LR11x0GnssSatellite_t* sats, uint8_t numSats)
|
||||||
int16_t LR11x0::getModem(ModemType_t* modem) {
|
int16_t LR11x0::getModem(ModemType_t* modem) {
|
||||||
RADIOLIB_ASSERT_PTR(modem);
|
RADIOLIB_ASSERT_PTR(modem);
|
||||||
|
|
||||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
uint8_t packetType = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||||
int16_t state = getPacketType(&type);
|
int16_t state = getPacketType(&packetType);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
switch(type) {
|
switch(packetType) {
|
||||||
case(RADIOLIB_LR11X0_PACKET_TYPE_LORA):
|
case(RADIOLIB_LR11X0_PACKET_TYPE_LORA):
|
||||||
*modem = ModemType_t::RADIOLIB_MODEM_LORA;
|
*modem = ModemType_t::LoRa;
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
case(RADIOLIB_LR11X0_PACKET_TYPE_GFSK):
|
case(RADIOLIB_LR11X0_PACKET_TYPE_GFSK):
|
||||||
*modem = ModemType_t::RADIOLIB_MODEM_FSK;
|
*modem = ModemType_t::FSK;
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
case(RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS):
|
case(RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS):
|
||||||
*modem = ModemType_t::RADIOLIB_MODEM_LRFHSS;
|
*modem = ModemType_t::LRFHSS;
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) {
|
|
||||||
int16_t state;
|
|
||||||
|
|
||||||
switch(mode) {
|
|
||||||
case(RADIOLIB_RADIO_MODE_RX): {
|
|
||||||
// check active modem
|
|
||||||
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
|
||||||
state = getPacketType(&modem);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
if((modem != RADIOLIB_LR11X0_PACKET_TYPE_LORA) &&
|
|
||||||
(modem != RADIOLIB_LR11X0_PACKET_TYPE_GFSK)) {
|
|
||||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set DIO mapping
|
|
||||||
if(cfg->receive.timeout != RADIOLIB_LR11X0_RX_TIMEOUT_INF) {
|
|
||||||
cfg->receive.irqMask |= (1UL << RADIOLIB_IRQ_TIMEOUT);
|
|
||||||
}
|
|
||||||
state = setDioIrqParams(getIrqMapped(cfg->receive.irqFlags & cfg->receive.irqMask));
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// clear interrupt flags
|
|
||||||
state = clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// set implicit mode and expected len if applicable
|
|
||||||
if((this->headerType == RADIOLIB_LR11X0_LORA_HEADER_IMPLICIT) && (modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA)) {
|
|
||||||
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->implicitLen, this->crcTypeLoRa, this->invertIQEnabled);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
}
|
|
||||||
this->rxTimeout = cfg->receive.timeout;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case(RADIOLIB_RADIO_MODE_TX): {
|
|
||||||
// check packet length
|
|
||||||
if(cfg->transmit.len > RADIOLIB_LR11X0_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_LR11X0_GFSK_ADDR_FILTER_DISABLED) && (cfg->transmit.len > RADIOLIB_LR11X0_MAX_PACKET_LENGTH - 1)) {
|
|
||||||
return(RADIOLIB_ERR_PACKET_TOO_LONG);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set packet Length
|
|
||||||
state = RADIOLIB_ERR_NONE;
|
|
||||||
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
|
||||||
state = getPacketType(&modem);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
|
||||||
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, cfg->transmit.len, this->crcTypeLoRa, this->invertIQEnabled);
|
|
||||||
|
|
||||||
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
|
||||||
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->preambleDetLength, this->syncWordLength, this->addrComp, this->packetType, cfg->transmit.len, this->crcTypeGFSK, this->whitening);
|
|
||||||
|
|
||||||
} else if(modem != RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
|
||||||
return(RADIOLIB_ERR_UNKNOWN);
|
|
||||||
|
|
||||||
}
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// set DIO mapping
|
|
||||||
state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_TX_DONE | RADIOLIB_LR11X0_IRQ_TIMEOUT);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
|
|
||||||
// in LR-FHSS mode, the packet is built by the device
|
|
||||||
// TODO add configurable device offset
|
|
||||||
state = lrFhssBuildFrame(this->lrFhssHdrCount, this->lrFhssCr, this->lrFhssGrid, true, this->lrFhssBw, this->lrFhssHopSeq, 0, cfg->transmit.data, cfg->transmit.len);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// write packet to buffer
|
|
||||||
state = writeBuffer8(cfg->transmit.data, cfg->transmit.len);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear interrupt flags
|
|
||||||
state = clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return(RADIOLIB_ERR_UNSUPPORTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->stagedMode = mode;
|
|
||||||
return(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t LR11x0::launchMode() {
|
|
||||||
int16_t state;
|
|
||||||
switch(this->stagedMode) {
|
|
||||||
case(RADIOLIB_RADIO_MODE_RX): {
|
|
||||||
this->mod->setRfSwitchState(Module::MODE_RX);
|
|
||||||
state = setRx(this->rxTimeout);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case(RADIOLIB_RADIO_MODE_TX): {
|
|
||||||
this->mod->setRfSwitchState(Module::MODE_TX);
|
|
||||||
state = setTx(RADIOLIB_LR11X0_TX_TIMEOUT_NONE);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// wait for BUSY to go low (= PA ramp up done)
|
|
||||||
while(this->mod->hal->digitalRead(this->mod->getGpio())) {
|
|
||||||
this->mod->hal->yield();
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return(RADIOLIB_ERR_UNSUPPORTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->stagedMode = RADIOLIB_RADIO_MODE_NONE;
|
|
||||||
return(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
|
int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
|
||||||
this->mod->init();
|
this->mod->init();
|
||||||
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
|
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
|
||||||
|
@ -2080,7 +2060,6 @@ int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
|
||||||
this->mod->spiConfig.stream = true;
|
this->mod->spiConfig.stream = true;
|
||||||
this->mod->spiConfig.parseStatusCb = SPIparseStatus;
|
this->mod->spiConfig.parseStatusCb = SPIparseStatus;
|
||||||
this->mod->spiConfig.checkStatusCb = SPIcheckStatus;
|
this->mod->spiConfig.checkStatusCb = SPIcheckStatus;
|
||||||
this->gnss = false;
|
|
||||||
|
|
||||||
// try to find the LR11x0 chip - this will also reset the module at least once
|
// try to find the LR11x0 chip - this will also reset the module at least once
|
||||||
if(!LR11x0::findChip(this->chipType)) {
|
if(!LR11x0::findChip(this->chipType)) {
|
||||||
|
@ -2095,7 +2074,7 @@ int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set TCXO control, if requested
|
// set TCXO control, if requested
|
||||||
if(!this->XTAL && tcxoVoltage > 0.0f) {
|
if(!this->XTAL && tcxoVoltage > 0.0) {
|
||||||
state = setTCXO(tcxoVoltage);
|
state = setTCXO(tcxoVoltage);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
}
|
}
|
||||||
|
@ -2127,7 +2106,7 @@ int16_t LR11x0::SPIcheckStatus(Module* mod) {
|
||||||
return(LR11x0::SPIparseStatus(buff[0]));
|
return(LR11x0::SPIparseStatus(buff[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out, size_t outLen) {
|
int16_t LR11x0::SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, uint8_t* out, size_t outLen) {
|
||||||
int16_t state = RADIOLIB_ERR_UNKNOWN;
|
int16_t state = RADIOLIB_ERR_UNKNOWN;
|
||||||
if(!write) {
|
if(!write) {
|
||||||
// the SPI interface of LR11x0 requires two separate transactions for reading
|
// the SPI interface of LR11x0 requires two separate transactions for reading
|
||||||
|
@ -2188,7 +2167,7 @@ int16_t LR11x0::config(uint8_t modem) {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// clear IRQ
|
// clear IRQ
|
||||||
state = this->clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
|
state = this->clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||||
state |= this->setDioIrqParams(RADIOLIB_LR11X0_IRQ_NONE);
|
state |= this->setDioIrqParams(RADIOLIB_LR11X0_IRQ_NONE);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
@ -2302,7 +2281,7 @@ Module* LR11x0::getMod() {
|
||||||
return(this->mod);
|
return(this->mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::writeRegMem32(uint32_t addr, const uint32_t* data, size_t len) {
|
int16_t LR11x0::writeRegMem32(uint32_t addr, uint32_t* data, size_t len) {
|
||||||
// check maximum size
|
// check maximum size
|
||||||
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
||||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||||
|
@ -2347,12 +2326,12 @@ int16_t LR11x0::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::writeBuffer8(const uint8_t* data, size_t len) {
|
int16_t LR11x0::writeBuffer8(uint8_t* data, size_t len) {
|
||||||
// check maximum size
|
// check maximum size
|
||||||
if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
|
if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
|
||||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||||
}
|
}
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WRITE_BUFFER, true, const_cast<uint8_t*>(data), len));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WRITE_BUFFER, true, data, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::readBuffer8(uint8_t* data, size_t len, size_t offset) {
|
int16_t LR11x0::readBuffer8(uint8_t* data, size_t len, size_t offset) {
|
||||||
|
@ -2467,10 +2446,10 @@ int16_t LR11x0::setDioIrqParams(uint32_t irq1, uint32_t irq2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::setDioIrqParams(uint32_t irq) {
|
int16_t LR11x0::setDioIrqParams(uint32_t irq) {
|
||||||
return(setDioIrqParams(irq, this->gnss ? 0 : irq));
|
return(setDioIrqParams(irq, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::clearIrqState(uint32_t irq) {
|
int16_t LR11x0::clearIrq(uint32_t irq) {
|
||||||
uint8_t buff[4] = {
|
uint8_t buff[4] = {
|
||||||
(uint8_t)((irq >> 24) & 0xFF), (uint8_t)((irq >> 16) & 0xFF), (uint8_t)((irq >> 8) & 0xFF), (uint8_t)(irq & 0xFF),
|
(uint8_t)((irq >> 24) & 0xFF), (uint8_t)((irq >> 16) & 0xFF), (uint8_t)((irq >> 8) & 0xFF), (uint8_t)(irq & 0xFF),
|
||||||
};
|
};
|
||||||
|
@ -2478,7 +2457,7 @@ int16_t LR11x0::clearIrqState(uint32_t irq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::configLfClock(uint8_t setup) {
|
int16_t LR11x0::configLfClock(uint8_t setup) {
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CONFIG_LF_CLOCK, true, &setup, 1));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CONFIG_LF_LOCK, true, &setup, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::setTcxoMode(uint8_t tune, uint32_t delay) {
|
int16_t LR11x0::setTcxoMode(uint8_t tune, uint32_t delay) {
|
||||||
|
@ -2772,7 +2751,7 @@ int16_t LR11x0::setModulationParamsLoRa(uint8_t sf, uint8_t bw, uint8_t cr, uint
|
||||||
// calculate symbol length and enable low data rate optimization, if auto-configuration is enabled
|
// calculate symbol length and enable low data rate optimization, if auto-configuration is enabled
|
||||||
if(this->ldroAuto) {
|
if(this->ldroAuto) {
|
||||||
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
|
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
|
||||||
if(symbolLength >= 16.0f) {
|
if(symbolLength >= 16.0) {
|
||||||
this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_ENABLED;
|
this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_ENABLED;
|
||||||
} else {
|
} else {
|
||||||
this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_DISABLED;
|
this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_DISABLED;
|
||||||
|
@ -2971,7 +2950,7 @@ int16_t LR11x0::setLoRaSyncWord(uint8_t sync) {
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_LORA_SYNC_WORD, true, buff, sizeof(buff)));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_LORA_SYNC_WORD, true, buff, sizeof(buff)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::lrFhssBuildFrame(uint8_t hdrCount, uint8_t cr, uint8_t grid, bool hop, uint8_t bw, uint16_t hopSeq, int8_t devOffset, const uint8_t* payload, size_t len) {
|
int16_t LR11x0::lrFhssBuildFrame(uint8_t hdrCount, uint8_t cr, uint8_t grid, bool hop, uint8_t bw, uint16_t hopSeq, int8_t devOffset, uint8_t* payload, size_t len) {
|
||||||
// check maximum size
|
// check maximum size
|
||||||
const uint8_t maxLen[4][4] = {
|
const uint8_t maxLen[4][4] = {
|
||||||
{ 189, 178, 167, 155, },
|
{ 189, 178, 167, 155, },
|
||||||
|
@ -3018,7 +2997,7 @@ int16_t LR11x0::lrFhssSetSyncWord(uint32_t sync) {
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_LR_FHSS_SET_SYNC_WORD, true, buff, sizeof(buff)));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_LR_FHSS_SET_SYNC_WORD, true, buff, sizeof(buff)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::configBleBeacon(uint8_t chan, const uint8_t* payload, size_t len) {
|
int16_t LR11x0::configBleBeacon(uint8_t chan, uint8_t* payload, size_t len) {
|
||||||
return(this->bleBeaconCommon(RADIOLIB_LR11X0_CMD_CONFIG_BLE_BEACON, chan, payload, len));
|
return(this->bleBeaconCommon(RADIOLIB_LR11X0_CMD_CONFIG_BLE_BEACON, chan, payload, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3032,11 +3011,11 @@ int16_t LR11x0::getLoRaRxHeaderInfos(uint8_t* info) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::bleBeaconSend(uint8_t chan, const uint8_t* payload, size_t len) {
|
int16_t LR11x0::bleBeaconSend(uint8_t chan, uint8_t* payload, size_t len) {
|
||||||
return(this->bleBeaconCommon(RADIOLIB_LR11X0_CMD_BLE_BEACON_SEND, chan, payload, len));
|
return(this->bleBeaconCommon(RADIOLIB_LR11X0_CMD_BLE_BEACON_SEND, chan, payload, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::bleBeaconCommon(uint16_t cmd, uint8_t chan, const uint8_t* payload, size_t len) {
|
int16_t LR11x0::bleBeaconCommon(uint16_t cmd, uint8_t chan, uint8_t* payload, size_t len) {
|
||||||
// check maximum size
|
// check maximum size
|
||||||
// TODO what is the actual maximum?
|
// TODO what is the actual maximum?
|
||||||
if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
|
if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
|
||||||
|
@ -3254,8 +3233,8 @@ int16_t LR11x0::gnssAssisted(uint32_t gpsTime, uint8_t effort, uint8_t resMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::gnssSetAssistancePosition(float lat, float lon) {
|
int16_t LR11x0::gnssSetAssistancePosition(float lat, float lon) {
|
||||||
int16_t latRaw = (lat*2048.0f)/90.0f + 0.5f;
|
uint16_t latRaw = (lat*2048.0f)/90.0f + 0.5f;
|
||||||
int16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
|
uint16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
|
||||||
uint8_t buff[4] = {
|
uint8_t buff[4] = {
|
||||||
(uint8_t)((latRaw >> 8) & 0xFF), (uint8_t)(latRaw & 0xFF),
|
(uint8_t)((latRaw >> 8) & 0xFF), (uint8_t)(latRaw & 0xFF),
|
||||||
(uint8_t)((lonRaw >> 8) & 0xFF), (uint8_t)(lonRaw & 0xFF),
|
(uint8_t)((lonRaw >> 8) & 0xFF), (uint8_t)(lonRaw & 0xFF),
|
||||||
|
@ -3269,11 +3248,11 @@ int16_t LR11x0::gnssReadAssistancePosition(float* lat, float* lon) {
|
||||||
|
|
||||||
// pass the replies
|
// pass the replies
|
||||||
if(lat) {
|
if(lat) {
|
||||||
int16_t latRaw = ((int16_t)(buff[0]) << 8) | (int16_t)(buff[1]);
|
uint16_t latRaw = ((uint16_t)(buff[0]) << 8) | (uint16_t)(buff[1]);
|
||||||
*lat = ((float)latRaw*90.0f)/2048.0f;
|
*lat = ((float)latRaw*90.0f)/2048.0f;
|
||||||
}
|
}
|
||||||
if(lon) {
|
if(lon) {
|
||||||
int16_t lonRaw = ((int16_t)(buff[2]) << 8) | (int16_t)(buff[3]);
|
uint16_t lonRaw = ((uint16_t)(buff[2]) << 8) | (uint16_t)(buff[3]);
|
||||||
*lon = ((float)lonRaw*180.0f)/2048.0f;
|
*lon = ((float)lonRaw*180.0f)/2048.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3379,7 +3358,7 @@ int16_t LR11x0::gnssAlmanacFullUpdateHeader(uint16_t date, uint32_t globalCrc) {
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE, true, buff, sizeof(buff)));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE, true, buff, sizeof(buff)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::gnssAlmanacFullUpdateSV(uint8_t svn, const uint8_t* svnAlmanac) {
|
int16_t LR11x0::gnssAlmanacFullUpdateSV(uint8_t svn, uint8_t* svnAlmanac) {
|
||||||
uint8_t buff[RADIOLIB_LR11X0_GNSS_ALMANAC_BLOCK_SIZE] = { svn };
|
uint8_t buff[RADIOLIB_LR11X0_GNSS_ALMANAC_BLOCK_SIZE] = { svn };
|
||||||
memcpy(&buff[1], svnAlmanac, RADIOLIB_LR11X0_GNSS_ALMANAC_BLOCK_SIZE - 1);
|
memcpy(&buff[1], svnAlmanac, RADIOLIB_LR11X0_GNSS_ALMANAC_BLOCK_SIZE - 1);
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE, true, buff, sizeof(buff)));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE, true, buff, sizeof(buff)));
|
||||||
|
@ -3403,8 +3382,8 @@ int16_t LR11x0::gnssAlmanacReadSV(uint8_t svId, uint8_t* almanac) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::gnssGetNbSvVisible(uint32_t time, float lat, float lon, uint8_t constellation, uint8_t* nbSv) {
|
int16_t LR11x0::gnssGetNbSvVisible(uint32_t time, float lat, float lon, uint8_t constellation, uint8_t* nbSv) {
|
||||||
int16_t latRaw = (lat*2048.0f)/90.0f + 0.5f;
|
uint16_t latRaw = (lat*2048.0f)/90.0f + 0.5f;
|
||||||
int16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
|
uint16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
|
||||||
uint8_t reqBuff[9] = {
|
uint8_t reqBuff[9] = {
|
||||||
(uint8_t)((time >> 24) & 0xFF), (uint8_t)((time >> 16) & 0xFF),
|
(uint8_t)((time >> 24) & 0xFF), (uint8_t)((time >> 16) & 0xFF),
|
||||||
(uint8_t)((time >> 8) & 0xFF), (uint8_t)(time & 0xFF),
|
(uint8_t)((time >> 8) & 0xFF), (uint8_t)(time & 0xFF),
|
||||||
|
@ -3541,21 +3520,21 @@ int16_t LR11x0::gnssReadDopplerSolverRes(uint8_t* error, uint8_t* nbSvUsed, floa
|
||||||
if(error) { *error = buff[0]; }
|
if(error) { *error = buff[0]; }
|
||||||
if(nbSvUsed) { *nbSvUsed = buff[1]; }
|
if(nbSvUsed) { *nbSvUsed = buff[1]; }
|
||||||
if(lat) {
|
if(lat) {
|
||||||
int16_t latRaw = ((int16_t)(buff[2]) << 8) | (int16_t)buff[3];
|
uint16_t latRaw = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3];
|
||||||
*lat = ((float)latRaw * 90.0f)/2048.0f;
|
*lat = ((float)latRaw * 90.0f)/2048.0f;
|
||||||
}
|
}
|
||||||
if(lon) {
|
if(lon) {
|
||||||
int16_t lonRaw = ((int16_t)(buff[4]) << 8) | (int16_t)buff[5];
|
uint16_t lonRaw = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5];
|
||||||
*lon = ((float)lonRaw * 180.0f)/2048.0f;
|
*lon = ((float)lonRaw * 180.0f)/2048.0f;
|
||||||
}
|
}
|
||||||
if(accuracy) { *accuracy = ((uint16_t)(buff[6]) << 8) | (uint16_t)buff[7]; }
|
if(accuracy) { *accuracy = ((uint16_t)(buff[6]) << 8) | (uint16_t)buff[7]; }
|
||||||
if(xtal) { *xtal = ((uint16_t)(buff[8]) << 8) | (uint16_t)buff[9]; }
|
if(xtal) { *xtal = ((uint16_t)(buff[8]) << 8) | (uint16_t)buff[9]; }
|
||||||
if(latFilt) {
|
if(latFilt) {
|
||||||
int16_t latRaw = ((int16_t)(buff[10]) << 8) | (int16_t)buff[11];
|
uint16_t latRaw = ((uint16_t)(buff[10]) << 8) | (uint16_t)buff[11];
|
||||||
*latFilt = ((float)latRaw * 90.0f)/2048.0f;
|
*latFilt = ((float)latRaw * 90.0f)/2048.0f;
|
||||||
}
|
}
|
||||||
if(lonFilt) {
|
if(lonFilt) {
|
||||||
int16_t lonRaw = ((int16_t)(buff[12]) << 8) | (int16_t)buff[13];
|
uint16_t lonRaw = ((uint16_t)(buff[12]) << 8) | (uint16_t)buff[13];
|
||||||
*lonFilt = ((float)lonRaw * 180.0f)/2048.0f;
|
*lonFilt = ((float)lonRaw * 180.0f)/2048.0f;
|
||||||
}
|
}
|
||||||
if(accuracyFilt) { *accuracyFilt = ((uint16_t)(buff[14]) << 8) | (uint16_t)buff[15]; }
|
if(accuracyFilt) { *accuracyFilt = ((uint16_t)(buff[14]) << 8) | (uint16_t)buff[15]; }
|
||||||
|
@ -3653,7 +3632,7 @@ void LR11x0::gnssAbort() {
|
||||||
// send the abort signal (single NOP)
|
// send the abort signal (single NOP)
|
||||||
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
|
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
|
||||||
// we need to call the most basic overload of the SPI write method otherwise the call will be ambiguous
|
// we need to call the most basic overload of the SPI write method otherwise the call will be ambiguous
|
||||||
const uint8_t cmd[2] = { 0, 0 };
|
uint8_t cmd[2] = { 0, 0 };
|
||||||
this->mod->SPIwriteStream(cmd, 2, NULL, 0, false, false);
|
this->mod->SPIwriteStream(cmd, 2, NULL, 0, false, false);
|
||||||
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
|
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
|
||||||
|
|
||||||
|
@ -3661,7 +3640,7 @@ void LR11x0::gnssAbort() {
|
||||||
this->mod->hal->delay(3000);
|
this->mod->hal->delay(3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoSetKey(uint8_t keyId, const uint8_t* key) {
|
int16_t LR11x0::cryptoSetKey(uint8_t keyId, uint8_t* key) {
|
||||||
RADIOLIB_ASSERT_PTR(key);
|
RADIOLIB_ASSERT_PTR(key);
|
||||||
uint8_t buff[1 + RADIOLIB_AES128_KEY_SIZE] = { 0 };
|
uint8_t buff[1 + RADIOLIB_AES128_KEY_SIZE] = { 0 };
|
||||||
buff[0] = keyId;
|
buff[0] = keyId;
|
||||||
|
@ -3669,7 +3648,7 @@ int16_t LR11x0::cryptoSetKey(uint8_t keyId, const uint8_t* key) {
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CRYPTO_SET_KEY, false, buff, sizeof(buff)));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CRYPTO_SET_KEY, false, buff, sizeof(buff)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, const uint8_t* key) {
|
int16_t LR11x0::cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, uint8_t* key) {
|
||||||
RADIOLIB_ASSERT_PTR(key);
|
RADIOLIB_ASSERT_PTR(key);
|
||||||
uint8_t buff[2 + RADIOLIB_AES128_KEY_SIZE] = { 0 };
|
uint8_t buff[2 + RADIOLIB_AES128_KEY_SIZE] = { 0 };
|
||||||
buff[0] = srcKeyId;
|
buff[0] = srcKeyId;
|
||||||
|
@ -3678,7 +3657,7 @@ int16_t LR11x0::cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, const uint8_
|
||||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CRYPTO_DERIVE_KEY, false, buff, sizeof(buff)));
|
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CRYPTO_DERIVE_KEY, false, buff, sizeof(buff)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoProcessJoinAccept(uint8_t decKeyId, uint8_t verKeyId, uint8_t lwVer, const uint8_t* header, const uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
int16_t LR11x0::cryptoProcessJoinAccept(uint8_t decKeyId, uint8_t verKeyId, uint8_t lwVer, uint8_t* header, uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
||||||
// calculate buffer sizes
|
// calculate buffer sizes
|
||||||
size_t headerLen = 1;
|
size_t headerLen = 1;
|
||||||
if(lwVer) {
|
if(lwVer) {
|
||||||
|
@ -3731,7 +3710,7 @@ int16_t LR11x0::cryptoProcessJoinAccept(uint8_t decKeyId, uint8_t verKeyId, uint
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoComputeAesCmac(uint8_t keyId, const uint8_t* data, size_t len, uint32_t* mic) {
|
int16_t LR11x0::cryptoComputeAesCmac(uint8_t keyId, uint8_t* data, size_t len, uint32_t* mic) {
|
||||||
size_t reqLen = sizeof(uint8_t) + len;
|
size_t reqLen = sizeof(uint8_t) + len;
|
||||||
#if RADIOLIB_STATIC_ONLY
|
#if RADIOLIB_STATIC_ONLY
|
||||||
uint8_t reqBuff[sizeof(uint8_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
|
uint8_t reqBuff[sizeof(uint8_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
|
||||||
|
@ -3758,7 +3737,7 @@ int16_t LR11x0::cryptoComputeAesCmac(uint8_t keyId, const uint8_t* data, size_t
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, const uint8_t* data, size_t len, bool* result) {
|
int16_t LR11x0::cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, uint8_t* data, size_t len, bool* result) {
|
||||||
size_t reqLen = sizeof(uint8_t) + sizeof(uint32_t) + len;
|
size_t reqLen = sizeof(uint8_t) + sizeof(uint32_t) + len;
|
||||||
#if RADIOLIB_STATIC_ONLY
|
#if RADIOLIB_STATIC_ONLY
|
||||||
uint8_t reqBuff[sizeof(uint8_t) + sizeof(uint32_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
|
uint8_t reqBuff[sizeof(uint8_t) + sizeof(uint32_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
|
||||||
|
@ -3789,15 +3768,15 @@ int16_t LR11x0::cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, const uint8_
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoAesEncrypt01(uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
int16_t LR11x0::cryptoAesEncrypt01(uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
||||||
return(this->cryptoCommon(RADIOLIB_LR11X0_CMD_CRYPTO_AES_ENCRYPT_01, keyId, dataIn, len, dataOut));
|
return(this->cryptoCommon(RADIOLIB_LR11X0_CMD_CRYPTO_AES_ENCRYPT_01, keyId, dataIn, len, dataOut));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoAesEncrypt(uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
int16_t LR11x0::cryptoAesEncrypt(uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
||||||
return(this->cryptoCommon(RADIOLIB_LR11X0_CMD_CRYPTO_AES_ENCRYPT, keyId, dataIn, len, dataOut));
|
return(this->cryptoCommon(RADIOLIB_LR11X0_CMD_CRYPTO_AES_ENCRYPT, keyId, dataIn, len, dataOut));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoAesDecrypt(uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
int16_t LR11x0::cryptoAesDecrypt(uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
||||||
return(this->cryptoCommon(RADIOLIB_LR11X0_CMD_CRYPTO_AES_DECRYPT, keyId, dataIn, len, dataOut));
|
return(this->cryptoCommon(RADIOLIB_LR11X0_CMD_CRYPTO_AES_DECRYPT, keyId, dataIn, len, dataOut));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3827,7 +3806,7 @@ int16_t LR11x0::cryptoGetParam(uint8_t id, uint32_t* value) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoCheckEncryptedFirmwareImage(uint32_t offset, const uint32_t* data, size_t len, bool nonvolatile) {
|
int16_t LR11x0::cryptoCheckEncryptedFirmwareImage(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile) {
|
||||||
// check maximum size
|
// check maximum size
|
||||||
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
||||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||||
|
@ -3854,7 +3833,7 @@ int16_t LR11x0::bootEraseFlash(void) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::bootWriteFlashEncrypted(uint32_t offset, const uint32_t* data, size_t len, bool nonvolatile) {
|
int16_t LR11x0::bootWriteFlashEncrypted(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile) {
|
||||||
// check maximum size
|
// check maximum size
|
||||||
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
||||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||||
|
@ -3902,8 +3881,7 @@ int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* d
|
||||||
for(size_t i = 0; i < len; i++) {
|
for(size_t i = 0; i < len; i++) {
|
||||||
uint32_t bin = 0;
|
uint32_t bin = 0;
|
||||||
if(nonvolatile) {
|
if(nonvolatile) {
|
||||||
uint32_t* ptr = const_cast<uint32_t*>(data) + i;
|
bin = RADIOLIB_NONVOLATILE_READ_DWORD(data + i);
|
||||||
bin = RADIOLIB_NONVOLATILE_READ_DWORD(ptr);
|
|
||||||
} else {
|
} else {
|
||||||
bin = data[i];
|
bin = data[i];
|
||||||
}
|
}
|
||||||
|
@ -3920,7 +3898,7 @@ int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* d
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t LR11x0::cryptoCommon(uint16_t cmd, uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
int16_t LR11x0::cryptoCommon(uint16_t cmd, uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut) {
|
||||||
// build buffers
|
// build buffers
|
||||||
#if RADIOLIB_STATIC_ONLY
|
#if RADIOLIB_STATIC_ONLY
|
||||||
uint8_t reqBuff[RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
|
uint8_t reqBuff[RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#define RADIOLIB_LR11X0_CMD_SET_DIO_AS_RF_SWITCH (0x0112)
|
#define RADIOLIB_LR11X0_CMD_SET_DIO_AS_RF_SWITCH (0x0112)
|
||||||
#define RADIOLIB_LR11X0_CMD_SET_DIO_IRQ_PARAMS (0x0113)
|
#define RADIOLIB_LR11X0_CMD_SET_DIO_IRQ_PARAMS (0x0113)
|
||||||
#define RADIOLIB_LR11X0_CMD_CLEAR_IRQ (0x0114)
|
#define RADIOLIB_LR11X0_CMD_CLEAR_IRQ (0x0114)
|
||||||
#define RADIOLIB_LR11X0_CMD_CONFIG_LF_CLOCK (0x0116)
|
#define RADIOLIB_LR11X0_CMD_CONFIG_LF_LOCK (0x0116)
|
||||||
#define RADIOLIB_LR11X0_CMD_SET_TCXO_MODE (0x0117)
|
#define RADIOLIB_LR11X0_CMD_SET_TCXO_MODE (0x0117)
|
||||||
#define RADIOLIB_LR11X0_CMD_REBOOT (0x0118)
|
#define RADIOLIB_LR11X0_CMD_REBOOT (0x0118)
|
||||||
#define RADIOLIB_LR11X0_CMD_GET_VBAT (0x0119)
|
#define RADIOLIB_LR11X0_CMD_GET_VBAT (0x0119)
|
||||||
|
@ -233,7 +233,7 @@
|
||||||
#define RADIOLIB_LR11X0_CALIBRATE_HF_RC (0x01UL << 1) // 1 1 high frequency RC
|
#define RADIOLIB_LR11X0_CALIBRATE_HF_RC (0x01UL << 1) // 1 1 high frequency RC
|
||||||
#define RADIOLIB_LR11X0_CALIBRATE_LF_RC (0x01UL << 0) // 0 0 low frequency RC
|
#define RADIOLIB_LR11X0_CALIBRATE_LF_RC (0x01UL << 0) // 0 0 low frequency RC
|
||||||
#define RADIOLIB_LR11X0_CALIBRATE_ALL (0x3FUL << 0) // 5 0 everything
|
#define RADIOLIB_LR11X0_CALIBRATE_ALL (0x3FUL << 0) // 5 0 everything
|
||||||
#define RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ (20.0f)
|
#define RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ (20.0)
|
||||||
|
|
||||||
// RADIOLIB_LR11X0_CMD_SET_REG_MODE
|
// RADIOLIB_LR11X0_CMD_SET_REG_MODE
|
||||||
#define RADIOLIB_LR11X0_REG_MODE_LDO (0x00UL << 0) // 0 0 regulator mode: LDO in all modes
|
#define RADIOLIB_LR11X0_REG_MODE_LDO (0x00UL << 0) // 0 0 regulator mode: LDO in all modes
|
||||||
|
@ -281,7 +281,7 @@
|
||||||
#define RADIOLIB_LR11X0_IRQ_ALL (0x1BF80FFCUL) // 31 0 all interrupts
|
#define RADIOLIB_LR11X0_IRQ_ALL (0x1BF80FFCUL) // 31 0 all interrupts
|
||||||
#define RADIOLIB_LR11X0_IRQ_NONE (0x00UL << 0) // 31 0 no interrupts
|
#define RADIOLIB_LR11X0_IRQ_NONE (0x00UL << 0) // 31 0 no interrupts
|
||||||
|
|
||||||
// RADIOLIB_LR11X0_CMD_CONFIG_LF_CLOCK
|
// RADIOLIB_LR11X0_CMD_CONFIG_LF_LOCK
|
||||||
#define RADIOLIB_LR11X0_LF_CLK_RC (0x00UL << 0) // 1 0 32.768 kHz source: RC oscillator
|
#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_XOSC (0x01UL << 0) // 1 0 crystal oscillator
|
||||||
#define RADIOLIB_LR11X0_LF_CLK_EXT (0x02UL << 0) // 1 0 external signal on DIO11
|
#define RADIOLIB_LR11X0_LF_CLK_EXT (0x02UL << 0) // 1 0 external signal on DIO11
|
||||||
|
@ -409,7 +409,7 @@
|
||||||
#define RADIOLIB_LR11X0_GFSK_RX_BW_312_0 (0x19UL << 0) // 7 0 312.0 kHz
|
#define RADIOLIB_LR11X0_GFSK_RX_BW_312_0 (0x19UL << 0) // 7 0 312.0 kHz
|
||||||
#define RADIOLIB_LR11X0_GFSK_RX_BW_373_6 (0x11UL << 0) // 7 0 373.6 kHz
|
#define RADIOLIB_LR11X0_GFSK_RX_BW_373_6 (0x11UL << 0) // 7 0 373.6 kHz
|
||||||
#define RADIOLIB_LR11X0_GFSK_RX_BW_467_0 (0x09UL << 0) // 7 0 467.0 kHz
|
#define RADIOLIB_LR11X0_GFSK_RX_BW_467_0 (0x09UL << 0) // 7 0 467.0 kHz
|
||||||
#define RADIOLIB_LR11X0_LR_FHSS_BIT_RATE (488.28215f) // 31 0 LR FHSS bit rate: 488.28215 bps
|
#define RADIOLIB_LR11X0_LR_FHSS_BIT_RATE (488.28215) // 31 0 LR FHSS bit rate: 488.28215 bps
|
||||||
#define RADIOLIB_LR11X0_LR_FHSS_BIT_RATE_RAW (0x8001E848UL) // 31 0 488.28215 bps in raw
|
#define RADIOLIB_LR11X0_LR_FHSS_BIT_RATE_RAW (0x8001E848UL) // 31 0 488.28215 bps in raw
|
||||||
#define RADIOLIB_LR11X0_LR_FHSS_SHAPING_GAUSSIAN_BT_1_0 (0x0BUL << 0) // 7 0 shaping filter: Gaussian, BT = 1.0
|
#define RADIOLIB_LR11X0_LR_FHSS_SHAPING_GAUSSIAN_BT_1_0 (0x0BUL << 0) // 7 0 shaping filter: Gaussian, BT = 1.0
|
||||||
#define RADIOLIB_LR11X0_SIGFOX_SHAPING_GAUSSIAN_BT_0_7 (0x16UL << 0) // 7 0 shaping filter: Gaussian, BT = 0.7
|
#define RADIOLIB_LR11X0_SIGFOX_SHAPING_GAUSSIAN_BT_0_7 (0x16UL << 0) // 7 0 shaping filter: Gaussian, BT = 0.7
|
||||||
|
@ -877,7 +877,6 @@ class LR11x0: public PhysicalLayer {
|
||||||
using PhysicalLayer::transmit;
|
using PhysicalLayer::transmit;
|
||||||
using PhysicalLayer::receive;
|
using PhysicalLayer::receive;
|
||||||
using PhysicalLayer::startTransmit;
|
using PhysicalLayer::startTransmit;
|
||||||
using PhysicalLayer::startReceive;
|
|
||||||
using PhysicalLayer::readData;
|
using PhysicalLayer::readData;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1074,6 +1073,16 @@ class LR11x0: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
void clearPacketSentAction() override;
|
void clearPacketSentAction() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Interrupt-driven binary transmit method.
|
||||||
|
Overloads for string-based transmissions are implemented in PhysicalLayer.
|
||||||
|
\param data Binary data to be sent.
|
||||||
|
\param len Number of bytes to send.
|
||||||
|
\param addr Address to send the data to. Will only be added if address filtering was enabled.
|
||||||
|
\returns \ref status_codes
|
||||||
|
*/
|
||||||
|
int16_t startTransmit(const uint8_t* data, size_t len, uint8_t addr = 0) override;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Clean up after transmission is done.
|
\brief Clean up after transmission is done.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
|
@ -1088,6 +1097,20 @@ class LR11x0: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
int16_t startReceive() override;
|
int16_t startReceive() override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Interrupt-driven receive method. IRQ1 will be activated when full packet is received.
|
||||||
|
\param timeout Raw timeout value, expressed as multiples of 1/32.768 kHz (approximately 30.52 us).
|
||||||
|
Defaults to RADIOLIB_LR11X0_RX_TIMEOUT_INF for infinite timeout (Rx continuous mode),
|
||||||
|
set to RADIOLIB_LR11X0_RX_TIMEOUT_NONE for no timeout (Rx single mode).
|
||||||
|
If timeout other than infinite is set, signal will be generated on IRQ1.
|
||||||
|
|
||||||
|
\param irqFlags Sets the IRQ flags that will trigger IRQ1, defaults to RADIOLIB_LR11X0_IRQ_RX_DONE.
|
||||||
|
\param irqMask Only for PhysicalLayer compatibility, not used.
|
||||||
|
\param len Only for PhysicalLayer compatibility, not used.
|
||||||
|
\returns \ref status_codes
|
||||||
|
*/
|
||||||
|
int16_t startReceive(uint32_t timeout, uint32_t irqFlags = RADIOLIB_LR11X0_IRQ_RX_DONE, uint32_t irqMask = 0, size_t len = 0);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Reads the current IRQ status.
|
\brief Reads the current IRQ status.
|
||||||
\returns IRQ status bits
|
\returns IRQ status bits
|
||||||
|
@ -1153,11 +1176,11 @@ class LR11x0: public PhysicalLayer {
|
||||||
int16_t setCodingRate(uint8_t cr, bool longInterleave = false);
|
int16_t setCodingRate(uint8_t cr, bool longInterleave = false);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets LoRa sync word.
|
\brief Sets LoRa or LR-FHSS sync word.
|
||||||
\param syncWord LoRa sync word to be set.
|
\param syncWord LoRa or LR-FHSS sync word to be set. For LoRa, only 8 least significant bits will be used
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t setSyncWord(uint8_t syncWord);
|
int16_t setSyncWord(uint32_t syncWord);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets GFSK bit rate. Allowed values range from 0.6 to 300.0 kbps.
|
\brief Sets GFSK bit rate. Allowed values range from 0.6 to 300.0 kbps.
|
||||||
|
@ -1599,21 +1622,15 @@ class LR11x0: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
int16_t calibrateImageRejection(float freqMin, float freqMax);
|
int16_t calibrateImageRejection(float freqMin, float freqMax);
|
||||||
|
|
||||||
/*! \copydoc PhysicalLayer::stageMode */
|
|
||||||
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) override;
|
|
||||||
|
|
||||||
/*! \copydoc PhysicalLayer::launchMode */
|
|
||||||
int16_t launchMode() override;
|
|
||||||
|
|
||||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||||
protected:
|
protected:
|
||||||
#endif
|
#endif
|
||||||
Module* getMod() override;
|
Module* getMod() override;
|
||||||
|
|
||||||
// LR11x0 SPI command implementations
|
// LR11x0 SPI command implementations
|
||||||
int16_t writeRegMem32(uint32_t addr, const uint32_t* data, size_t len);
|
int16_t writeRegMem32(uint32_t addr, uint32_t* data, size_t len);
|
||||||
int16_t readRegMem32(uint32_t addr, uint32_t* data, size_t len);
|
int16_t readRegMem32(uint32_t addr, uint32_t* data, size_t len);
|
||||||
int16_t writeBuffer8(const uint8_t* data, size_t len);
|
int16_t writeBuffer8(uint8_t* data, size_t len);
|
||||||
int16_t readBuffer8(uint8_t* data, size_t len, size_t offset);
|
int16_t readBuffer8(uint8_t* data, size_t len, size_t offset);
|
||||||
int16_t clearRxBuffer(void);
|
int16_t clearRxBuffer(void);
|
||||||
int16_t writeRegMemMask32(uint32_t addr, uint32_t mask, uint32_t data);
|
int16_t writeRegMemMask32(uint32_t addr, uint32_t mask, uint32_t data);
|
||||||
|
@ -1627,7 +1644,7 @@ class LR11x0: public PhysicalLayer {
|
||||||
int16_t setDioAsRfSwitch(uint8_t en, uint8_t stbyCfg, uint8_t rxCfg, uint8_t txCfg, uint8_t txHpCfg, uint8_t txHfCfg, uint8_t gnssCfg, uint8_t wifiCfg);
|
int16_t setDioAsRfSwitch(uint8_t en, uint8_t stbyCfg, uint8_t rxCfg, uint8_t txCfg, uint8_t txHpCfg, uint8_t txHfCfg, uint8_t gnssCfg, uint8_t wifiCfg);
|
||||||
int16_t setDioIrqParams(uint32_t irq1, uint32_t irq2);
|
int16_t setDioIrqParams(uint32_t irq1, uint32_t irq2);
|
||||||
int16_t setDioIrqParams(uint32_t irq);
|
int16_t setDioIrqParams(uint32_t irq);
|
||||||
int16_t clearIrqState(uint32_t irq);
|
int16_t clearIrq(uint32_t irq);
|
||||||
int16_t configLfClock(uint8_t setup);
|
int16_t configLfClock(uint8_t setup);
|
||||||
int16_t setTcxoMode(uint8_t tune, uint32_t delay);
|
int16_t setTcxoMode(uint8_t tune, uint32_t delay);
|
||||||
int16_t reboot(bool stay);
|
int16_t reboot(bool stay);
|
||||||
|
@ -1685,11 +1702,11 @@ class LR11x0: public PhysicalLayer {
|
||||||
int16_t setRangingParameter(uint8_t symbolNum);
|
int16_t setRangingParameter(uint8_t symbolNum);
|
||||||
int16_t setRssiCalibration(const int8_t* tune, int16_t gainOffset);
|
int16_t setRssiCalibration(const int8_t* tune, int16_t gainOffset);
|
||||||
int16_t setLoRaSyncWord(uint8_t sync);
|
int16_t setLoRaSyncWord(uint8_t sync);
|
||||||
int16_t lrFhssBuildFrame(uint8_t hdrCount, uint8_t cr, uint8_t grid, bool hop, uint8_t bw, uint16_t hopSeq, int8_t devOffset, const uint8_t* payload, size_t len);
|
int16_t lrFhssBuildFrame(uint8_t hdrCount, uint8_t cr, uint8_t grid, bool hop, uint8_t bw, uint16_t hopSeq, int8_t devOffset, uint8_t* payload, size_t len);
|
||||||
int16_t lrFhssSetSyncWord(uint32_t sync);
|
int16_t lrFhssSetSyncWord(uint32_t sync);
|
||||||
int16_t configBleBeacon(uint8_t chan, const uint8_t* payload, size_t len);
|
int16_t configBleBeacon(uint8_t chan, uint8_t* payload, size_t len);
|
||||||
int16_t getLoRaRxHeaderInfos(uint8_t* info);
|
int16_t getLoRaRxHeaderInfos(uint8_t* info);
|
||||||
int16_t bleBeaconSend(uint8_t chan, const uint8_t* payload, size_t len);
|
int16_t bleBeaconSend(uint8_t chan, uint8_t* payload, size_t len);
|
||||||
|
|
||||||
int16_t wifiScan(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t nbMaxRes, uint8_t nbScanPerChan, uint16_t timeout, uint8_t abortOnTimeout);
|
int16_t wifiScan(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t nbMaxRes, uint8_t nbScanPerChan, uint16_t timeout, uint8_t abortOnTimeout);
|
||||||
int16_t wifiScanTimeLimit(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t nbMaxRes, uint16_t timePerChan, uint16_t timeout);
|
int16_t wifiScanTimeLimit(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t nbMaxRes, uint16_t timePerChan, uint16_t timeout);
|
||||||
|
@ -1727,7 +1744,7 @@ class LR11x0: public PhysicalLayer {
|
||||||
int16_t gnssGetResultSize(uint16_t* size);
|
int16_t gnssGetResultSize(uint16_t* size);
|
||||||
int16_t gnssReadResults(uint8_t* result, uint16_t size);
|
int16_t gnssReadResults(uint8_t* result, uint16_t size);
|
||||||
int16_t gnssAlmanacFullUpdateHeader(uint16_t date, uint32_t globalCrc);
|
int16_t gnssAlmanacFullUpdateHeader(uint16_t date, uint32_t globalCrc);
|
||||||
int16_t gnssAlmanacFullUpdateSV(uint8_t svn, const uint8_t* svnAlmanac);
|
int16_t gnssAlmanacFullUpdateSV(uint8_t svn, uint8_t* svnAlmanac);
|
||||||
int16_t gnssAlmanacReadAddrSize(uint32_t* addr, uint16_t* size);
|
int16_t gnssAlmanacReadAddrSize(uint32_t* addr, uint16_t* size);
|
||||||
int16_t gnssAlmanacReadSV(uint8_t svId, uint8_t* almanac);
|
int16_t gnssAlmanacReadSV(uint8_t svId, uint8_t* almanac);
|
||||||
int16_t gnssGetNbSvVisible(uint32_t time, float lat, float lon, uint8_t constellation, uint8_t* nbSv);
|
int16_t gnssGetNbSvVisible(uint32_t time, float lat, float lon, uint8_t constellation, uint8_t* nbSv);
|
||||||
|
@ -1756,29 +1773,29 @@ class LR11x0: public PhysicalLayer {
|
||||||
int16_t gnssWriteBitMaskSatActivated(uint8_t bitMask, uint32_t* bitMaskActivated0, uint32_t* bitMaskActivated1);
|
int16_t gnssWriteBitMaskSatActivated(uint8_t bitMask, uint32_t* bitMaskActivated0, uint32_t* bitMaskActivated1);
|
||||||
void gnssAbort();
|
void gnssAbort();
|
||||||
|
|
||||||
int16_t cryptoSetKey(uint8_t keyId, const uint8_t* key);
|
int16_t cryptoSetKey(uint8_t keyId, uint8_t* key);
|
||||||
int16_t cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, const uint8_t* key);
|
int16_t cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, uint8_t* key);
|
||||||
int16_t cryptoProcessJoinAccept(uint8_t decKeyId, uint8_t verKeyId, uint8_t lwVer, const uint8_t* header, const uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
int16_t cryptoProcessJoinAccept(uint8_t decKeyId, uint8_t verKeyId, uint8_t lwVer, uint8_t* header, uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
||||||
int16_t cryptoComputeAesCmac(uint8_t keyId, const uint8_t* data, size_t len, uint32_t* mic);
|
int16_t cryptoComputeAesCmac(uint8_t keyId, uint8_t* data, size_t len, uint32_t* mic);
|
||||||
int16_t cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, const uint8_t* data, size_t len, bool* result);
|
int16_t cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, uint8_t* data, size_t len, bool* result);
|
||||||
int16_t cryptoAesEncrypt01(uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
int16_t cryptoAesEncrypt01(uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
||||||
int16_t cryptoAesEncrypt(uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
int16_t cryptoAesEncrypt(uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
||||||
int16_t cryptoAesDecrypt(uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
int16_t cryptoAesDecrypt(uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
||||||
int16_t cryptoStoreToFlash(void);
|
int16_t cryptoStoreToFlash(void);
|
||||||
int16_t cryptoRestoreFromFlash(void);
|
int16_t cryptoRestoreFromFlash(void);
|
||||||
int16_t cryptoSetParam(uint8_t id, uint32_t value);
|
int16_t cryptoSetParam(uint8_t id, uint32_t value);
|
||||||
int16_t cryptoGetParam(uint8_t id, uint32_t* value);
|
int16_t cryptoGetParam(uint8_t id, uint32_t* value);
|
||||||
int16_t cryptoCheckEncryptedFirmwareImage(uint32_t offset, const uint32_t* data, size_t len, bool nonvolatile);
|
int16_t cryptoCheckEncryptedFirmwareImage(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile);
|
||||||
int16_t cryptoCheckEncryptedFirmwareImageResult(bool* result);
|
int16_t cryptoCheckEncryptedFirmwareImageResult(bool* result);
|
||||||
|
|
||||||
int16_t bootEraseFlash(void);
|
int16_t bootEraseFlash(void);
|
||||||
int16_t bootWriteFlashEncrypted(uint32_t offset, const uint32_t* data, size_t len, bool nonvolatile);
|
int16_t bootWriteFlashEncrypted(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile);
|
||||||
int16_t bootReboot(bool stay);
|
int16_t bootReboot(bool stay);
|
||||||
int16_t bootGetPin(uint8_t* pin);
|
int16_t bootGetPin(uint8_t* pin);
|
||||||
int16_t bootGetChipEui(uint8_t* eui);
|
int16_t bootGetChipEui(uint8_t* eui);
|
||||||
int16_t bootGetJoinEui(uint8_t* eui);
|
int16_t bootGetJoinEui(uint8_t* eui);
|
||||||
|
|
||||||
int16_t SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out = NULL, size_t outLen = 0);
|
int16_t SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, uint8_t* out = NULL, size_t outLen = 0);
|
||||||
|
|
||||||
#if !RADIOLIB_GODMODE
|
#if !RADIOLIB_GODMODE
|
||||||
protected:
|
protected:
|
||||||
|
@ -1811,8 +1828,6 @@ class LR11x0: public PhysicalLayer {
|
||||||
float dataRateMeasured = 0;
|
float dataRateMeasured = 0;
|
||||||
|
|
||||||
uint8_t wifiScanMode = 0;
|
uint8_t wifiScanMode = 0;
|
||||||
bool gnss = false;
|
|
||||||
uint32_t rxTimeout = 0;
|
|
||||||
|
|
||||||
int16_t modSetup(float tcxoVoltage, uint8_t modem);
|
int16_t modSetup(float tcxoVoltage, uint8_t modem);
|
||||||
static int16_t SPIparseStatus(uint8_t in);
|
static int16_t SPIparseStatus(uint8_t in);
|
||||||
|
@ -1824,9 +1839,9 @@ class LR11x0: public PhysicalLayer {
|
||||||
int16_t setHeaderType(uint8_t hdrType, size_t len = 0xFF);
|
int16_t setHeaderType(uint8_t hdrType, size_t len = 0xFF);
|
||||||
|
|
||||||
// common methods to avoid some copy-paste
|
// common methods to avoid some copy-paste
|
||||||
int16_t bleBeaconCommon(uint16_t cmd, uint8_t chan, const uint8_t* payload, size_t len);
|
int16_t bleBeaconCommon(uint16_t cmd, uint8_t chan, uint8_t* payload, size_t len);
|
||||||
int16_t writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile);
|
int16_t writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile);
|
||||||
int16_t cryptoCommon(uint16_t cmd, uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
int16_t cryptoCommon(uint16_t cmd, uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#if !RADIOLIB_EXCLUDE_RF69
|
#if !RADIOLIB_EXCLUDE_RF69
|
||||||
|
|
||||||
RF69::RF69(Module* module) : PhysicalLayer() {
|
RF69::RF69(Module* module) : PhysicalLayer(RADIOLIB_RF69_FREQUENCY_STEP_SIZE, RADIOLIB_RF69_MAX_PACKET_LENGTH) {
|
||||||
this->freqStep = RADIOLIB_RF69_FREQUENCY_STEP_SIZE;
|
|
||||||
this->maxPacketLength = RADIOLIB_RF69_MAX_PACKET_LENGTH;
|
|
||||||
this->mod = module;
|
this->mod = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +122,7 @@ int16_t RF69::transmit(const uint8_t* data, size_t len, uint8_t addr) {
|
||||||
|
|
||||||
int16_t RF69::receive(uint8_t* data, size_t len) {
|
int16_t RF69::receive(uint8_t* data, size_t len) {
|
||||||
// calculate timeout (500 ms + 400 full 64-byte packets at current bit rate)
|
// calculate timeout (500 ms + 400 full 64-byte packets at current bit rate)
|
||||||
RadioLibTime_t timeout = 500 + (1.0f/(this->bitRate))*(RADIOLIB_RF69_MAX_PACKET_LENGTH*400.0f);
|
RadioLibTime_t timeout = 500 + (1.0/(this->bitRate))*(RADIOLIB_RF69_MAX_PACKET_LENGTH*400.0);
|
||||||
|
|
||||||
// start reception
|
// start reception
|
||||||
int16_t state = startReceive();
|
int16_t state = startReceive();
|
||||||
|
@ -221,7 +219,7 @@ int16_t RF69::packetMode() {
|
||||||
return(this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_PACKET_MODE, 6, 5));
|
return(this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_PACKET_MODE, 6, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RF69::setAESKey(const uint8_t* key) {
|
void RF69::setAESKey(uint8_t* key) {
|
||||||
this->mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_AES_KEY_1, key, 16);
|
this->mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_AES_KEY_1, key, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,10 +321,6 @@ void RF69::clearFifoEmptyAction() {
|
||||||
clearDio1Action();
|
clearDio1Action();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RF69::setFifoThreshold(uint8_t threshold) {
|
|
||||||
this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, threshold, 6, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RF69::setFifoFullAction(void (*func)(void)) {
|
void RF69::setFifoFullAction(void (*func)(void)) {
|
||||||
// set the interrupt
|
// set the interrupt
|
||||||
this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_FIFO_THRESH, 6, 0);
|
this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_FIFO_THRESH, 6, 0);
|
||||||
|
@ -366,7 +360,7 @@ bool RF69::fifoAdd(uint8_t* data, int totalLen, int* remLen) {
|
||||||
|
|
||||||
bool RF69::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) {
|
bool RF69::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) {
|
||||||
// get pointer to the correct position in data buffer
|
// get pointer to the correct position in data buffer
|
||||||
uint8_t* dataPtr = const_cast<uint8_t*>(&data[*rcvLen]);
|
uint8_t* dataPtr = (uint8_t*)&data[*rcvLen];
|
||||||
|
|
||||||
// check how much data are we still expecting
|
// check how much data are we still expecting
|
||||||
uint8_t len = RADIOLIB_RF69_FIFO_THRESH - 1;
|
uint8_t len = RADIOLIB_RF69_FIFO_THRESH - 1;
|
||||||
|
@ -525,9 +519,9 @@ int16_t RF69::setOokPeakThresholdDecrement(uint8_t value) {
|
||||||
|
|
||||||
int16_t RF69::setFrequency(float freq) {
|
int16_t RF69::setFrequency(float freq) {
|
||||||
// check allowed frequency range
|
// check allowed frequency range
|
||||||
if(!(((freq > 290.0f) && (freq < 340.0f)) ||
|
if(!(((freq > 290.0) && (freq < 340.0)) ||
|
||||||
((freq > 431.0f) && (freq < 510.0f)) ||
|
((freq > 431.0) && (freq < 510.0)) ||
|
||||||
((freq > 862.0f) && (freq < 1020.0f)))) {
|
((freq > 862.0) && (freq < 1020.0)))) {
|
||||||
return(RADIOLIB_ERR_INVALID_FREQUENCY);
|
return(RADIOLIB_ERR_INVALID_FREQUENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,7 +555,7 @@ int16_t RF69::getFrequency(float *freq) {
|
||||||
|
|
||||||
int16_t RF69::setBitRate(float br) {
|
int16_t RF69::setBitRate(float br) {
|
||||||
// datasheet says 1.2 kbps should be the smallest possible, but 0.512 works fine
|
// datasheet says 1.2 kbps should be the smallest possible, but 0.512 works fine
|
||||||
RADIOLIB_CHECK_RANGE(br, 0.5f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
|
RADIOLIB_CHECK_RANGE(br, 0.5, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
|
||||||
|
|
||||||
// check bitrate-bandwidth ratio
|
// check bitrate-bandwidth ratio
|
||||||
if(!(br < 2000 * this->rxBandwidth)) {
|
if(!(br < 2000 * this->rxBandwidth)) {
|
||||||
|
@ -594,8 +588,8 @@ int16_t RF69::setRxBandwidth(float rxBw) {
|
||||||
// calculate exponent and mantissa values for receiver bandwidth
|
// calculate exponent and mantissa values for receiver bandwidth
|
||||||
for(int8_t e = 7; e >= 0; e--) {
|
for(int8_t e = 7; e >= 0; e--) {
|
||||||
for(int8_t m = 2; m >= 0; m--) {
|
for(int8_t m = 2; m >= 0; m--) {
|
||||||
float point = (RADIOLIB_RF69_CRYSTAL_FREQ * 1000000.0f)/(((4 * m) + 16) * ((uint32_t)1 << (e + (this->ookEnabled ? 3 : 2))));
|
float point = (RADIOLIB_RF69_CRYSTAL_FREQ * 1000000.0)/(((4 * m) + 16) * ((uint32_t)1 << (e + (this->ookEnabled ? 3 : 2))));
|
||||||
if(fabsf(rxBw - (point / 1000.0f)) <= 0.1f) {
|
if(fabsf(rxBw - (point / 1000.0)) <= 0.1) {
|
||||||
// set Rx bandwidth
|
// set Rx bandwidth
|
||||||
state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_BW, (m << 3) | e, 4, 0);
|
state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_BW, (m << 3) | e, 4, 0);
|
||||||
if(state == RADIOLIB_ERR_NONE) {
|
if(state == RADIOLIB_ERR_NONE) {
|
||||||
|
@ -612,8 +606,8 @@ int16_t RF69::setRxBandwidth(float rxBw) {
|
||||||
int16_t RF69::setFrequencyDeviation(float freqDev) {
|
int16_t RF69::setFrequencyDeviation(float freqDev) {
|
||||||
// set frequency deviation to lowest available setting (required for digimodes)
|
// set frequency deviation to lowest available setting (required for digimodes)
|
||||||
float newFreqDev = freqDev;
|
float newFreqDev = freqDev;
|
||||||
if(freqDev < 0.0f) {
|
if(freqDev < 0.0) {
|
||||||
newFreqDev = 0.6f;
|
newFreqDev = 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check frequency deviation range
|
// check frequency deviation range
|
||||||
|
@ -650,7 +644,7 @@ int16_t RF69::getFrequencyDeviation(float *freqDev) {
|
||||||
|
|
||||||
// calculate frequency deviation from raw value obtained from register
|
// calculate frequency deviation from raw value obtained from register
|
||||||
// Fdev = Fstep * Fdev(13:0) (pag. 20 of datasheet)
|
// Fdev = Fstep * Fdev(13:0) (pag. 20 of datasheet)
|
||||||
*freqDev = (1000.0f * fdev * RADIOLIB_RF69_CRYSTAL_FREQ) /
|
*freqDev = (1000.0 * fdev * RADIOLIB_RF69_CRYSTAL_FREQ) /
|
||||||
(uint32_t(1) << RADIOLIB_RF69_DIV_EXPONENT);
|
(uint32_t(1) << RADIOLIB_RF69_DIV_EXPONENT);
|
||||||
|
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
|
@ -694,9 +688,9 @@ int16_t RF69::setOutputPower(int8_t pwr, bool highPower) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t RF69::setSyncWord(const uint8_t* syncWord, size_t len, uint8_t maxErrBits) {
|
int16_t RF69::setSyncWord(uint8_t* syncWord, size_t len, uint8_t maxErrBits) {
|
||||||
// check constraints
|
// check constraints
|
||||||
if((maxErrBits > 7) || (len == 0) || (len > 8)) {
|
if((maxErrBits > 7) || (len > 8)) {
|
||||||
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,15 +701,16 @@ int16_t RF69::setSyncWord(const uint8_t* syncWord, size_t len, uint8_t maxErrBit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable filtering
|
|
||||||
int16_t state = enableSyncWordFiltering(maxErrBits);
|
int16_t state = enableSyncWordFiltering(maxErrBits);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set the length
|
|
||||||
state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, (len-1)<<3, 5, 3);
|
|
||||||
|
|
||||||
// set sync word register
|
// set sync word register
|
||||||
this->mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_SYNC_VALUE_1, syncWord, len);
|
this->mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_SYNC_VALUE_1, syncWord, len);
|
||||||
|
|
||||||
|
if(state == RADIOLIB_ERR_NONE) {
|
||||||
|
this->syncWordLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,11 +801,7 @@ int16_t RF69::variablePacketLengthMode(uint8_t maxLen) {
|
||||||
|
|
||||||
int16_t RF69::enableSyncWordFiltering(uint8_t maxErrBits) {
|
int16_t RF69::enableSyncWordFiltering(uint8_t maxErrBits) {
|
||||||
// enable sync word recognition
|
// enable sync word recognition
|
||||||
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, RADIOLIB_RF69_SYNC_ON | RADIOLIB_RF69_FIFO_FILL_CONDITION_SYNC, 7, 6);
|
return(this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, RADIOLIB_RF69_SYNC_ON | RADIOLIB_RF69_FIFO_FILL_CONDITION_SYNC | (this->syncWordLength - 1) << 3 | maxErrBits, 7, 0));
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// set maximum error bits
|
|
||||||
return(this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, maxErrBits, 2, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t RF69::disableSyncWordFiltering() {
|
int16_t RF69::disableSyncWordFiltering() {
|
||||||
|
@ -933,9 +924,9 @@ float RF69::getRSSI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t RF69::setRSSIThreshold(float dbm) {
|
int16_t RF69::setRSSIThreshold(float dbm) {
|
||||||
RADIOLIB_CHECK_RANGE(dbm, -127.5f, 0.0f, RADIOLIB_ERR_INVALID_RSSI_THRESHOLD);
|
RADIOLIB_CHECK_RANGE(dbm, -127.5, 0, RADIOLIB_ERR_INVALID_RSSI_THRESHOLD);
|
||||||
|
|
||||||
return this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_RSSI_THRESH, (uint8_t)(-2.0f * dbm), 7, 0);
|
return this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_RSSI_THRESH, (uint8_t)(-2.0 * dbm), 7, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RF69::setRfSwitchPins(uint32_t rxEn, uint32_t txEn) {
|
void RF69::setRfSwitchPins(uint32_t rxEn, uint32_t txEn) {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// RF69 physical layer properties
|
// RF69 physical layer properties
|
||||||
#define RADIOLIB_RF69_FREQUENCY_STEP_SIZE 61.03515625
|
#define RADIOLIB_RF69_FREQUENCY_STEP_SIZE 61.03515625
|
||||||
#define RADIOLIB_RF69_MAX_PACKET_LENGTH 64
|
#define RADIOLIB_RF69_MAX_PACKET_LENGTH 64
|
||||||
#define RADIOLIB_RF69_CRYSTAL_FREQ 32.0f
|
#define RADIOLIB_RF69_CRYSTAL_FREQ 32.0
|
||||||
#define RADIOLIB_RF69_DIV_EXPONENT 19
|
#define RADIOLIB_RF69_DIV_EXPONENT 19
|
||||||
|
|
||||||
// RF69 register map
|
// RF69 register map
|
||||||
|
@ -577,7 +577,7 @@ class RF69: public PhysicalLayer {
|
||||||
\brief Sets AES key.
|
\brief Sets AES key.
|
||||||
\param key Key to be used for AES encryption. Must be exactly 16 bytes long.
|
\param key Key to be used for AES encryption. Must be exactly 16 bytes long.
|
||||||
*/
|
*/
|
||||||
void setAESKey(const uint8_t* key);
|
void setAESKey(uint8_t* key);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Enables AES encryption.
|
\brief Enables AES encryption.
|
||||||
|
@ -648,14 +648,6 @@ class RF69: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
void clearFifoEmptyAction();
|
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.
|
\brief Set interrupt service routine function to call when FIFO is full.
|
||||||
\param func Pointer to interrupt service routine.
|
\param func Pointer to interrupt service routine.
|
||||||
|
@ -789,7 +781,7 @@ class RF69: public PhysicalLayer {
|
||||||
\param len Sync word length in bytes.
|
\param len Sync word length in bytes.
|
||||||
\param maxErrBits Maximum allowed number of bit errors in received sync word. Defaults to 0.
|
\param maxErrBits Maximum allowed number of bit errors in received sync word. Defaults to 0.
|
||||||
*/
|
*/
|
||||||
int16_t setSyncWord(const uint8_t* syncWord, size_t len, uint8_t maxErrBits = 0);
|
int16_t setSyncWord(uint8_t* syncWord, size_t len, uint8_t maxErrBits = 0);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets preamble length.
|
\brief Sets preamble length.
|
||||||
|
@ -1031,6 +1023,8 @@ class RF69: public PhysicalLayer {
|
||||||
|
|
||||||
bool promiscuous = false;
|
bool promiscuous = false;
|
||||||
|
|
||||||
|
uint8_t syncWordLength = RADIOLIB_RF69_DEFAULT_SW_LEN;
|
||||||
|
|
||||||
bool bitSync = true;
|
bool bitSync = true;
|
||||||
|
|
||||||
int16_t directMode();
|
int16_t directMode();
|
||||||
|
|
|
@ -17,10 +17,7 @@ int16_t SX1231::begin(float freq, float br, float freqDev, float rxBw, int8_t po
|
||||||
bool flagFound = false;
|
bool flagFound = false;
|
||||||
while((i < 10) && !flagFound) {
|
while((i < 10) && !flagFound) {
|
||||||
int16_t version = getChipVersion();
|
int16_t version = getChipVersion();
|
||||||
if((version == RADIOLIB_SX123X_CHIP_REVISION_2_A) ||
|
if((version == RADIOLIB_SX123X_CHIP_REVISION_2_A) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_B) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_C)) {
|
||||||
(version == RADIOLIB_SX123X_CHIP_REVISION_2_B) ||
|
|
||||||
(version == RADIOLIB_SX123X_CHIP_REVISION_2_C) ||
|
|
||||||
(version == RADIOLIB_SX123X_CHIP_REVISION_2_D)) {
|
|
||||||
flagFound = true;
|
flagFound = true;
|
||||||
this->chipRevision = version;
|
this->chipRevision = version;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#define RADIOLIB_SX123X_CHIP_REVISION_2_A 0x21
|
#define RADIOLIB_SX123X_CHIP_REVISION_2_A 0x21
|
||||||
#define RADIOLIB_SX123X_CHIP_REVISION_2_B 0x22
|
#define RADIOLIB_SX123X_CHIP_REVISION_2_B 0x22
|
||||||
#define RADIOLIB_SX123X_CHIP_REVISION_2_C 0x23
|
#define RADIOLIB_SX123X_CHIP_REVISION_2_C 0x23
|
||||||
#define RADIOLIB_SX123X_CHIP_REVISION_2_D 0x24
|
|
||||||
|
|
||||||
// RADIOLIB_SX1231 specific register map
|
// RADIOLIB_SX1231 specific register map
|
||||||
#define RADIOLIB_SX1231_REG_TEST_OOK 0x6E
|
#define RADIOLIB_SX1231_REG_TEST_OOK 0x6E
|
||||||
|
@ -109,7 +108,7 @@ class SX1231: public RF69 {
|
||||||
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
|
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
virtual int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint8_t preambleLen = 16);
|
int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint8_t preambleLen = 16);
|
||||||
|
|
||||||
#if !RADIOLIB_GODMODE
|
#if !RADIOLIB_GODMODE
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -18,10 +18,7 @@ int16_t SX1233::begin(float freq, float br, float freqDev, float rxBw, int8_t po
|
||||||
bool flagFound = false;
|
bool flagFound = false;
|
||||||
while((i < 10) && !flagFound) {
|
while((i < 10) && !flagFound) {
|
||||||
int16_t version = getChipVersion();
|
int16_t version = getChipVersion();
|
||||||
if((version == RADIOLIB_SX123X_CHIP_REVISION_2_A) ||
|
if((version == RADIOLIB_SX123X_CHIP_REVISION_2_A) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_B) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_C)) {
|
||||||
(version == RADIOLIB_SX123X_CHIP_REVISION_2_B) ||
|
|
||||||
(version == RADIOLIB_SX123X_CHIP_REVISION_2_C) ||
|
|
||||||
(version == RADIOLIB_SX123X_CHIP_REVISION_2_D)) {
|
|
||||||
flagFound = true;
|
flagFound = true;
|
||||||
this->chipRevision = version;
|
this->chipRevision = version;
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,11 +93,11 @@ int16_t SX1233::begin(float freq, float br, float freqDev, float rxBw, int8_t po
|
||||||
int16_t SX1233::setBitRate(float br) {
|
int16_t SX1233::setBitRate(float br) {
|
||||||
// check high bit-rate operation
|
// check high bit-rate operation
|
||||||
uint8_t pllBandwidth = RADIOLIB_SX1233_PLL_BW_LOW_BIT_RATE;
|
uint8_t pllBandwidth = RADIOLIB_SX1233_PLL_BW_LOW_BIT_RATE;
|
||||||
if((fabsf(br - 500.0f) < 0.1f) || (fabsf(br - 600.0f) < 0.1f)) {
|
if((fabsf(br - 500.0f) < 0.1) || (fabsf(br - 600.0f) < 0.1)) {
|
||||||
pllBandwidth = RADIOLIB_SX1233_PLL_BW_HIGH_BIT_RATE;
|
pllBandwidth = RADIOLIB_SX1233_PLL_BW_HIGH_BIT_RATE;
|
||||||
} else {
|
} else {
|
||||||
// datasheet says 1.2 kbps should be the smallest possible, but 0.512 works fine
|
// datasheet says 1.2 kbps should be the smallest possible, but 0.512 works fine
|
||||||
RADIOLIB_CHECK_RANGE(br, 0.5f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
|
RADIOLIB_CHECK_RANGE(br, 0.5, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class SX1233: public SX1231 {
|
||||||
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
|
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint8_t preambleLen = 16) override;
|
int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint8_t preambleLen = 16);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets bit rate. Allowed values range from 0.5 to 300.0 kbps.
|
\brief Sets bit rate. Allowed values range from 0.5 to 300.0 kbps.
|
||||||
|
|
|
@ -45,7 +45,7 @@ int16_t STM32WLx::setOutputPower(int8_t power) {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// check the user did not request power output that is not possible
|
// check the user did not request power output that is not possible
|
||||||
const Module* mod = this->getMod();
|
Module* mod = this->getMod();
|
||||||
bool hp_supported = mod->findRfSwitchMode(MODE_TX_HP);
|
bool hp_supported = mod->findRfSwitchMode(MODE_TX_HP);
|
||||||
bool lp_supported = mod->findRfSwitchMode(MODE_TX_LP);
|
bool lp_supported = mod->findRfSwitchMode(MODE_TX_LP);
|
||||||
if((!lp_supported && (power < -9)) || (!hp_supported && (power > 14))) {
|
if((!lp_supported && (power < -9)) || (!hp_supported && (power > 14))) {
|
||||||
|
|
|
@ -66,12 +66,12 @@ class STM32WLx : public SX1262 {
|
||||||
/*!
|
/*!
|
||||||
\copydoc SX1262::begin
|
\copydoc SX1262::begin
|
||||||
*/
|
*/
|
||||||
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX126X_SYNC_WORD_PRIVATE, int8_t power = 10, uint16_t preambleLength = 8, float tcxoVoltage = 1.6, bool useRegulatorLDO = false) override;
|
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX126X_SYNC_WORD_PRIVATE, int8_t power = 10, uint16_t preambleLength = 8, float tcxoVoltage = 1.6, bool useRegulatorLDO = false);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\copydoc SX1262::beginFSK
|
\copydoc SX1262::beginFSK
|
||||||
*/
|
*/
|
||||||
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 156.2, int8_t power = 10, uint16_t preambleLength = 16, float tcxoVoltage = 1.6, bool useRegulatorLDO = false) override;
|
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 156.2, int8_t power = 10, uint16_t preambleLength = 16, float tcxoVoltage = 1.6, bool useRegulatorLDO = false);
|
||||||
|
|
||||||
// configuration methods
|
// configuration methods
|
||||||
|
|
||||||
|
@ -113,12 +113,12 @@ class STM32WLx : public SX1262 {
|
||||||
\brief Sets interrupt service routine to call when DIO1/2/3 activates.
|
\brief Sets interrupt service routine to call when DIO1/2/3 activates.
|
||||||
\param func ISR to call.
|
\param func ISR to call.
|
||||||
*/
|
*/
|
||||||
void setDio1Action(void (*func)(void)) override;
|
void setDio1Action(void (*func)(void));
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Clears interrupt service routine to call when DIO1/2/3 activates.
|
\brief Clears interrupt service routine to call when DIO1/2/3 activates.
|
||||||
*/
|
*/
|
||||||
void clearDio1Action() override;
|
void clearDio1Action();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets interrupt service routine to call when a packet is received.
|
\brief Sets interrupt service routine to call when a packet is received.
|
||||||
|
|
|
@ -16,19 +16,11 @@ int16_t SX1261::setOutputPower(int8_t power) {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set PA config
|
// set PA config
|
||||||
uint8_t paDutyCycle = 0x04;
|
state = SX126x::setPaConfig(0x04, RADIOLIB_SX126X_PA_CONFIG_SX1261, 0x00);
|
||||||
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);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set output power with default 200us ramp
|
// set output power with default 200us ramp
|
||||||
state = SX126x::setTxParams(txPwr, RADIOLIB_SX126X_PA_RAMP_200U);
|
state = SX126x::setTxParams(power, RADIOLIB_SX126X_PA_RAMP_200U);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// restore OCP configuration
|
// restore OCP configuration
|
||||||
|
@ -37,9 +29,9 @@ int16_t SX1261::setOutputPower(int8_t power) {
|
||||||
|
|
||||||
int16_t SX1261::checkOutputPower(int8_t power, int8_t* clipped) {
|
int16_t SX1261::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||||
if(clipped) {
|
if(clipped) {
|
||||||
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(15, power));
|
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
|
||||||
}
|
}
|
||||||
RADIOLIB_CHECK_RANGE(power, -17, 15, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||||
return(RADIOLIB_ERR_NONE);
|
return(RADIOLIB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class SX1261 : public SX1262 {
|
||||||
SX1261(Module* mod); // cppcheck-suppress noExplicitConstructor
|
SX1261(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Sets output power. Allowed values are in range from -17 to 15 dBm.
|
\brief Sets output power. Allowed values are in range from -17 to 14 dBm.
|
||||||
\param power Output power to be set in dBm.
|
\param power Output power to be set in dBm.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue