Update RadioLib to main branch

This commit is contained in:
lewisxhe 2024-06-22 09:14:48 +08:00
commit 743e36546e
18 changed files with 915 additions and 177 deletions

View file

@ -0,0 +1,30 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**IMPORTANT: Check the wiki**
Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
**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**.
**To Reproduce**
Minimal Arduino sketch to reproduce the behavior. Please use Markdown to style the code to make it readable (see [Markdown Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)).
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional info (please complete):**
- MCU: [e.g. Arduino Uno, ESP8266 etc.]
- Link to Arduino core: [e.g. https://github.com/stm32duino/Arduino_Core_STM32 when using official STM32 core. See readme for links to all supported cores]
- Wireless module type [e.g. CC1101, SX1268, etc.]
- Arduino IDE version [e.g. 1.8.5]
- Library version [e.g. 3.0.0]

View file

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: RadioLib Discussions
url: https://github.com/jgromes/RadioLib/discussions
about: Please ask generic questions here.

View file

@ -0,0 +1,23 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**IMPORTANT: Check the wiki**
Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
**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 [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -0,0 +1,34 @@
---
name: Module not working
about: Template to use when your module isn't working
title: ''
labels: ''
assignees: ''
---
**IMPORTANT: Before submitting an issue, please check the following:**
1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored.
2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases).
4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib!
5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html).
**Sketch that is causing the module fail**
```c++
paste the sketch here, even if it is an unmodified example code
```
**Hardware setup**
Wiring diagram, schematic, pictures etc.
**Debug mode output**
Enable the appropriate [debug levels](https://github.com/jgromes/RadioLib/wiki/Debug-mode) and paste the Serial monitor output here. For debugging protocols, enable `RADIOLIB_DEBUG_PROTOCOL`. For debugging issues with the radio module itself, enable `RADIOLIB_DEBUG_SPI`.
**Additional info (please complete):**
- MCU: [e.g. Arduino Uno, ESP8266 etc.]
- Link to Arduino core: [e.g. https://github.com/stm32duino/Arduino_Core_STM32 when using official STM32 core. See readme for links to all supported cores]
- Wireless module type [e.g. CC1101, SX1268, etc.]
- Arduino IDE version [e.g. 1.8.5]
- Library version [e.g. 3.0.0]

View file

@ -0,0 +1,15 @@
---
name: Regular issue
about: Use this template for any other issue
title: ''
labels: ''
assignees: ''
---
**IMPORTANT: Before submitting an issue, please check the following:**
1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored.
2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases).
4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib!
5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html).

View file

@ -0,0 +1,14 @@
## Pull request template
Thank you for taking the time to contribute to RadioLib development!
To keep this library organized, please follow these rules.
1. Make sure the the code in your PR is tested and that you understand all its impacts.
2. Ensure that all CI actions pass - PRs with failed CI will not be merged. CI actions run automatically for every commit pushed to the PR and test the following:
a. Compilation for Arduino, ESP-IDF and on Raspberry Pi
b. Runtime test on Raspberry Pi
c. GitHub CodeQL check
d. Cppcheck static code scan
3. Follow code style guidelines in [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)
4. Heads up - all PRs undergo review, during which you may be asked to correct or change some things. The purpose of this review is to keep regressions and bugs at the minimum, and to keep consistent coding style. Please take them as constructive criticism from people who may have a different point-of-view than you do.
After addressing/accepting the points above, delete the contents of this template and replace it with text explaining what is the goal of your PR, why you want to add it to the upstream and what are the foreseen impacts. Once again, thank you for taking the time to contribute!

View file

@ -0,0 +1,60 @@
name: "CodeQL"
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
security-events: write
strategy:
fail-fast: false
matrix:
language: ['cpp']
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Install arduino-cli
run:
|
mkdir -p ~/.local/bin
echo "~/.local/bin" >> $GITHUB_PATH
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh
- name: Install platform
run:
|
arduino-cli core update-index
arduino-cli core install arduino:avr
- name: Static link
run:
|
# static link fix from https://github.com/github/securitylab/discussions/171
for i in ~/.arduino*/packages/arduino/tools/avr-gcc/*/bin/*; do
mv "$i" "$i.real";
printf '#!/bin/bash\nexec "'"$i"'.real" ${1+"$@"}\n' > "$i";
chmod +x "$i";
done
- name: Build example
run:
arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn arduino:avr:uno $PWD/examples/SX126x/SX126x_Transmit_Blocking/SX126x_Transmit_Blocking.ino --warnings=all
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

View file

@ -0,0 +1,25 @@
name: "Cppcheck"
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
jobs:
check:
name: Perform static code check
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install cppcheck
run: |
sudo apt-get update
sudo apt-get install -y cppcheck
- name: Run cppcheck
run: ./extras/cppcheck/cppcheck.sh

View file

@ -0,0 +1,26 @@
name: Doxygen
on:
push:
branches: [ master ]
workflow_dispatch:
jobs:
doxygen:
runs-on: ubuntu-latest
steps:
- name: Install Doxygen
run: |
sudo apt-get update
sudo apt-get install -y doxygen
- uses: actions/checkout@v4
- name: Generate docs
run: doxygen Doxyfile
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages
FOLDER: docs/html

317
lib/RadioLib/.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,317 @@
name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
inputs:
id:
description: The ID of the platform on which the build is run
required: true
default: arduino:avr:uno
type: choice
options:
- all
- none
- arduino:avr:uno
- arduino:avr:mega
- arduino:mbed:nano33ble
- arduino:mbed:envie_m4
- arduino:megaavr:uno2018
- arduino:sam:arduino_due_x
- arduino:samd:arduino_zero_native
- adafruit:samd:adafruit_feather_m0
- adafruit:nrf52:feather52832
- esp32:esp32:esp32
- esp8266:esp8266:generic
- Intel:arc32:arduino_101
- SparkFun:apollo3:sfe_artemis
- STMicroelectronics:stm32:GenF3:pnum=BLACKPILL_F303CC
- STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1
- stm32duino:STM32F1:mapleMini
- MegaCoreX:megaavr:4809
- arduino:mbed_rp2040:pico
- rp2040:rp2040:rpipico
- CubeCell:CubeCell:CubeCell-Board
- MegaCore:avr:1281
- teensy:avr:teensy41
- arduino:renesas_uno:minima
jobs:
build:
strategy:
matrix:
# platform-dependent settings - extra board options, board index URLs, skip patterns etc.
include:
- id: arduino:avr:uno
run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update|Pager)" >> $GITHUB_OUTPUT
- id: arduino:avr:mega
run: |
echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: arduino:mbed:nano33ble
- id: arduino:mbed:envie_m4
- id: arduino:megaavr:uno2018
run: |
echo "options=':mode=on'" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: arduino:sam:arduino_due_x
- id: arduino:samd:arduino_zero_native
run: |
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: adafruit:samd:adafruit_feather_m0
run: |
echo "options=':usbstack=arduino,debug=off'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: adafruit:nrf52:feather52832
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-pip python3-setuptools
pip3 install wheel
pip3 install --user adafruit-nrfutil
echo "/home/runner/.local/bin" >> $GITHUB_PATH
echo "options=':softdevice=s132v6,debug=l0'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: esp32:esp32:esp32
run: |
python -m pip install pyserial
echo "index-url=--additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" >> $GITHUB_OUTPUT
- id: esp8266:esp8266:generic
run: |
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
- id: SparkFun:apollo3:sfe_artemis
run: |
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
echo "warnings='none'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://raw.githubusercontent.com/sparkfun/Arduino_Apollo3/master/package_sparkfun_apollo3_index.json" >> $GITHUB_OUTPUT
- id: STMicroelectronics:stm32:GenF3:pnum=BLACKPILL_F303CC
run: |
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
- id: STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1
run: |
# Do *not* skip STM32WL examples
echo "skip-pattern='LR11x0_Firmware_Update'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
- id: stm32duino:STM32F1:mapleMini
run: |
echo "options=':bootloader_version=original,cpu_speed=speed_72mhz'" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls http://dan.drown.org/stm32duino/package_STM32duino_index.json" >> $GITHUB_OUTPUT
- id: MegaCoreX:megaavr:4809
run: |
echo "index-url=--additional-urls https://mcudude.github.io/MegaCoreX/package_MCUdude_MegaCoreX_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: arduino:mbed_rp2040:pico
- id: rp2040:rp2040:rpipico
run: echo "index-url=--additional-urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json" >> $GITHUB_OUTPUT
- id: CubeCell:CubeCell:CubeCell-Board
run: |
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://resource.heltec.cn/download/package_CubeCell_index.json" >> $GITHUB_OUTPUT
- id: MegaCore:avr:1281
run: |
echo "index-url=--additional-urls https://mcudude.github.io/MegaCore/package_MCUdude_MegaCore_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: teensy:avr:teensy41
run: |
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://www.pjrc.com/teensy/package_teensy_index.json" >> $GITHUB_OUTPUT
- id: arduino:renesas_uno:minima
run: |
echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
runs-on: ubuntu-latest
name: ${{ matrix.id }}
env:
run-build: ${{ (inputs.id != 'none' && matrix.id == 'arduino:avr:uno') || contains(github.event.head_commit.message, 'CI_BUILD_ALL') || contains(github.event.head_commit.message, 'Bump version to') || contains(github.event.head_commit.message, format('{0}', matrix.id)) || inputs.id == 'all' || inputs.id == matrix.id }}
steps:
- name: Install arduino-cli
if: ${{ env.run-build == 'true' }}
run:
|
mkdir -p ~/.local/bin
echo "~/.local/bin" >> $GITHUB_PATH
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh
- name: Get platform name
if: ${{ env.run-build == 'true' }}
uses: jungwinter/split@v1
id: split
with:
msg: ${{ matrix.id }}
seperator: ':'
- name: Prepare platform-specific settings
if: ${{ env.run-build == 'true' }}
id: prep
run:
|
# common settings - no extra options, skip STM32WL examples, all warnings
echo "options=''" >> $GITHUB_OUTPUT
echo "skip-pattern=STM32WL" >> $GITHUB_OUTPUT
echo "warnings=all" >> $GITHUB_OUTPUT
# run platform-dependent scripts defined in matrix
${{ matrix.run }}
- name: Install platform
if: ${{ env.run-build == 'true' }}
run:
|
arduino-cli core update-index ${{ format('{0}', steps.prep.outputs.index-url) }}
arduino-cli core install ${{ format('{0}:{1} {2}', steps.split.outputs._0, steps.split.outputs._1, steps.prep.outputs.index-url) }}
- name: Checkout repository
if: ${{ env.run-build == 'true' }}
uses: actions/checkout@v4
- name: Build examples
if: ${{ env.run-build == 'true' }}
run:
|
for example in $(find $PWD/examples -name '*.ino' | sort); do
# check whether to skip this sketch
if [ ! -z '${{ steps.prep.outputs.skip-pattern }}' ] && [[ ${example} =~ ${{ steps.prep.outputs.skip-pattern }} ]]; then
# skip sketch
echo -e "\n\033[1;33mSkipped ${example##*/} (matched with ${{ steps.prep.outputs.skip-pattern }})\033[0m";
else
# apply special flags for LoRaWAN
if [[ ${example} =~ "LoRaWAN" ]]; then
flags="-DRADIOLIB_LORAWAN_DEV_ADDR=0 -DRADIOLIB_LORAWAN_FNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_SNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_NWKSENC_KEY=0 -DRADIOLIB_LORAWAN_APPS_KEY=0 -DRADIOLIB_LORAWAN_APP_KEY=0 -DRADIOLIB_LORAWAN_NWK_KEY=0 -DRADIOLIB_LORAWAN_DEV_EUI=0 -DARDUINO_TTGO_LORA32_V1"
fi
# build sketch
echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m";
arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn ${{ matrix.id }}${{ steps.prep.outputs.options }} --build-property compiler.cpp.extra_flags="$flags" $example --warnings=${{ steps.prep.outputs.warnings }}
if [ $? -ne 0 ]; then
echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n";
exit 1;
else
echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n";
fi
fi
done
esp-build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
- name: Clone ESP-IDF
run: |
mkdir -p ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git
- name: Install ESP-IDF
run: |
cd ~/esp/esp-idf
./install.sh esp32
- name: Build the example
run: |
cd $PWD/examples/NonArduino/ESP-IDF
. ~/esp/esp-idf/export.sh
idf.py build
tock-build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: |
sudo apt-get install -y gcc-arm-none-eabi gcc-riscv64-unknown-elf
cargo install elf2tab
- name: Build the example
run: |
cd $PWD/examples/NonArduino/Tock
git clone https://github.com/tock/libtock-c.git
cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../
LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
rpi-build:
runs-on: [self-hosted, ARM64]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake wget swig python-dev python3-dev python-setuptools python3-setuptools
wget http://abyz.me.uk/lg/lg.zip
unzip lg.zip
cd lg
make
sudo make install
cd ..
sudo rm -rf lg
- name: Install the library
run: |
cd $PWD
mkdir build
cd build
cmake ..
sudo make install
- name: Build the example
run: |
cd $PWD/examples/NonArduino/Raspberry
./build.sh
rpi-test:
needs: rpi-build
runs-on: [self-hosted, ARM64]
steps:
- name: SX126x test
run: |
cd $PWD/extras/test/SX126x
./clean.sh
./build.sh
sudo ./build/rpi-sx1261
rpi-pico-build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt update
sudo apt install git cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
- name: Clone the SDK
run: |
mkdir -p ~/rpi-pico
cd ~/rpi-pico
git clone https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk && git checkout 1.5.1
- name: Build the example
run: |
export PICO_SDK_PATH=~/rpi-pico/pico-sdk
cd $PWD/examples/NonArduino/Pico
./build.sh

View file

@ -7,31 +7,40 @@ LR1110::LR1110(Module* mod) : LR11x0(mod) {
int16_t LR1110::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
int16_t state = LR11x0::begin(bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
int16_t state = LR11x0::begin(bw, sf, cr, syncWord, preambleLength, tcxoVoltage);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
return(state);
}
int16_t LR1110::beginGFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
// execute common part
int16_t state = LR11x0::beginGFSK(br, freqDev, rxBw, power, preambleLength, tcxoVoltage);
int16_t state = LR11x0::beginGFSK(br, freqDev, rxBw, preambleLength, tcxoVoltage);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
return(state);
}
int16_t LR1110::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage) {
// execute common part
int16_t state = LR11x0::beginLRFHSS(bw, cr, power, tcxoVoltage);
int16_t state = LR11x0::beginLRFHSS(bw, cr, tcxoVoltage);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
return(state);
}
@ -52,4 +61,48 @@ int16_t LR1110::setFrequency(float freq, bool calibrate, float band) {
return(LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f)));
}
int16_t LR1110::setOutputPower(int8_t power) {
return(this->setOutputPower(power, false));
}
int16_t LR1110::setOutputPower(int8_t power, bool forceHighPower) {
// check if power value is configurable
int16_t state = this->checkOutputPower(power, NULL, forceHighPower);
RADIOLIB_ASSERT(state);
// determine whether to use HP or LP PA and check range accordingly
bool useHp = forceHighPower || (power > 14);
// TODO how and when to configure OCP?
// update PA config - always use VBAT for high-power PA
state = setPaConfig((uint8_t)useHp, (uint8_t)useHp, 0x04, 0x07);
RADIOLIB_ASSERT(state);
// set output power
state = setTxParams(power, RADIOLIB_LR11X0_PA_RAMP_48U);
return(state);
}
int16_t LR1110::checkOutputPower(int8_t power, int8_t* clipped) {
return(checkOutputPower(power, clipped, false));
}
int16_t LR1110::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower) {
if(forceHighPower || (power > 14)) {
if(clipped) {
*clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
}
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
} else {
if(clipped) {
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
}
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
}
return(RADIOLIB_ERR_NONE);
}
#endif

View file

@ -87,6 +87,41 @@ class LR1110: public LR11x0 {
*/
int16_t setFrequency(float freq, bool calibrate, float band = 4);
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA).
\param power Output power to be set in dBm, output PA is determined automatically preferring the low-power PA.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power) override;
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA).
\param power Output power to be set in dBm.
\param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically
based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power, bool forceHighPower);
/*!
\brief Check if output power is configurable.
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
\param power Output power in dBm, PA will be determined automatically.
\param clipped Clipped output power value to what is possible within the module's range.
\returns \ref status_codes
*/
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
/*!
\brief Check if output power is configurable.
\param power Output power in dBm.
\param clipped Clipped output power value to what is possible within the module's range.
\param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically
based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used.
\returns \ref status_codes
*/
int16_t checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower);
#if !RADIOLIB_GODMODE
private:
#endif

View file

@ -7,31 +7,40 @@ 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) {
// execute common part
int16_t state = LR11x0::begin(bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
int16_t state = LR11x0::begin(bw, sf, cr, syncWord, preambleLength, tcxoVoltage);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
return(state);
}
int16_t LR1120::beginGFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
// execute common part
int16_t state = LR11x0::beginGFSK(br, freqDev, rxBw, power, preambleLength, tcxoVoltage);
int16_t state = LR11x0::beginGFSK(br, freqDev, rxBw, preambleLength, tcxoVoltage);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
return(state);
}
int16_t LR1120::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage) {
// execute common part
int16_t state = LR11x0::beginLRFHSS(bw, cr, power, tcxoVoltage);
int16_t state = LR11x0::beginLRFHSS(bw, cr, tcxoVoltage);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
return(state);
}
@ -47,13 +56,76 @@ int16_t LR1120::setFrequency(float freq, bool calibrate, float band) {
}
// calibrate image rejection
int16_t state;
if(calibrate) {
int16_t state = LR11x0::calibImage(freq - band, freq + band);
state = LR11x0::calibImage(freq - band, freq + band);
RADIOLIB_ASSERT(state);
}
// set frequency
return(LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f)));
state = LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f));
RADIOLIB_ASSERT(state);
this->highFreq = (freq > 1000.0);
return(RADIOLIB_ERR_NONE);
}
int16_t LR1120::setOutputPower(int8_t power) {
return(this->setOutputPower(power, false));
}
int16_t LR1120::setOutputPower(int8_t power, bool forceHighPower) {
// check if power value is configurable
int16_t state = this->checkOutputPower(power, NULL, forceHighPower);
RADIOLIB_ASSERT(state);
// determine whether to use HP or LP PA and check range accordingly
uint8_t paSel = 0;
uint8_t paSupply = 0;
if(this->highFreq) {
paSel = 2;
} else if(forceHighPower || (power > 14)) {
paSel = 1;
paSupply = 1;
}
// TODO how and when to configure OCP?
// update PA config - always use VBAT for high-power PA
state = setPaConfig(paSel, paSupply, 0x04, 0x07);
RADIOLIB_ASSERT(state);
// set output power
state = setTxParams(power, RADIOLIB_LR11X0_PA_RAMP_48U);
return(state);
}
int16_t LR1120::checkOutputPower(int8_t power, int8_t* clipped) {
return(checkOutputPower(power, clipped, false));
}
int16_t LR1120::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower) {
if(this->highFreq) {
if(clipped) {
*clipped = RADIOLIB_MAX(-18, RADIOLIB_MIN(13, power));
}
RADIOLIB_CHECK_RANGE(power, -18, 13, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
return(RADIOLIB_ERR_NONE);
}
if(forceHighPower || (power > 14)) {
if(clipped) {
*clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
}
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
} else {
if(clipped) {
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
}
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
}
return(RADIOLIB_ERR_NONE);
}
#endif

View file

@ -71,6 +71,8 @@ class LR1120: public LR11x0 {
/*!
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz,
1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations.
NOTE: When switching between sub-GHz and high-frequency bands, after changing the frequency,
setOutputPower() must be called in order to set the correct power amplifier!
\param freq Carrier frequency to be set in MHz.
\returns \ref status_codes
*/
@ -79,6 +81,8 @@ class LR1120: public LR11x0 {
/*!
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz,
1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations.
NOTE: When switching between sub-GHz and high-frequency bands, after changing the frequency,
setOutputPower() must be called in order to set the correct power amplifier!
\param freq Carrier frequency to be set in MHz.
\param calibrate Run image calibration.
\param band Half bandwidth for image calibration. For example,
@ -88,9 +92,51 @@ class LR1120: public LR11x0 {
*/
int16_t setFrequency(float freq, bool calibrate, float band = 4);
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA).
\param power Output power to be set in dBm, output PA is determined automatically preferring the low-power PA.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power) override;
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA), -17 to 14 dBm (low-power PA)
or -18 to 13 dBm (high-frequency PA).
\param power Output power to be set in dBm.
\param forceHighPower Force using the high-power PA in sub-GHz bands, or high-frequency PA in 2.4 GHz band.
If set to false, PA will be determined automatically based on configured output power and frequency,
preferring the low-power PA but always using high-frequency PA in 2.4 GHz band.
Ignored when operating in 2.4 GHz band.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power, bool forceHighPower);
/*!
\brief Check if output power is configurable.
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
\param power Output power in dBm, PA will be determined automatically.
\param clipped Clipped output power value to what is possible within the module's range.
\returns \ref status_codes
*/
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
/*!
\brief Check if output power is configurable.
\param power Output power in dBm.
\param clipped Clipped output power value to what is possible within the module's range.
\param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically
based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used.
Ignored when operating in 2.4 GHz band.
\returns \ref status_codes
*/
int16_t checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower);
#if !RADIOLIB_GODMODE
private:
#endif
// flag to determine whether we are in the sub-GHz or 2.4 GHz range
// this is needed to automatically detect which PA to use
bool highFreq = false;
};

View file

@ -5,44 +5,4 @@ LR1121::LR1121(Module* mod) : LR1120(mod) {
chipType = RADIOLIB_LR11X0_DEVICE_LR1121;
}
int16_t LR1121::setOutputPower(int8_t power, bool useHighFreqPa)
{
int16_t state = RADIOLIB_ERR_INVALID_OUTPUT_POWER;
if (useHighFreqPa) {
if ((-18 <= power ) && ( power <= 13 )) {
state = setPaConfig(0x02, // High-frequency Power Amplifier
0x00, // Power amplifier supplied by the main regulator
0x04, // Power Amplifier duty cycle (Default 0x04)
0x07 // Number of slices for HPA (Default 0x07)
);
} else {
return RADIOLIB_ERR_INVALID_OUTPUT_POWER;
}
} else {
if (( -17 <= power ) && (power <= 22 )) {
if (power == 22) {
state = setPaConfig(0x01, // High-power Power Amplifier
0x01, // Power amplifier supplied by the battery
0x04, // Power Amplifier duty cycle (Default 0x04)
0x07 // Number of slices for HPA (Default 0x07)
);
} else {
state = setPaConfig(0x00, // Low-power Power Amplifier
0x00, // Power amplifier supplied by the main regulator
0x04, // Power Amplifier duty cycle (Default 0x04)
0x07 // Number of slices for HPA (Default 0x07)
);
}
} else {
return RADIOLIB_ERR_INVALID_OUTPUT_POWER;
}
}
RADIOLIB_ASSERT(state);
// set output power
state = setTxParams(power, RADIOLIB_LR11X0_PA_RAMP_48U);
return (state);
}
#endif

View file

@ -21,15 +21,6 @@ class LR1121: public LR1120 {
*/
LR1121(Module* mod); // cppcheck-suppress noExplicitConstructor
/*!
\brief Sets output power. Allowed values are in range from -17 to 22 dBm (high-power PA) or -18 to 13 dBm (High-frequency PA).
\param power Output power to be set in dBm.
\param useHighFreqPa When using 2.4G frequency, need to switch to High-frequency PA
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power,bool useHighFreqPa = false);
// TODO this is where overrides to disable GNSS+WiFi scanning methods on LR1121
// will be put once those are implemented

View file

@ -13,7 +13,7 @@ LR11x0::LR11x0(Module* mod) : PhysicalLayer(RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE,
this->XTAL = false;
}
int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage) {
// set module properties and perform initial setup
int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_LORA);
RADIOLIB_ASSERT(state);
@ -31,9 +31,6 @@ int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t
state = setSyncWord(syncWord);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);
state = setPreambleLength(preambleLength);
RADIOLIB_ASSERT(state);
@ -50,7 +47,7 @@ int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t
return(RADIOLIB_ERR_NONE);
}
int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, uint16_t preambleLength, float tcxoVoltage) {
// set module properties and perform initial setup
int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_GFSK);
RADIOLIB_ASSERT(state);
@ -65,9 +62,6 @@ int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, int8_t power, uin
state = setRxBandwidth(rxBw);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);
state = setPreambleLength(preambleLength);
RADIOLIB_ASSERT(state);
@ -94,7 +88,7 @@ int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, int8_t power, uin
return(RADIOLIB_ERR_NONE);
}
int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage) {
int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, float tcxoVoltage) {
// set module properties and perform initial setup
int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS);
RADIOLIB_ASSERT(state);
@ -103,9 +97,6 @@ int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, int8_t power, float tcxoVolt
state = setLrFhssConfig(bw, cr);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
RADIOLIB_ASSERT(state);
state = setSyncWord(0x12AD101B);
RADIOLIB_ASSERT(state);
@ -605,50 +596,6 @@ int16_t LR11x0::getChannelScanResult() {
return(RADIOLIB_ERR_UNKNOWN);
}
int16_t LR11x0::setOutputPower(int8_t power) {
return(this->setOutputPower(power, false));
}
int16_t LR11x0::setOutputPower(int8_t power, bool forceHighPower) {
// check if power value is configurable
int16_t state = checkOutputPower(power, NULL, forceHighPower);
RADIOLIB_ASSERT(state);
// determine whether to use HP or LP PA and check range accordingly
bool useHp = forceHighPower || (power > 14);
// TODO how and when to configure OCP?
// update PA config - always use VBAT for high-power PA
state = setPaConfig((uint8_t)useHp, (uint8_t)useHp, 0x04, 0x07);
RADIOLIB_ASSERT(state);
// set output power
state = setTxParams(power, RADIOLIB_LR11X0_PA_RAMP_48U);
return(state);
}
int16_t LR11x0::checkOutputPower(int8_t power, int8_t* clipped) {
return(checkOutputPower(power, clipped, false));
}
int16_t LR11x0::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower) {
if(forceHighPower || (power > 14)) {
if(clipped) {
*clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
}
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
} else {
if(clipped) {
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
}
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
}
return(RADIOLIB_ERR_NONE);
}
int16_t LR11x0::setBandwidth(float bw) {
// check active modem
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
@ -1057,6 +1004,10 @@ int16_t LR11x0::setDataRate(DataRate_t dr) {
// set the coding rate
state = this->setCodingRate(dr.lora.codingRate);
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
}
return(state);
@ -1627,13 +1578,18 @@ int16_t LR11x0::getVersionInfo(LR11x0VersionInfo_t* info) {
int16_t state = this->getVersion(&info->hardware, &info->device, &info->fwMajor, &info->fwMinor);
RADIOLIB_ASSERT(state);
if(this->chipType != RADIOLIB_LR11X0_DEVICE_LR1121){
// LR1121 does not have GNSS and WiFi scanning
if(this->chipType == RADIOLIB_LR11X0_DEVICE_LR1121) {
info->fwMajorWiFi = 0;
info->fwMinorWiFi = 0;
info->fwGNSS = 0;
info->almanacGNSS = 0;
return(RADIOLIB_ERR_NONE);
}
state = this->wifiReadVersion(&info->fwMajorWiFi, &info->fwMinorWiFi);
RADIOLIB_ASSERT(state);
return(this->gnssReadVersion(&info->fwGNSS, &info->almanacGNSS));
}
return RADIOLIB_ERR_NONE;
}
int16_t LR11x0::updateFirmware(const uint32_t* image, size_t size, bool nonvolatile) {
@ -1696,6 +1652,112 @@ int16_t LR11x0::updateFirmware(const uint32_t* image, size_t size, bool nonvolat
return(state);
}
int16_t LR11x0::isGnssScanCapable() {
// get the version
LR11x0VersionInfo_t version;
int16_t state = this->getVersionInfo(&version);
RADIOLIB_ASSERT(state);
// check the device firmware version is sufficient
uint16_t versionFull = ((uint16_t)version.fwMajor << 8) | (uint16_t)version.fwMinor;
if((version.device == RADIOLIB_LR11X0_DEVICE_LR1110) && (versionFull >= 0x0401)) {
return(RADIOLIB_ERR_NONE);
} else if((version.device == RADIOLIB_LR11X0_DEVICE_LR1120) && (versionFull >= 0x0201)) {
return(RADIOLIB_ERR_NONE);
}
return(RADIOLIB_ERR_UNSUPPORTED);
}
int16_t LR11x0::gnssScan(uint16_t* resSize) {
// go to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set DIO mapping
state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_GNSS_DONE, 0);
RADIOLIB_ASSERT(state);
state = this->gnssSetConstellationToUse(0x03);
RADIOLIB_ASSERT(state);
// set scan mode
state = this->gnssSetMode(0x03);
RADIOLIB_ASSERT(state);
// start scan with high effort
RADIOLIB_DEBUG_BASIC_PRINTLN("GNSS scan start");
state = this->gnssPerformScan(0x01, 0x3C, 8);
RADIOLIB_ASSERT(state);
// wait for scan finished or timeout
RadioLibTime_t softTimeout = 300UL * 1000UL;
RadioLibTime_t start = this->mod->hal->millis();
while(!this->mod->hal->digitalRead(this->mod->getIrq())) {
this->mod->hal->yield();
if(this->mod->hal->millis() - start > softTimeout) {
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout waiting for IRQ");
this->standby();
return(RADIOLIB_ERR_RX_TIMEOUT);
}
}
RADIOLIB_DEBUG_BASIC_PRINTLN("GNSS scan done in %lu ms", (long unsigned int)(this->mod->hal->millis() - start));
state = this->clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
RADIOLIB_ASSERT(state);
int8_t status = 0;
uint8_t info = 0;
state = this->gnssReadDemodStatus(&status, &info);
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_BASIC_PRINTLN("Demod status %d, info %02x", (int)status, (unsigned int)info);
uint8_t fwVersion = 0;
uint32_t almanacCrc = 0;
uint8_t errCode = 0;
uint8_t almUpdMask = 0;
uint8_t freqSpace = 0;
state = this->gnssGetContextStatus(&fwVersion, &almanacCrc, &errCode, &almUpdMask, &freqSpace);
RADIOLIB_DEBUG_BASIC_PRINTLN("Context status fwVersion %d, almanacCrc %lx, errCode %d, almUpdMask %d, freqSpace %d",
(int)fwVersion, (unsigned long)almanacCrc, (int)errCode, (int)almUpdMask, (int)freqSpace);
RADIOLIB_ASSERT(state);
uint8_t stat[53] = { 0 };
state = this->gnssReadAlmanacStatus(stat);
RADIOLIB_ASSERT(state);
//Module::hexdump(NULL, stat, 53);
return(this->gnssGetResultSize(resSize));
}
int16_t LR11x0::getGnssScanResult(uint16_t size) {
// read the result
uint8_t res[256] = { 0 };
int16_t state = this->gnssReadResults(res, size);
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_BASIC_PRINTLN("Result type: %02x", (int)res[0]);
//Module::hexdump(NULL, res, size);
return(state);
}
int16_t LR11x0::getGnssPosition(float* lat, float* lon, bool filtered) {
uint8_t error = 0;
uint8_t nbSvUsed = 0;
uint16_t accuracy = 0;
int16_t state;
if(filtered) {
state = this->gnssReadDopplerSolverRes(&error, &nbSvUsed, NULL, NULL, NULL, NULL, lat, lon, &accuracy, NULL);
} else {
state = this->gnssReadDopplerSolverRes(&error, &nbSvUsed, lat, lon, &accuracy, NULL, NULL, NULL, NULL, NULL);
}
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_BASIC_PRINTLN("Solver error %d, nbSvUsed %d, accuracy = %u", (int)error, (int)nbSvUsed, (unsigned int)accuracy);
return(state);
}
int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
this->mod->init();
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
@ -1792,7 +1854,7 @@ bool LR11x0::findChip(uint8_t ver) {
if((state == RADIOLIB_ERR_NONE) && (info.device == ver)) {
RADIOLIB_DEBUG_BASIC_PRINTLN("Found LR11x0: RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", info.device);
RADIOLIB_DEBUG_BASIC_PRINTLN("Base FW version: %d.%d", (int)info.fwMajor, (int)info.fwMinor);
if(this->chipType != RADIOLIB_LR11X0_DEVICE_LR1121){
if(this->chipType != RADIOLIB_LR11X0_DEVICE_LR1121) {
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi FW version: %d.%d", (int)info.fwMajorWiFi, (int)info.fwMinorWiFi);
RADIOLIB_DEBUG_BASIC_PRINTLN("GNSS FW version: %d.%d", (int)info.fwGNSS, (int)info.almanacGNSS);
}
@ -2880,21 +2942,17 @@ int16_t LR11x0::gnssPushDmMsg(uint8_t* payload, size_t len) {
}
int16_t LR11x0::gnssGetContextStatus(uint8_t* fwVersion, uint32_t* almanacCrc, uint8_t* errCode, uint8_t* almUpdMask, uint8_t* freqSpace) {
// send the command
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_GET_CONTEXT_STATUS, true, NULL, 0);
RADIOLIB_ASSERT(state);
// read the result - this requires some magic bytes first, that's why LR11x0::SPIcommand cannot be used
uint8_t cmd_buff[3] = { 0x00, 0x02, 0x18 };
// send the command - datasheet here shows extra bytes being sent in the request
// but doing that fails so treat it like any other read command
uint8_t buff[9] = { 0 };
state = this->mod->SPItransferStream(cmd_buff, sizeof(cmd_buff), false, NULL, buff, sizeof(buff), true);
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_GET_CONTEXT_STATUS, false, buff, sizeof(buff));
// pass the replies
if(fwVersion) { *fwVersion = buff[0]; }
if(almanacCrc) { *almanacCrc = ((uint32_t)(buff[1]) << 24) | ((uint32_t)(buff[2]) << 16) | ((uint32_t)(buff[3]) << 8) | (uint32_t)buff[4]; }
if(errCode) { *errCode = (buff[5] & 0xF0) >> 4; }
if(almUpdMask) { *almUpdMask = (buff[5] & 0x0E) >> 1; }
if(freqSpace) { *freqSpace = ((buff[5] & 0x01) << 1) | ((buff[6] & 0x80) >> 7); }
if(fwVersion) { *fwVersion = buff[2]; }
if(almanacCrc) { *almanacCrc = ((uint32_t)(buff[3]) << 24) | ((uint32_t)(buff[4]) << 16) | ((uint32_t)(buff[5]) << 8) | (uint32_t)buff[6]; }
if(errCode) { *errCode = (buff[7] & 0xF0) >> 4; }
if(almUpdMask) { *almUpdMask = (buff[7] & 0x0E) >> 1; }
if(freqSpace) { *freqSpace = ((buff[7] & 0x01) << 1) | ((buff[8] & 0x80) >> 7); }
return(state);
}
@ -2995,10 +3053,10 @@ int16_t LR11x0::gnssGetSvVisible(uint32_t time, float lat, float lon, uint8_t co
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_GET_SV_VISIBLE, false, nbSv, 1, reqBuff, sizeof(reqBuff)));
}
// TODO check version > 02.01
int16_t LR11x0::gnssScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax) {
int16_t LR11x0::gnssPerformScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax) {
uint8_t buff[3] = { effort, resMask, nbSvMax };
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_SCAN, true, buff, sizeof(buff)));
// call the SPI write stream directly to skip waiting for BUSY - it will be set to high once the scan starts
return(this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_GNSS_SCAN, buff, sizeof(buff), false, false));
}
int16_t LR11x0::gnssReadLastScanModeLaunched(uint8_t* lastScanMode) {

View file

@ -700,6 +700,10 @@ struct LR11x0VersionInfo_t {
uint8_t almanacGNSS;
};
struct LR11x0GnssResult_t {
};
/*!
\class LR11x0
\brief Base class for %LR11x0 series. All derived classes for %LR11x0 (e.g. LR1110 or LR1120) inherit from this base class.
@ -753,34 +757,31 @@ class LR11x0: public PhysicalLayer {
\param sf LoRa spreading factor.
\param cr LoRa coding rate denominator.
\param syncWord 1-byte LoRa sync word.
\param power Output power in dBm.
\param preambleLength LoRa preamble length in symbols
\param tcxoVoltage TCXO reference voltage to be set.
\returns \ref status_codes
*/
int16_t begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage);
int16_t begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage);
/*!
\brief Initialization method for FSK modem.
\param br FSK bit rate in kbps.
\param freqDev Frequency deviation from carrier frequency in kHz.
\param rxBw Receiver bandwidth in kHz.
\param power Output power in dBm.
\param preambleLength FSK preamble length in bits.
\param tcxoVoltage TCXO reference voltage to be set.
\returns \ref status_codes
*/
int16_t beginGFSK(float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage);
int16_t beginGFSK(float br, float freqDev, float rxBw, uint16_t preambleLength, float tcxoVoltage);
/*!
\brief Initialization method for LR-FHSS modem.
\param bw LR-FHSS bandwidth, one of RADIOLIB_LR11X0_LR_FHSS_BW_* values.
\param cr LR-FHSS coding rate, one of RADIOLIB_LR11X0_LR_FHSS_CR_* values.
\param power Output power in dBm.
\param tcxoVoltage TCXO reference voltage to be set.
\returns \ref status_codes
*/
int16_t beginLRFHSS(uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage);
int16_t beginLRFHSS(uint8_t bw, uint8_t cr, float tcxoVoltage);
/*!
\brief Reset method. Will reset the chip to the default state using RST pin.
@ -981,41 +982,6 @@ class LR11x0: public PhysicalLayer {
// configuration methods
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA).
\param power Output power to be set in dBm, output PA is determined automatically preferring the low-power PA.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power) override;
/*!
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA).
\param power Output power to be set in dBm.
\param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically
based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power, bool forceHighPower);
/*!
\brief Check if output power is configurable.
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
\param power Output power in dBm, PA will be determined automatically.
\param clipped Clipped output power value to what is possible within the module's range.
\returns \ref status_codes
*/
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
/*!
\brief Check if output power is configurable.
\param power Output power in dBm.
\param clipped Clipped output power value to what is possible within the module's range.
\param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically
based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used.
\returns \ref status_codes
*/
int16_t checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower);
/*!
\brief Sets LoRa bandwidth. Allowed values are 62.5, 125.0, 250.0 and 500.0 kHz.
\param bw LoRa bandwidth to be set in kHz.
@ -1393,6 +1359,14 @@ class LR11x0: public PhysicalLayer {
*/
int16_t updateFirmware(const uint32_t* image, size_t size, bool nonvolatile = true);
int16_t isGnssScanCapable();
int16_t gnssScan(uint16_t* resSize);
int16_t getGnssScanResult(uint16_t size);
int16_t getGnssPosition(float* lat, float* lon, bool filtered);
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
protected:
#endif
@ -1514,7 +1488,7 @@ class LR11x0: public PhysicalLayer {
int16_t gnssAlmanacFullUpdateHeader(uint16_t date, uint32_t globalCrc);
int16_t gnssAlmanacFullUpdateSV(uint8_t svn, uint8_t* svnAlmanac);
int16_t gnssGetSvVisible(uint32_t time, float lat, float lon, uint8_t constellation, uint8_t* nbSv);
int16_t gnssScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax);
int16_t gnssPerformScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax);
int16_t gnssReadLastScanModeLaunched(uint8_t* lastScanMode);
int16_t gnssFetchTime(uint8_t effort, uint8_t opt);
int16_t gnssReadTime(uint8_t* err, uint32_t* time, uint32_t* nbUs, uint32_t* timeAccuracy);