Compare commits

..

No commits in common. "master" and "17.0.1" have entirely different histories.

110 changed files with 1636 additions and 2593 deletions

View file

@ -83,14 +83,12 @@ jobs:
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 "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: |
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 "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: STMicroelectronics:stm32:Nucleo_64
- id: STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1
run: |
echo "options=':pnum=NUCLEO_WL55JC1'" >> $GITHUB_OUTPUT
# 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
@ -185,20 +183,19 @@ jobs:
cd $PWD/extras/test/ci
./build_examples.sh ${{ matrix.id }} "${{ steps.prep.outputs.skip-pattern }}" ${{ steps.prep.outputs.options }}
- name: Extract short commit hash
id: short-hash
run: echo "::set-output name=short_sha::$(git rev-parse --short HEAD)"
- name: Parse sizes
if: ${{ env.run-build == 'true' }}
run:
|
cd $PWD/extras/test/ci
./parse_size.sh ${{ matrix.id }}
cat size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv
- name: Extract short commit hash
id: short-hash
run: echo "::set-output name=short_sha::$(git rev-parse --short HEAD)"
- name: Upload size report as artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: size-file-${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}
path: extras/test/ci/size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv
@ -206,7 +203,6 @@ jobs:
metrics:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/master'
steps:
- name: Set up SSH
run: |
@ -225,7 +221,7 @@ jobs:
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
- name: Download size artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v3
with:
path: aggregated-sizes
@ -293,7 +289,6 @@ jobs:
LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
rpi-build:
if: false # self-hosted runner temporarily disabled
runs-on: [self-hosted, ARM64]
steps:
- name: Checkout repository
@ -325,7 +320,6 @@ jobs:
./build.sh
rpi-test:
if: false # self-hosted runner temporarily disabled
needs: rpi-build
runs-on: [self-hosted, ARM64]
steps:

View file

@ -10,7 +10,7 @@ on:
jobs:
unit-test:
name: Build and run unit test
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- name: Checkout repository
@ -19,30 +19,9 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libboost-all-dev libfmt-dev lcov
sudo apt-get install -y libboost-all-dev libfmt-dev
- 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

3
.gitignore vendored
View file

@ -11,6 +11,9 @@
# Jetbrain IDEs
.idea
# Spectrum scan
extras/SX126x_Spectrum_Scan/out/*
# PlatformIO
.pio*

View file

@ -36,7 +36,7 @@ target_include_directories(RadioLib
set_property(TARGET RadioLib PROPERTY CXX_STANDARD 20)
# enable most warnings
target_compile_options(RadioLib PRIVATE -Wall -Wextra -Wpedantic -Wdouble-promotion)
target_compile_options(RadioLib PRIVATE -Wall -Wextra)
include(GNUInstallDirs)

View file

@ -82,11 +82,10 @@ void setup() {
void loop() {
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 64 characters long
int state = radio.transmit("Hello World!");
// you can also transmit byte array up to 255 bytes long
// With some limitations see here: https://github.com/jgromes/RadioLib/discussions/1138
// you can also transmit byte array up to 64 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);

View file

@ -2,7 +2,7 @@
RadioLib CC1101 Blocking Transmit Example
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
- null-terminated char array (C-string)
- arbitrary binary data (byte array)
@ -57,11 +57,11 @@ int count = 0;
void loop() {
Serial.print(F("[CC1101] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to 255 characters long
// you can transmit C-string or Arduino string up to 64 characters long
String str = "Hello World! #" + String(count++);
int state = radio.transmit(str);
// you can also transmit byte array up to 255 bytes long with some limitations; https://github.com/jgromes/RadioLib/discussions/1138
// you can also transmit byte array up to 64 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
@ -72,7 +72,7 @@ void loop() {
Serial.println(F("success!"));
} 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!"));
} else {

View file

@ -3,7 +3,7 @@
This example transmits packets using CC1101 FSK radio module.
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
- null-terminated char array (C-string)
- arbitrary binary data (byte array)
@ -73,12 +73,10 @@ void setup() {
Serial.print(F("[CC1101] Sending first packet ... "));
// you can transmit C-string or Arduino string up to
// 255 characters long
// 64 characters long
transmissionState = radio.startTransmit("Hello World!");
// you can also transmit byte array up to 255 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
// you can also transmit byte array up to 64 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
0x78, 0xAB, 0xCD, 0xEF};
@ -121,11 +119,11 @@ void loop() {
Serial.print(F("[CC1101] Sending another packet ... "));
// you can transmit C-string or Arduino string up to
// 255 characters long
// 64 characters long
String str = "Hello World! #" + String(count++);
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 64 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};

View file

@ -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
// 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;
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
const uint8_t subBand = 0;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...

View file

@ -48,9 +48,6 @@ void setup() {
// Override the default join rate
uint8_t joinDR = 4;
// Optionally provide a custom sleep function - see config.h
//node.setSleepFunction(customDelay);
// Setup the OTAA session information
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);

View file

@ -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
// 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;
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
const uint8_t subBand = 0;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
@ -144,19 +142,4 @@ void arrayDump(uint8_t *buffer, uint16_t len) {
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

View file

@ -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
// 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;
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
const uint8_t subBand = 0;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...

View file

@ -8,7 +8,7 @@ RadioLib LoRaWAN examples.
## 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**.
The catch is in the Regional Parameters: as RP002 1.0.4 is newer than RP001 1.1, it is more up to date regarding local laws & regulations. Therefore, RadioLib implements 1.0.4 as baseline and 1.1 (revision B) as fallback, and as such **RP002 Regional Parameters 1.0.4 is preferred**.
_Note: the 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 RP001 1.1 revision B, as the RP002 1.0.4 version is much too complex._
To activate a LoRaWAN 1.1 session, supply all the required keys:
```cpp

View file

@ -0,0 +1,96 @@
/*
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);
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67};
state = radio.setSyncWord(syncWord, 4);
if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to set configuration, code "));
Serial.println(state);
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);
}
}

View file

@ -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);
}

View file

@ -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);
*/
}
}
}

View file

@ -1,2 +0,0 @@
# all output pictures
*.png

View file

@ -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

View file

@ -2,14 +2,7 @@
file=cppcheck.txt
cppcheck --version
cppcheck src --enable=all \
--force \
--inline-suppr \
--suppress=ConfigurationNotChecked \
--suppress=unusedFunction \
--suppress=missingIncludeSystem \
--suppress=missingInclude \
--quiet >> $file 2>&1
cppcheck src --enable=all --force --inline-suppr --suppress=ConfigurationNotChecked --suppress=unusedFunction --quiet >> $file 2>&1
echo "Cppcheck finished with exit code $?"
error=$(grep ": error:" $file | wc -l)

View file

@ -1,2 +1 @@
build/
lcov*

View file

@ -18,13 +18,12 @@ add_executable(${PROJECT_NAME} ${TEST_SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC include)
# link RadioLib
target_link_libraries(${PROJECT_NAME} RadioLib fmt gcov)
target_link_libraries(${PROJECT_NAME} RadioLib fmt)
# 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})
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra)
# set RadioLib debug
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI RADIOLIB_DEBUG_PROTOCOL)
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI)
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_PORT=stdout)

View file

@ -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"

View file

@ -47,9 +47,6 @@ class TestHal : public RadioLibHal {
this->gpio[i].event = false;
this->gpio[i].func = PIN_UNASSIGNED;
}
// wipe history log
this->spiLogWipe();
}
void term() override {
@ -107,18 +104,10 @@ class TestHal : public RadioLibHal {
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 {
@ -170,11 +159,6 @@ class TestHal : public RadioLibHal {
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);
}
@ -184,6 +168,10 @@ class TestHal : public RadioLibHal {
void spiBeginTransaction() {
HAL_LOG("TestHal::spiBeginTransaction()");
// wipe history log
memset(this->spiLog, 0x00, TEST_HAL_SPI_LOG_LENGTH);
this->spiLogPtr = this->spiLog;
}
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
@ -196,12 +184,7 @@ class TestHal : public RadioLibHal {
// 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
// outpu debug
HAL_LOG(fmt::format("out={:#02x}, in={:#02x}", out[i], in[i]));
}
}
@ -216,30 +199,15 @@ class TestHal : public RadioLibHal {
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;
return(memcmp(this->spiLog, in, n));
}
// method that "connects" the emualted radio hardware to this HAL

View file

@ -3,8 +3,7 @@
set -e
# build the test binary
rm -rf build
mkdir build
mkdir -p build
cd build
cmake -G "CodeBlocks - Unix Makefiles" ..
make -j4

View file

@ -48,9 +48,8 @@ BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
// 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);
BOOST_TEST(ret == 0x3E);
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
ret = mod->SPIgetRegValue(address, lsb, msb);
@ -61,60 +60,6 @@ BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
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 ---");
@ -143,9 +88,8 @@ BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
// 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);
BOOST_TEST(ret == 0x3E);
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
ret = mod->SPIgetRegValue(address, lsb, msb);
@ -156,74 +100,4 @@ BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
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()

View file

@ -1,4 +1,4 @@
version: "17.0.3"
version: "7.1.2"
description: "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN)."
tags:
- radio
@ -33,8 +33,8 @@ tags:
- lr1110
- lr1120
- lr1121
url: "https://git.cheetah.cat/forks/RadioLibSmol"
repository: "https://git.cheetah.cat/forks/RadioLibSmol.git"
url: "https://github.com/jgromes/RadioLib"
repository: "https://github.com/jgromes/RadioLib.git"
license: "MIT"
dependencies:
# Required IDF version

View file

@ -86,7 +86,7 @@ EU868 KEYWORD1
US915 KEYWORD1
EU433 KEYWORD1
AU915 KEYWORD1
CN470 KEYWORD1
CN500 KEYWORD1
AS923 KEYWORD1
AS923_2 KEYWORD1
AS923_3 KEYWORD1
@ -246,7 +246,6 @@ spectralScanAbort KEYWORD2
spectralScanGetStatus KEYWORD2
spectralScanGetResult KEYWORD2
setPaRampTime KEYWORD2
hopLRFHSS KEYWORD2
# nRF24
setIrqAction KEYWORD2
@ -343,8 +342,6 @@ setDataRate KEYWORD2
checkDataRate KEYWORD2
setModem KEYWORD2
getModem KEYWORD2
stageMode KEYWORD2
launchMode KEYWORD2
# LoRaWAN
getBufferNonces KEYWORD2
@ -379,7 +376,6 @@ getLastToA KEYWORD2
dutyCycleInterval KEYWORD2
timeUntilUplink KEYWORD2
getMaxPayloadLen KEYWORD2
setSleepFunction KEYWORD2
#######################################
# Constants (LITERAL1)

View file

@ -1,6 +1,6 @@
{
"name": "RadioLib",
"version": "17.0.3",
"version": "17.0.2",
"description": "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN).",
"keywords": "radio, communication, morse, cc1101, aprs, sx1276, sx1278, sx1272, rtty, ax25, afsk, nrf24, rf69, sx1231, rfm96, rfm98, sstv, sx1280, sx1281, sx1282, sx1261, sx1262, sx1268, si4432, rfm22, llcc68, pager, pocsag, lorawan, lr1110, lr1120, lr1121",
"homepage": "https://github.com/jgromes/RadioLib",

View file

@ -1,5 +1,5 @@
name=RadioLib
version=17.0.3
version=17.0.2
author=Jan Gromes <gromes.jan@gmail.com>
maintainer=Jan Gromes <gromes.jan@gmail.com>
sentence=Universal wireless communication library

View file

@ -29,11 +29,7 @@
// 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)
#if !defined(RADIOLIB_DEBUG_PORT)
#if ARDUINO >= 100
#define RADIOLIB_DEBUG_PORT Serial
#else
#define RADIOLIB_DEBUG_PORT stdout
#endif
#endif
/*
@ -118,10 +114,6 @@
//#define RADIOLIB_CLOCK_DRIFT_MS (0)
#endif
#if !defined(RADIOLIB_LINE_FEED)
#define RADIOLIB_LINE_FEED "\r\n"
#endif
#if ARDUINO >= 100
// Arduino build
#include "Arduino.h"
@ -268,24 +260,20 @@
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_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
#define RADIOLIB_TONE_UNSUPPORTED
#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
#define RADIOLIB_PLATFORM "Portenta H7"
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_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
#define RADIOLIB_TONE_UNSUPPORTED
#define RADIOLIB_MBED_TONE_OVERRIDE
#endif
#elif defined(__STM32F4__) || defined(__STM32F1__)
// Arduino STM32 core by Roger Clark (https://github.com/rogerclarkmelbourne/Arduino_STM32)
@ -441,10 +429,14 @@
#define RADIOLIB_NC (0xFFFFFFFF)
#define RADIOLIB_NONVOLATILE
#define RADIOLIB_NONVOLATILE_READ_BYTE(addr) (*(reinterpret_cast<uint8_t *>(reinterpret_cast<void *>(addr))))
#define RADIOLIB_NONVOLATILE_READ_DWORD(addr) (*(reinterpret_cast<uint32_t *>(reinterpret_cast<void *>(addr))))
#define RADIOLIB_NONVOLATILE_READ_BYTE(addr) (*((uint8_t *)(void *)(addr)))
#define RADIOLIB_NONVOLATILE_READ_DWORD(addr) (*((uint32_t *)(void *)(addr)))
#define RADIOLIB_TYPE_ALIAS(type, alias) using alias = type;
#if !defined(RADIOLIB_DEBUG_PORT)
#define RADIOLIB_DEBUG_PORT stdout
#endif
#define DEC 10
#define HEX 16
#define OCT 8
@ -473,20 +465,23 @@
#endif
#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)
#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)
#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)
#endif
@ -494,74 +489,63 @@
#else
#define RADIOLIB_DEBUG_PRINT(...) {}
#define RADIOLIB_DEBUG_PRINTLN(...) {}
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) {}
#define RADIOLIB_DEBUG_PRINT_FLOAT(VAL, DECIMALS) {}
#define RADIOLIB_DEBUG_HEXDUMP(...) {}
#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
#define RADIOLIB_DEBUG_BASIC_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT(RADIOLIB_DEBUG_TAG_BASIC, __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT(__VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN(__VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_DBG: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT_LVL("", __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("RLB_DBG: ", __VA_ARGS__);
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_DBG: ", __VA_ARGS__);
#else
#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_PRINTLN_NOTAG(...) {}
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) {}
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) {}
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) {}
#endif
#if RADIOLIB_DEBUG_PROTOCOL
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL(RADIOLIB_DEBUG_TAG_PROTOCOL, __VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL(RADIOLIB_DEBUG_TAG_PROTOCOL, __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(RADIOLIB_DEBUG_TAG_PROTOCOL, __VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT(__VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN(__VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_PRO: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_PRO: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_PRO: ", __VA_ARGS__);
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_PRO: ", __VA_ARGS__);
#else
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_NOTAG(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN_NOTAG(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) {}
#endif
#if RADIOLIB_DEBUG_SPI
#define RADIOLIB_DEBUG_SPI_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT(RADIOLIB_DEBUG_TAG_SPI, __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT(__VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN(__VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_SPI: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT_LVL("", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_SPI: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN_LVL("", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_SPI: ", __VA_ARGS__);
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_SPI: ", __VA_ARGS__);
#else
#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_PRINTLN(...) {}
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) {}
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) {}
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) {}
#endif
// debug info strings
#define RADIOLIB_VALUE_TO_STRING(x) #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_MINOR) "." \
RADIOLIB_VALUE(RADIOLIB_VERSION_PATCH) "." \
RADIOLIB_VALUE(RADIOLIB_VERSION_EXTRA) "\"\r\n" \
"Platform: " RADIOLIB_VALUE(RADIOLIB_PLATFORM) "\r\n" \
RADIOLIB_VALUE(__DATE__) " " RADIOLIB_VALUE(__TIME__)
RADIOLIB_VALUE(RADIOLIB_VERSION_EXTRA) "\"\n" \
"Platform: " RADIOLIB_VALUE(RADIOLIB_PLATFORM) "\n" \
"Compiled: " RADIOLIB_VALUE(__DATE__) " " RADIOLIB_VALUE(__TIME__)
/*!
\brief A simple assert macro, will return on error.

View file

@ -1,18 +1,12 @@
#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)
: GpioModeInput(input),
GpioModeOutput(output),
GpioLevelLow(low),
GpioLevelHigh(high),
GpioInterruptRising(rising),
GpioInterruptFalling(falling) {
if(!rlb_timestamp_hal) {
rlb_timestamp_hal = this;
}
}
GpioInterruptFalling(falling) {}
void RadioLibHal::init() {
@ -39,7 +33,3 @@ void RadioLibHal::yield() {
uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) {
return(pin);
}
RadioLibTime_t rlb_time_us() {
return(rlb_timestamp_hal == nullptr ? 0 : rlb_timestamp_hal->micros());
}

View file

@ -6,9 +6,6 @@
#include "BuildOpt.h"
/*! \brief Global-scope function that returns timestamp since start (in microseconds). */
RadioLibTime_t rlb_time_us();
/*!
\class RadioLibHal
\brief Hardware abstraction library base interface.

View file

@ -25,7 +25,7 @@ Module::Module(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->irqPin = mod.irqPin;
this->rstPin = mod.rstPin;
@ -142,7 +142,7 @@ uint8_t Module::SPIreadRegister(uint32_t reg) {
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) {
SPItransfer(spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE], reg, data, NULL, numBytes);
} else {
@ -174,7 +174,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
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
@ -216,7 +216,7 @@ void Module::SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uin
// print debug information
#if RADIOLIB_DEBUG_SPI
const uint8_t* debugBuffPtr = NULL;
uint8_t* debugBuffPtr = NULL;
if(cmd == spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE]) {
RADIOLIB_DEBUG_SPI_PRINT("W\t%X\t", reg);
debugBuffPtr = &buffOut[this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8];
@ -227,7 +227,7 @@ void Module::SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uin
for(size_t n = 0; n < numBytes; n++) {
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", debugBuffPtr[n]);
}
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
#endif
#if !RADIOLIB_STATIC_ONLY
@ -245,7 +245,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));
}
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
int16_t state = this->SPItransferStream(cmd, cmdLen, false, NULL, data, numBytes, waitForGpio);
RADIOLIB_ASSERT(state);
@ -264,7 +264,7 @@ int16_t Module::SPIreadStream(const uint8_t* cmd, uint8_t cmdLen, uint8_t* data,
#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* cmdPtr = cmdBuf;
for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
@ -273,7 +273,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));
}
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
int16_t state = this->SPItransferStream(cmd, cmdLen, true, data, NULL, numBytes, waitForGpio);
RADIOLIB_ASSERT(state);
@ -315,9 +315,8 @@ int16_t Module::SPIcheckStream() {
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
int16_t state = RADIOLIB_ERR_NONE;
size_t buffLen = cmdLen + numBytes;
if(!write) {
buffLen += (this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] / 8);
@ -349,9 +348,6 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
RadioLibTime_t start = this->hal->millis();
while(this->hal->digitalRead(this->gpioPin)) {
this->hal->yield();
// this timeout check triggers a false positive from cppcheck
// cppcheck-suppress unsignedLessThanZero
if(this->hal->millis() - start >= this->spiConfig.timeout) {
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO pre-transfer timeout, is it connected?");
#if !RADIOLIB_STATIC_ONLY
@ -359,7 +355,6 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
#endif
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
}
}
}
}
@ -387,23 +382,21 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
RadioLibTime_t start = this->hal->millis();
while(this->hal->digitalRead(this->gpioPin)) {
this->hal->yield();
// this timeout check triggers a false positive from cppcheck
// cppcheck-suppress unsignedLessThanZero
if(this->hal->millis() - start >= this->spiConfig.timeout) {
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO post-transfer timeout, is it connected?");
// do not return yet to display the debug output
state = RADIOLIB_ERR_SPI_CMD_TIMEOUT;
break;
#if !RADIOLIB_STATIC_ONLY
delete[] buffOut;
delete[] buffIn;
#endif
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
}
}
}
}
// parse status (only if GPIO did not timeout)
if((state == RADIOLIB_ERR_NONE) && (this->spiConfig.parseStatusCb != nullptr) && (numBytes > 0)) {
// parse status
int16_t state = RADIOLIB_ERR_NONE;
if((this->spiConfig.parseStatusCb != nullptr) && (numBytes > 0)) {
state = this->spiConfig.parseStatusCb(buffIn[this->spiConfig.statusPos]);
}
@ -426,7 +419,7 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
for(; n < cmdLen; n++) {
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", cmd[n]);
}
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
// print data bytes
RADIOLIB_DEBUG_SPI_PRINT("SI\t");
@ -436,12 +429,12 @@ int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write
for(; n < buffLen; 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");
for(n = 0; n < buffLen; n++) {
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffIn[n]);
}
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
#endif
#if !RADIOLIB_STATIC_ONLY

View file

@ -298,7 +298,7 @@ class Module {
\param data Pointer to array that holds the data 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.
@ -315,7 +315,7 @@ class Module {
\param dataIn Data that was transferred from slave to master.
\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.
@ -344,7 +344,7 @@ class Module {
\param verify Whether to verify the result of the transaction after it is finished.
\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.
@ -355,7 +355,7 @@ class Module {
\param verify Whether to verify the result of the transaction after it is finished.
\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.
@ -367,7 +367,7 @@ class Module {
\param verify Whether to verify the result of the transaction after it is finished.
\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.).
@ -380,7 +380,7 @@ class Module {
\param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
\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
// getCs is omitted on purpose, as it can interfere when accessing the SPI in a concurrent environment

View file

@ -22,7 +22,6 @@
- PhysicalLayer - FSK and LoRa radio modules
\see https://github.com/jgromes/RadioLib
\see https://jgromes.github.io/RadioLib/coverage/src/index.html
\copyright Copyright (c) 2019 Jan Gromes
*/

View file

@ -2,9 +2,7 @@
#include <math.h>
#if !RADIOLIB_EXCLUDE_CC1101
CC1101::CC1101(Module* module) : PhysicalLayer() {
this->freqStep = RADIOLIB_CC1101_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_CC1101_MAX_PACKET_LENGTH;
CC1101::CC1101(Module* module) : PhysicalLayer(RADIOLIB_CC1101_FREQUENCY_STEP_SIZE, RADIOLIB_CC1101_MAX_PACKET_LENGTH) {
this->mod = module;
}
@ -60,7 +58,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) {
// 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
int16_t state = startReceive();
@ -118,12 +116,6 @@ int16_t CC1101::standby(uint8_t mode) {
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) {
return transmitDirect(true, frf);
}
@ -238,50 +230,23 @@ int16_t CC1101::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
// flush Tx FIFO
SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX);
// Turn on freq oscilator
SPIsendCommand(RADIOLIB_CC1101_CMD_FSTXON);
// 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);
// set GDO0 mapping
int16_t 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
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);
dataSent+= 1;
}
// check address filtering
uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0);
if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) {
SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, addr);
dataSent += 1;
}
// 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), initialWrite);
dataSent += initialWrite;
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast<uint8_t*>(data), len);
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_TX);
@ -289,40 +254,11 @@ int16_t CC1101::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
// set mode to transmit
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);
}
int16_t CC1101::finishTransmit() {
// 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();
RADIOLIB_ASSERT(state);
@ -418,9 +354,9 @@ int16_t CC1101::readData(uint8_t* data, size_t len) {
int16_t CC1101::setFrequency(float freq) {
// check allowed frequency range
#if RADIOLIB_CHECK_PARAMS
if(!(((freq >= 300.0f) && (freq <= 348.0f)) ||
((freq >= 387.0f) && (freq <= 464.0f)) ||
((freq >= 779.0f) && (freq <= 928.0f)))) {
if(!(((freq >= 300.0) && (freq <= 348.0)) ||
((freq >= 387.0) && (freq <= 464.0)) ||
((freq >= 779.0) && (freq <= 928.0)))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY);
}
#endif
@ -430,7 +366,7 @@ int16_t CC1101::setFrequency(float freq) {
//set carrier frequency
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);
state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ1, (FRF & 0x00FF00) >> 8, 7, 0);
state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ0, FRF & 0x0000FF, 7, 0);
@ -444,7 +380,7 @@ int16_t CC1101::setFrequency(float freq) {
}
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
SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE);
@ -452,7 +388,7 @@ int16_t CC1101::setBitRate(float br) {
// calculate exponent and mantissa values
uint8_t e = 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
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, e, 3, 0);
@ -473,7 +409,7 @@ int16_t CC1101::setBitRateTolerance(uint8_t brt) {
}
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
SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE);
@ -481,8 +417,8 @@ int16_t CC1101::setRxBandwidth(float rxBw) {
// calculate exponent and mantissa values
for(int8_t e = 3; e >= 0; e--) {
for(int8_t m = 3; m >= 0; m --) {
float point = (RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0f)/(8 * (m + 4) * ((uint32_t)1 << e));
if(fabs((rxBw * 1000.0f - point) <= 1000.0f)) {
float point = (RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0)/(8 * (m + 4) * ((uint32_t)1 << e));
if(fabs((rxBw * 1000.0) - point) <= 1000) {
// set Rx channel filter bandwidth
return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, (e << 6) | (m << 4), 7, 4));
}
@ -500,27 +436,27 @@ int16_t CC1101::autoSetRxBandwidth() {
uncertainty = (uncertainty/1000); //Since bitrate is in kBit
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++) {
if(options[i] > minbw) {
return(setRxBandwidth(options[i]));
if (possibles[i] > minbw) {
int16_t state = setRxBandwidth(possibles[i]);
return(state);
}
}
return(RADIOLIB_ERR_UNKNOWN);
}
int16_t CC1101::setFrequencyDeviation(float freqDev) {
// set frequency deviation to lowest available setting (required for digimodes)
float newFreqDev = freqDev;
if(freqDev < 0.0f) {
newFreqDev = 1.587f;
if(freqDev < 0.0) {
newFreqDev = 1.587;
}
// check range unless 0 (special value)
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
@ -529,7 +465,7 @@ int16_t CC1101::setFrequencyDeviation(float freqDev) {
// calculate exponent and mantissa values
uint8_t e = 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
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_DEVIATN, (e << 4), 6, 4);
@ -558,7 +494,7 @@ int16_t CC1101::getFrequencyDeviation(float *freqDev) {
//
// 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);
}
@ -577,7 +513,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[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);
return(RADIOLIB_ERR_NONE);
@ -622,13 +558,13 @@ int16_t CC1101::checkOutputPower(int8_t power, int8_t* clipped, uint8_t* raw) {
// round to the known frequency settings
uint8_t f;
if(this->frequency < 374.0f) {
if(this->frequency < 374.0) {
// 315 MHz
f = 0;
} else if(this->frequency < 650.5f) {
} else if(this->frequency < 650.5) {
// 434 MHz
f = 1;
} else if(this->frequency < 891.5f) {
} else if(this->frequency < 891.5) {
// 868 MHz
f = 2;
} else {
@ -656,7 +592,7 @@ int16_t CC1101::checkOutputPower(int8_t power, int8_t* clipped, uint8_t* raw) {
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)) {
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
}
@ -781,9 +717,9 @@ float CC1101::getRSSI() {
if(!this->directModeEnabled) {
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 {
rssi = (((float)this->rawRSSI)/2.0f) - 74.0f;
rssi = (((float)this->rawRSSI)/2.0) - 74.0;
}
} else {
uint8_t rawRssi = SPIreadRegister(RADIOLIB_CC1101_REG_RSSI);
@ -1065,7 +1001,7 @@ int16_t CC1101::beginCommon(float freq, float br, float freqDev, float rxBw, int
RADIOLIB_ASSERT(state);
// set default sync word
const uint8_t sw[RADIOLIB_CC1101_DEFAULT_SW_LEN] = RADIOLIB_CC1101_DEFAULT_SW;
uint8_t sw[RADIOLIB_CC1101_DEFAULT_SW_LEN] = RADIOLIB_CC1101_DEFAULT_SW;
state = setSyncWord(sw[0], sw[1], 0, false);
RADIOLIB_ASSERT(state);
@ -1128,7 +1064,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) {
// 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
for(int8_t e = expMax; e >= 0; e--) {
@ -1219,7 +1155,7 @@ void CC1101::SPIwriteRegister(uint8_t reg, uint8_t 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);
}

View file

@ -8,9 +8,8 @@
// CC1101 physical layer properties
#define RADIOLIB_CC1101_FREQUENCY_STEP_SIZE 396.7285156
#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 255
#define RADIOLIB_CC1101_FIFO_SIZE 64
#define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0f
#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 64
#define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0
#define RADIOLIB_CC1101_DIV_EXPONENT 16
// CC1101 SPI commands
@ -615,12 +614,6 @@ class CC1101: public PhysicalLayer {
*/
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.
\param frf Raw RF frequency value. Defaults to 0, required for quick frequency shifts in RTTY.
@ -702,10 +695,7 @@ class CC1101: public PhysicalLayer {
void clearPacketSentAction() override;
/*!
\brief Interrupt-driven binary transmit method for packets less than 64 bytes.
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
\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.
@ -843,7 +833,7 @@ class CC1101: public PhysicalLayer {
\param requireCarrierSense Require carrier sense above threshold in addition to sync word.
\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.
@ -1013,7 +1003,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);
void SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes);
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 SPIsendCommand(uint8_t cmd);

View file

@ -37,58 +37,8 @@ int16_t LLCC68::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
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) {
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));
}
@ -145,14 +95,14 @@ int16_t LLCC68::checkDataRate(DataRate_t dr) {
// select interpretation based on active modem
uint8_t modem = this->getPacketType();
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.freqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6, 200.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
return(RADIOLIB_ERR_NONE);
} 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);
uint8_t bw_div2 = dr.lora.bandwidth / 2 + 0.01f;
uint8_t bw_div2 = dr.lora.bandwidth / 2 + 0.01;
switch (bw_div2) {
case 62: // 125.0:
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 5, 9, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);

View file

@ -39,38 +39,7 @@ class LLCC68: public SX1262 {
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
\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;
/*!
\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;
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);
// configuration methods
@ -79,14 +48,14 @@ class LLCC68: public SX1262 {
\param bw LoRa bandwidth to be set in kHz.
\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.
\param sf LoRa spreading factor to be set.
\returns \ref status_codes
*/
int16_t setSpreadingFactor(uint8_t sf) override;
int16_t setSpreadingFactor(uint8_t sf);
/*!
\brief Set data.

View file

@ -51,7 +51,7 @@ int16_t LR1110::setFrequency(float freq) {
}
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
int16_t state;

View file

@ -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) {
// 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);
// configure publicly accessible settings
@ -51,13 +51,11 @@ int16_t LR1120::setFrequency(float freq) {
}
int16_t LR1120::setFrequency(float freq, bool skipCalibration, float band) {
#if RADIOLIB_CHECK_PARAMS
if(!(((freq >= 150.0f) && (freq <= 960.0f)) ||
((freq >= 1900.0f) && (freq <= 2200.0f)) ||
((freq >= 2400.0f) && (freq <= 2500.0f)))) {
if(!(((freq >= 150.0) && (freq <= 960.0)) ||
((freq >= 1900.0) && (freq <= 2200.0)) ||
((freq >= 2400.0) && (freq <= 2500.0)))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY);
}
#endif
// check if we need to recalibrate image
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));
RADIOLIB_ASSERT(state);
this->freqMHz = freq;
this->highFreq = (freq > 1000.0f);
this->highFreq = (freq > 1000.0);
return(RADIOLIB_ERR_NONE);
}

View file

@ -8,9 +8,7 @@
#if !RADIOLIB_EXCLUDE_LR11X0
LR11x0::LR11x0(Module* mod) : PhysicalLayer() {
this->freqStep = RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_LR11X0_MAX_PACKET_LENGTH;
LR11x0::LR11x0(Module* mod) : PhysicalLayer(RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE, RADIOLIB_LR11X0_MAX_PACKET_LENGTH) {
this->mod = mod;
this->XTAL = false;
this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_LR11X0_IRQ_TX_DONE;
@ -221,7 +219,7 @@ int16_t LR11x0::transmit(const uint8_t* data, size_t len, uint8_t addr) {
RadioLibTime_t elapsed = this->mod->hal->micros() - start;
// update data rate
this->dataRateMeasured = (len*8.0f)/((float)elapsed/1000000.0f);
this->dataRateMeasured = (len*8.0)/((float)elapsed/1000000.0);
return(finishTransmit());
}
@ -240,7 +238,7 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
// calculate timeout (100 LoRa symbols, the default for SX127x series)
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
timeout = (RadioLibTime_t)(symbolLength * 100.0f);
timeout = (RadioLibTime_t)(symbolLength * 100.0);
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
// calculate timeout (500 % of expected time-one-air)
@ -248,8 +246,8 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
if(len == 0) {
maxLen = 0xFF;
}
float brBps = ((float)(RADIOLIB_LR11X0_CRYSTAL_FREQ) * 1000000.0f * 32.0f) / (float)this->bitRate;
timeout = (RadioLibTime_t)(((maxLen * 8.0f) / brBps) * 1000.0f * 5.0f);
float brBps = ((float)(RADIOLIB_LR11X0_CRYSTAL_FREQ) * 1000000.0 * 32.0) / (float)this->bitRate;
timeout = (RadioLibTime_t)(((maxLen * 8.0) / brBps) * 1000.0 * 5.0);
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
// this modem cannot receive
@ -263,7 +261,7 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout);
// 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);
RADIOLIB_ASSERT(state);
@ -289,7 +287,7 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
// check whether this was a timeout or not
if((getIrqStatus() & RADIOLIB_LR11X0_IRQ_TIMEOUT) || softTimeout) {
standby();
clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
return(RADIOLIB_ERR_RX_TIMEOUT);
}
@ -416,9 +414,76 @@ void LR11x0::clearPacketSentAction() {
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() {
// clear interrupt flags
clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
// set mode to standby to disable transmitter/RF switch
return(standby());
@ -428,6 +493,46 @@ int16_t LR11x0::startReceive() {
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() {
// there is no dedicated "get IRQ" command, the IRQ bits are sent after the status bytes
uint8_t buff[6] = { 0 };
@ -475,7 +580,7 @@ int16_t LR11x0::readData(uint8_t* data, size_t len) {
RADIOLIB_ASSERT(state);
// 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
RADIOLIB_ASSERT(crcState);
@ -521,7 +626,7 @@ int16_t LR11x0::startChannelScan(const ChannelScanConfig_t &config) {
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
RADIOLIB_ASSERT(state);
// set mode to CAD
@ -562,22 +667,22 @@ int16_t LR11x0::setBandwidth(float bw, bool high) {
// ensure byte conversion doesn't overflow
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;
} else if(fabsf(bw - 406.25f) <= 0.001f) {
} else if(fabsf(bw - 406.25) <= 0.001) {
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;
} else {
return(RADIOLIB_ERR_INVALID_BANDWIDTH);
}
} 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
uint8_t bw_div2 = bw / 2 + 0.01f;
uint8_t bw_div2 = bw / 2 + 0.01;
switch (bw_div2) {
case 31: // 62.5:
this->bandwidth = RADIOLIB_LR11X0_LORA_BW_62_5;
@ -668,7 +773,7 @@ int16_t LR11x0::setSyncWord(uint8_t syncWord) {
}
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
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
@ -680,7 +785,7 @@ int16_t LR11x0::setBitRate(float br) {
// set bit rate value
// 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));
}
@ -695,12 +800,12 @@ int16_t LR11x0::setFrequencyDeviation(float freqDev) {
// set frequency deviation to lowest available setting (required for digimodes)
float newFreqDev = freqDev;
if(freqDev < 0.0f) {
newFreqDev = 0.6f;
if(freqDev < 0.0) {
newFreqDev = 0.6;
}
RADIOLIB_CHECK_RANGE(newFreqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
this->frequencyDev = newFreqDev * 1000.0f;
RADIOLIB_CHECK_RANGE(newFreqDev, 0.6, 200.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
this->frequencyDev = newFreqDev * 1000.0;
return(setModulationParamsGFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
}
@ -719,47 +824,47 @@ int16_t LR11x0::setRxBandwidth(float rxBw) {
}*/
// 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} 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;
} else {
return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
@ -999,13 +1104,13 @@ int16_t LR11x0::checkDataRate(DataRate_t dr) {
RADIOLIB_ASSERT(state);
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.freqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6, 200.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
return(RADIOLIB_ERR_NONE);
} 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.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);
return(RADIOLIB_ERR_NONE);
@ -1053,28 +1158,28 @@ int16_t LR11x0::setTCXO(float voltage, uint32_t delay) {
}
// check 0 V disable
if(fabsf(voltage - 0.0f) <= 0.001f) {
if(fabsf(voltage - 0.0) <= 0.001) {
setTcxoMode(0, 0);
return(reset());
}
// check allowed voltage values
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;
} else if(fabsf(voltage - 1.7f) <= 0.001f) {
} else if(fabsf(voltage - 1.7) <= 0.001) {
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;
} else if(fabsf(voltage - 2.2f) <= 0.001f) {
} else if(fabsf(voltage - 2.2) <= 0.001) {
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;
} else if(fabsf(voltage - 2.7f) <= 0.001f) {
} else if(fabsf(voltage - 2.7) <= 0.001) {
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;
} else if(fabsf(voltage - 3.3f) <= 0.001f) {
} else if(fabsf(voltage - 3.3) <= 0.001) {
tune = RADIOLIB_LR11X0_TCXO_VOLTAGE_3_3;
} else {
return(RADIOLIB_ERR_INVALID_TCXO_VOLTAGE);
@ -1248,7 +1353,7 @@ RadioLibTime_t LR11x0::getTimeOnAir(size_t len) {
uint32_t N_symbolPreamble = (this->preambleLengthLoRa & 0x0F) * (uint32_t(1) << ((this->preambleLengthLoRa & 0xF0) >> 4));
// 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 {
// long interleaving - abandon hope all ye who enter here
@ -1257,7 +1362,7 @@ RadioLibTime_t LR11x0::getTimeOnAir(size_t len) {
}
// 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) {
return(((uint32_t)len * 8 * 1000000UL) / this->bitRate);
@ -1314,7 +1419,7 @@ int16_t LR11x0::setIrqFlags(uint32_t irq) {
}
int16_t LR11x0::clearIrqFlags(uint32_t irq) {
return(this->clearIrqState(irq));
return(this->clearIrq(irq));
}
uint8_t LR11x0::randomByte() {
@ -1489,7 +1594,7 @@ void LR11x0::clearWiFiScanAction() {
int16_t LR11x0::getWifiScanResultsCount(uint8_t* count) {
// 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);
uint8_t buff[1] = { 0 };
@ -1660,7 +1765,7 @@ int16_t LR11x0::updateFirmware(const uint32_t* image, size_t size, bool nonvolat
uint32_t offset = i * 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);
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
@ -1706,7 +1811,7 @@ int16_t LR11x0::isGnssScanCapable() {
size_t len = sz > 32 ? 32 : sz/sizeof(uint32_t);
state = this->readRegMem32(addr, buff, len);
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);
sz -= len*sizeof(uint32_t);
}
@ -1765,7 +1870,7 @@ int16_t LR11x0::gnssScan(LR11x0GnssResult_t* res) {
// distinguish between GNSS-done and GNSS-abort outcomes and clear the flags
uint32_t irq = this->getIrqStatus();
this->clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
this->clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
if(irq & RADIOLIB_LR11X0_IRQ_GNSS_ABORT) {
return(RADIOLIB_ERR_RX_TIMEOUT);
}
@ -1877,7 +1982,7 @@ int16_t LR11x0::updateGnssAlmanac(uint8_t constellation) {
// distinguish between GNSS-done and GNSS-abort outcomes and clear the flags
uint32_t irq = this->getIrqStatus();
this->clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
this->clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
if(irq & RADIOLIB_LR11X0_IRQ_GNSS_ABORT) {
state = RADIOLIB_ERR_RX_TIMEOUT;
}
@ -1928,11 +2033,11 @@ int16_t LR11x0::getGnssSatellites(LR11x0GnssSatellite_t* sats, uint8_t numSats)
int16_t LR11x0::getModem(ModemType_t* modem) {
RADIOLIB_ASSERT_PTR(modem);
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
int16_t state = getPacketType(&type);
uint8_t packetType = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
int16_t state = getPacketType(&packetType);
RADIOLIB_ASSERT(state);
switch(type) {
switch(packetType) {
case(RADIOLIB_LR11X0_PACKET_TYPE_LORA):
*modem = ModemType_t::RADIOLIB_MODEM_LORA;
return(RADIOLIB_ERR_NONE);
@ -1947,124 +2052,6 @@ int16_t LR11x0::getModem(ModemType_t* 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) {
this->mod->init();
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
@ -2095,7 +2082,7 @@ int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
RADIOLIB_ASSERT(state);
// set TCXO control, if requested
if(!this->XTAL && tcxoVoltage > 0.0f) {
if(!this->XTAL && tcxoVoltage > 0.0) {
state = setTCXO(tcxoVoltage);
RADIOLIB_ASSERT(state);
}
@ -2127,7 +2114,7 @@ int16_t LR11x0::SPIcheckStatus(Module* mod) {
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;
if(!write) {
// the SPI interface of LR11x0 requires two separate transactions for reading
@ -2188,7 +2175,7 @@ int16_t LR11x0::config(uint8_t modem) {
RADIOLIB_ASSERT(state);
// clear IRQ
state = this->clearIrqState(RADIOLIB_LR11X0_IRQ_ALL);
state = this->clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
state |= this->setDioIrqParams(RADIOLIB_LR11X0_IRQ_NONE);
RADIOLIB_ASSERT(state);
@ -2302,7 +2289,7 @@ Module* LR11x0::getMod() {
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
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
@ -2347,12 +2334,12 @@ int16_t LR11x0::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
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
if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
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) {
@ -2470,7 +2457,7 @@ int16_t LR11x0::setDioIrqParams(uint32_t irq) {
return(setDioIrqParams(irq, this->gnss ? 0 : irq));
}
int16_t LR11x0::clearIrqState(uint32_t irq) {
int16_t LR11x0::clearIrq(uint32_t irq) {
uint8_t buff[4] = {
(uint8_t)((irq >> 24) & 0xFF), (uint8_t)((irq >> 16) & 0xFF), (uint8_t)((irq >> 8) & 0xFF), (uint8_t)(irq & 0xFF),
};
@ -2772,7 +2759,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
if(this->ldroAuto) {
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;
} else {
this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_DISABLED;
@ -2971,7 +2958,7 @@ int16_t LR11x0::setLoRaSyncWord(uint8_t sync) {
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
const uint8_t maxLen[4][4] = {
{ 189, 178, 167, 155, },
@ -3018,7 +3005,7 @@ int16_t LR11x0::lrFhssSetSyncWord(uint32_t sync) {
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));
}
@ -3032,11 +3019,11 @@ int16_t LR11x0::getLoRaRxHeaderInfos(uint8_t* info) {
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));
}
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
// TODO what is the actual maximum?
if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
@ -3254,8 +3241,8 @@ int16_t LR11x0::gnssAssisted(uint32_t gpsTime, uint8_t effort, uint8_t resMask,
}
int16_t LR11x0::gnssSetAssistancePosition(float lat, float lon) {
int16_t latRaw = (lat*2048.0f)/90.0f + 0.5f;
int16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
uint16_t latRaw = (lat*2048.0f)/90.0f + 0.5f;
uint16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
uint8_t buff[4] = {
(uint8_t)((latRaw >> 8) & 0xFF), (uint8_t)(latRaw & 0xFF),
(uint8_t)((lonRaw >> 8) & 0xFF), (uint8_t)(lonRaw & 0xFF),
@ -3269,11 +3256,11 @@ int16_t LR11x0::gnssReadAssistancePosition(float* lat, float* lon) {
// pass the replies
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;
}
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;
}
@ -3379,7 +3366,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)));
}
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 };
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)));
@ -3403,8 +3390,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 latRaw = (lat*2048.0f)/90.0f + 0.5f;
int16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
uint16_t latRaw = (lat*2048.0f)/90.0f + 0.5f;
uint16_t lonRaw = (lon*2048.0f)/180.0f + 0.5f;
uint8_t reqBuff[9] = {
(uint8_t)((time >> 24) & 0xFF), (uint8_t)((time >> 16) & 0xFF),
(uint8_t)((time >> 8) & 0xFF), (uint8_t)(time & 0xFF),
@ -3541,21 +3528,21 @@ int16_t LR11x0::gnssReadDopplerSolverRes(uint8_t* error, uint8_t* nbSvUsed, floa
if(error) { *error = buff[0]; }
if(nbSvUsed) { *nbSvUsed = buff[1]; }
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;
}
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;
}
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(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;
}
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;
}
if(accuracyFilt) { *accuracyFilt = ((uint16_t)(buff[14]) << 8) | (uint16_t)buff[15]; }
@ -3653,7 +3640,7 @@ void LR11x0::gnssAbort() {
// send the abort signal (single NOP)
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
const uint8_t cmd[2] = { 0, 0 };
uint8_t cmd[2] = { 0, 0 };
this->mod->SPIwriteStream(cmd, 2, NULL, 0, false, false);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
@ -3661,7 +3648,7 @@ void LR11x0::gnssAbort() {
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);
uint8_t buff[1 + RADIOLIB_AES128_KEY_SIZE] = { 0 };
buff[0] = keyId;
@ -3669,7 +3656,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)));
}
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);
uint8_t buff[2 + RADIOLIB_AES128_KEY_SIZE] = { 0 };
buff[0] = srcKeyId;
@ -3678,7 +3665,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)));
}
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
size_t headerLen = 1;
if(lwVer) {
@ -3731,7 +3718,7 @@ int16_t LR11x0::cryptoProcessJoinAccept(uint8_t decKeyId, uint8_t verKeyId, uint
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;
#if RADIOLIB_STATIC_ONLY
uint8_t reqBuff[sizeof(uint8_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
@ -3758,7 +3745,7 @@ int16_t LR11x0::cryptoComputeAesCmac(uint8_t keyId, const uint8_t* data, size_t
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;
#if RADIOLIB_STATIC_ONLY
uint8_t reqBuff[sizeof(uint8_t) + sizeof(uint32_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
@ -3789,15 +3776,15 @@ int16_t LR11x0::cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, const uint8_
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));
}
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));
}
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));
}
@ -3827,7 +3814,7 @@ int16_t LR11x0::cryptoGetParam(uint8_t id, uint32_t* value) {
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
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
@ -3854,7 +3841,7 @@ int16_t LR11x0::bootEraseFlash(void) {
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
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
@ -3902,8 +3889,7 @@ int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* d
for(size_t i = 0; i < len; i++) {
uint32_t bin = 0;
if(nonvolatile) {
uint32_t* ptr = const_cast<uint32_t*>(data) + i;
bin = RADIOLIB_NONVOLATILE_READ_DWORD(ptr);
bin = RADIOLIB_NONVOLATILE_READ_DWORD(data + i);
} else {
bin = data[i];
}
@ -3920,7 +3906,7 @@ int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* d
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
#if RADIOLIB_STATIC_ONLY
uint8_t reqBuff[RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];

View file

@ -233,7 +233,7 @@
#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_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
#define RADIOLIB_LR11X0_REG_MODE_LDO (0x00UL << 0) // 0 0 regulator mode: LDO in all modes
@ -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_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_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_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
@ -877,7 +877,6 @@ class LR11x0: public PhysicalLayer {
using PhysicalLayer::transmit;
using PhysicalLayer::receive;
using PhysicalLayer::startTransmit;
using PhysicalLayer::startReceive;
using PhysicalLayer::readData;
/*!
@ -1074,6 +1073,16 @@ class LR11x0: public PhysicalLayer {
*/
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.
\returns \ref status_codes
@ -1088,6 +1097,20 @@ class LR11x0: public PhysicalLayer {
*/
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.
\returns IRQ status bits
@ -1599,21 +1622,15 @@ class LR11x0: public PhysicalLayer {
*/
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
protected:
#endif
Module* getMod() override;
// 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 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 clearRxBuffer(void);
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 setDioIrqParams(uint32_t irq1, uint32_t irq2);
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 setTcxoMode(uint8_t tune, uint32_t delay);
int16_t reboot(bool stay);
@ -1685,11 +1702,11 @@ class LR11x0: public PhysicalLayer {
int16_t setRangingParameter(uint8_t symbolNum);
int16_t setRssiCalibration(const int8_t* tune, int16_t gainOffset);
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 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 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 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 gnssReadResults(uint8_t* result, uint16_t size);
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 gnssAlmanacReadSV(uint8_t svId, uint8_t* almanac);
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);
void gnssAbort();
int16_t cryptoSetKey(uint8_t keyId, const uint8_t* key);
int16_t cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, const 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 cryptoComputeAesCmac(uint8_t keyId, const 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 cryptoAesEncrypt01(uint8_t keyId, const 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 cryptoAesDecrypt(uint8_t keyId, const uint8_t* dataIn, size_t len, uint8_t* dataOut);
int16_t cryptoSetKey(uint8_t keyId, 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, uint8_t* header, uint8_t* dataIn, size_t len, uint8_t* dataOut);
int16_t cryptoComputeAesCmac(uint8_t keyId, uint8_t* data, size_t len, uint32_t* mic);
int16_t cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, uint8_t* data, size_t len, bool* result);
int16_t cryptoAesEncrypt01(uint8_t keyId, 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, uint8_t* dataIn, size_t len, uint8_t* dataOut);
int16_t cryptoStoreToFlash(void);
int16_t cryptoRestoreFromFlash(void);
int16_t cryptoSetParam(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 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 bootGetPin(uint8_t* pin);
int16_t bootGetChipEui(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
protected:
@ -1812,7 +1829,6 @@ class LR11x0: public PhysicalLayer {
uint8_t wifiScanMode = 0;
bool gnss = false;
uint32_t rxTimeout = 0;
int16_t modSetup(float tcxoVoltage, uint8_t modem);
static int16_t SPIparseStatus(uint8_t in);
@ -1824,9 +1840,9 @@ class LR11x0: public PhysicalLayer {
int16_t setHeaderType(uint8_t hdrType, size_t len = 0xFF);
// 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 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

View file

@ -2,9 +2,7 @@
#include <math.h>
#if !RADIOLIB_EXCLUDE_RF69
RF69::RF69(Module* module) : PhysicalLayer() {
this->freqStep = RADIOLIB_RF69_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_RF69_MAX_PACKET_LENGTH;
RF69::RF69(Module* module) : PhysicalLayer(RADIOLIB_RF69_FREQUENCY_STEP_SIZE, RADIOLIB_RF69_MAX_PACKET_LENGTH) {
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) {
// 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
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));
}
void RF69::setAESKey(const uint8_t* key) {
void RF69::setAESKey(uint8_t* key) {
this->mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_AES_KEY_1, key, 16);
}
@ -366,7 +364,7 @@ bool RF69::fifoAdd(uint8_t* data, int totalLen, int* remLen) {
bool RF69::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) {
// 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
uint8_t len = RADIOLIB_RF69_FIFO_THRESH - 1;
@ -525,9 +523,9 @@ int16_t RF69::setOokPeakThresholdDecrement(uint8_t value) {
int16_t RF69::setFrequency(float freq) {
// check allowed frequency range
if(!(((freq > 290.0f) && (freq < 340.0f)) ||
((freq > 431.0f) && (freq < 510.0f)) ||
((freq > 862.0f) && (freq < 1020.0f)))) {
if(!(((freq > 290.0) && (freq < 340.0)) ||
((freq > 431.0) && (freq < 510.0)) ||
((freq > 862.0) && (freq < 1020.0)))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY);
}
@ -561,7 +559,7 @@ int16_t RF69::getFrequency(float *freq) {
int16_t RF69::setBitRate(float br) {
// 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
if(!(br < 2000 * this->rxBandwidth)) {
@ -594,8 +592,8 @@ int16_t RF69::setRxBandwidth(float rxBw) {
// calculate exponent and mantissa values for receiver bandwidth
for(int8_t e = 7; e >= 0; e--) {
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))));
if(fabsf(rxBw - (point / 1000.0f)) <= 0.1f) {
float point = (RADIOLIB_RF69_CRYSTAL_FREQ * 1000000.0)/(((4 * m) + 16) * ((uint32_t)1 << (e + (this->ookEnabled ? 3 : 2))));
if(fabsf(rxBw - (point / 1000.0)) <= 0.1) {
// set Rx bandwidth
state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_BW, (m << 3) | e, 4, 0);
if(state == RADIOLIB_ERR_NONE) {
@ -612,8 +610,8 @@ int16_t RF69::setRxBandwidth(float rxBw) {
int16_t RF69::setFrequencyDeviation(float freqDev) {
// set frequency deviation to lowest available setting (required for digimodes)
float newFreqDev = freqDev;
if(freqDev < 0.0f) {
newFreqDev = 0.6f;
if(freqDev < 0.0) {
newFreqDev = 0.6;
}
// check frequency deviation range
@ -650,7 +648,7 @@ int16_t RF69::getFrequencyDeviation(float *freqDev) {
// calculate frequency deviation from raw value obtained from register
// 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);
return(RADIOLIB_ERR_NONE);
@ -694,9 +692,9 @@ int16_t RF69::setOutputPower(int8_t pwr, bool highPower) {
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
if((maxErrBits > 7) || (len == 0) || (len > 8)) {
if((maxErrBits > 7) || (len > 8)) {
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
}
@ -707,15 +705,16 @@ int16_t RF69::setSyncWord(const uint8_t* syncWord, size_t len, uint8_t maxErrBit
}
}
// enable filtering
int16_t state = enableSyncWordFiltering(maxErrBits);
RADIOLIB_ASSERT(state);
// set the length
state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, (len-1)<<3, 5, 3);
// set sync word register
this->mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_SYNC_VALUE_1, syncWord, len);
if(state == RADIOLIB_ERR_NONE) {
this->syncWordLength = len;
}
return(state);
}
@ -806,11 +805,7 @@ int16_t RF69::variablePacketLengthMode(uint8_t maxLen) {
int16_t RF69::enableSyncWordFiltering(uint8_t maxErrBits) {
// 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);
RADIOLIB_ASSERT(state);
// set maximum error bits
return(this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, maxErrBits, 2, 0));
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));
}
int16_t RF69::disableSyncWordFiltering() {
@ -933,9 +928,9 @@ float RF69::getRSSI() {
}
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) {

View file

@ -12,7 +12,7 @@
// RF69 physical layer properties
#define RADIOLIB_RF69_FREQUENCY_STEP_SIZE 61.03515625
#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
// RF69 register map
@ -577,7 +577,7 @@ class RF69: public PhysicalLayer {
\brief Sets AES key.
\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.
@ -789,7 +789,7 @@ class RF69: public PhysicalLayer {
\param len Sync word length in bytes.
\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.
@ -1031,6 +1031,8 @@ class RF69: public PhysicalLayer {
bool promiscuous = false;
uint8_t syncWordLength = RADIOLIB_RF69_DEFAULT_SW_LEN;
bool bitSync = true;
int16_t directMode();

View file

@ -17,10 +17,7 @@ int16_t SX1231::begin(float freq, float br, float freqDev, float rxBw, int8_t po
bool flagFound = false;
while((i < 10) && !flagFound) {
int16_t version = getChipVersion();
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_D)) {
if((version == RADIOLIB_SX123X_CHIP_REVISION_2_A) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_B) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_C)) {
flagFound = true;
this->chipRevision = version;
} else {

View file

@ -11,7 +11,6 @@
#define RADIOLIB_SX123X_CHIP_REVISION_2_A 0x21
#define RADIOLIB_SX123X_CHIP_REVISION_2_B 0x22
#define RADIOLIB_SX123X_CHIP_REVISION_2_C 0x23
#define RADIOLIB_SX123X_CHIP_REVISION_2_D 0x24
// RADIOLIB_SX1231 specific register map
#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.
\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
protected:

View file

@ -18,10 +18,7 @@ int16_t SX1233::begin(float freq, float br, float freqDev, float rxBw, int8_t po
bool flagFound = false;
while((i < 10) && !flagFound) {
int16_t version = getChipVersion();
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_D)) {
if((version == RADIOLIB_SX123X_CHIP_REVISION_2_A) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_B) || (version == RADIOLIB_SX123X_CHIP_REVISION_2_C)) {
flagFound = true;
this->chipRevision = version;
} 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) {
// check high bit-rate operation
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;
} else {
// 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);
}

View file

@ -38,7 +38,7 @@ class SX1233: public SX1231 {
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
\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.

View file

@ -45,7 +45,7 @@ int16_t STM32WLx::setOutputPower(int8_t power) {
RADIOLIB_ASSERT(state);
// 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 lp_supported = mod->findRfSwitchMode(MODE_TX_LP);
if((!lp_supported && (power < -9)) || (!hp_supported && (power > 14))) {

View file

@ -66,12 +66,12 @@ class STM32WLx : public SX1262 {
/*!
\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
*/
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
@ -113,12 +113,12 @@ class STM32WLx : public SX1262 {
\brief Sets interrupt service routine to call when DIO1/2/3 activates.
\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.
*/
void clearDio1Action() override;
void clearDio1Action();
/*!
\brief Sets interrupt service routine to call when a packet is received.

View file

@ -72,7 +72,7 @@ int16_t SX1262::setFrequency(float freq) {
}
int16_t SX1262::setFrequency(float freq, bool skipCalibration) {
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
if(!skipCalibration && (fabsf(freq - this->freqMHz) >= RADIOLIB_SX126X_CAL_IMG_FREQ_TRIG_MHZ)) {

View file

@ -44,7 +44,7 @@ class SX1262: public SX126x {
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
\returns \ref status_codes
*/
virtual 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);
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);
/*!
\brief Initialization method for FSK modem.
@ -60,7 +60,7 @@ class SX1262: public SX126x {
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
\returns \ref status_codes
*/
virtual 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);
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);
/*!
\brief Initialization method for LR-FHSS modem. This modem only supports transmission!
@ -75,7 +75,7 @@ class SX1262: public SX126x {
\param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false.
\returns \ref status_codes
*/
virtual 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 = 1.6, bool useRegulatorLDO = false);
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 = 1.6, bool useRegulatorLDO = false);
// configuration methods

View file

@ -73,7 +73,7 @@ int16_t SX1268::setFrequency(float freq) {
/// \todo integers only (all modules - frequency, data rate, bandwidth etc.)
int16_t SX1268::setFrequency(float freq, bool skipCalibration) {
RADIOLIB_CHECK_RANGE(freq, 410.0f, 810.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 410.0, 810.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// check if we need to recalibrate image
if(!skipCalibration && (fabsf(freq - this->freqMHz) >= RADIOLIB_SX126X_CAL_IMG_FREQ_TRIG_MHZ)) {

View file

@ -3,9 +3,7 @@
#include <math.h>
#if !RADIOLIB_EXCLUDE_SX126X
SX126x::SX126x(Module* mod) : PhysicalLayer() {
this->freqStep = RADIOLIB_SX126X_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_SX126X_MAX_PACKET_LENGTH;
SX126x::SX126x(Module* mod) : PhysicalLayer(RADIOLIB_SX126X_FREQUENCY_STEP_SIZE, RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
this->mod = mod;
this->XTAL = false;
this->standbyXOSC = false;
@ -237,14 +235,15 @@ int16_t SX126x::transmit(const uint8_t* data, size_t len, uint8_t addr) {
break;
} else {
// handle frequency hop
this->hopLRFHSS();
this->setLRFHSSHop(this->lrFhssHopNum % 16);
clearIrqStatus();
}
}
}
// update data rate
RadioLibTime_t elapsed = this->mod->hal->millis() - start;
this->dataRateMeasured = (len*8.0f)/((float)elapsed/1000.0f);
this->dataRateMeasured = (len*8.0)/((float)elapsed/1000.0);
return(finishTransmit());
}
@ -261,7 +260,7 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
// calculate timeout (100 LoRa symbols, the default for SX127x series)
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
timeout = (RadioLibTime_t)(symbolLength * 100.0f);
timeout = (RadioLibTime_t)(symbolLength * 100.0);
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
// calculate timeout (500 % of expected time-one-air)
@ -269,8 +268,8 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
if(len == 0) {
maxLen = 0xFF;
}
float brBps = (RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0f * 32.0f) / (float)this->bitRate;
timeout = (RadioLibTime_t)(((maxLen * 8.0f) / brBps) * 1000.0f * 5.0f);
float brBps = ((float)(RADIOLIB_SX126X_CRYSTAL_FREQ) * 1000000.0 * 32.0) / (float)this->bitRate;
timeout = (RadioLibTime_t)(((maxLen * 8.0) / brBps) * 1000.0 * 5.0);
} else {
return(RADIOLIB_ERR_UNKNOWN);
@ -280,7 +279,7 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout);
// start reception
uint32_t timeoutValue = (uint32_t)(((float)timeout * 1000.0f) / 15.625f);
uint32_t timeoutValue = (uint32_t)(((float)timeout * 1000.0) / 15.625);
state = startReceive(timeoutValue);
RADIOLIB_ASSERT(state);
@ -332,7 +331,7 @@ int16_t SX126x::transmitDirect(uint32_t frf) {
RADIOLIB_ASSERT(state);
// direct mode activation intentionally skipped here, as it seems to lead to much worse results
const uint8_t data[] = { RADIOLIB_SX126X_CMD_NOP };
uint8_t data[] = { RADIOLIB_SX126X_CMD_NOP };
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_TX_CONTINUOUS_WAVE, data, 1));
}
@ -474,20 +473,10 @@ int16_t SX126x::standby(uint8_t mode, bool wakeup) {
(void)this->mod->SPIwriteStream((uint16_t)RADIOLIB_SX126X_CMD_NOP, NULL, 0, false, false);
}
const uint8_t data[] = { mode };
uint8_t data[] = { mode };
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_STANDBY, data, 1));
}
int16_t SX126x::hopLRFHSS() {
if(!(this->getIrqFlags() & RADIOLIB_SX126X_IRQ_LR_FHSS_HOP)) {
return(RADIOLIB_ERR_TX_TIMEOUT);
}
int16_t state = this->setLRFHSSHop(this->lrFhssHopNum % 16);
RADIOLIB_ASSERT(state);
return(clearIrqStatus());
}
void SX126x::setDio1Action(void (*func)(void)) {
this->mod->hal->attachInterrupt(this->mod->hal->pinToInterrupt(this->mod->getIrq()), func, this->mod->hal->GpioInterruptRising);
}
@ -520,6 +509,115 @@ void SX126x::clearChannelScanAction() {
this->clearDio1Action();
}
int16_t SX126x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
(void)addr;
// check packet length
if(len > RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// maximum packet length is decreased by 1 when address filtering is active
if((RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF != RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF) && (len > RADIOLIB_SX126X_MAX_PACKET_LENGTH - 1)) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// set packet Length
int16_t state = RADIOLIB_ERR_NONE;
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
state = setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, len, this->headerType, this->invertIQEnabled);
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType, len);
} else if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
return(RADIOLIB_ERR_UNKNOWN);
}
RADIOLIB_ASSERT(state);
// set DIO mapping
if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
state = setDioIrqParams(RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT, RADIOLIB_SX126X_IRQ_TX_DONE);
} else {
state = setDioIrqParams(RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_LR_FHSS_HOP, RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_LR_FHSS_HOP);
}
RADIOLIB_ASSERT(state);
// set buffer pointers
state = setBufferBaseAddress();
RADIOLIB_ASSERT(state);
// write packet to buffer
if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
state = writeBuffer(const_cast<uint8_t*>(data), len);
} else {
// first, reset the LR-FHSS state machine
state = resetLRFHSS();
RADIOLIB_ASSERT(state);
// skip hopping for the first 4 - lrFhssHdrCount blocks
for(int i = 0; i < 4 - this->lrFhssHdrCount; ++i ) {
stepLRFHSS();
}
// in LR-FHSS mode, we need to build the entire packet manually
uint8_t frame[RADIOLIB_SX126X_MAX_PACKET_LENGTH] = { 0 };
size_t frameLen = 0;
this->lrFhssFrameBitsRem = 0;
this->lrFhssFrameHopsRem = 0;
this->lrFhssHopNum = 0;
state = buildLRFHSSPacket(const_cast<uint8_t*>(data), len, frame, &frameLen, &this->lrFhssFrameBitsRem, &this->lrFhssFrameHopsRem);
RADIOLIB_ASSERT(state);
// FIXME check max len for FHSS
state = writeBuffer(frame, frameLen);
RADIOLIB_ASSERT(state);
// activate hopping
uint8_t hopCfg[] = { RADIOLIB_SX126X_HOPPING_ENABLED, (uint8_t)frameLen, (uint8_t)this->lrFhssFrameHopsRem };
state = writeRegister(RADIOLIB_SX126X_REG_HOPPING_ENABLE, hopCfg, 3);
RADIOLIB_ASSERT(state);
// write the initial hopping table
uint8_t initHops = this->lrFhssFrameHopsRem;
if(initHops > 16) {
initHops = 16;
};
for(size_t i = 0; i < initHops; i++) {
// set the hop frequency and symbols
state = this->setLRFHSSHop(i);
RADIOLIB_ASSERT(state);
}
}
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// fix sensitivity
state = fixSensitivity();
RADIOLIB_ASSERT(state);
// set RF switch (if present)
this->mod->setRfSwitchState(this->txMode);
// start transmission
state = setTx(RADIOLIB_SX126X_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 SX126x::finishTransmit() {
// clear interrupt flags
int16_t state = clearIrqStatus();
@ -533,6 +631,25 @@ int16_t SX126x::startReceive() {
return(this->startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0));
}
int16_t SX126x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) {
// in implicit header mode, use the provided length if it is nonzero
// otherwise we trust the user has previously set the payload length manually
if((this->headerType == RADIOLIB_SX126X_LORA_HEADER_IMPLICIT) && (len != 0)) {
this->implicitLen = len;
}
int16_t state = startReceiveCommon(timeout, irqFlags, irqMask);
RADIOLIB_ASSERT(state);
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_RX);
// set mode to receive
state = setRx(timeout);
return(state);
}
int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask) {
// datasheet claims time to go to sleep is ~500us, same to wake up, compensate for that with 1 ms + TCXO delay
uint32_t transitionTime = this->tcxoDelay + 1000;
@ -555,7 +672,7 @@ int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, R
int16_t state = startReceiveCommon(RADIOLIB_SX126X_RX_TIMEOUT_INF, irqFlags, irqMask);
RADIOLIB_ASSERT(state);
const uint8_t data[6] = {(uint8_t)((rxPeriodRaw >> 16) & 0xFF), (uint8_t)((rxPeriodRaw >> 8) & 0xFF), (uint8_t)(rxPeriodRaw & 0xFF),
uint8_t data[6] = {(uint8_t)((rxPeriodRaw >> 16) & 0xFF), (uint8_t)((rxPeriodRaw >> 8) & 0xFF), (uint8_t)(rxPeriodRaw & 0xFF),
(uint8_t)((sleepPeriodRaw >> 16) & 0xFF), (uint8_t)((sleepPeriodRaw >> 8) & 0xFF), (uint8_t)(sleepPeriodRaw & 0xFF)};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_RX_DUTY_CYCLE, data, 6));
}
@ -737,10 +854,10 @@ int16_t SX126x::setBandwidth(float bw) {
}
// ensure byte conversion doesn't overflow
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
uint8_t bw_div2 = bw / 2 + 0.01f;
uint8_t bw_div2 = bw / 2 + 0.01;
switch (bw_div2) {
case 3: // 7.8:
this->bandwidth = RADIOLIB_SX126X_LORA_BW_7_8;
@ -814,7 +931,7 @@ int16_t SX126x::setSyncWord(uint8_t syncWord, uint8_t controlBits) {
}
// update register
const uint8_t data[2] = {(uint8_t)((syncWord & 0xF0) | ((controlBits & 0xF0) >> 4)), (uint8_t)(((syncWord & 0x0F) << 4) | (controlBits & 0x0F))};
uint8_t data[2] = {(uint8_t)((syncWord & 0xF0) | ((controlBits & 0xF0) >> 4)), (uint8_t)(((syncWord & 0x0F) << 4) | (controlBits & 0x0F))};
return(writeRegister(RADIOLIB_SX126X_REG_LORA_SYNC_WORD_MSB, data, 2));
}
@ -825,7 +942,7 @@ int16_t SX126x::setCurrentLimit(float currentLimit) {
}
// calculate raw value
uint8_t rawLimit = (uint8_t)(currentLimit / 2.5f);
uint8_t rawLimit = (uint8_t)(currentLimit / 2.5);
// update register
return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &rawLimit, 1));
@ -837,7 +954,7 @@ float SX126x::getCurrentLimit() {
readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
// return the actual value
return((float)ocp * 2.5f);
return((float)ocp * 2.5);
}
int16_t SX126x::setPreambleLength(size_t preambleLength) {
@ -869,14 +986,14 @@ int16_t SX126x::setFrequencyDeviation(float freqDev) {
// set frequency deviation to lowest available setting (required for digimodes)
float newFreqDev = freqDev;
if(freqDev < 0.0f) {
newFreqDev = 0.6f;
if(freqDev < 0.0) {
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);
// calculate raw frequency deviation value
uint32_t freqDevRaw = (uint32_t)(((newFreqDev * 1000.0f) * (float)((uint32_t)(1) << 25)) / (RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0f));
uint32_t freqDevRaw = (uint32_t)(((newFreqDev * 1000.0) * (float)((uint32_t)(1) << 25)) / (RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0));
// check modulation parameters
this->frequencyDev = freqDevRaw;
@ -893,11 +1010,11 @@ int16_t SX126x::setBitRate(float br) {
}
if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
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);
}
// calculate raw bit rate value
uint32_t brRaw = (uint32_t)((RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0f * 32.0f) / (br * 1000.0f));
uint32_t brRaw = (uint32_t)((RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0 * 32.0) / (br * 1000.0));
// check modulation parameters
this->bitRate = brRaw;
@ -950,13 +1067,13 @@ int16_t SX126x::checkDataRate(DataRate_t dr) {
// select interpretation based on active modem
uint8_t modem = this->getPacketType();
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.freqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6, 200.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
return(RADIOLIB_ERR_NONE);
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
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);
return(RADIOLIB_ERR_NONE);
@ -978,47 +1095,47 @@ int16_t SX126x::setRxBandwidth(float rxBw) {
this->rxBandwidthKhz = rxBw;
// check allowed receiver bandwidth values
if(fabsf(rxBw - 4.8f) <= 0.001f) {
if(fabsf(rxBw - 4.8) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_4_8;
} else if(fabsf(rxBw - 5.8f) <= 0.001f) {
} else if(fabsf(rxBw - 5.8) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_5_8;
} else if(fabsf(rxBw - 7.3f) <= 0.001f) {
} else if(fabsf(rxBw - 7.3) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_7_3;
} else if(fabsf(rxBw - 9.7f) <= 0.001f) {
} else if(fabsf(rxBw - 9.7) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_9_7;
} else if(fabsf(rxBw - 11.7f) <= 0.001f) {
} else if(fabsf(rxBw - 11.7) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_11_7;
} else if(fabsf(rxBw - 14.6f) <= 0.001f) {
} else if(fabsf(rxBw - 14.6) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_14_6;
} else if(fabsf(rxBw - 19.5f) <= 0.001f) {
} else if(fabsf(rxBw - 19.5) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_19_5;
} else if(fabsf(rxBw - 23.4f) <= 0.001f) {
} else if(fabsf(rxBw - 23.4) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_23_4;
} else if(fabsf(rxBw - 29.3f) <= 0.001f) {
} else if(fabsf(rxBw - 29.3) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_29_3;
} else if(fabsf(rxBw - 39.0f) <= 0.001f) {
} else if(fabsf(rxBw - 39.0) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_39_0;
} else if(fabsf(rxBw - 46.9f) <= 0.001f) {
} else if(fabsf(rxBw - 46.9) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_46_9;
} else if(fabsf(rxBw - 58.6f) <= 0.001f) {
} else if(fabsf(rxBw - 58.6) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_58_6;
} else if(fabsf(rxBw - 78.2f) <= 0.001f) {
} else if(fabsf(rxBw - 78.2) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_78_2;
} else if(fabsf(rxBw - 93.8f) <= 0.001f) {
} else if(fabsf(rxBw - 93.8) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_93_8;
} else if(fabsf(rxBw - 117.3f) <= 0.001f) {
} else if(fabsf(rxBw - 117.3) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_117_3;
} else if(fabsf(rxBw - 156.2f) <= 0.001f) {
} else if(fabsf(rxBw - 156.2) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_156_2;
} else if(fabsf(rxBw - 187.2f) <= 0.001f) {
} else if(fabsf(rxBw - 187.2) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_187_2;
} else if(fabsf(rxBw - 234.3f) <= 0.001f) {
} else if(fabsf(rxBw - 234.3) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_234_3;
} else if(fabsf(rxBw - 312.0f) <= 0.001f) {
} else if(fabsf(rxBw - 312.0) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_312_0;
} else if(fabsf(rxBw - 373.6f) <= 0.001f) {
} else if(fabsf(rxBw - 373.6) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_373_6;
} else if(fabsf(rxBw - 467.0f) <= 0.001f) {
} else if(fabsf(rxBw - 467.0) <= 0.001) {
this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_467_0;
} else {
return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
@ -1037,7 +1154,7 @@ int16_t SX126x::setRxBoostedGainMode(bool rxbgm, bool persist) {
// add Rx Gain register to retention memory if requested
if(persist) {
// values and registers below are specified in SX126x datasheet v2.1 section 9.6, just below table 9-3
const uint8_t data[] = { 0x01, (uint8_t)((RADIOLIB_SX126X_REG_RX_GAIN >> 8) & 0xFF), (uint8_t)(RADIOLIB_SX126X_REG_RX_GAIN & 0xFF) };
uint8_t data[] = { 0x01, (uint8_t)((RADIOLIB_SX126X_REG_RX_GAIN >> 8) & 0xFF), (uint8_t)(RADIOLIB_SX126X_REG_RX_GAIN & 0xFF) };
state = writeRegister(RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_0, data, 3);
}
@ -1256,7 +1373,7 @@ float SX126x::getRSSI(bool packet) {
// get instantaneous RSSI value
uint8_t rssiRaw = 0;
this->mod->SPIreadStream(RADIOLIB_SX126X_CMD_GET_RSSI_INST, &rssiRaw, 1);
return((float)rssiRaw / (-2.0f));
return((float)rssiRaw / (-2.0));
}
}
@ -1301,9 +1418,9 @@ float SX126x::getFrequencyError() {
// frequency error is negative
efe |= (uint32_t) 0xFFF00000;
efe = ~efe + 1;
error = 1.55f * (float) efe / (1600.0f / (float) this->bandwidthKhz) * -1.0f;
error = 1.55 * (float) efe / (1600.0 / (float) this->bandwidthKhz) * -1.0;
} else {
error = 1.55f * (float) efe / (1600.0f / (float) this->bandwidthKhz);
error = 1.55 * (float) efe / (1600.0 / (float) this->bandwidthKhz);
}
return(error);
@ -1411,7 +1528,7 @@ RadioLibTime_t SX126x::getTimeOnAir(size_t len) {
RadioLibTime_t SX126x::calculateRxTimeout(RadioLibTime_t timeoutUs) {
// the timeout value is given in units of 15.625 microseconds
// the calling function should provide some extra width, as this number of units is truncated to integer
RadioLibTime_t timeout = timeoutUs / 15.625f;
RadioLibTime_t timeout = timeoutUs / 15.625;
return(timeout);
}
@ -1524,8 +1641,8 @@ int16_t SX126x::invertIQ(bool enable) {
int16_t SX126x::getModem(ModemType_t* modem) {
RADIOLIB_ASSERT_PTR(modem);
uint8_t type = getPacketType();
switch(type) {
uint8_t packetType = getPacketType();
switch(packetType) {
case(RADIOLIB_SX126X_PACKET_TYPE_LORA):
*modem = ModemType_t::RADIOLIB_MODEM_LORA;
return(RADIOLIB_ERR_NONE);
@ -1540,152 +1657,6 @@ int16_t SX126x::getModem(ModemType_t* modem) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
int16_t SX126x::stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) {
int16_t state;
switch(mode) {
case(RADIOLIB_RADIO_MODE_RX): {
// in implicit header mode, use the provided length if it is nonzero
// otherwise we trust the user has previously set the payload length manually
if((this->headerType == RADIOLIB_SX126X_LORA_HEADER_IMPLICIT) && (cfg->receive.len != 0)) {
this->implicitLen = cfg->receive.len;
}
state = startReceiveCommon(cfg->receive.timeout, cfg->receive.irqFlags, cfg->receive.irqMask);
RADIOLIB_ASSERT(state);
this->rxTimeout = cfg->receive.timeout;
} break;
case(RADIOLIB_RADIO_MODE_TX): {
// check packet length
if(cfg->transmit.len > RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// maximum packet length is decreased by 1 when address filtering is active
if((RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF != RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF) &&
(cfg->transmit.len > RADIOLIB_SX126X_MAX_PACKET_LENGTH - 1)) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// set packet Length
state = RADIOLIB_ERR_NONE;
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
state = setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, cfg->transmit.len, this->headerType, this->invertIQEnabled);
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType, cfg->transmit.len);
} else if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
return(RADIOLIB_ERR_UNKNOWN);
}
RADIOLIB_ASSERT(state);
// set DIO mapping
if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
state = setDioIrqParams(RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT, RADIOLIB_SX126X_IRQ_TX_DONE);
} else {
state = setDioIrqParams(RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_LR_FHSS_HOP, RADIOLIB_SX126X_IRQ_TX_DONE | RADIOLIB_SX126X_IRQ_LR_FHSS_HOP);
}
RADIOLIB_ASSERT(state);
// set buffer pointers
state = setBufferBaseAddress();
RADIOLIB_ASSERT(state);
// write packet to buffer
if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
state = writeBuffer(cfg->transmit.data, cfg->transmit.len);
} else {
// first, reset the LR-FHSS state machine
state = resetLRFHSS();
RADIOLIB_ASSERT(state);
// skip hopping for the first 4 - lrFhssHdrCount blocks
for(int i = 0; i < 4 - this->lrFhssHdrCount; ++i ) {
stepLRFHSS();
}
// in LR-FHSS mode, we need to build the entire packet manually
uint8_t frame[RADIOLIB_SX126X_MAX_PACKET_LENGTH] = { 0 };
size_t frameLen = 0;
this->lrFhssFrameBitsRem = 0;
this->lrFhssFrameHopsRem = 0;
this->lrFhssHopNum = 0;
state = buildLRFHSSPacket(cfg->transmit.data, cfg->transmit.len, frame, &frameLen, &this->lrFhssFrameBitsRem, &this->lrFhssFrameHopsRem);
RADIOLIB_ASSERT(state);
// FIXME check max len for FHSS
state = writeBuffer(frame, frameLen);
RADIOLIB_ASSERT(state);
// activate hopping
const uint8_t hopCfg[] = { RADIOLIB_SX126X_HOPPING_ENABLED, (uint8_t)frameLen, (uint8_t)this->lrFhssFrameHopsRem };
state = writeRegister(RADIOLIB_SX126X_REG_HOPPING_ENABLE, hopCfg, 3);
RADIOLIB_ASSERT(state);
// write the initial hopping table
uint8_t initHops = this->lrFhssFrameHopsRem;
if(initHops > 16) {
initHops = 16;
};
for(size_t i = 0; i < initHops; i++) {
// set the hop frequency and symbols
state = this->setLRFHSSHop(i);
RADIOLIB_ASSERT(state);
}
}
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// fix sensitivity
state = fixSensitivity();
RADIOLIB_ASSERT(state);
} break;
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
this->stagedMode = mode;
return(state);
}
int16_t SX126x::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(this->txMode);
state = setTx(RADIOLIB_SX126X_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);
}
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
void SX126x::setDirectAction(void (*func)(void)) {
setDio1Action(func);
@ -1716,8 +1687,7 @@ int16_t SX126x::uploadPatch(const uint32_t* patch, size_t len, bool nonvolatile)
for(uint32_t i = 0; i < len / sizeof(uint32_t); i++) {
uint32_t bin = 0;
if(nonvolatile) {
uint32_t* ptr = const_cast<uint32_t*>(patch) + i;
bin = RADIOLIB_NONVOLATILE_READ_DWORD(ptr);
bin = RADIOLIB_NONVOLATILE_READ_DWORD(patch + i);
} else {
bin = patch[i];
}
@ -1756,7 +1726,7 @@ int16_t SX126x::spectralScanStart(uint16_t numSamples, uint8_t window, uint8_t i
RADIOLIB_ASSERT(state);
// now set the actual spectral scan parameters
const uint8_t data[3] = { (uint8_t)((numSamples >> 8) & 0xFF), (uint8_t)(numSamples & 0xFF), interval };
uint8_t data[3] = { (uint8_t)((numSamples >> 8) & 0xFF), (uint8_t)(numSamples & 0xFF), interval };
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_SPECTR_SCAN_PARAMS, data, 3));
}
@ -1799,34 +1769,34 @@ int16_t SX126x::setTCXO(float voltage, uint32_t delay) {
}
// check 0 V disable
if(fabsf(voltage - 0.0f) <= 0.001f) {
if(fabsf(voltage - 0.0) <= 0.001) {
return(reset(true));
}
// check alowed voltage values
uint8_t data[4];
if(fabsf(voltage - 1.6f) <= 0.001f) {
if(fabsf(voltage - 1.6) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_1_6;
} else if(fabsf(voltage - 1.7f) <= 0.001f) {
} else if(fabsf(voltage - 1.7) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_1_7;
} else if(fabsf(voltage - 1.8f) <= 0.001f) {
} else if(fabsf(voltage - 1.8) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_1_8;
} else if(fabsf(voltage - 2.2f) <= 0.001f) {
} else if(fabsf(voltage - 2.2) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_2_2;
} else if(fabsf(voltage - 2.4f) <= 0.001f) {
} else if(fabsf(voltage - 2.4) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_2_4;
} else if(fabsf(voltage - 2.7f) <= 0.001f) {
} else if(fabsf(voltage - 2.7) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_2_7;
} else if(fabsf(voltage - 3.0f) <= 0.001f) {
} else if(fabsf(voltage - 3.0) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_3_0;
} else if(fabsf(voltage - 3.3f) <= 0.001f) {
} else if(fabsf(voltage - 3.3) <= 0.001) {
data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_3_3;
} else {
return(RADIOLIB_ERR_INVALID_TCXO_VOLTAGE);
}
// calculate delay
uint32_t delayValue = (float)delay / 15.625f;
uint32_t delayValue = (float)delay / 15.625;
data[1] = (uint8_t)((delayValue >> 16) & 0xFF);
data[2] = (uint8_t)((delayValue >> 8) & 0xFF);
data[3] = (uint8_t)(delayValue & 0xFF);
@ -1852,12 +1822,12 @@ int16_t SX126x::setFs() {
}
int16_t SX126x::setTx(uint32_t timeout) {
const uint8_t data[] = { (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF)} ;
uint8_t data[] = { (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF)} ;
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_TX, data, 3));
}
int16_t SX126x::setRx(uint32_t timeout) {
const uint8_t data[] = { (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF) };
uint8_t data[] = { (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF) };
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_RX, data, 3, true, false));
}
@ -1909,11 +1879,11 @@ int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8
}
int16_t SX126x::setPaConfig(uint8_t paDutyCycle, uint8_t deviceSel, uint8_t hpMax, uint8_t paLut) {
const uint8_t data[] = { paDutyCycle, hpMax, deviceSel, paLut };
uint8_t data[] = { paDutyCycle, hpMax, deviceSel, paLut };
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_PA_CONFIG, data, 4));
}
int16_t SX126x::writeRegister(uint16_t addr, const uint8_t* data, uint8_t numBytes) {
int16_t SX126x::writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
this->mod->SPIwriteRegisterBurst(addr, data, numBytes);
return(RADIOLIB_ERR_NONE);
}
@ -1927,18 +1897,18 @@ int16_t SX126x::readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
return(state);
}
int16_t SX126x::writeBuffer(const uint8_t* data, uint8_t numBytes, uint8_t offset) {
const uint8_t cmd[] = { RADIOLIB_SX126X_CMD_WRITE_BUFFER, offset };
int16_t SX126x::writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset) {
uint8_t cmd[] = { RADIOLIB_SX126X_CMD_WRITE_BUFFER, offset };
return(this->mod->SPIwriteStream(cmd, 2, data, numBytes));
}
int16_t SX126x::readBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset) {
const uint8_t cmd[] = { RADIOLIB_SX126X_CMD_READ_BUFFER, offset };
uint8_t cmd[] = { RADIOLIB_SX126X_CMD_READ_BUFFER, offset };
return(this->mod->SPIreadStream(cmd, 2, data, numBytes));
}
int16_t SX126x::setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask) {
const uint8_t data[8] = {(uint8_t)((irqMask >> 8) & 0xFF), (uint8_t)(irqMask & 0xFF),
uint8_t data[8] = {(uint8_t)((irqMask >> 8) & 0xFF), (uint8_t)(irqMask & 0xFF),
(uint8_t)((dio1Mask >> 8) & 0xFF), (uint8_t)(dio1Mask & 0xFF),
(uint8_t)((dio2Mask >> 8) & 0xFF), (uint8_t)(dio2Mask & 0xFF),
(uint8_t)((dio3Mask >> 8) & 0xFF), (uint8_t)(dio3Mask & 0xFF)};
@ -1946,12 +1916,12 @@ int16_t SX126x::setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t di
}
int16_t SX126x::clearIrqStatus(uint16_t clearIrqParams) {
const uint8_t data[] = { (uint8_t)((clearIrqParams >> 8) & 0xFF), (uint8_t)(clearIrqParams & 0xFF) };
uint8_t data[] = { (uint8_t)((clearIrqParams >> 8) & 0xFF), (uint8_t)(clearIrqParams & 0xFF) };
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CLEAR_IRQ_STATUS, data, 2));
}
int16_t SX126x::setRfFrequency(uint32_t frf) {
const uint8_t data[] = { (uint8_t)((frf >> 24) & 0xFF), (uint8_t)((frf >> 16) & 0xFF), (uint8_t)((frf >> 8) & 0xFF), (uint8_t)(frf & 0xFF) };
uint8_t data[] = { (uint8_t)((frf >> 24) & 0xFF), (uint8_t)((frf >> 16) & 0xFF), (uint8_t)((frf >> 8) & 0xFF), (uint8_t)(frf & 0xFF) };
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_RF_FREQUENCY, data, 4));
}
@ -2004,7 +1974,7 @@ int16_t SX126x::setPaRampTime(uint8_t rampTime) {
return(this->setTxParams(this->pwr, rampTime));
}
int16_t SX126x::calibrateImage(const uint8_t* data) {
int16_t SX126x::calibrateImage(uint8_t* data) {
int16_t state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE_IMAGE, data, 2);
// if something failed, show the device errors
@ -2026,7 +1996,7 @@ uint8_t SX126x::getPacketType() {
}
int16_t SX126x::setTxParams(uint8_t pwr, uint8_t rampTime) {
const uint8_t data[] = { pwr, rampTime };
uint8_t data[] = { pwr, rampTime };
int16_t state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_TX_PARAMS, data, 2);
if(state == RADIOLIB_ERR_NONE) {
this->pwr = pwr;
@ -2070,7 +2040,7 @@ int16_t SX126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t
// calculate symbol length and enable low data rate optimization, if auto-configuration is enabled
if(this->ldroAuto) {
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
if(symbolLength >= 16.0f) {
if(symbolLength >= 16.0) {
this->ldrOptimize = RADIOLIB_SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_ON;
} else {
this->ldrOptimize = RADIOLIB_SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_OFF;
@ -2080,12 +2050,12 @@ int16_t SX126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t
}
// 500/9/8 - 0x09 0x04 0x03 0x00 - SF9, BW125, 4/8
// 500/11/8 - 0x0B 0x04 0x03 0x00 - SF11 BW125, 4/7
const uint8_t data[4] = {sf, bw, cr, this->ldrOptimize};
uint8_t data[4] = {sf, bw, cr, this->ldrOptimize};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_MODULATION_PARAMS, data, 4));
}
int16_t SX126x::setModulationParamsFSK(uint32_t br, uint8_t sh, uint8_t rxBw, uint32_t freqDev) {
const uint8_t data[8] = {(uint8_t)((br >> 16) & 0xFF), (uint8_t)((br >> 8) & 0xFF), (uint8_t)(br & 0xFF),
uint8_t data[8] = {(uint8_t)((br >> 16) & 0xFF), (uint8_t)((br >> 8) & 0xFF), (uint8_t)(br & 0xFF),
sh, rxBw,
(uint8_t)((freqDev >> 16) & 0xFF), (uint8_t)((freqDev >> 8) & 0xFF), (uint8_t)(freqDev & 0xFF)};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_MODULATION_PARAMS, data, 8));
@ -2094,24 +2064,24 @@ int16_t SX126x::setModulationParamsFSK(uint32_t br, uint8_t sh, uint8_t rxBw, ui
int16_t SX126x::setPacketParams(uint16_t preambleLen, uint8_t crcType, uint8_t payloadLen, uint8_t hdrType, uint8_t invertIQ) {
int16_t state = fixInvertedIQ(invertIQ);
RADIOLIB_ASSERT(state);
const uint8_t data[6] = {(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF), hdrType, payloadLen, crcType, invertIQ};
uint8_t data[6] = {(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF), hdrType, payloadLen, crcType, invertIQ};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_PACKET_PARAMS, data, 6));
}
int16_t SX126x::setPacketParamsFSK(uint16_t preambleLen, uint8_t preambleDetectorLen, uint8_t crcType, uint8_t syncWordLen, uint8_t addrCmp, uint8_t whiten, uint8_t packType, uint8_t payloadLen) {
const uint8_t data[9] = {(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF),
uint8_t data[9] = {(uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF),
preambleDetectorLen, syncWordLen, addrCmp,
packType, payloadLen, crcType, whiten};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_PACKET_PARAMS, data, 9));
}
int16_t SX126x::setBufferBaseAddress(uint8_t txBaseAddress, uint8_t rxBaseAddress) {
const uint8_t data[2] = {txBaseAddress, rxBaseAddress};
uint8_t data[2] = {txBaseAddress, rxBaseAddress};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_BUFFER_BASE_ADDRESS, data, 2));
}
int16_t SX126x::setRegulatorMode(uint8_t mode) {
const uint8_t data[1] = {mode};
uint8_t data[1] = {mode};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_REGULATOR_MODE, data, 1));
}
@ -2135,7 +2105,7 @@ uint16_t SX126x::getDeviceErrors() {
}
int16_t SX126x::clearDeviceErrors() {
const uint8_t data[2] = {RADIOLIB_SX126X_CMD_NOP, RADIOLIB_SX126X_CMD_NOP};
uint8_t data[2] = {RADIOLIB_SX126X_CMD_NOP, RADIOLIB_SX126X_CMD_NOP};
return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CLEAR_DEVICE_ERRORS, data, 2));
}
@ -2156,7 +2126,7 @@ int16_t SX126x::fixSensitivity() {
RADIOLIB_ASSERT(state);
// fix the value for LoRa with 500 kHz bandwidth
if((getPacketType() == RADIOLIB_SX126X_PACKET_TYPE_LORA) && (fabsf(this->bandwidthKhz - 500.0f) <= 0.001f)) {
if((getPacketType() == RADIOLIB_SX126X_PACKET_TYPE_LORA) && (fabsf(this->bandwidthKhz - 500.0) <= 0.001)) {
sensitivityConfig &= 0xFB;
} else {
sensitivityConfig |= 0x04;
@ -2262,7 +2232,7 @@ int16_t SX126x::modSetup(float tcxoVoltage, bool useRegulatorLDO, uint8_t modem)
RADIOLIB_ASSERT(state);
// set TCXO control, if requested
if(!this->XTAL && tcxoVoltage > 0.0f) {
if(!this->XTAL && tcxoVoltage > 0.0) {
state = setTCXO(tcxoVoltage);
RADIOLIB_ASSERT(state);
}
@ -2359,7 +2329,7 @@ bool SX126x::findChip(const char* verStr) {
reset();
// read the version string
char version[16] = { 0 };
char version[16];
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, reinterpret_cast<uint8_t*>(version));
// check version register

View file

@ -14,7 +14,7 @@
// SX126X physical layer properties
#define RADIOLIB_SX126X_FREQUENCY_STEP_SIZE 0.9536743164
#define RADIOLIB_SX126X_MAX_PACKET_LENGTH 255
#define RADIOLIB_SX126X_CRYSTAL_FREQ 32.0f
#define RADIOLIB_SX126X_CRYSTAL_FREQ 32.0
#define RADIOLIB_SX126X_DIV_EXPONENT 25
// SX126X SPI commands
@ -201,7 +201,7 @@
#define RADIOLIB_SX126X_CAL_IMG_863_MHZ_2 0xDB
#define RADIOLIB_SX126X_CAL_IMG_902_MHZ_1 0xE1
#define RADIOLIB_SX126X_CAL_IMG_902_MHZ_2 0xE9
#define RADIOLIB_SX126X_CAL_IMG_FREQ_TRIG_MHZ (20.0f)
#define RADIOLIB_SX126X_CAL_IMG_FREQ_TRIG_MHZ (20.0)
//RADIOLIB_SX126X_CMD_SET_PA_CONFIG
#define RADIOLIB_SX126X_PA_CONFIG_HP_MAX 0x07
@ -478,7 +478,6 @@ class SX126x: public PhysicalLayer {
using PhysicalLayer::transmit;
using PhysicalLayer::receive;
using PhysicalLayer::startTransmit;
using PhysicalLayer::startReceive;
using PhysicalLayer::readData;
/*!
@ -629,25 +628,18 @@ class SX126x: public PhysicalLayer {
*/
int16_t standby(uint8_t mode, bool wakeup = true);
/*!
\brief Handle LR-FHSS hop.
When using LR-FHSS in interrupt-driven mode, this method MUST be called each time an interrupt is triggered!
\returns \ref status_codes
*/
int16_t hopLRFHSS();
// interrupt methods
/*!
\brief Sets interrupt service routine to call when DIO1 activates.
\param func ISR to call.
*/
virtual void setDio1Action(void (*func)(void));
void setDio1Action(void (*func)(void));
/*!
\brief Clears interrupt service routine to call when DIO1 activates.
*/
virtual void clearDio1Action();
void clearDio1Action();
/*!
\brief Sets interrupt service routine to call when a packet is received.
@ -682,6 +674,16 @@ class SX126x: public PhysicalLayer {
*/
void clearChannelScanAction() 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.
\returns \ref status_codes
@ -696,6 +698,23 @@ class SX126x: public PhysicalLayer {
*/
int16_t startReceive() override;
/*!
\brief Interrupt-driven receive method. DIO1 will be activated when full packet is received.
\param timeout Receive mode type and/or raw timeout value, expressed as multiples of 15.625 us.
When set to RADIOLIB_SX126X_RX_TIMEOUT_INF, the timeout will be infinite and the device will remain
in Rx mode until explicitly commanded to stop (Rx continuous mode).
When set to RADIOLIB_SX126X_RX_TIMEOUT_NONE, there will be no timeout and the device will return
to standby when a packet is received (Rx single mode).
For any other value, timeout will be applied and signal will be generated on DIO1 for conditions
defined by irqFlags and irqMask.
\param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error.
\param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done.
\param len Only for PhysicalLayer compatibility, not used.
\returns \ref status_codes
*/
int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0);
/*!
\brief Interrupt-driven receive method where the device mostly sleeps and periodically wakes to listen.
Note that this function assumes the unit will take 500us + TCXO_delay to change state.
@ -764,14 +783,14 @@ class SX126x: public PhysicalLayer {
\param bw LoRa bandwidth to be set in kHz.
\returns \ref status_codes
*/
virtual int16_t setBandwidth(float bw);
int16_t setBandwidth(float bw);
/*!
\brief Sets LoRa spreading factor. Allowed values range from 5 to 12.
\param sf LoRa spreading factor to be set.
\returns \ref status_codes
*/
virtual int16_t setSpreadingFactor(uint8_t sf);
int16_t setSpreadingFactor(uint8_t sf);
/*!
\brief Sets LoRa coding rate denominator. Allowed values range from 5 to 8.
@ -889,6 +908,27 @@ class SX126x: public PhysicalLayer {
*/
int16_t setSyncBits(uint8_t *syncWord, uint8_t bitsLen);
/*!
\brief Sets node address. Calling this method will also enable address filtering for node address only.
\param addr Node address to be set.
\returns \ref status_codes
*/
int16_t setNodeAddress(uint8_t addr);
/*!
\brief Sets broadcast address. Calling this method will also enable address
filtering for node and broadcast address.
\param broadAddr Node address to be set.
\returns \ref status_codes
*/
int16_t setBroadcastAddress(uint8_t broadAddr);
/*!
\brief Disables address filtering. Calling this method will also erase previously set addresses.
\returns \ref status_codes
*/
int16_t disableAddressFiltering();
/*!
\brief Sets CRC configuration.
\param len CRC length in bytes, Allowed values are 1 or 2, set to 0 to disable CRC.
@ -1099,12 +1139,6 @@ class SX126x: public PhysicalLayer {
*/
int16_t getModem(ModemType_t* modem) override;
/*! \copydoc PhysicalLayer::stageMode */
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) override;
/*! \copydoc PhysicalLayer::launchMode */
int16_t launchMode() override;
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
/*!
\brief Set interrupt service routine function to call when data bit is received in direct mode.
@ -1204,14 +1238,14 @@ class SX126x: public PhysicalLayer {
int16_t setTx(uint32_t timeout = 0);
int16_t setRx(uint32_t timeout);
int16_t setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout);
int16_t writeRegister(uint16_t addr, const uint8_t* data, uint8_t numBytes);
int16_t writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);
int16_t readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);
int16_t writeBuffer(const uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00);
int16_t writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00);
int16_t readBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00);
int16_t setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask = RADIOLIB_SX126X_IRQ_NONE, uint16_t dio3Mask = RADIOLIB_SX126X_IRQ_NONE);
virtual int16_t clearIrqStatus(uint16_t clearIrqParams = RADIOLIB_SX126X_IRQ_ALL);
int16_t setRfFrequency(uint32_t frf);
int16_t calibrateImage(const uint8_t* data);
int16_t calibrateImage(uint8_t* data);
uint8_t getPacketType();
int16_t setTxParams(uint8_t power, uint8_t rampTime);
int16_t setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro);
@ -1263,7 +1297,6 @@ class SX126x: public PhysicalLayer {
size_t implicitLen = 0;
uint8_t invertIQEnabled = RADIOLIB_SX126X_LORA_IQ_STANDARD;
uint32_t rxTimeout = 0;
// LR-FHSS stuff - there's a lot of it because all the encoding happens in software
uint8_t lrFhssCr = RADIOLIB_SX126X_LR_FHSS_CR_2_3;

View file

@ -87,7 +87,7 @@ int16_t SX126x::buildLRFHSSPacket(const uint8_t* in, size_t in_len, uint8_t* out
// for rates other than the 1/3 base, puncture the code
if(this->lrFhssCr != RADIOLIB_SX126X_LR_FHSS_CR_1_3) {
uint32_t matrix_index = 0;
const uint8_t matrix[15] = { 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0 };
uint8_t matrix[15] = { 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0 };
uint8_t matrix_len = 0;
switch(this->lrFhssCr) {
case RADIOLIB_SX126X_LR_FHSS_CR_5_6:
@ -364,7 +364,7 @@ int16_t SX126x::setLRFHSSHop(uint8_t index) {
}
}
const uint8_t frq[4] = { (uint8_t)((freq_raw >> 24) & 0xFF), (uint8_t)((freq_raw >> 16) & 0xFF), (uint8_t)((freq_raw >> 8) & 0xFF), (uint8_t)(freq_raw & 0xFF) };
uint8_t frq[4] = { (uint8_t)((freq_raw >> 24) & 0xFF), (uint8_t)((freq_raw >> 16) & 0xFF), (uint8_t)((freq_raw >> 8) & 0xFF), (uint8_t)(freq_raw & 0xFF) };
int16_t state = writeRegister(RADIOLIB_SX126X_REG_LR_FHSS_FREQX_0(index), frq, sizeof(freq_raw));
RADIOLIB_ASSERT(state);
@ -380,7 +380,7 @@ int16_t SX126x::setLRFHSSHop(uint8_t index) {
}
// write hop length in symbols
const uint8_t sym[2] = { (uint8_t)((numSymbols >> 8) & 0xFF), (uint8_t)(numSymbols & 0xFF) };
uint8_t sym[2] = { (uint8_t)((numSymbols >> 8) & 0xFF), (uint8_t)(numSymbols & 0xFF) };
state = writeRegister(RADIOLIB_SX126X_REG_LR_FHSS_NUM_SYMBOLS_FREQX_MSB(index), sym, sizeof(uint16_t));
RADIOLIB_ASSERT(state);

View file

@ -83,7 +83,7 @@ void SX1272::reset() {
}
int16_t SX1272::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 860.0f, 1020.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 860.0, 1020.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// set frequency and if successful, save the new setting
int16_t state = SX127x::setFrequencyRaw(freq);
@ -102,11 +102,11 @@ int16_t SX1272::setBandwidth(float bw) {
uint8_t newBandwidth;
// check allowed bandwidth values
if(fabsf(bw - 125.0f) <= 0.001f) {
if(fabsf(bw - 125.0) <= 0.001) {
newBandwidth = RADIOLIB_SX1272_BW_125_00_KHZ;
} else if(fabsf(bw - 250.0f) <= 0.001f) {
} else if(fabsf(bw - 250.0) <= 0.001) {
newBandwidth = RADIOLIB_SX1272_BW_250_00_KHZ;
} else if(fabsf(bw - 500.0f) <= 0.001f) {
} else if(fabsf(bw - 500.0) <= 0.001) {
newBandwidth = RADIOLIB_SX1272_BW_500_00_KHZ;
} else {
return(RADIOLIB_ERR_INVALID_BANDWIDTH);
@ -121,7 +121,7 @@ int16_t SX1272::setBandwidth(float bw) {
if(this->ldroAuto) {
float symbolLength = (float)(uint32_t(1) << SX127x::spreadingFactor) / (float)SX127x::bandwidth;
Module* mod = this->getMod();
if(symbolLength >= 16.0f) {
if(symbolLength >= 16.0) {
state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
} else {
state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
@ -175,7 +175,7 @@ int16_t SX1272::setSpreadingFactor(uint8_t sf) {
if(this->ldroAuto) {
float symbolLength = (float)(uint32_t(1) << SX127x::spreadingFactor) / (float)SX127x::bandwidth;
Module* mod = this->getMod();
if(symbolLength >= 16.0f) {
if(symbolLength >= 16.0) {
state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
} else {
state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
@ -258,15 +258,15 @@ int16_t SX1272::checkDataRate(DataRate_t dr) {
// select interpretation based on active modem
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_FSK_OOK) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0f <= 250.0f) && (dr.fsk.freqDev <= 200.0f))) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0 <= 250.0) && (dr.fsk.freqDev <= 200.0))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
}
return(RADIOLIB_ERR_NONE);
} else if(modem == RADIOLIB_SX127X_LORA) {
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 6, 12, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
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);
return(RADIOLIB_ERR_NONE);
@ -279,9 +279,8 @@ int16_t SX1272::setOutputPower(int8_t power) {
return(this->setOutputPower(power, false));
}
int16_t SX1272::setOutputPower(int8_t power, bool forceRfo) {
int16_t SX1272::setOutputPower(int8_t power, bool useRfo) {
// check if power value is configurable
bool useRfo = (power < 2) || forceRfo;
int16_t state = checkOutputPower(power, NULL, useRfo);
RADIOLIB_ASSERT(state);

View file

@ -118,7 +118,7 @@ class SX1272: public SX127x {
Set to 0 to enable automatic gain control (recommended).
\returns \ref status_codes
*/
virtual int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
/*!
\brief FSK modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
@ -160,7 +160,7 @@ class SX1272: public SX127x {
\param sf %LoRa link spreading factor to be set.
\returns \ref status_codes
*/
virtual int16_t setSpreadingFactor(uint8_t sf);
int16_t setSpreadingFactor(uint8_t sf);
/*!
\brief Sets %LoRa link coding rate denominator. Allowed values range from 5 to 8. Only available in %LoRa mode.
@ -201,11 +201,10 @@ class SX1272: public SX127x {
/*!
\brief Sets transmission output power. Allowed values range from -1 to 14 dBm (RFO pin) or +2 to +20 dBm (PA_BOOST pin).
\param power Transmission output power in dBm.
\param forceRfo Whether to force using the RFO pin for the RF output (true)
or to leave the selection up to user (false) based on power output.
\param useRfo Whether to use the RFO (true) or the PA_BOOST (false) pin for the RF output.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power, bool forceRfo);
int16_t setOutputPower(int8_t power, bool useRfo);
/*!
\brief Check if output power is configurable.
@ -318,7 +317,7 @@ class SX1272: public SX127x {
int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
int16_t setCodingRateRaw(uint8_t newCodingRate);
int16_t configFSK() override;
int16_t configFSK();
void errataFix(bool rx) override;
#if !RADIOLIB_GODMODE

View file

@ -98,15 +98,15 @@ int16_t SX1273::checkDataRate(DataRate_t dr) {
// select interpretation based on active modem
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_FSK_OOK) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0f <= 250.0f) && (dr.fsk.freqDev <= 200.0f))) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0 <= 250.0) && (dr.fsk.freqDev <= 200.0))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
}
return(RADIOLIB_ERR_NONE);
} else if(modem == RADIOLIB_SX127X_LORA) {
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 6, 9, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
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);
return(RADIOLIB_ERR_NONE);

View file

@ -38,7 +38,7 @@ class SX1273: public SX1272 {
Set to 0 to enable automatic gain control (recommended).
\returns \ref status_codes
*/
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0) override;
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
// configuration methods
@ -47,7 +47,7 @@ class SX1273: public SX1272 {
\param sf %LoRa link spreading factor to be set.
\returns \ref status_codes
*/
int16_t setSpreadingFactor(uint8_t sf) override;
int16_t setSpreadingFactor(uint8_t sf);
/*!
\brief Set data.

View file

@ -7,7 +7,7 @@ SX1276::SX1276(Module* mod) : SX1278(mod) {
int16_t SX1276::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::begin(versions, 3, syncWord, preambleLength);
RADIOLIB_ASSERT(state);
@ -39,7 +39,7 @@ int16_t SX1276::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1276::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::beginFSK(versions, 3, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
@ -69,7 +69,7 @@ int16_t SX1276::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
}
int16_t SX1276::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 137.0f, 1020.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 137.0, 1020.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// set frequency and if successful, save the new setting
int16_t state = SX127x::setFrequencyRaw(freq);

View file

@ -27,7 +27,7 @@ class SX1276: public SX1278 {
/*!
\brief %LoRa modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
\param freq Carrier frequency in MHz. Allowed values range from 137.0 MHz to 1020.0 MHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param sf %LoRa link spreading factor. Allowed values range from 6 to 12.
\param cr %LoRa link coding rate denominator. Allowed values range from 5 to 8.
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN networks.
@ -38,7 +38,7 @@ class SX1276: public SX1278 {
Set to 0 to enable automatic gain control (recommended).
\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_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0) override;
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
/*!
\brief FSK modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
@ -52,7 +52,7 @@ class SX1276: public SX1278 {
\param enableOOK Use OOK modulation instead of FSK.
\returns \ref status_codes
*/
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false) override;
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false);
// configuration methods

View file

@ -7,7 +7,7 @@ SX1277::SX1277(Module* mod) : SX1278(mod) {
int16_t SX1277::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::begin(versions, 3, syncWord, preambleLength);
RADIOLIB_ASSERT(state);
@ -39,7 +39,7 @@ int16_t SX1277::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1277::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::beginFSK(versions, 3, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
@ -69,7 +69,7 @@ int16_t SX1277::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
}
int16_t SX1277::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 137.0f, 1020.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 137.0, 1020.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// set frequency and if successful, save the new setting
int16_t state = SX127x::setFrequencyRaw(freq);
@ -140,15 +140,15 @@ int16_t SX1277::checkDataRate(DataRate_t dr) {
// select interpretation based on active modem
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_FSK_OOK) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0f <= 250.0f) && (dr.fsk.freqDev <= 200.0f))) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0 <= 250.0) && (dr.fsk.freqDev <= 200.0))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
}
return(RADIOLIB_ERR_NONE);
} else if(modem == RADIOLIB_SX127X_LORA) {
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 6, 9, 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);
return(RADIOLIB_ERR_NONE);

View file

@ -27,7 +27,7 @@ class SX1277: public SX1278 {
/*!
\brief %LoRa modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
\param freq Carrier frequency in MHz. Allowed values range from 137.0 MHz to 1020.0 MHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param sf %LoRa link spreading factor. Allowed values range from 6 to 9.
\param cr %LoRa link coding rate denominator. Allowed values range from 5 to 8.
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN networks.
@ -38,7 +38,7 @@ class SX1277: public SX1278 {
Set to 0 to enable automatic gain control (recommended).
\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_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0) override;
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
/*!
\brief FSK modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
@ -52,7 +52,7 @@ class SX1277: public SX1278 {
\param enableOOK Use OOK modulation instead of FSK.
\returns \ref status_codes
*/
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false) override;
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false);
// configuration methods
@ -68,7 +68,7 @@ class SX1277: public SX1278 {
\param sf %LoRa link spreading factor to be set.
\returns \ref status_codes
*/
int16_t setSpreadingFactor(uint8_t sf) override;
int16_t setSpreadingFactor(uint8_t sf);
/*!
\brief Set data.

View file

@ -8,7 +8,7 @@ SX1278::SX1278(Module* mod) : SX127x(mod) {
int16_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::begin(versions, 3, syncWord, preambleLength);
RADIOLIB_ASSERT(state);
@ -40,7 +40,7 @@ int16_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1278::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::beginFSK(versions, 3, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
@ -83,7 +83,7 @@ void SX1278::reset() {
}
int16_t SX1278::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 137.0f, 525.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 137.0, 525.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// set frequency and if successful, save the new setting
int16_t state = SX127x::setFrequencyRaw(freq);
@ -102,25 +102,25 @@ int16_t SX1278::setBandwidth(float bw) {
uint8_t newBandwidth;
// check allowed bandwidth values
if(fabsf(bw - 7.8f) <= 0.001f) {
if(fabsf(bw - 7.8) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_7_80_KHZ;
} else if(fabsf(bw - 10.4f) <= 0.001f) {
} else if(fabsf(bw - 10.4) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_10_40_KHZ;
} else if(fabsf(bw - 15.6f) <= 0.001f) {
} else if(fabsf(bw - 15.6) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_15_60_KHZ;
} else if(fabsf(bw - 20.8f) <= 0.001f) {
} else if(fabsf(bw - 20.8) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_20_80_KHZ;
} else if(fabsf(bw - 31.25f) <= 0.001f) {
} else if(fabsf(bw - 31.25) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_31_25_KHZ;
} else if(fabsf(bw - 41.7f) <= 0.001f) {
} else if(fabsf(bw - 41.7) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_41_70_KHZ;
} else if(fabsf(bw - 62.5f) <= 0.001f) {
} else if(fabsf(bw - 62.5) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_62_50_KHZ;
} else if(fabsf(bw - 125.0f) <= 0.001f) {
} else if(fabsf(bw - 125.0) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_125_00_KHZ;
} else if(fabsf(bw - 250.0f) <= 0.001f) {
} else if(fabsf(bw - 250.0) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_250_00_KHZ;
} else if(fabsf(bw - 500.0f) <= 0.001f) {
} else if(fabsf(bw - 500.0) <= 0.001) {
newBandwidth = RADIOLIB_SX1278_BW_500_00_KHZ;
} else {
return(RADIOLIB_ERR_INVALID_BANDWIDTH);
@ -135,7 +135,7 @@ int16_t SX1278::setBandwidth(float bw) {
if(this->ldroAuto) {
float symbolLength = (float)(uint32_t(1) << SX127x::spreadingFactor) / (float)SX127x::bandwidth;
Module* mod = this->getMod();
if(symbolLength >= 16.0f) {
if(symbolLength >= 16.0) {
state = mod->SPIsetRegValue(RADIOLIB_SX1278_REG_MODEM_CONFIG_3, RADIOLIB_SX1278_LOW_DATA_RATE_OPT_ON, 3, 3);
} else {
state = mod->SPIsetRegValue(RADIOLIB_SX1278_REG_MODEM_CONFIG_3, RADIOLIB_SX1278_LOW_DATA_RATE_OPT_OFF, 3, 3);
@ -189,7 +189,7 @@ int16_t SX1278::setSpreadingFactor(uint8_t sf) {
if(this->ldroAuto) {
float symbolLength = (float)(uint32_t(1) << SX127x::spreadingFactor) / (float)SX127x::bandwidth;
Module* mod = this->getMod();
if(symbolLength >= 16.0f) {
if(symbolLength >= 16.0) {
state = mod->SPIsetRegValue(RADIOLIB_SX1278_REG_MODEM_CONFIG_3, RADIOLIB_SX1278_LOW_DATA_RATE_OPT_ON, 3, 3);
} else {
state = mod->SPIsetRegValue(RADIOLIB_SX1278_REG_MODEM_CONFIG_3, RADIOLIB_SX1278_LOW_DATA_RATE_OPT_OFF, 3, 3);
@ -272,15 +272,15 @@ int16_t SX1278::checkDataRate(DataRate_t dr) {
// select interpretation based on active modem
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_FSK_OOK) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0f <= 250.0f) && (dr.fsk.freqDev <= 200.0f))) {
RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.5, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
if(!((dr.fsk.freqDev + dr.fsk.bitRate/2.0 <= 250.0) && (dr.fsk.freqDev <= 200.0))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
}
return(RADIOLIB_ERR_NONE);
} else if(modem == RADIOLIB_SX127X_LORA) {
RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 6, 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);
return(RADIOLIB_ERR_NONE);
@ -293,9 +293,8 @@ int16_t SX1278::setOutputPower(int8_t power) {
return(this->setOutputPower(power, false));
}
int16_t SX1278::setOutputPower(int8_t power, bool forceRfo) {
int16_t SX1278::setOutputPower(int8_t power, bool useRfo) {
// check if power value is configurable
bool useRfo = (power < 2) || forceRfo;
int16_t state = checkOutputPower(power, NULL, useRfo);
RADIOLIB_ASSERT(state);
@ -345,9 +344,9 @@ int16_t SX1278::checkOutputPower(int8_t power, int8_t* clipped, bool useRfo) {
if(useRfo) {
// RFO output
if(clipped) {
*clipped = RADIOLIB_MAX(-4, RADIOLIB_MIN(15, power));
*clipped = RADIOLIB_MAX(-3, RADIOLIB_MIN(15, power));
}
RADIOLIB_CHECK_RANGE(power, -4, 15, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
RADIOLIB_CHECK_RANGE(power, -3, 15, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
} else {
// PA_BOOST output, check high-power operation
if(clipped) {
@ -477,7 +476,7 @@ float SX1278::getRSSI() {
float SX1278::getRSSI(bool packet, bool skipReceive) {
int16_t offset = -157;
if(frequency < 868.0f) {
if(frequency < 868.0) {
offset = -164;
}
return(SX127x::getRSSI(packet, skipReceive, offset));
@ -607,11 +606,11 @@ void SX1278::errataFix(bool rx) {
// sensitivity optimization for 500kHz bandwidth
// see SX1276/77/78 Errata, section 2.1 for details
Module* mod = this->getMod();
if(fabsf(SX127x::bandwidth - 500.0f) <= 0.001f) {
if((frequency >= 862.0f) && (frequency <= 1020.0f)) {
if(fabsf(SX127x::bandwidth - 500.0) <= 0.001) {
if((frequency >= 862.0) && (frequency <= 1020.0)) {
mod->SPIwriteRegister(0x36, 0x02);
mod->SPIwriteRegister(0x3a, 0x64);
} else if((frequency >= 410.0f) && (frequency <= 525.0f)) {
} else if((frequency >= 410.0) && (frequency <= 525.0)) {
mod->SPIwriteRegister(0x36, 0x02);
mod->SPIwriteRegister(0x3a, 0x7F);
}
@ -623,49 +622,49 @@ void SX1278::errataFix(bool rx) {
// figure out what we need to set
uint8_t fixedRegs[3] = { 0x00, 0x00, 0x00 };
float rxFreq = frequency;
if(fabsf(SX127x::bandwidth - 7.8f) <= 0.001f) {
if(fabsf(SX127x::bandwidth - 7.8) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x48;
fixedRegs[2] = 0x00;
rxFreq += 0.00781f;
} else if(fabsf(SX127x::bandwidth - 10.4f) <= 0.001f) {
rxFreq += 0.00781;
} else if(fabsf(SX127x::bandwidth - 10.4) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x44;
fixedRegs[2] = 0x00;
rxFreq += 0.01042f;
} else if(fabsf(SX127x::bandwidth - 15.6f) <= 0.001f) {
rxFreq += 0.01042;
} else if(fabsf(SX127x::bandwidth - 15.6) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x44;
fixedRegs[2] = 0x00;
rxFreq += 0.01562f;
} else if(fabsf(SX127x::bandwidth - 20.8f) <= 0.001f) {
rxFreq += 0.01562;
} else if(fabsf(SX127x::bandwidth - 20.8) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x44;
fixedRegs[2] = 0x00;
rxFreq += 0.02083f;
} else if(fabsf(SX127x::bandwidth - 31.25f) <= 0.001f) {
rxFreq += 0.02083;
} else if(fabsf(SX127x::bandwidth - 31.25) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x44;
fixedRegs[2] = 0x00;
rxFreq += 0.03125f;
} else if(fabsf(SX127x::bandwidth - 41.7f) <= 0.001f) {
rxFreq += 0.03125;
} else if(fabsf(SX127x::bandwidth - 41.7) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x44;
fixedRegs[2] = 0x00;
rxFreq += 0.04167f;
} else if(fabsf(SX127x::bandwidth - 62.5f) <= 0.001f) {
rxFreq += 0.04167;
} else if(fabsf(SX127x::bandwidth - 62.5) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x40;
fixedRegs[2] = 0x00;
} else if(fabsf(SX127x::bandwidth - 125.0f) <= 0.001f) {
} else if(fabsf(SX127x::bandwidth - 125.0) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x40;
fixedRegs[2] = 0x00;
} else if(fabsf(SX127x::bandwidth - 250.0f) <= 0.001f) {
} else if(fabsf(SX127x::bandwidth - 250.0) <= 0.001) {
fixedRegs[0] = 0b00000000;
fixedRegs[1] = 0x40;
fixedRegs[2] = 0x00;
} else if(fabsf(SX127x::bandwidth - 500.0f) <= 0.001f) {
} else if(fabsf(SX127x::bandwidth - 500.0) <= 0.001) {
fixedRegs[0] = 0b10000000;
fixedRegs[1] = mod->SPIreadRegister(0x2F);
fixedRegs[2] = mod->SPIreadRegister(0x30);

View file

@ -118,7 +118,7 @@ class SX1278: public SX127x {
/*!
\brief %LoRa modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
\param freq Carrier frequency in MHz. Allowed values range from 137.0 MHz to 525.0 MHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param sf %LoRa link spreading factor. Allowed values range from 6 to 12.
\param cr %LoRa link coding rate denominator. Allowed values range from 5 to 8.
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN networks.
@ -129,7 +129,7 @@ class SX1278: public SX127x {
Set to 0 to enable automatic gain control (recommended).
\returns \ref status_codes
*/
virtual int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
/*!
\brief FSK modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
@ -143,7 +143,7 @@ class SX1278: public SX127x {
\param enableOOK Use OOK modulation instead of FSK.
\returns \ref status_codes
*/
virtual int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false);
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false);
/*!
\brief Reset method. Will reset the chip to the default state using RST pin.
@ -160,7 +160,7 @@ class SX1278: public SX127x {
int16_t setFrequency(float freq) override;
/*!
\brief Sets %LoRa link bandwidth. Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz. Only available in %LoRa mode.
\brief Sets %LoRa link bandwidth. Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz. Only available in %LoRa mode.
\param bw %LoRa link bandwidth to be set in kHz.
\returns \ref status_codes
*/
@ -171,7 +171,7 @@ class SX1278: public SX127x {
\param sf %LoRa link spreading factor to be set.
\returns \ref status_codes
*/
virtual int16_t setSpreadingFactor(uint8_t sf);
int16_t setSpreadingFactor(uint8_t sf);
/*!
\brief Sets %LoRa link coding rate denominator. Allowed values range from 5 to 8. Only available in %LoRa mode.
@ -202,7 +202,7 @@ class SX1278: public SX127x {
int16_t checkDataRate(DataRate_t dr) override;
/*!
\brief Sets transmission output power. Allowed values range from -4 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin).
\brief Sets transmission output power. Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin).
High power +20 dBm operation is also supported, on the PA_BOOST pin. Defaults to PA_BOOST.
\param power Transmission output power in dBm.
\returns \ref status_codes
@ -210,14 +210,13 @@ class SX1278: public SX127x {
int16_t setOutputPower(int8_t power) override;
/*!
\brief Sets transmission output power. Allowed values range from -4 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin).
\brief Sets transmission output power. Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin).
High power +20 dBm operation is also supported, on the PA_BOOST pin.
\param power Transmission output power in dBm.
\param forceRfo Whether to force using the RFO pin for the RF output (true)
or to leave the selection up to user (false) based on power output.
\param useRfo Whether to use the RFO (true) or the PA_BOOST (false) pin for the RF output.
\returns \ref status_codes
*/
int16_t setOutputPower(int8_t power, bool forceRfo);
int16_t setOutputPower(int8_t power, bool useRfo);
/*!
\brief Check if output power is configurable.
@ -330,7 +329,7 @@ class SX1278: public SX127x {
int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
int16_t setCodingRateRaw(uint8_t newCodingRate);
int16_t configFSK() override;
int16_t configFSK();
void errataFix(bool rx) override;
#if !RADIOLIB_GODMODE

View file

@ -7,7 +7,7 @@ SX1279::SX1279(Module* mod) : SX1278(mod) {
int16_t SX1279::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::begin(versions, 3, syncWord, preambleLength);
RADIOLIB_ASSERT(state);
@ -39,7 +39,7 @@ int16_t SX1279::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
int16_t SX1279::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) {
// execute common part
const uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
uint8_t versions[] = { RADIOLIB_SX1278_CHIP_VERSION, RADIOLIB_SX1278_CHIP_VERSION_ALT, RADIOLIB_SX1278_CHIP_VERSION_RFM9X };
int16_t state = SX127x::beginFSK(versions, 3, freqDev, rxBw, preambleLength, enableOOK);
RADIOLIB_ASSERT(state);
@ -69,7 +69,7 @@ int16_t SX1279::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t
}
int16_t SX1279::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 137.0f, 960.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 137.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// set frequency and if successful, save the new setting
int16_t state = SX127x::setFrequencyRaw(freq);

View file

@ -27,7 +27,7 @@ class SX1279: public SX1278 {
/*!
\brief %LoRa modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
\param freq Carrier frequency in MHz. Allowed values range from 137.0 MHz to 960.0 MHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param bw %LoRa link bandwidth in kHz. Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
\param sf %LoRa link spreading factor. Allowed values range from 6 to 12.
\param cr %LoRa link coding rate denominator. Allowed values range from 5 to 8.
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN networks.
@ -38,7 +38,7 @@ class SX1279: public SX1278 {
Set to 0 to enable automatic gain control (recommended).
\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_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0) override;
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0);
/*!
\brief FSK modem initialization method. Must be called at least once from Arduino sketch to initialize the module.
@ -52,7 +52,7 @@ class SX1279: public SX1278 {
\param enableOOK Use OOK modulation instead of FSK.
\returns \ref status_codes
*/
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false) override;
int16_t beginFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 125.0, int8_t power = 10, uint16_t preambleLength = 16, bool enableOOK = false);
// configuration methods

View file

@ -2,13 +2,11 @@
#include <math.h>
#if !RADIOLIB_EXCLUDE_SX127X
SX127x::SX127x(Module* mod) : PhysicalLayer() {
this->freqStep = RADIOLIB_SX127X_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_SX127X_MAX_PACKET_LENGTH;
SX127x::SX127x(Module* mod) : PhysicalLayer(RADIOLIB_SX127X_FREQUENCY_STEP_SIZE, RADIOLIB_SX127X_MAX_PACKET_LENGTH) {
this->mod = mod;
}
int16_t SX127x::begin(const uint8_t* chipVersions, uint8_t numVersions, uint8_t syncWord, uint16_t preambleLength) {
int16_t SX127x::begin(uint8_t* chipVersions, uint8_t numVersions, uint8_t syncWord, uint16_t preambleLength) {
// set module properties
this->mod->init();
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
@ -71,7 +69,7 @@ int16_t SX127x::begin(const uint8_t* chipVersions, uint8_t numVersions, uint8_t
return(state);
}
int16_t SX127x::beginFSK(const uint8_t* chipVersions, uint8_t numVersions, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK) {
int16_t SX127x::beginFSK(uint8_t* chipVersions, uint8_t numVersions, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK) {
// set module properties
this->mod->init();
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
@ -206,7 +204,7 @@ int16_t SX127x::transmit(const uint8_t* data, size_t len, uint8_t addr) {
// update data rate
RadioLibTime_t elapsed = this->mod->hal->millis() - start;
this->dataRate = (len*8.0f)/((float)elapsed/1000.0f);
this->dataRate = (len*8.0)/((float)elapsed/1000.0);
return(finishTransmit());
}
@ -226,7 +224,7 @@ int16_t SX127x::receive(uint8_t* data, size_t len) {
RadioLibTime_t timeout = 0;
if(this->mod->getGpio() == RADIOLIB_NC) {
float symbolLength = (float) (uint32_t(1) << this->spreadingFactor) / (float) this->bandwidth;
timeout = (RadioLibTime_t)(symbolLength * 100.0f);
timeout = (RadioLibTime_t)(symbolLength * 100.0);
}
// wait for packet reception or timeout
@ -391,6 +389,67 @@ int16_t SX127x::startReceive() {
return(this->startReceive(0, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0));
}
int16_t SX127x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) {
uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS;
// set mode to standby
int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
RADIOLIB_ASSERT(state);
// set DIO pin mapping
state = this->setIrqFlags(getIrqMapped(irqFlags & irqMask));
RADIOLIB_ASSERT(state);
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_LORA) {
if(timeout != 0) {
// for non-zero timeout value, change mode to Rx single and set the timeout
mode = RADIOLIB_SX127X_RXSINGLE;
uint8_t msb_sym = (timeout > 0x3FF) ? 0x3 : (uint8_t)(timeout >> 8);
uint8_t lsb_sym = (timeout > 0x3FF) ? 0xFF : (uint8_t)(timeout & 0xFF);
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, msb_sym, 1, 0);
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYMB_TIMEOUT_LSB, lsb_sym);
RADIOLIB_ASSERT(state);
}
// in FHSS mode, enable channel change interrupt
if(this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 5, 4);
}
// in implicit header mode, use the provided length if it is nonzero
// otherwise we trust the user has previously set the payload length manually
if((this->implicitHdr) && (len != 0)) {
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len);
this->packetLength = len;
}
// apply fixes to errata
RADIOLIB_ERRATA_SX127X(true);
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// set FIFO pointers
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_RX_BASE_ADDR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX);
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX);
RADIOLIB_ASSERT(state);
} else if(modem == RADIOLIB_SX127X_FSK_OOK) {
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// FSK modem does not distinguish between Rx single and continuous
mode = RADIOLIB_SX127X_RX;
}
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_RX);
// set mode to receive
return(setMode(mode));
}
void SX127x::setDio0Action(void (*func)(void), uint32_t dir) {
this->mod->hal->attachInterrupt(this->mod->hal->pinToInterrupt(this->mod->getIrq()), func, dir);
}
@ -489,7 +548,7 @@ bool SX127x::fifoAdd(uint8_t* data, int totalLen, int* remLen) {
bool SX127x::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) {
// 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
uint8_t len = RADIOLIB_SX127X_FIFO_THRESH - 1;
@ -509,6 +568,80 @@ bool SX127x::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen)
return(false);
}
int16_t SX127x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
// set mode to standby
int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_LORA) {
// check packet length
if(len > RADIOLIB_SX127X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// set DIO mapping
if(this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE | RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 7, 4);
} else {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE, 7, 6);
}
// apply fixes to errata
RADIOLIB_ERRATA_SX127X(false);
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// set packet length
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len);
// set FIFO pointers
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_TX_BASE_ADDR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX);
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX);
} else if(modem == RADIOLIB_SX127X_FSK_OOK) {
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// set DIO mapping
if(len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK) {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_PACK_FIFO_EMPTY, 5, 4);
} else {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PACKET_SENT, 7, 6);
}
// set packet length - increased by 1 when address filter is enabled
uint8_t filter = this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 2, 1);
if(this->packetLengthConfig == RADIOLIB_SX127X_PACKET_VARIABLE) {
if((filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST)) {
this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, len + 1);
this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, addr);
} else {
this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, len);
}
}
}
// write packet to FIFO
size_t packetLen = len;
if((modem == RADIOLIB_SX127X_FSK_OOK) && (len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK)) {
packetLen = RADIOLIB_SX127X_FIFO_THRESH - 1;
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_TX_START_FIFO_NOT_EMPTY, 7, 7);
}
this->mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_FIFO, const_cast<uint8_t*>(data), packetLen);
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_TX);
// start transmission
state |= setMode(RADIOLIB_SX127X_TX);
RADIOLIB_ASSERT(state);
return(RADIOLIB_ERR_NONE);
}
int16_t SX127x::finishTransmit() {
// wait for at least 1 bit at the lowest possible bit rate before clearing IRQ flags
// not doing this and clearing RADIOLIB_SX127X_FLAG_FIFO_OVERRUN will dump the FIFO,
@ -711,14 +844,14 @@ float SX127x::getFrequencyError(bool autoCorrect) {
// frequency error is negative
raw |= (uint32_t)0xFFF00000;
raw = ~raw + 1;
error = (((float)raw * (float)base)/32000000.0f) * (this->bandwidth/500.0f) * -1.0f;
error = (((float)raw * (float)base)/32000000.0) * (this->bandwidth/500.0) * -1.0;
} else {
error = (((float)raw * (float)base)/32000000.0f) * (this->bandwidth/500.0f);
error = (((float)raw * (float)base)/32000000.0) * (this->bandwidth/500.0);
}
if(autoCorrect) {
// adjust LoRa modem data rate
float ppmOffset = 0.95f * (error/32.0f);
float ppmOffset = 0.95 * (error/32.0);
this->mod->SPIwriteRegister(0x27, (uint8_t)ppmOffset);
}
@ -737,9 +870,9 @@ float SX127x::getFrequencyError(bool autoCorrect) {
// frequency error is negative
raw |= (uint32_t)0xFFF00000;
raw = ~raw + 1;
error = (float)raw * (32000000.0f / (float)(base << 19)) * -1.0f;
error = (float)raw * (32000000.0 / (float)(base << 19)) * -1.0;
} else {
error = (float)raw * (32000000.0f / (float)(base << 19));
error = (float)raw * (32000000.0 / (float)(base << 19));
}
return(error);
@ -761,7 +894,7 @@ float SX127x::getAFCError()
raw |= this->mod->SPIreadRegister(RADIOLIB_SX127X_REG_AFC_LSB);
uint32_t base = 1;
return raw * (32000000.0f / (float)(base << 19));
return raw * (32000000.0 / (float)(base << 19));
}
float SX127x::getSNR() {
@ -788,9 +921,9 @@ int16_t SX127x::setBitRateCommon(float br, uint8_t fracRegAddr) {
// check allowed bit rate
// datasheet says 1.2 kbps should be the smallest possible, but 0.512 works fine
if(ookEnabled) {
RADIOLIB_CHECK_RANGE(br, 0.5f, 32.768002f, RADIOLIB_ERR_INVALID_BIT_RATE); // Found that 32.768 is 32.768002
RADIOLIB_CHECK_RANGE(br, 0.5, 32.768002, RADIOLIB_ERR_INVALID_BIT_RATE); // Found that 32.768 is 32.768002
} else {
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);
}
// set mode to STANDBY
@ -798,13 +931,13 @@ int16_t SX127x::setBitRateCommon(float br, uint8_t fracRegAddr) {
RADIOLIB_ASSERT(state);
// set bit rate
uint16_t bitRateRaw = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0f) / br;
uint16_t bitRateRaw = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0) / br;
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_MSB, (bitRateRaw & 0xFF00) >> 8, 7, 0);
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_LSB, bitRateRaw & 0x00FF, 7, 0);
// set fractional part of bit rate
if(!ookEnabled) {
float bitRateRem = ((RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0f) / br) - (float)bitRateRaw;
float bitRateRem = ((RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0) / (float)br) - (float)bitRateRaw;
uint8_t bitRateFrac = bitRateRem * 16;
state |= this->mod->SPIsetRegValue(fracRegAddr, bitRateFrac, 7, 0);
}
@ -823,12 +956,12 @@ int16_t SX127x::setFrequencyDeviation(float freqDev) {
// set frequency deviation to lowest available setting (required for digimodes)
float newFreqDev = freqDev;
if(freqDev < 0.0f) {
newFreqDev = 0.6f;
if(freqDev < 0.0) {
newFreqDev = 0.6;
}
// check frequency deviation range
if(!((newFreqDev + this->bitRate/2.0f <= 250.0f) && (freqDev <= 200.0f))) {
if(!((newFreqDev + this->bitRate/2.0 <= 250.0) && (freqDev <= 200.0))) {
return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
}
@ -848,8 +981,8 @@ uint8_t SX127x::calculateBWManExp(float bandwidth)
{
for(uint8_t e = 7; e >= 1; e--) {
for(int8_t m = 2; m >= 0; m--) {
float point = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000000.0f)/(((4 * m) + 16) * ((uint32_t)1 << (e + 2)));
if(fabsf(bandwidth - ((point / 1000.0f) + 0.05f)) <= 0.5f) {
float point = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000000.0)/(((4 * m) + 16) * ((uint32_t)1 << (e + 2)));
if(fabsf(bandwidth - ((point / 1000.0) + 0.05)) <= 0.5) {
return((m << 3) | e);
}
}
@ -863,7 +996,7 @@ int16_t SX127x::setRxBandwidth(float rxBw) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
RADIOLIB_CHECK_RANGE(rxBw, 2.6f, 250.0f, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
RADIOLIB_CHECK_RANGE(rxBw, 2.6, 250.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
// set mode to STANDBY
int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
@ -879,7 +1012,7 @@ int16_t SX127x::setAFCBandwidth(float rxBw) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
RADIOLIB_CHECK_RANGE(rxBw, 2.6f, 250.0f, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
RADIOLIB_CHECK_RANGE(rxBw, 2.6, 250.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
// set mode to STANDBY
int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
@ -1118,7 +1251,7 @@ float SX127x::getNumSymbols(size_t len) {
// get Low Data Rate optimization flag
float de = 0;
if (symbolLength >= 16.0f) {
if (symbolLength >= 16.0) {
de = 1;
}
@ -1132,7 +1265,7 @@ float SX127x::getNumSymbols(size_t len) {
float n_pre = (float) ((this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB) << 8) | this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB));
// get number of payload symbols
float n_pay = 8.0f + RADIOLIB_MAX(ceilf((8.0f * (float) len - 4.0f * (float) this->spreadingFactor + 28.0f + 16.0f * crc - 20.0f * ih) / (4.0f * (float) this->spreadingFactor - 8.0f * de)) * (float) this->codingRate, 0.0f);
float n_pay = 8.0 + RADIOLIB_MAX(ceilf((8.0 * (float) len - 4.0 * (float) this->spreadingFactor + 28.0 + 16.0 * crc - 20.0 * ih) / (4.0 * (float) this->spreadingFactor - 8.0 * de)) * (float) this->codingRate, 0.0);
// add 4.25 symbols for the sync
return(n_pre + n_pay + 4.25f);
@ -1168,7 +1301,7 @@ RadioLibTime_t SX127x::getTimeOnAir(size_t len) {
}
// calculate time-on-air in us {[(length in bytes) * (8 bits / 1 byte)] / [(Bit Rate in kbps) * (1000 bps / 1 kbps)]} * (1000000 us in 1 sec)
return((uint32_t) (((crc + n_syncWord + n_pre + (float) (len * 8)) / (this->bitRate * 1000.0f)) * 1000000.0f));
return((uint32_t) (((crc + n_syncWord + n_pre + (float) (len * 8)) / (this->bitRate * 1000.0)) * 1000000.0));
}
return(RADIOLIB_ERR_UNKNOWN);
@ -1315,9 +1448,9 @@ int16_t SX127x::setCrcFiltering(bool enable) {
}
int16_t SX127x::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_SX127X_REG_RSSI_THRESH, (uint8_t)(-2.0f * dbm), 7, 0);
return this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_THRESH, (uint8_t)(-2.0 * dbm), 7, 0);
}
int16_t SX127x::setRSSIConfig(uint8_t smoothingSamples, int8_t offset) {
@ -1643,161 +1776,6 @@ int16_t SX127x::getModem(ModemType_t* modem) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
int16_t SX127x::stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) {
int16_t state;
switch(mode) {
case(RADIOLIB_RADIO_MODE_RX): {
this->rxMode = RADIOLIB_SX127X_RXCONTINUOUS;
// set mode to standby
state = setMode(RADIOLIB_SX127X_STANDBY);
RADIOLIB_ASSERT(state);
// set DIO pin mapping
state = this->setIrqFlags(getIrqMapped(cfg->receive.irqFlags & cfg->receive.irqMask));
RADIOLIB_ASSERT(state);
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_LORA) {
if(cfg->receive.timeout != 0) {
// for non-zero timeout value, change mode to Rx single and set the timeout
this->rxMode = RADIOLIB_SX127X_RXSINGLE;
uint8_t msb_sym = (cfg->receive.timeout > 0x3FF) ? 0x3 : (uint8_t)(cfg->receive.timeout >> 8);
uint8_t lsb_sym = (cfg->receive.timeout > 0x3FF) ? 0xFF : (uint8_t)(cfg->receive.timeout & 0xFF);
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, msb_sym, 1, 0);
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYMB_TIMEOUT_LSB, lsb_sym);
RADIOLIB_ASSERT(state);
}
// in FHSS mode, enable channel change interrupt
if(this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 5, 4);
}
// in implicit header mode, use the provided length if it is nonzero
// otherwise we trust the user has previously set the payload length manually
if((this->implicitHdr) && (cfg->receive.len != 0)) {
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, cfg->receive.len);
this->packetLength = cfg->receive.len;
}
// apply fixes to errata
RADIOLIB_ERRATA_SX127X(true);
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// set FIFO pointers
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_RX_BASE_ADDR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX);
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX);
RADIOLIB_ASSERT(state);
} else if(modem == RADIOLIB_SX127X_FSK_OOK) {
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// FSK modem does not distinguish between Rx single and continuous
this->rxMode = RADIOLIB_SX127X_RX;
}
} break;
case(RADIOLIB_RADIO_MODE_TX): {
// set mode to standby
state = setMode(RADIOLIB_SX127X_STANDBY);
int16_t modem = getActiveModem();
if(modem == RADIOLIB_SX127X_LORA) {
// check packet length
if(cfg->transmit.len > RADIOLIB_SX127X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// set DIO mapping
if(this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE | RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 7, 4);
} else {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE, 7, 6);
}
// apply fixes to errata
RADIOLIB_ERRATA_SX127X(false);
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// set packet length
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, cfg->transmit.len);
// set FIFO pointers
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_TX_BASE_ADDR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX);
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX);
} else if(modem == RADIOLIB_SX127X_FSK_OOK) {
// clear interrupt flags
clearIrqFlags(RADIOLIB_SX127X_FLAGS_ALL);
// set DIO mapping
if(cfg->transmit.len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK) {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_PACK_FIFO_EMPTY, 5, 4);
} else {
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PACKET_SENT, 7, 6);
}
// set packet length - increased by 1 when address filter is enabled
uint8_t filter = this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 2, 1);
if(this->packetLengthConfig == RADIOLIB_SX127X_PACKET_VARIABLE) {
if((filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST)) {
this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, cfg->transmit.len + 1);
this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, cfg->transmit.addr);
} else {
this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, cfg->transmit.len);
}
}
}
// write packet to FIFO
size_t packetLen = cfg->transmit.len;
if((modem == RADIOLIB_SX127X_FSK_OOK) && (cfg->transmit.len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK)) {
packetLen = RADIOLIB_SX127X_FIFO_THRESH - 1;
this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_TX_START_FIFO_NOT_EMPTY, 7, 7);
}
this->mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_FIFO, cfg->transmit.data, packetLen);
} break;
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
this->stagedMode = mode;
return(state);
}
int16_t SX127x::launchMode() {
int16_t state;
switch(this->stagedMode) {
case(RADIOLIB_RADIO_MODE_RX): {
this->mod->setRfSwitchState(Module::MODE_RX);
state = setMode(this->rxMode);
RADIOLIB_ASSERT(state);
} break;
case(RADIOLIB_RADIO_MODE_TX): {
this->mod->setRfSwitchState(Module::MODE_TX);
state = setMode(RADIOLIB_SX127X_TX);
RADIOLIB_ASSERT(state);
} break;
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
this->stagedMode = RADIOLIB_RADIO_MODE_NONE;
return(state);
}
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
void SX127x::setDirectAction(void (*func)(void)) {
setDio1Action(func, this->mod->hal->GpioInterruptRising);
@ -1852,7 +1830,7 @@ float SX127x::getRSSI(bool packet, bool skipReceive, int16_t offset) {
// spread-spectrum modulation signal can be received below noise floor
// check last packet SNR and if it's less than 0, add it to reported RSSI to get the correct value
float lastPacketSNR = SX127x::getSNR();
if(lastPacketSNR < 0.0f) {
if(lastPacketSNR < 0.0) {
lastPacketRSSI += lastPacketSNR;
}
return(lastPacketRSSI);
@ -1872,7 +1850,7 @@ float SX127x::getRSSI(bool packet, bool skipReceive, int16_t offset) {
}
// read the value for FSK
float rssi = (float)this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_RSSI_VALUE_FSK) / -2.0f;
float rssi = (float)this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_RSSI_VALUE_FSK) / -2.0;
// set mode back to standby
if(!skipReceive) {
@ -1891,11 +1869,12 @@ int16_t SX127x::setHeaderType(uint8_t headerType, uint8_t bitIndex, size_t len)
}
// set requested packet mode
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, headerType, bitIndex, bitIndex);
Module* mod = this->getMod();
int16_t state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, headerType, bitIndex, bitIndex);
RADIOLIB_ASSERT(state);
// set length to register
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len);
state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len);
RADIOLIB_ASSERT(state);
// update cached value

View file

@ -13,7 +13,7 @@
#define RADIOLIB_SX127X_FREQUENCY_STEP_SIZE 61.03515625
#define RADIOLIB_SX127X_MAX_PACKET_LENGTH 255
#define RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK 64
#define RADIOLIB_SX127X_CRYSTAL_FREQ 32.0f
#define RADIOLIB_SX127X_CRYSTAL_FREQ 32.0
#define RADIOLIB_SX127X_DIV_EXPONENT 19
// SX127x series common LoRa registers
@ -586,7 +586,6 @@ class SX127x: public PhysicalLayer {
using PhysicalLayer::transmit;
using PhysicalLayer::receive;
using PhysicalLayer::startTransmit;
using PhysicalLayer::startReceive;
using PhysicalLayer::readData;
// constructor
@ -607,7 +606,7 @@ class SX127x: public PhysicalLayer {
\param preambleLength Length of %LoRa transmission preamble in symbols.
\returns \ref status_codes
*/
int16_t begin(const uint8_t* chipVersions, uint8_t numVersions, uint8_t syncWord, uint16_t preambleLength);
int16_t begin(uint8_t* chipVersions, uint8_t numVersions, uint8_t syncWord, uint16_t preambleLength);
/*!
\brief Reset method. Will reset the chip to the default state using RST pin. Declared pure virtual since SX1272 and SX1278 implementations differ.
@ -624,7 +623,7 @@ class SX127x: public PhysicalLayer {
\param enableOOK Flag to specify OOK mode. This modulation is similar to FSK.
\returns \ref status_codes
*/
int16_t beginFSK(const uint8_t* chipVersions, uint8_t numVersions, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK);
int16_t beginFSK(uint8_t* chipVersions, uint8_t numVersions, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK);
/*!
\brief Binary transmit method. Will transmit arbitrary binary data up to 255 bytes long using %LoRa or up to 63 bytes using FSK modem.
@ -799,6 +798,15 @@ class SX127x: public PhysicalLayer {
*/
bool fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen);
/*!
\brief Interrupt-driven binary transmit method. Will start transmitting arbitrary binary data up to 255 bytes long using %LoRa or up to 63 bytes using FSK modem.
\param data Binary data that will be transmitted.
\param len Length of binary data to transmit (in bytes).
\param addr Node address to transmit the packet to. Only used in FSK mode.
\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.
\returns \ref status_codes
@ -812,6 +820,19 @@ class SX127x: public PhysicalLayer {
*/
int16_t startReceive() override;
/*!
\brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer.
\param timeout Receive mode type and/or raw timeout value in symbols.
When set to 0, the timeout will be infinite and the device will remain
in Rx mode until explicitly commanded to stop (Rx continuous mode).
When non-zero (maximum 1023), the device will be set to Rx single mode and timeout will be set.
\param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error.
\param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done.
\param len Expected length of packet to be received. Required for LoRa spreading factor 6.
\returns \ref status_codes
*/
int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0) override;
/*!
\brief Reads data that was received after calling startReceive method. When the packet length is not known in advance,
getPacketLength method must be called BEFORE calling readData!
@ -1143,12 +1164,6 @@ class SX127x: public PhysicalLayer {
*/
int16_t getModem(ModemType_t* modem) override;
/*! \copydoc PhysicalLayer::stageMode */
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) override;
/*! \copydoc PhysicalLayer::launchMode */
int16_t launchMode() override;
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
/*!
\brief Set interrupt service routine function to call when data bit is received in direct mode.
@ -1236,7 +1251,7 @@ class SX127x: public PhysicalLayer {
bool ookEnabled = false;
bool implicitHdr = false;
virtual int16_t configFSK();
int16_t configFSK();
int16_t getActiveModem();
int16_t setFrequencyRaw(float newFreq);
int16_t setBitRateCommon(float br, uint8_t fracRegAddr);
@ -1253,7 +1268,6 @@ class SX127x: public PhysicalLayer {
float dataRate = 0;
bool packetLengthQueried = false; // FSK packet length is the first byte in FIFO, length can only be queried once
uint8_t packetLengthConfig = RADIOLIB_SX127X_PACKET_VARIABLE;
uint8_t rxMode = RADIOLIB_SX127X_RXCONTINUOUS;
int16_t config();
int16_t directMode();

View file

@ -33,7 +33,7 @@ int16_t SX1280::range(bool master, uint32_t addr, uint16_t calTable[3][6]) {
return(state);
}
int16_t SX1280::startRanging(bool master, uint32_t addr, const uint16_t calTable[3][6]) {
int16_t SX1280::startRanging(bool master, uint32_t addr, uint16_t calTable[3][6]) {
// check active modem
uint8_t modem = getPacketType();
if(!((modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) || (modem == RADIOLIB_SX128X_PACKET_TYPE_RANGING))) {
@ -80,7 +80,7 @@ int16_t SX1280::startRanging(bool master, uint32_t addr, const uint16_t calTable
}
// set ranging address
const uint8_t addrBuff[] = { (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF) };
uint8_t addrBuff[] = { (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF) };
state = writeRegister(addrReg, addrBuff, 4);
RADIOLIB_ASSERT(state);
@ -116,7 +116,7 @@ int16_t SX1280::startRanging(bool master, uint32_t addr, const uint16_t calTable
default:
return(RADIOLIB_ERR_INVALID_BANDWIDTH);
}
const uint8_t calBuff[] = { (uint8_t)((val >> 8) & 0xFF), (uint8_t)(val & 0xFF) };
uint8_t calBuff[] = { (uint8_t)((val >> 8) & 0xFF), (uint8_t)(val & 0xFF) };
state = writeRegister(RADIOLIB_SX128X_REG_RANGING_CALIBRATION_MSB, calBuff, 2);
RADIOLIB_ASSERT(state);
@ -178,7 +178,7 @@ float SX1280::getRangingResult() {
// calculate the real result
uint32_t uraw = ((uint32_t)data[0] << 16) | ((uint32_t)data[1] << 8) | data[2];
int32_t raw = (uraw & ((1UL << 23) - 1)) | (uraw >> 23 << 31);
return((float)raw * 150.0f / (4.096f * this->bandwidthKhz));
return((float)raw * 150.0 / (4.096 * this->bandwidthKhz));
}
#endif

View file

@ -37,7 +37,7 @@ class SX1280: public SX1281 {
\param calTable Ranging calibration table - set to NULL to use the default.
\returns \ref status_codes
*/
int16_t startRanging(bool master, uint32_t addr, const uint16_t calTable[3][6] = NULL);
int16_t startRanging(bool master, uint32_t addr, uint16_t calTable[3][6] = NULL);
/*!
\brief Gets ranging result of the last ranging exchange.

View file

@ -2,9 +2,7 @@
#include <math.h>
#if !RADIOLIB_EXCLUDE_SX128X
SX128x::SX128x(Module* mod) : PhysicalLayer() {
this->freqStep = RADIOLIB_SX128X_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_SX128X_MAX_PACKET_LENGTH;
SX128x::SX128x(Module* mod) : PhysicalLayer(RADIOLIB_SX128X_FREQUENCY_STEP_SIZE, RADIOLIB_SX128X_MAX_PACKET_LENGTH) {
this->mod = mod;
this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_SX128X_IRQ_TX_DONE;
this->irqMap[RADIOLIB_IRQ_RX_DONE] = RADIOLIB_SX128X_IRQ_RX_DONE;
@ -366,7 +364,7 @@ int16_t SX128x::receive(uint8_t* data, size_t len) {
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout);
// start reception
uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625f);
uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625);
state = startReceive(timeoutValue);
RADIOLIB_ASSERT(state);
@ -487,7 +485,7 @@ int16_t SX128x::standby(uint8_t mode, bool wakeup) {
(void)this->mod->SPIwriteStream((uint16_t)RADIOLIB_SX128X_CMD_NOP, NULL, 0, false, false);
}
const uint8_t data[] = { mode };
uint8_t data[] = { mode };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_STANDBY, data, 1));
}
@ -515,6 +513,70 @@ void SX128x::clearPacketSentAction() {
this->clearDio1Action();
}
int16_t SX128x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
// suppress unused variable warning
(void)addr;
// check packet length
if(len > RADIOLIB_SX128X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// set packet Length
int16_t state = RADIOLIB_ERR_NONE;
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) {
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, len, this->crcLoRa, this->invertIQEnabled);
} else if((modem == RADIOLIB_SX128X_PACKET_TYPE_GFSK) || (modem == RADIOLIB_SX128X_PACKET_TYPE_FLRC)) {
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, len);
} else if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
state = setPacketParamsBLE(this->connectionState, this->crcBLE, this->bleTestPayload, this->whitening);
} else {
return(RADIOLIB_ERR_WRONG_MODEM);
}
RADIOLIB_ASSERT(state);
// update output power
state = setTxParams(this->power);
RADIOLIB_ASSERT(state);
// set buffer pointers
state = setBufferBaseAddress();
RADIOLIB_ASSERT(state);
// write packet to buffer
if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
// first 2 bytes of BLE payload are PDU header
state = writeBuffer(const_cast<uint8_t*>(data), len, 2);
RADIOLIB_ASSERT(state);
} else {
state = writeBuffer(const_cast<uint8_t*>(data), len);
RADIOLIB_ASSERT(state);
}
// set DIO mapping
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_TX_DONE | RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT, RADIOLIB_SX128X_IRQ_TX_DONE);
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_TX);
// start transmission
state = setTx(RADIOLIB_SX128X_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 SX128x::finishTransmit() {
// clear interrupt flags
clearIrqStatus();
@ -527,6 +589,49 @@ int16_t SX128x::startReceive() {
return(this->startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0));
}
int16_t SX128x::startReceive(uint16_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) {
// in implicit header mode, use the provided length if it is nonzero
// otherwise we trust the user has previously set the payload length manually
if((this->headerType == RADIOLIB_SX128X_LORA_HEADER_IMPLICIT) && (len != 0)) {
this->payloadLen = len;
}
// check active modem
if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
// set DIO mapping
if(timeout != RADIOLIB_SX128X_RX_TIMEOUT_INF) {
irqMask |= (1UL << RADIOLIB_IRQ_TIMEOUT);
}
int16_t state = setDioIrqParams(getIrqMapped(irqFlags), getIrqMapped(irqMask));
RADIOLIB_ASSERT(state);
// set buffer pointers
state = setBufferBaseAddress();
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// set implicit mode and expected len if applicable
if((this->headerType == RADIOLIB_SX128X_LORA_HEADER_IMPLICIT) && (getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_LORA)) {
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa, 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);
}
int16_t SX128x::readData(uint8_t* data, size_t len) {
// check active modem
if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
@ -640,7 +745,7 @@ int16_t SX128x::getChannelScanResult() {
}
int16_t SX128x::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 2400.0f, 2500.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 2400.0, 2500.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// calculate raw value
uint32_t frf = (freq * (uint32_t(1) << RADIOLIB_SX128X_DIV_EXPONENT)) / RADIOLIB_SX128X_CRYSTAL_FREQ;
@ -652,21 +757,21 @@ int16_t SX128x::setBandwidth(float bw) {
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) {
// check range for LoRa
RADIOLIB_CHECK_RANGE(bw, 203.125f, 1625.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
RADIOLIB_CHECK_RANGE(bw, 203.125, 1625.0, RADIOLIB_ERR_INVALID_BANDWIDTH);
} else if(modem == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
// check range for ranging
RADIOLIB_CHECK_RANGE(bw, 406.25f, 1625.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
RADIOLIB_CHECK_RANGE(bw, 406.25, 1625.0, RADIOLIB_ERR_INVALID_BANDWIDTH);
} else {
return(RADIOLIB_ERR_WRONG_MODEM);
}
if(fabsf(bw - 203.125f) <= 0.001f) {
if(fabsf(bw - 203.125) <= 0.001) {
this->bandwidth = RADIOLIB_SX128X_LORA_BW_203_125;
} else if(fabsf(bw - 406.25f) <= 0.001f) {
} else if(fabsf(bw - 406.25) <= 0.001) {
this->bandwidth = RADIOLIB_SX128X_LORA_BW_406_25;
} else if(fabsf(bw - 812.5f) <= 0.001f) {
} else if(fabsf(bw - 812.5) <= 0.001) {
this->bandwidth = RADIOLIB_SX128X_LORA_BW_812_50;
} else if(fabsf(bw - 1625.0f) <= 0.001f) {
} else if(fabsf(bw - 1625.0) <= 0.001) {
this->bandwidth = RADIOLIB_SX128X_LORA_BW_1625_00;
} else {
return(RADIOLIB_ERR_INVALID_BANDWIDTH);
@ -772,7 +877,8 @@ int16_t SX128x::setModem(ModemType_t modem) {
int16_t SX128x::getModem(ModemType_t* modem) {
RADIOLIB_ASSERT_PTR(modem);
switch(getPacketType()) {
uint8_t packetType = getPacketType();
switch(packetType) {
case(RADIOLIB_SX128X_PACKET_TYPE_LORA):
*modem = ModemType_t::RADIOLIB_MODEM_LORA;
return(RADIOLIB_ERR_NONE);
@ -826,7 +932,7 @@ int16_t SX128x::setPreambleLength(uint32_t preambleLength) {
// update packet parameters
this->preambleLengthGFSK = ((preambleLength / 4) - 1) << 4;
return(setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, this->packetType));
return(setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening));
}
return(RADIOLIB_ERR_WRONG_MODEM);
@ -914,21 +1020,21 @@ int16_t SX128x::setFrequencyDeviation(float freqDev) {
// set frequency deviation to lowest available setting (required for digimodes)
float newFreqDev = freqDev;
if(freqDev < 0.0f) {
newFreqDev = 62.5f;
if(freqDev < 0.0) {
newFreqDev = 62.5;
}
RADIOLIB_CHECK_RANGE(newFreqDev, 62.5f, 1000.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
RADIOLIB_CHECK_RANGE(newFreqDev, 62.5, 1000.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
// override for the lowest possible frequency deviation - required for some PhysicalLayer protocols
if(newFreqDev == 0.0f) {
if(newFreqDev == 0.0) {
this->modIndex = RADIOLIB_SX128X_BLE_GFSK_MOD_IND_0_35;
this->bitRate = RADIOLIB_SX128X_BLE_GFSK_BR_0_125_BW_0_3;
return(setModulationParams(this->bitRate, this->modIndex, this->shaping));
}
// update modulation parameters
uint8_t modInd = (uint8_t)((8.0f * (newFreqDev / (float)this->bitRateKbps)) - 1.0f);
uint8_t modInd = (uint8_t)((8.0 * (newFreqDev / (float)this->bitRateKbps)) - 1.0);
if(modInd > RADIOLIB_SX128X_BLE_GFSK_MOD_IND_4_00) {
return(RADIOLIB_ERR_INVALID_MODULATION_PARAMETERS);
}
@ -996,8 +1102,14 @@ int16_t SX128x::setSyncWord(const uint8_t* syncWord, uint8_t len) {
this->syncWordLen = len;
}
// reverse sync word byte order
uint8_t syncWordBuff[] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
for(uint8_t i = 0; i < len; i++) {
syncWordBuff[4 - i] = syncWord[i];
}
// update sync word
int16_t state = SX128x::writeRegister(RADIOLIB_SX128X_REG_SYNC_WORD_1_BYTE_4 + (5 - len), const_cast<uint8_t*>(syncWord), len);
int16_t state = SX128x::writeRegister(RADIOLIB_SX128X_REG_SYNC_WORD_1_BYTE_4, syncWordBuff, 5);
RADIOLIB_ASSERT(state);
// update packet parameters
@ -1007,7 +1119,7 @@ int16_t SX128x::setSyncWord(const uint8_t* syncWord, uint8_t len) {
/// \todo add support for multiple sync words
this->syncWordMatch = RADIOLIB_SX128X_GFSK_FLRC_SYNC_WORD_1;
}
return(setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, this->packetType));
return(setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening));
}
int16_t SX128x::setSyncWord(uint8_t syncWord, uint8_t controlBits) {
@ -1017,7 +1129,7 @@ int16_t SX128x::setSyncWord(uint8_t syncWord, uint8_t controlBits) {
}
// update register
const uint8_t data[2] = {(uint8_t)((syncWord & 0xF0) | ((controlBits & 0xF0) >> 4)), (uint8_t)(((syncWord & 0x0F) << 4) | (controlBits & 0x0F))};
uint8_t data[2] = {(uint8_t)((syncWord & 0xF0) | ((controlBits & 0xF0) >> 4)), (uint8_t)(((syncWord & 0x0F) << 4) | (controlBits & 0x0F))};
return(writeRegister(RADIOLIB_SX128X_REG_LORA_SYNC_WORD_MSB, data, 2));
}
@ -1038,7 +1150,7 @@ int16_t SX128x::setCRC(uint8_t len, uint32_t initial, uint16_t polynomial) {
}
}
this->crcGFSK = len << 4;
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, this->packetType);
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening);
RADIOLIB_ASSERT(state);
// set initial CRC value
@ -1065,7 +1177,7 @@ int16_t SX128x::setCRC(uint8_t len, uint32_t initial, uint16_t polynomial) {
RADIOLIB_ASSERT(state);
// set initial CRC value
const uint8_t data[] = { (uint8_t)((initial >> 16) & 0xFF), (uint8_t)((initial >> 8) & 0xFF), (uint8_t)(initial & 0xFF) };
uint8_t data[] = { (uint8_t)((initial >> 16) & 0xFF), (uint8_t)((initial >> 8) & 0xFF), (uint8_t)(initial & 0xFF) };
state = writeRegister(RADIOLIB_SX128X_REG_BLE_CRC_INITIAL_MSB, data, 3);
return(state);
@ -1100,7 +1212,7 @@ int16_t SX128x::setWhitening(bool enabled) {
}
if(modem == RADIOLIB_SX128X_PACKET_TYPE_GFSK) {
return(setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, this->packetType));
return(setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening));
}
return(setPacketParamsBLE(this->connectionState, this->crcBLE, this->bleTestPayload, this->whitening));
}
@ -1112,7 +1224,7 @@ int16_t SX128x::setAccessAddress(uint32_t addr) {
}
// set the address
const uint8_t addrBuff[] = { (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF) };
uint8_t addrBuff[] = { (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF) };
return(SX128x::writeRegister(RADIOLIB_SX128X_REG_ACCESS_ADDRESS_BYTE_3, addrBuff, 4));
}
@ -1181,7 +1293,7 @@ float SX128x::getRSSI() {
uint8_t rssiSync = packetStatus[0];
float rssiMeasured = -1.0 * rssiSync/2.0;
float snr = getSNR();
if(snr <= 0.0f) {
if(snr <= 0.0) {
return(rssiMeasured - snr);
} else {
return(rssiMeasured);
@ -1198,7 +1310,7 @@ float SX128x::getRSSI(bool packet) {
// get instantaneous RSSI value
uint8_t data[3] = {0, 0, 0}; // RssiInst, Status, RFU
this->mod->SPIreadStream(RADIOLIB_SX128X_CMD_GET_RSSI_INST, data, 3);
return ((float)data[0] / (-2.0f));
return ((float)data[0] / (-2.0));
} else {
return this->getRSSI();
}
@ -1220,7 +1332,7 @@ float SX128x::getSNR() {
if(snr < 128) {
return(snr/4.0);
} else {
return((snr - 256)/4.0f);
return((snr - 256)/4.0);
}
}
@ -1249,9 +1361,9 @@ float SX128x::getFrequencyError() {
// frequency error is negative
efe |= (uint32_t) 0xFFF00000;
efe = ~efe + 1;
error = 1.55f * (float) efe / (1600.0f / this->bandwidthKhz) * -1.0f;
error = 1.55 * (float) efe / (1600.0 / (float) this->bandwidthKhz) * -1.0;
} else {
error = 1.55f * (float) efe / (1600.0f / this->bandwidthKhz);
error = 1.55 * (float) efe / (1600.0 / (float) this->bandwidthKhz);
}
return(error);
@ -1277,14 +1389,6 @@ size_t SX128x::getPacketLength(bool update, uint8_t* offset) {
return((size_t)rxBufStatus[0]);
}
int16_t SX128x::fixedPacketLengthMode(uint8_t len) {
return(setPacketMode(RADIOLIB_SX128X_GFSK_FLRC_PACKET_FIXED, len));
}
int16_t SX128x::variablePacketLengthMode(uint8_t maxLen) {
return(setPacketMode(RADIOLIB_SX128X_GFSK_FLRC_PACKET_VARIABLE, maxLen));
}
RadioLibTime_t SX128x::getTimeOnAir(size_t len) {
// check active modem
uint8_t modem = getPacketType();
@ -1332,7 +1436,7 @@ RadioLibTime_t SX128x::getTimeOnAir(size_t len) {
uint32_t N_symbolPreamble = (this->preambleLengthLoRa & 0x0F) * (uint32_t(1) << ((this->preambleLengthLoRa & 0xF0) >> 4));
// 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->codingRateLoRa + 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->codingRateLoRa + 4);
} else {
// long interleaving - abandon hope all ye who enter here
@ -1341,7 +1445,7 @@ RadioLibTime_t SX128x::getTimeOnAir(size_t len) {
}
// get time-on-air in us
return(((uint32_t(1) << sf) / this->bandwidthKhz) * N_symbol * 1000.0f);
return(((uint32_t(1) << sf) / this->bandwidthKhz) * N_symbol * 1000.0);
} else {
return(((uint32_t)len * 8 * 1000) / this->bitRateKbps);
@ -1389,128 +1493,6 @@ int16_t SX128x::invertIQ(bool enable) {
return(setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa, this->invertIQEnabled));
}
int16_t SX128x::stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) {
int16_t state;
switch(mode) {
case(RADIOLIB_RADIO_MODE_RX): {
// in implicit header mode, use the provided length if it is nonzero
// otherwise we trust the user has previously set the payload length manually
if((this->headerType == RADIOLIB_SX128X_LORA_HEADER_IMPLICIT) && (cfg->receive.len != 0)) {
this->payloadLen = cfg->receive.len;
}
// check active modem
if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
// set DIO mapping
if(cfg->receive.timeout != RADIOLIB_SX128X_RX_TIMEOUT_INF) {
cfg->receive.irqMask |= (1UL << RADIOLIB_IRQ_TIMEOUT);
}
state = setDioIrqParams(getIrqMapped(cfg->receive.irqFlags), getIrqMapped(cfg->receive.irqMask));
RADIOLIB_ASSERT(state);
// set buffer pointers
state = setBufferBaseAddress();
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// set implicit mode and expected len if applicable
if((this->headerType == RADIOLIB_SX128X_LORA_HEADER_IMPLICIT) && (getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_LORA)) {
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa, this->invertIQEnabled);
RADIOLIB_ASSERT(state);
}
this->rxTimeout = cfg->receive.timeout;
} break;
case(RADIOLIB_RADIO_MODE_TX): {
// check packet length
if(cfg->transmit.len > RADIOLIB_SX128X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// set packet Length
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) {
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, cfg->transmit.len, this->crcLoRa, this->invertIQEnabled);
} else if((modem == RADIOLIB_SX128X_PACKET_TYPE_GFSK) || (modem == RADIOLIB_SX128X_PACKET_TYPE_FLRC)) {
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, this->packetType, cfg->transmit.len);
} else if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
state = setPacketParamsBLE(this->connectionState, this->crcBLE, this->bleTestPayload, this->whitening);
} else {
return(RADIOLIB_ERR_WRONG_MODEM);
}
RADIOLIB_ASSERT(state);
// update output power
state = setTxParams(this->power);
RADIOLIB_ASSERT(state);
// set buffer pointers
state = setBufferBaseAddress();
RADIOLIB_ASSERT(state);
// write packet to buffer
if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
// first 2 bytes of BLE payload are PDU header
state = writeBuffer(cfg->transmit.data, cfg->transmit.len, 2);
RADIOLIB_ASSERT(state);
} else {
state = writeBuffer(cfg->transmit.data, cfg->transmit.len);
RADIOLIB_ASSERT(state);
}
// set DIO mapping
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_TX_DONE | RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT, RADIOLIB_SX128X_IRQ_TX_DONE);
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
} break;
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
this->stagedMode = mode;
return(state);
}
int16_t SX128x::launchMode() {
int16_t state;
switch(this->stagedMode) {
case(RADIOLIB_RADIO_MODE_RX): {
this->mod->setRfSwitchState(Module::MODE_RX);
state = setRx(this->rxTimeout);
RADIOLIB_ASSERT(state);
} break;
case(RADIOLIB_RADIO_MODE_TX): {
this->mod->setRfSwitchState(Module::MODE_TX);
state = setTx(RADIOLIB_SX128X_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);
}
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
void SX128x::setDirectAction(void (*func)(void)) {
// SX128x is unable to perform direct mode reception
@ -1535,7 +1517,7 @@ uint8_t SX128x::getStatus() {
return(data);
}
int16_t SX128x::writeRegister(uint16_t addr, const uint8_t* data, uint8_t numBytes) {
int16_t SX128x::writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
this->mod->SPIwriteRegisterBurst(addr, data, numBytes);
return(RADIOLIB_ERR_NONE);
}
@ -1549,23 +1531,23 @@ int16_t SX128x::readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
return(state);
}
int16_t SX128x::writeBuffer(const uint8_t* data, uint8_t numBytes, uint8_t offset) {
const uint8_t cmd[] = { RADIOLIB_SX128X_CMD_WRITE_BUFFER, offset };
int16_t SX128x::writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset) {
uint8_t cmd[] = { RADIOLIB_SX128X_CMD_WRITE_BUFFER, offset };
return(this->mod->SPIwriteStream(cmd, 2, data, numBytes));
}
int16_t SX128x::readBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset) {
const uint8_t cmd[] = { RADIOLIB_SX128X_CMD_READ_BUFFER, offset };
uint8_t cmd[] = { RADIOLIB_SX128X_CMD_READ_BUFFER, offset };
return(this->mod->SPIreadStream(cmd, 2, data, numBytes));
}
int16_t SX128x::setTx(uint16_t periodBaseCount, uint8_t periodBase) {
const uint8_t data[] = { periodBase, (uint8_t)((periodBaseCount >> 8) & 0xFF), (uint8_t)(periodBaseCount & 0xFF) };
uint8_t data[] = { periodBase, (uint8_t)((periodBaseCount >> 8) & 0xFF), (uint8_t)(periodBaseCount & 0xFF) };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_TX, data, 3));
}
int16_t SX128x::setRx(uint16_t periodBaseCount, uint8_t periodBase) {
const uint8_t data[] = { periodBase, (uint8_t)((periodBaseCount >> 8) & 0xFF), (uint8_t)(periodBaseCount & 0xFF) };
uint8_t data[] = { periodBase, (uint8_t)((periodBaseCount >> 8) & 0xFF), (uint8_t)(periodBaseCount & 0xFF) };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_RX, data, 3));
}
@ -1585,42 +1567,42 @@ uint8_t SX128x::getPacketType() {
}
int16_t SX128x::setRfFrequency(uint32_t frf) {
const uint8_t data[] = { (uint8_t)((frf >> 16) & 0xFF), (uint8_t)((frf >> 8) & 0xFF), (uint8_t)(frf & 0xFF) };
uint8_t data[] = { (uint8_t)((frf >> 16) & 0xFF), (uint8_t)((frf >> 8) & 0xFF), (uint8_t)(frf & 0xFF) };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_RF_FREQUENCY, data, 3));
}
int16_t SX128x::setTxParams(uint8_t pwr, uint8_t rampTime) {
const uint8_t data[] = { pwr, rampTime };
uint8_t data[] = { pwr, rampTime };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_TX_PARAMS, data, 2));
}
int16_t SX128x::setBufferBaseAddress(uint8_t txBaseAddress, uint8_t rxBaseAddress) {
const uint8_t data[] = { txBaseAddress, rxBaseAddress };
uint8_t data[] = { txBaseAddress, rxBaseAddress };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_BUFFER_BASE_ADDRESS, data, 2));
}
int16_t SX128x::setModulationParams(uint8_t modParam1, uint8_t modParam2, uint8_t modParam3) {
const uint8_t data[] = { modParam1, modParam2, modParam3 };
uint8_t data[] = { modParam1, modParam2, modParam3 };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_MODULATION_PARAMS, data, 3));
}
int16_t SX128x::setPacketParamsGFSK(uint8_t preambleLen, uint8_t syncLen, uint8_t syncMatch, uint8_t crcLen, uint8_t whiten, uint8_t hdrType, uint8_t payLen) {
const uint8_t data[] = { preambleLen, syncLen, syncMatch, hdrType, payLen, crcLen, whiten };
int16_t SX128x::setPacketParamsGFSK(uint8_t preambleLen, uint8_t syncLen, uint8_t syncMatch, uint8_t crcLen, uint8_t whiten, uint8_t payLen, uint8_t hdrType) {
uint8_t data[] = { preambleLen, syncLen, syncMatch, hdrType, payLen, crcLen, whiten };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_PACKET_PARAMS, data, 7));
}
int16_t SX128x::setPacketParamsBLE(uint8_t connState, uint8_t crcLen, uint8_t bleTest, uint8_t whiten) {
const uint8_t data[] = { connState, crcLen, bleTest, whiten, 0x00, 0x00, 0x00 };
uint8_t data[] = { connState, crcLen, bleTest, whiten, 0x00, 0x00, 0x00 };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_PACKET_PARAMS, data, 7));
}
int16_t SX128x::setPacketParamsLoRa(uint8_t preambleLen, uint8_t hdrType, uint8_t payLen, uint8_t crc, uint8_t invIQ) {
const uint8_t data[] = { preambleLen, hdrType, payLen, crc, invIQ, 0x00, 0x00 };
uint8_t data[] = { preambleLen, hdrType, payLen, crc, invIQ, 0x00, 0x00 };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_PACKET_PARAMS, data, 7));
}
int16_t SX128x::setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask) {
const uint8_t data[] = { (uint8_t)((irqMask >> 8) & 0xFF), (uint8_t)(irqMask & 0xFF),
uint8_t data[] = { (uint8_t)((irqMask >> 8) & 0xFF), (uint8_t)(irqMask & 0xFF),
(uint8_t)((dio1Mask >> 8) & 0xFF), (uint8_t)(dio1Mask & 0xFF),
(uint8_t)((dio2Mask >> 8) & 0xFF), (uint8_t)(dio2Mask & 0xFF),
(uint8_t)((dio3Mask >> 8) & 0xFF), (uint8_t)(dio3Mask & 0xFF) };
@ -1634,35 +1616,20 @@ uint16_t SX128x::getIrqStatus() {
}
int16_t SX128x::clearIrqStatus(uint16_t clearIrqParams) {
const uint8_t data[] = { (uint8_t)((clearIrqParams >> 8) & 0xFF), (uint8_t)(clearIrqParams & 0xFF) };
uint8_t data[] = { (uint8_t)((clearIrqParams >> 8) & 0xFF), (uint8_t)(clearIrqParams & 0xFF) };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_CLEAR_IRQ_STATUS, data, 2));
}
int16_t SX128x::setRangingRole(uint8_t role) {
const uint8_t data[] = { role };
uint8_t data[] = { role };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_RANGING_ROLE, data, 1));
}
int16_t SX128x::setPacketType(uint8_t type) {
const uint8_t data[] = { type };
uint8_t data[] = { type };
return(this->mod->SPIwriteStream(RADIOLIB_SX128X_CMD_SET_PACKET_TYPE, data, 1));
}
int16_t SX128x::setPacketMode(uint8_t mode, uint8_t len) {
// check active modem
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_GFSK) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
// set requested packet mode
int16_t state = setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, mode, len);
RADIOLIB_ASSERT(state);
// update cached value
this->packetType = mode;
return(state);
}
int16_t SX128x::setHeaderType(uint8_t hdrType, size_t len) {
// check active modem
uint8_t modem = getPacketType();

View file

@ -12,7 +12,7 @@
// SX128X physical layer properties
#define RADIOLIB_SX128X_FREQUENCY_STEP_SIZE 198.3642578
#define RADIOLIB_SX128X_MAX_PACKET_LENGTH 255
#define RADIOLIB_SX128X_CRYSTAL_FREQ 52.0f
#define RADIOLIB_SX128X_CRYSTAL_FREQ 52.0
#define RADIOLIB_SX128X_DIV_EXPONENT 18
// SX128X SPI commands
@ -354,7 +354,6 @@ class SX128x: public PhysicalLayer {
using PhysicalLayer::transmit;
using PhysicalLayer::receive;
using PhysicalLayer::startTransmit;
using PhysicalLayer::startReceive;
using PhysicalLayer::readData;
/*!
@ -531,6 +530,16 @@ class SX128x: public PhysicalLayer {
*/
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. Unsupported, compatibility only.
\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.
\returns \ref status_codes
@ -545,6 +554,20 @@ class SX128x: public PhysicalLayer {
*/
int16_t startReceive() override;
/*!
\brief Interrupt-driven receive method. DIO1 will be activated when full packet is received.
\param timeout Raw timeout value, expressed as multiples of 15.625 us. Defaults to
RADIOLIB_SX128X_RX_TIMEOUT_INF for infinite timeout (Rx continuous mode),
set to RADIOLIB_SX128X_RX_TIMEOUT_NONE for no timeout (Rx single mode).
If timeout other than infinite is set, signal will be generated on DIO1.
\param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error.
\param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done.
\param len Only for PhysicalLayer compatibility, not used.
\returns \ref status_codes
*/
int16_t startReceive(uint16_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0);
/*!
\brief Reads the current IRQ status.
\returns IRQ status bits
@ -795,20 +818,6 @@ class SX128x: public PhysicalLayer {
*/
size_t getPacketLength(bool update, uint8_t* offset);
/*!
\brief Set modem in fixed packet length mode. Available in GFSK mode only.
\param len Packet length.
\returns \ref status_codes
*/
int16_t fixedPacketLengthMode(uint8_t len = RADIOLIB_SX128X_MAX_PACKET_LENGTH);
/*!
\brief Set modem in variable packet length mode. Available in GFSK mode only.
\param maxLen Maximum packet length.
\returns \ref status_codes
*/
int16_t variablePacketLengthMode(uint8_t maxLen = RADIOLIB_SX128X_MAX_PACKET_LENGTH);
/*!
\brief Get expected time-on-air for a given size of payload.
\param len Payload length in bytes.
@ -855,12 +864,6 @@ class SX128x: public PhysicalLayer {
*/
int16_t invertIQ(bool enable) override;
/*! \copydoc PhysicalLayer::stageMode */
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) override;
/*! \copydoc PhysicalLayer::launchMode */
int16_t launchMode() override;
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
/*!
\brief Dummy method, to ensure PhysicalLayer compatibility.
@ -887,9 +890,9 @@ class SX128x: public PhysicalLayer {
// SX128x SPI command implementations
uint8_t getStatus();
int16_t writeRegister(uint16_t addr, const uint8_t* data, uint8_t numBytes);
int16_t writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);
int16_t readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);
int16_t writeBuffer(const uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00);
int16_t writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00);
int16_t readBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset = 0x00);
int16_t setTx(uint16_t periodBaseCount = RADIOLIB_SX128X_TX_TIMEOUT_NONE, uint8_t periodBase = RADIOLIB_SX128X_PERIOD_BASE_15_625_US);
int16_t setRx(uint16_t periodBaseCount, uint8_t periodBase = RADIOLIB_SX128X_PERIOD_BASE_15_625_US);
@ -899,7 +902,7 @@ class SX128x: public PhysicalLayer {
int16_t setTxParams(uint8_t pwr, uint8_t rampTime = RADIOLIB_SX128X_PA_RAMP_10_US);
int16_t setBufferBaseAddress(uint8_t txBaseAddress = 0x00, uint8_t rxBaseAddress = 0x00);
int16_t setModulationParams(uint8_t modParam1, uint8_t modParam2, uint8_t modParam3);
int16_t setPacketParamsGFSK(uint8_t preambleLen, uint8_t syncLen, uint8_t syncMatch, uint8_t crcLen, uint8_t whiten, uint8_t hdrType, uint8_t payLen = 0xFF);
int16_t setPacketParamsGFSK(uint8_t preambleLen, uint8_t syncLen, uint8_t syncMatch, uint8_t crcLen, uint8_t whiten, uint8_t payLen = 0xFF, uint8_t hdrType = RADIOLIB_SX128X_GFSK_FLRC_PACKET_VARIABLE);
int16_t setPacketParamsBLE(uint8_t connState, uint8_t crcLen, uint8_t bleTest, uint8_t whiten);
int16_t setPacketParamsLoRa(uint8_t preambleLen, uint8_t hdrType, uint8_t payLen, uint8_t crc, uint8_t invIQ = RADIOLIB_SX128X_LORA_IQ_STANDARD);
int16_t setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask = RADIOLIB_SX128X_IRQ_NONE, uint16_t dio3Mask = RADIOLIB_SX128X_IRQ_NONE);
@ -917,7 +920,6 @@ class SX128x: public PhysicalLayer {
// common parameters
uint8_t power = 0;
uint32_t rxTimeout = 0;
// cached LoRa parameters
uint8_t invertIQEnabled = RADIOLIB_SX128X_LORA_IQ_STANDARD;
@ -927,7 +929,6 @@ class SX128x: public PhysicalLayer {
uint16_t bitRateKbps = 0;
uint8_t bitRate = 0, modIndex = 0, shaping = 0;
uint8_t preambleLengthGFSK = 0, syncWordLen = 0, syncWordMatch = 0, crcGFSK = 0, whitening = 0;
uint8_t packetType = RADIOLIB_SX128X_GFSK_FLRC_PACKET_VARIABLE;
// cached FLRC parameters
uint8_t codingRateFLRC = 0;
@ -936,7 +937,6 @@ class SX128x: public PhysicalLayer {
uint8_t connectionState = 0, crcBLE = 0, bleTestPayload = 0;
int16_t config(uint8_t modem);
int16_t setPacketMode(uint8_t mode, uint8_t len);
int16_t setHeaderType(uint8_t hdrType, size_t len = 0xFF);
};

View file

@ -22,7 +22,7 @@ int16_t Si4430::begin(float freq, float br, float freqDev, float rxBw, int8_t po
}
int16_t Si4430::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 900.0f, 960.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 900.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// set frequency
return(Si443x::setFrequencyRaw(freq));

View file

@ -35,7 +35,7 @@ class Si4430: public Si4432 {
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
\returns \ref status_codes
*/
int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 181.1, 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 = 181.1, int8_t power = 10, uint8_t preambleLen = 16);
// configuration methods

View file

@ -35,7 +35,7 @@ class Si4431: public Si4432 {
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
\returns \ref status_codes
*/
int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 181.1, 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 = 181.1, int8_t power = 10, uint8_t preambleLen = 16);
// configuration methods

View file

@ -22,7 +22,7 @@ int16_t Si4432::begin(float freq, float br, float freqDev, float rxBw, int8_t po
}
int16_t Si4432::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 240.0f, 930.0f, RADIOLIB_ERR_INVALID_FREQUENCY);
RADIOLIB_CHECK_RANGE(freq, 240.0, 930.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// set frequency
return(Si443x::setFrequencyRaw(freq));

View file

@ -35,7 +35,7 @@ class Si4432: public Si443x {
\param preambleLen Preamble Length in bits. Defaults to 16 bits.
\returns \ref status_codes
*/
virtual int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 181.1, 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 = 181.1, int8_t power = 10, uint8_t preambleLen = 16);
// configuration methods

View file

@ -2,9 +2,7 @@
#include <math.h>
#if !RADIOLIB_EXCLUDE_SI443X
Si443x::Si443x(Module* mod) : PhysicalLayer() {
this->freqStep = RADIOLIB_SI443X_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_SI443X_MAX_PACKET_LENGTH;
Si443x::Si443x(Module* mod) : PhysicalLayer(RADIOLIB_SI443X_FREQUENCY_STEP_SIZE, RADIOLIB_SI443X_MAX_PACKET_LENGTH) {
this->mod = mod;
}
@ -28,7 +26,7 @@ int16_t Si443x::begin(float br, float freqDev, float rxBw, uint8_t preambleLen)
this->mod->SPIwriteRegister(RADIOLIB_SI443X_REG_OP_FUNC_CONTROL_1, RADIOLIB_SI443X_SOFTWARE_RESET);
// clear POR interrupt
clearIrqStatus();
clearIRQFlags();
// configure settings not accessible by API
int16_t state = config();
@ -54,13 +52,10 @@ int16_t Si443x::begin(float br, float freqDev, float rxBw, uint8_t preambleLen)
state = packetMode();
RADIOLIB_ASSERT(state);
state = setDataShaping(RADIOLIB_SHAPING_NONE);
state = setDataShaping(0);
RADIOLIB_ASSERT(state);
state = setEncoding(RADIOLIB_ENCODING_NRZ);
RADIOLIB_ASSERT(state);
state = setCRC(true);
state = setEncoding(0);
RADIOLIB_ASSERT(state);
state = variablePacketLengthMode();
@ -99,7 +94,7 @@ int16_t Si443x::transmit(const uint8_t* data, size_t len, uint8_t addr) {
int16_t Si443x::receive(uint8_t* data, size_t len) {
// calculate timeout (500 ms + 400 full 64-byte packets at current bit rate)
RadioLibTime_t timeout = 500 + (1.0f/(this->bitRate))*(RADIOLIB_SI443X_MAX_PACKET_LENGTH*400.0f);
RadioLibTime_t timeout = 500 + (1.0/(this->bitRate))*(RADIOLIB_SI443X_MAX_PACKET_LENGTH*400.0);
// start reception
int16_t state = startReceive();
@ -110,7 +105,7 @@ int16_t Si443x::receive(uint8_t* data, size_t len) {
while(this->mod->hal->digitalRead(this->mod->getIrq())) {
if(this->mod->hal->millis() - start > timeout) {
standby();
clearIrqStatus();
clearIRQFlags();
return(RADIOLIB_ERR_RX_TIMEOUT);
}
}
@ -158,7 +153,7 @@ int16_t Si443x::transmitDirect(uint32_t frf) {
// check high/low band
uint8_t bandSelect = RADIOLIB_SI443X_BAND_SELECT_LOW;
uint8_t freqBand = (newFreq / 10) - 24;
if(newFreq >= 480.0f) {
if(newFreq >= 480.0) {
bandSelect = RADIOLIB_SI443X_BAND_SELECT_HIGH;
freqBand = (newFreq / 20) - 24;
}
@ -246,7 +241,7 @@ int16_t Si443x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_OP_FUNC_CONTROL_2, RADIOLIB_SI443X_TX_FIFO_CLEAR, 0, 0);
// clear interrupt flags
clearIrqStatus();
clearIRQFlags();
// set packet length
if (this->packetLengthConfig == RADIOLIB_SI443X_FIXED_PACKET_LENGTH_OFF) {
@ -274,7 +269,7 @@ int16_t Si443x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
int16_t Si443x::finishTransmit() {
// clear interrupt flags
clearIrqStatus();
clearIRQFlags();
// set mode to standby to disable transmitter/RF switch
return(standby());
@ -290,14 +285,13 @@ int16_t Si443x::startReceive() {
this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_OP_FUNC_CONTROL_2, RADIOLIB_SI443X_RX_FIFO_CLEAR, 1, 1);
// clear interrupt flags
clearIrqStatus();
clearIRQFlags();
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_RX);
// set interrupt mapping
uint8_t irq = this->crcEnabled ? (RADIOLIB_SI443X_VALID_PACKET_RECEIVED_ENABLED | RADIOLIB_SI443X_CRC_ERROR_ENABLED) : RADIOLIB_SI443X_VALID_PACKET_RECEIVED_ENABLED;
this->mod->SPIwriteRegister(RADIOLIB_SI443X_REG_INTERRUPT_ENABLE_1, irq);
this->mod->SPIwriteRegister(RADIOLIB_SI443X_REG_INTERRUPT_ENABLE_1, RADIOLIB_SI443X_VALID_PACKET_RECEIVED_ENABLED | RADIOLIB_SI443X_CRC_ERROR_ENABLED);
this->mod->SPIwriteRegister(RADIOLIB_SI443X_REG_INTERRUPT_ENABLE_2, 0x00);
// set mode to receive
@ -315,15 +309,8 @@ int16_t Si443x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMa
}
int16_t Si443x::readData(uint8_t* data, size_t len) {
// read interrupt flags
uint32_t irq = getIrqFlags();
// check integrity CRC
// Si443x does not have the option to keep the data after CRC failed
// reading the FIFO will just repeat the first byte (see https://github.com/jgromes/RadioLib/issues/1430)
if(irq & RADIOLIB_SI443X_CRC_ERROR_INTERRUPT) {
return(RADIOLIB_ERR_CRC_MISMATCH);
}
// clear interrupt flags
clearIRQFlags();
// get packet length
size_t length = getPacketLength();
@ -350,25 +337,25 @@ int16_t Si443x::readData(uint8_t* data, size_t len) {
RADIOLIB_ASSERT(state);
// clear interrupt flags
clearIrqStatus();
clearIRQFlags();
return(RADIOLIB_ERR_NONE);
}
int16_t Si443x::setBitRate(float br) {
RADIOLIB_CHECK_RANGE(br, 0.123f, 256.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
RADIOLIB_CHECK_RANGE(br, 0.123, 256.0, RADIOLIB_ERR_INVALID_BIT_RATE);
// check high data rate
uint8_t dataRateMode = RADIOLIB_SI443X_LOW_DATA_RATE_MODE;
uint8_t exp = 21;
if(br >= 30.0f) {
if(br >= 30.0) {
// bit rate above 30 kbps
dataRateMode = RADIOLIB_SI443X_HIGH_DATA_RATE_MODE;
exp = 16;
}
// calculate raw data rate value
uint16_t txDr = (br * ((uint32_t)1 << exp)) / 1000.0f;
uint16_t txDr = (br * ((uint32_t)1 << exp)) / 1000.0;
// update registers
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, dataRateMode, 5, 5);
@ -389,14 +376,14 @@ int16_t Si443x::setBitRate(float br) {
int16_t Si443x::setFrequencyDeviation(float freqDev) {
// set frequency deviation to lowest available setting (required for digimodes)
float newFreqDev = freqDev;
if(freqDev < 0.0f) {
newFreqDev = 0.625f;
if(freqDev < 0.0) {
newFreqDev = 0.625;
}
RADIOLIB_CHECK_RANGE(newFreqDev, 0.625f, 320.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
RADIOLIB_CHECK_RANGE(newFreqDev, 0.625, 320.0, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
// calculate raw frequency deviation value
uint16_t fdev = (uint16_t)(newFreqDev / 0.625f);
uint16_t fdev = (uint16_t)(newFreqDev / 0.625);
// update registers
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_2, (uint8_t)((fdev & 0x0100) >> 6), 2, 2);
@ -410,7 +397,7 @@ int16_t Si443x::setFrequencyDeviation(float freqDev) {
}
int16_t Si443x::setRxBandwidth(float rxBw) {
RADIOLIB_CHECK_RANGE(rxBw, 2.6f, 620.7f, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
RADIOLIB_CHECK_RANGE(rxBw, 2.6, 620.7, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
// decide which approximation to use for decimation rate and filter tap calculation
uint8_t bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_OFF;
@ -418,84 +405,84 @@ int16_t Si443x::setRxBandwidth(float rxBw) {
uint8_t filterSet = RADIOLIB_SI443X_IF_FILTER_COEFF_SET;
// this is the "well-behaved" section - can be linearly approximated
if((rxBw >= 2.6f) && (rxBw <= 4.5f)) {
if((rxBw >= 2.6) && (rxBw <= 4.5)) {
decRate = 5;
filterSet = ((rxBw - 2.1429f)/0.3250f + 0.5f);
} else if((rxBw > 4.5f) && (rxBw <= 8.8f)) {
filterSet = ((rxBw - 2.1429)/0.3250 + 0.5);
} else if((rxBw > 4.5) && (rxBw <= 8.8)) {
decRate = 4;
filterSet = ((rxBw - 3.9857f)/0.6643f + 0.5f);
} else if((rxBw > 8.8f) && (rxBw <= 17.5f)) {
filterSet = ((rxBw - 3.9857)/0.6643 + 0.5);
} else if((rxBw > 8.8) && (rxBw <= 17.5)) {
decRate = 3;
filterSet = ((rxBw - 7.6714f)/1.3536f + 0.5f);
} else if((rxBw > 17.5f) && (rxBw <= 34.7f)) {
filterSet = ((rxBw - 7.6714)/1.3536 + 0.5);
} else if((rxBw > 17.5) && (rxBw <= 34.7)) {
decRate = 2;
filterSet = ((rxBw - 15.2000f)/2.6893f + 0.5f);
} else if((rxBw > 34.7f) && (rxBw <= 69.2f)) {
filterSet = ((rxBw - 15.2000)/2.6893 + 0.5);
} else if((rxBw > 34.7) && (rxBw <= 69.2)) {
decRate = 1;
filterSet = ((rxBw - 30.2430f)/5.3679f + 0.5f);
} else if((rxBw > 69.2f) && (rxBw <= 137.9f)) {
filterSet = ((rxBw - 30.2430)/5.3679 + 0.5);
} else if((rxBw > 69.2) && (rxBw <= 137.9)) {
decRate = 0;
filterSet = ((rxBw - 60.286f)/10.7000f + 0.5f);
filterSet = ((rxBw - 60.286)/10.7000 + 0.5);
// this is the "Lord help thee who tread 'ere" section - no way to approximate this mess
/// \todo float tolerance equality as macro?
} else if(fabsf(rxBw - 142.8f) <= 0.001f) {
} else if(fabsf(rxBw - 142.8) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 1;
filterSet = 4;
} else if(fabsf(rxBw - 167.8f) <= 0.001f) {
} else if(fabsf(rxBw - 167.8) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 1;
filterSet = 5;
} else if(fabsf(rxBw - 181.1f) <= 0.001f) {
} else if(fabsf(rxBw - 181.1) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 1;
filterSet = 6;
} else if(fabsf(rxBw - 191.5f) <= 0.001f) {
} else if(fabsf(rxBw - 191.5) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 15;
} else if(fabsf(rxBw - 225.1f) <= 0.001f) {
} else if(fabsf(rxBw - 225.1) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 1;
} else if(fabsf(rxBw - 248.8f) <= 0.001f) {
} else if(fabsf(rxBw - 248.8) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 2;
} else if(fabsf(rxBw - 269.3f) <= 0.001f) {
} else if(fabsf(rxBw - 269.3) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 3;
} else if(fabsf(rxBw - 284.8f) <= 0.001f) {
} else if(fabsf(rxBw - 284.8) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 4;
} else if(fabsf(rxBw -335.5f) <= 0.001f) {
} else if(fabsf(rxBw -335.5) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 8;
} else if(fabsf(rxBw - 391.8f) <= 0.001f) {
} else if(fabsf(rxBw - 391.8) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 9;
} else if(fabsf(rxBw - 420.2f) <= 0.001f) {
} else if(fabsf(rxBw - 420.2) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 10;
} else if(fabsf(rxBw - 468.4f) <= 0.001f) {
} else if(fabsf(rxBw - 468.4) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 11;
} else if(fabsf(rxBw - 518.8f) <= 0.001f) {
} else if(fabsf(rxBw - 518.8) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 12;
} else if(fabsf(rxBw - 577.0f) <= 0.001f) {
} else if(fabsf(rxBw - 577.0) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 13;
} else if(fabsf(rxBw - 620.7f) <= 0.001f) {
} else if(fabsf(rxBw - 620.7) <= 0.001) {
bypass = RADIOLIB_SI443X_BYPASS_DEC_BY_3_ON;
decRate = 0;
filterSet = 14;
@ -646,25 +633,6 @@ int16_t Si443x::variablePacketLengthMode(uint8_t maxLen) {
return(Si443x::setPacketMode(RADIOLIB_SI443X_FIXED_PACKET_LENGTH_OFF, maxLen));
}
uint32_t Si443x::getIrqFlags() {
uint8_t data[] = { 0x00, 0x00 };
this->mod->SPIreadRegisterBurst(RADIOLIB_SI443X_REG_INTERRUPT_STATUS_1, 2, data);
return(((uint32_t)(data[0]) << 8) | data[1]);
}
int16_t Si443x::clearIrqFlags(uint32_t irq) {
(void)irq;
(void)getIrqFlags();
return(RADIOLIB_ERR_NONE);
}
int16_t Si443x::setCRC(bool enable, bool mode) {
this->crcEnabled = enable;
uint8_t crcEn = enable ? RADIOLIB_SI443X_CRC_ON : RADIOLIB_SI443X_CRC_OFF;
uint8_t crcCfg = mode ? RADIOLIB_SI443X_CRC_IBM_CRC16 : RADIOLIB_SI443X_CRC_CCITT;
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_DATA_ACCESS_CONTROL, crcEn | crcCfg, 2, 0));
}
Module* Si443x::getMod() {
return(this->mod);
}
@ -679,7 +647,7 @@ int16_t Si443x::setFrequencyRaw(float newFreq) {
uint8_t freqBand = (newFreq / 10) - 24;
uint8_t afcLimiter = 80;
this->frequency = newFreq;
if(newFreq >= 480.0f) {
if(newFreq >= 480.0) {
bandSelect = RADIOLIB_SI443X_BAND_SELECT_HIGH;
freqBand = (newFreq / 20) - 24;
afcLimiter = 40;
@ -737,8 +705,9 @@ bool Si443x::findChip() {
return(flagFound);
}
void Si443x::clearIrqStatus() {
(void)getIrqFlags();
void Si443x::clearIRQFlags() {
uint8_t buff[2];
this->mod->SPIreadRegisterBurst(RADIOLIB_SI443X_REG_INTERRUPT_STATUS_1, 2, buff);
}
void Si443x::clearFIFO(size_t count) {
@ -788,17 +757,17 @@ int16_t Si443x::updateClockRecovery() {
ndec = (uint16_t)1 << ndecExp;
} else {
ndecExp *= -1;
ndec = 1.0f/(float)((uint16_t)1 << ndecExp);
ndec = 1.0/(float)((uint16_t)1 << ndecExp);
}
float rxOsr = ((float)(500 * (1 + 2*bypass))) / (ndec * this->bitRate * ((float)(1 + manch)));
uint32_t ncoOff = (this->bitRate * (1 + manch) * ((uint32_t)(1) << (20 + decRate))) / (500 * (1 + 2*bypass));
uint16_t crGain = 2 + (((float)(65536.0f * (1 + manch)) * this->bitRate) / (rxOsr * (this->frequencyDev / 0.625f)));
uint16_t crGain = 2 + (((float)(65536.0 * (1 + manch)) * this->bitRate) / (rxOsr * (this->frequencyDev / 0.625)));
uint16_t rxOsr_fixed = (uint16_t)rxOsr;
// print that whole mess
RADIOLIB_DEBUG_BASIC_PRINTLN("%X %X %X", bypass, decRate, manch);
RADIOLIB_DEBUG_BASIC_PRINT_FLOAT((double)rxOsr, 2);
RADIOLIB_DEBUG_BASIC_PRINTLN("\t%d\t%X" RADIOLIB_LINE_FEED "%lu\t%lX" RADIOLIB_LINE_FEED "%d\t%X", rxOsr_fixed, rxOsr_fixed, (long unsigned int)ncoOff, (long unsigned int)ncoOff, crGain, crGain);
RADIOLIB_DEBUG_BASIC_PRINTLN("%X\n%X\n%X", bypass, decRate, manch);
RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(rxOsr, 2);
RADIOLIB_DEBUG_BASIC_PRINTLN("\t%d\t%X\n%lu\t%lX\n%d\t%X", rxOsr_fixed, rxOsr_fixed, (long unsigned int)ncoOff, (long unsigned int)ncoOff, crGain, crGain);
// update oversampling ratio
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_CLOCK_REC_OFFSET_2, (uint8_t)((rxOsr_fixed & 0x0700) >> 3), 7, 5);

View file

@ -128,19 +128,19 @@
#define RADIOLIB_SI443X_IDLE 0b00000000 // 1 0 idle
// RADIOLIB_SI443X_REG_INTERRUPT_STATUS_1
#define RADIOLIB_SI443X_FIFO_LEVEL_ERROR_INTERRUPT 0b10000000 << 8 // 7 7 Tx/Rx FIFO overflow or underflow
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_FULL_INTERRUPT 0b01000000 << 8 // 6 6 Tx FIFO almost full
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_EMPTY_INTERRUPT 0b00100000 << 8 // 5 5 Tx FIFO almost empty
#define RADIOLIB_SI443X_RX_FIFO_ALMOST_FULL_INTERRUPT 0b00010000 << 8 // 4 4 Rx FIFO almost full
#define RADIOLIB_SI443X_EXTERNAL_INTERRUPT 0b00001000 << 8 // 3 3 external interrupt occurred on GPIOx
#define RADIOLIB_SI443X_PACKET_SENT_INTERRUPT 0b00000100 << 8 // 2 2 packet transmission done
#define RADIOLIB_SI443X_VALID_PACKET_RECEIVED_INTERRUPT 0b00000010 << 8 // 1 1 valid packet has been received
#define RADIOLIB_SI443X_CRC_ERROR_INTERRUPT 0b00000001 << 8 // 0 0 CRC failed
#define RADIOLIB_SI443X_FIFO_LEVEL_ERROR_INTERRUPT 0b10000000 // 7 7 Tx/Rx FIFO overflow or underflow
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_FULL_INTERRUPT 0b01000000 // 6 6 Tx FIFO almost full
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_EMPTY_INTERRUPT 0b00100000 // 5 5 Tx FIFO almost empty
#define RADIOLIB_SI443X_RX_FIFO_ALMOST_FULL_INTERRUPT 0b00010000 // 4 4 Rx FIFO almost full
#define RADIOLIB_SI443X_EXTERNAL_INTERRUPT 0b00001000 // 3 3 external interrupt occurred on GPIOx
#define RADIOLIB_SI443X_PACKET_SENT_INTERRUPT 0b00000100 // 2 2 packet transmission done
#define RADIOLIB_SI443X_VALID_PACKET_RECEIVED_INTERRUPT 0b00000010 // 1 1 valid packet has been received
#define RADIOLIB_SI443X_CRC_ERROR_INTERRUPT 0b00000001 // 0 0 CRC failed
// RADIOLIB_SI443X_REG_INTERRUPT_STATUS_2
#define RADIOLIB_SI443X_SYNC_WORD_DETECTED_INTERRUPT 0b10000000 // 7 7 sync word has been detected
#define RADIOLIB_SI443X_VALID_PREAMBLE_DETECTED_INTERRUPT 0b01000000 // 6 6 valid preamble has been detected
#define RADIOLIB_SI443X_INVALID_PREAMBLE_DETECTED_INTERRUPT 0b00100000 // 5 5 invalid preamble has been detected
#define RADIOLIB_SI443X_VALID_RADIOLIB_PREAMBLE_DETECTED_INTERRUPT 0b01000000 // 6 6 valid preamble has been detected
#define RADIOLIB_SI443X_INVALID_RADIOLIB_PREAMBLE_DETECTED_INTERRUPT 0b00100000 // 5 5 invalid preamble has been detected
#define RADIOLIB_SI443X_RSSI_INTERRUPT 0b00010000 // 4 4 RSSI exceeded programmed threshold
#define RADIOLIB_SI443X_WAKEUP_TIMER_INTERRUPT 0b00001000 // 3 3 wake-up timer expired
#define RADIOLIB_SI443X_LOW_BATTERY_INTERRUPT 0b00000100 // 2 2 low battery detected
@ -159,8 +159,8 @@
// RADIOLIB_SI443X_REG_INTERRUPT_ENABLE_2
#define RADIOLIB_SI443X_SYNC_WORD_DETECTED_ENABLED 0b10000000 // 7 7 sync word interrupt enabled
#define RADIOLIB_SI443X_VALID_PREAMBLE_DETECTED_ENABLED 0b01000000 // 6 6 valid preamble interrupt enabled
#define RADIOLIB_SI443X_INVALID_PREAMBLE_DETECTED_ENABLED 0b00100000 // 5 5 invalid preamble interrupt enabled
#define RADIOLIB_SI443X_VALID_RADIOLIB_PREAMBLE_DETECTED_ENABLED 0b01000000 // 6 6 valid preamble interrupt enabled
#define RADIOLIB_SI443X_INVALID_RADIOLIB_PREAMBLE_DETECTED_ENABLED 0b00100000 // 5 5 invalid preamble interrupt enabled
#define RADIOLIB_SI443X_RSSI_ENABLED 0b00010000 // 4 4 RSSI exceeded programmed threshold interrupt enabled
#define RADIOLIB_SI443X_WAKEUP_TIMER_ENABLED 0b00001000 // 3 3 wake-up timer interrupt enabled
#define RADIOLIB_SI443X_LOW_BATTERY_ENABLED 0b00000100 // 2 2 low battery interrupt enabled
@ -823,27 +823,6 @@ class Si443x: public PhysicalLayer {
*/
int16_t variablePacketLengthMode(uint8_t maxLen = RADIOLIB_SI443X_MAX_PACKET_LENGTH);
/*!
\brief Read currently active IRQ flags.
\returns IRQ flags.
*/
uint32_t getIrqFlags() override;
/*!
\brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone).
\param irq Module-specific IRQ flags.
\returns \ref status_codes
*/
int16_t clearIrqFlags(uint32_t irq) override;
/*!
\brief Enables/disables CRC of transmitted or received packets.
\param enable Enable (true) or disable (false) CRC.
\param mode Set CRC mode
\returns \ref status_codes
*/
int16_t setCRC(bool enable, bool mode = false);
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
protected:
#endif
@ -866,10 +845,9 @@ class Si443x: public PhysicalLayer {
size_t packetLength = 0;
bool packetLengthQueried = false;
uint8_t packetLengthConfig = RADIOLIB_SI443X_FIXED_PACKET_LENGTH_ON;
bool crcEnabled = false;
bool findChip();
void clearIrqStatus();
void clearIRQFlags();
void clearFIFO(size_t count);
int16_t config();
int16_t updateClockRecovery();

View file

@ -2,9 +2,7 @@
#include <string.h>
#if !RADIOLIB_EXCLUDE_NRF24
nRF24::nRF24(Module* mod) : PhysicalLayer() {
this->freqStep = RADIOLIB_NRF24_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_NRF24_MAX_PACKET_LENGTH;
nRF24::nRF24(Module* mod) : PhysicalLayer(RADIOLIB_NRF24_FREQUENCY_STEP_SIZE, RADIOLIB_NRF24_MAX_PACKET_LENGTH) {
this->mod = mod;
}
@ -389,7 +387,7 @@ int16_t nRF24::setAddressWidth(uint8_t addrWidth) {
return(state);
}
int16_t nRF24::setTransmitPipe(const uint8_t* addr) {
int16_t nRF24::setTransmitPipe(uint8_t* addr) {
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
@ -404,7 +402,7 @@ int16_t nRF24::setTransmitPipe(const uint8_t* addr) {
return(state);
}
int16_t nRF24::setReceivePipe(uint8_t pipeNum, const uint8_t* addr) {
int16_t nRF24::setReceivePipe(uint8_t pipeNum, uint8_t* addr) {
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
@ -563,10 +561,6 @@ int16_t nRF24::setEncoding(uint8_t encoding) {
return(RADIOLIB_ERR_NONE);
}
int16_t nRF24::setLNA(bool enable) {
return(this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, enable ? RADIOLIB_NRF24_RF_LNA_ON : RADIOLIB_NRF24_RF_LNA_OFF, 0, 0));
}
void nRF24::clearIRQ() {
// clear status bits
this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_STATUS, RADIOLIB_NRF24_RX_DR | RADIOLIB_NRF24_TX_DS | RADIOLIB_NRF24_MAX_RT, 6, 4);
@ -616,11 +610,11 @@ void nRF24::SPIreadRxPayload(uint8_t* data, uint8_t numBytes) {
SPItransfer(RADIOLIB_NRF24_CMD_READ_RX_PAYLOAD, false, NULL, data, numBytes);
}
void nRF24::SPIwriteTxPayload(const uint8_t* data, uint8_t numBytes) {
void nRF24::SPIwriteTxPayload(uint8_t* data, uint8_t numBytes) {
SPItransfer(RADIOLIB_NRF24_CMD_WRITE_TX_PAYLOAD, true, data, NULL, numBytes);
}
void nRF24::SPItransfer(uint8_t cmd, bool write, const uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes) {
void nRF24::SPItransfer(uint8_t cmd, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes) {
(void)this->mod->SPItransferStream(&cmd, 1, write, dataOut, dataIn, numBytes, false);
}

View file

@ -123,8 +123,6 @@
#define RADIOLIB_NRF24_RF_PWR_12_DBM 0b00000010 // 2 1 -12 dBm
#define RADIOLIB_NRF24_RF_PWR_6_DBM 0b00000100 // 2 1 -6 dBm
#define RADIOLIB_NRF24_RF_PWR_0_DBM 0b00000110 // 2 1 0 dBm (default)
#define RADIOLIB_NRF24_RF_LNA_OFF 0b00000000 // 0 0 LNA gain: Off
#define RADIOLIB_NRF24_RF_LNA_ON 0b00000001 // 0 0 On
// RADIOLIB_NRF24_REG_STATUS
#define RADIOLIB_NRF24_RX_DR 0b01000000 // 6 6 Rx data ready
@ -376,7 +374,7 @@ class nRF24: public PhysicalLayer {
\param addr Address to which the next packet shall be transmitted.
\returns \ref status_codes
*/
int16_t setTransmitPipe(const uint8_t* addr);
int16_t setTransmitPipe(uint8_t* addr);
/*!
\brief Sets address of receive pipes 0 or 1. The address width must be the same as the same
@ -386,7 +384,7 @@ class nRF24: public PhysicalLayer {
\param addr Address from which %nRF24 shall receive new packets on the specified pipe.
\returns \ref status_codes
*/
int16_t setReceivePipe(uint8_t pipeNum, const uint8_t* addr);
int16_t setReceivePipe(uint8_t pipeNum, uint8_t* addr);
/*!
\brief Sets address of receive pipes 2 - 5. The first 2 - 4 address bytes for these pipes
@ -467,22 +465,14 @@ class nRF24: public PhysicalLayer {
*/
int16_t setEncoding(uint8_t encoding) override;
/*!
\brief Enable or disable the low-noise amplifier.
Improves receive performance at the cost of increased power consumption.
\param enable True to enable.
\returns \ref status_codes
*/
int16_t setLNA(bool enable);
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
protected:
#endif
Module* getMod() override;
void SPIreadRxPayload(uint8_t* data, uint8_t numBytes);
void SPIwriteTxPayload(const uint8_t* data, uint8_t numBytes);
void SPItransfer(uint8_t cmd, bool write = false, const uint8_t* dataOut = NULL, uint8_t* dataIn = NULL, uint8_t numBytes = 0);
void SPIwriteTxPayload(uint8_t* data, uint8_t numBytes);
void SPItransfer(uint8_t cmd, bool write = false, uint8_t* dataOut = NULL, uint8_t* dataIn = NULL, uint8_t numBytes = 0);
#if !RADIOLIB_GODMODE
private:

View file

@ -14,7 +14,7 @@ APRSClient::APRSClient(PhysicalLayer* phy) {
phyLayer = phy;
}
int16_t APRSClient::begin(char sym, const char* callsign, uint8_t ssid, bool alt) {
int16_t APRSClient::begin(char sym, char* callsign, uint8_t ssid, bool alt) {
RADIOLIB_CHECK_RANGE(sym, ' ', '}', RADIOLIB_ERR_INVALID_SYMBOL);
symbol = sym;
@ -39,7 +39,7 @@ int16_t APRSClient::begin(char sym, const char* callsign, uint8_t ssid, bool alt
return(RADIOLIB_ERR_NONE);
}
int16_t APRSClient::sendPosition(char* destCallsign, uint8_t destSSID, const char* lat, const char* lon, const char* msg, const char* time) {
int16_t APRSClient::sendPosition(char* destCallsign, uint8_t destSSID, char* lat, char* lon, char* msg, char* time) {
size_t len = 1 + strlen(lat) + 1 + strlen(lon);
if(msg != NULL) {
len += 1 + strlen(msg);
@ -84,7 +84,7 @@ int16_t APRSClient::sendPosition(char* destCallsign, uint8_t destSSID, const cha
return(state);
}
int16_t APRSClient::sendMicE(float lat, float lon, uint16_t heading, uint16_t speed, uint8_t type, const uint8_t* telem, size_t telemLen, const char* grid, const char* status, int32_t alt) {
int16_t APRSClient::sendMicE(float lat, float lon, uint16_t heading, uint16_t speed, uint8_t type, uint8_t* telem, size_t telemLen, char* grid, char* status, int32_t alt) {
// sanity checks first
if(((telemLen == 0) && (telem != NULL)) || ((telemLen != 0) && (telem == NULL))) {
return(RADIOLIB_ERR_INVALID_MIC_E_TELEMETRY);

View file

@ -106,7 +106,7 @@ class APRSClient {
\param alt Whether to use the primary (false) or alternate (true) symbol table. Defaults to primary table.
\returns \ref status_codes
*/
int16_t begin(char sym, const char* callsign = NULL, uint8_t ssid = 0, bool alt = false);
int16_t begin(char sym, char* callsign = NULL, uint8_t ssid = 0, bool alt = false);
/*!
\brief Transmit position.
@ -118,7 +118,7 @@ class APRSClient {
\param time Position timestamp. Defaults to NULL (no timestamp).
\returns \ref status_codes
*/
int16_t sendPosition(char* destCallsign, uint8_t destSSID, const char* lat, const char* lon, const char* msg = NULL, const char* time = NULL);
int16_t sendPosition(char* destCallsign, uint8_t destSSID, char* lat, char* lon, char* msg = NULL, char* time = NULL);
/*!
\brief Transmit position using Mic-E encoding.
@ -133,7 +133,7 @@ class APRSClient {
\param status Status message to send. NULL when not used.
\param alt Altitude to send. RADIOLIB_APRS_MIC_E_ALTITUDE_UNUSED when not used.
*/
int16_t sendMicE(float lat, float lon, uint16_t heading, uint16_t speed, uint8_t type, const uint8_t* telem = NULL, size_t telemLen = 0, const char* grid = NULL, const char* status = NULL, int32_t alt = RADIOLIB_APRS_MIC_E_ALTITUDE_UNUSED);
int16_t sendMicE(float lat, float lon, uint16_t heading, uint16_t speed, uint8_t type, uint8_t* telem = NULL, size_t telemLen = 0, char* grid = NULL, char* status = NULL, int32_t alt = RADIOLIB_APRS_MIC_E_ALTITUDE_UNUSED);
/*!
\brief Transmit generic APRS frame.

View file

@ -14,7 +14,7 @@ AX25Frame::AX25Frame(const char* destCallsign, uint8_t destSSID, const char* src
}
AX25Frame::AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control, uint8_t protocolID, const uint8_t* info, uint16_t infoLen) {
AX25Frame::AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control, uint8_t protocolID, uint8_t* info, uint16_t infoLen) {
// destination callsign/SSID
memcpy(this->destCallsign, destCallsign, strlen(destCallsign));
this->destCallsign[strlen(destCallsign)] = '\0';
@ -142,7 +142,7 @@ AX25Frame& AX25Frame::operator=(const AX25Frame& frame) {
return(*this);
}
int16_t AX25Frame::setRepeaters(char** repeaterCallsigns, const uint8_t* repeaterSSIDs, uint8_t numRepeaters) {
int16_t AX25Frame::setRepeaters(char** repeaterCallsigns, uint8_t* repeaterSSIDs, uint8_t numRepeaters) {
// check number of repeaters
if((numRepeaters < 1) || (numRepeaters > 8)) {
return(RADIOLIB_ERR_INVALID_NUM_REPEATERS);

View file

@ -185,7 +185,7 @@ class AX25Frame {
\param info Information field, in the form of arbitrary binary buffer.
\param infoLen Number of bytes in the information field.
*/
AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control, uint8_t protocolID, const uint8_t* info, uint16_t infoLen);
AX25Frame(const char* destCallsign, uint8_t destSSID, const char* srcCallsign, uint8_t srcSSID, uint8_t control, uint8_t protocolID, uint8_t* info, uint16_t infoLen);
/*!
\brief Copy constructor.
@ -211,7 +211,7 @@ class AX25Frame {
\param numRepeaters Number of repeaters, maximum is 8.
\returns \ref status_codes
*/
int16_t setRepeaters(char** repeaterCallsigns, const uint8_t* repeaterSSIDs, uint8_t numRepeaters);
int16_t setRepeaters(char** repeaterCallsigns, uint8_t* repeaterSSIDs, uint8_t numRepeaters);
/*!
\brief Method to set receive sequence number.

View file

@ -43,7 +43,7 @@ int16_t BellClient::begin(const BellModem_t& modem) {
int16_t BellClient::setModem(const BellModem_t& modem) {
this->modemType = modem;
this->toneLen = (1000000.0f/(float)this->modemType.baudRate)*this->correction;
this->toneLen = (1000000.0/(float)this->modemType.baudRate)*this->correction;
return(RADIOLIB_ERR_NONE);
}

View file

@ -1,23 +1,20 @@
#include "ExternalRadio.h"
#if defined(RADIOLIB_BUILD_ARDUINO)
ExternalRadio::ExternalRadio(uint32_t pin) : PhysicalLayer() {
this->freqStep = 1;
ExternalRadio::ExternalRadio(uint32_t pin) : PhysicalLayer(1, 0) {
mod = new Module(RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, pin);
mod->hal->pinMode(pin, mod->hal->GpioModeOutput);
this->prevFrf = 0;
}
#endif
ExternalRadio::ExternalRadio(RadioLibHal *hal, uint32_t pin) : PhysicalLayer() {
this->freqStep = 1;
ExternalRadio::ExternalRadio(RadioLibHal *hal, uint32_t pin) : PhysicalLayer(1, 0) {
mod = new Module(hal, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, pin);
mod->hal->pinMode(pin, mod->hal->GpioModeOutput);
this->prevFrf = 0;
}
ExternalRadio::ExternalRadio(const ExternalRadio& ext) : PhysicalLayer() {
this->freqStep = 1;
ExternalRadio::ExternalRadio(const ExternalRadio& ext) : PhysicalLayer(1, 0) {
this->prevFrf = ext.prevFrf;
if(ext.mod) {
this->mod = new Module(ext.mod->hal, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, ext.mod->getGpio());
@ -35,8 +32,10 @@ ExternalRadio& ExternalRadio::operator=(const ExternalRadio& ext) {
}
ExternalRadio::~ExternalRadio() {
if(this->mod) {
delete this->mod;
}
}
Module* ExternalRadio::getMod() {
return(mod);

View file

@ -34,7 +34,7 @@ int16_t FSK4Client::begin(float base, uint32_t shift, uint16_t rate) {
}
// calculate 24-bit frequency
baseFreq = (base * 1000000.0f) / phyLayer->freqStep;
baseFreq = (base * 1000000.0) / phyLayer->getFreqStep();
// configure for direct mode
return(phyLayer->startDirect());
@ -54,7 +54,7 @@ int16_t FSK4Client::setCorrection(int16_t offsets[], float length) {
return(RADIOLIB_ERR_NONE);
}
size_t FSK4Client::write(const uint8_t* buff, size_t len) {
size_t FSK4Client::write(uint8_t* buff, size_t len) {
size_t n = 0;
for(size_t i = 0; i < len; i++) {
n += FSK4Client::write(buff[i]);
@ -109,7 +109,7 @@ int16_t FSK4Client::standby() {
int32_t FSK4Client::getRawShift(int32_t shift) {
// calculate module carrier frequency resolution
int32_t step = round(phyLayer->freqStep);
int32_t step = round(phyLayer->getFreqStep());
// check minimum shift value
if(RADIOLIB_ABS(shift) < step / 2) {

View file

@ -59,7 +59,7 @@ class FSK4Client {
\param len Number of bytes to transmit.
\returns Number of transmitted bytes.
*/
size_t write(const uint8_t* buff, size_t len);
size_t write(uint8_t* buff, size_t len);
/*!
\brief Transmit a single byte.

View file

@ -21,10 +21,10 @@ HellClient::HellClient(AFSKClient* audio) {
int16_t HellClient::begin(float base, float rate) {
// calculate 24-bit frequency
baseFreqHz = base;
baseFreq = (base * 1000000.0f) / phyLayer->freqStep;
baseFreq = (base * 1000000.0) / phyLayer->getFreqStep();
// calculate "pixel" duration
pixelDuration = 1000000.0f/rate;
pixelDuration = 1000000.0/rate;
// configure for direct mode
return(phyLayer->startDirect());
@ -73,8 +73,7 @@ size_t HellClient::write(uint8_t b) {
uint8_t buff[RADIOLIB_HELL_FONT_WIDTH];
buff[0] = 0x00;
for(uint8_t i = 0; i < RADIOLIB_HELL_FONT_WIDTH - 2; i++) {
uint8_t* ptr = const_cast<uint8_t*>(&HellFont[pos][i]);
buff[i + 1] = RADIOLIB_NONVOLATILE_READ_BYTE(ptr);
buff[i + 1] = RADIOLIB_NONVOLATILE_READ_BYTE(&HellFont[pos][i]);
}
buff[RADIOLIB_HELL_FONT_WIDTH - 1] = 0x00;

View file

@ -144,6 +144,9 @@ class HellClient: public RadioLibPrint {
uint32_t pixelDuration = 0;
bool invert = false;
size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
int16_t transmitDirect(uint32_t freq = 0, uint32_t freqHz = 0);
int16_t standby();
};

View file

@ -24,16 +24,16 @@ int16_t LoRaWANNode::sendReceive(const String& strUp, uint8_t fPort, String& str
// build a temporary buffer
// LoRaWAN downlinks can have 250 bytes at most with 1 extra byte for NULL
size_t lenDown = 0;
uint8_t dataDown[RADIOLIB_LORAWAN_MAX_DOWNLINK_SIZE + 1];
uint8_t dataDown[251];
state = this->sendReceive(reinterpret_cast<const uint8_t*>(dataUp), strlen(dataUp), fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown);
state = this->sendReceive((const uint8_t*)dataUp, strlen(dataUp), fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown);
if(state == RADIOLIB_ERR_NONE) {
// add null terminator
dataDown[lenDown] = '\0';
// initialize Arduino String class
strDown = String(reinterpret_cast<char*>(dataDown));
strDown = String((char*)dataDown);
}
return(state);
@ -44,20 +44,20 @@ int16_t LoRaWANNode::sendReceive(const char* strUp, uint8_t fPort, bool isConfir
// build a temporary buffer
// LoRaWAN downlinks can have 250 bytes at most with 1 extra byte for NULL
size_t lenDown = 0;
uint8_t dataDown[RADIOLIB_LORAWAN_MAX_DOWNLINK_SIZE + 1];
uint8_t dataDown[251];
return(this->sendReceive(reinterpret_cast<uint8_t*>(const_cast<char*>(strUp)), strlen(strUp), fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown));
return(this->sendReceive((uint8_t*)strUp, strlen(strUp), fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown));
}
int16_t LoRaWANNode::sendReceive(const char* strUp, uint8_t fPort, uint8_t* dataDown, size_t* lenDown, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) {
return(this->sendReceive(reinterpret_cast<uint8_t*>(const_cast<char*>(strUp)), strlen(strUp), fPort, dataDown, lenDown, isConfirmed, eventUp, eventDown));
return(this->sendReceive((uint8_t*)strUp, strlen(strUp), fPort, dataDown, lenDown, isConfirmed, eventUp, eventDown));
}
int16_t LoRaWANNode::sendReceive(const uint8_t* dataUp, size_t lenUp, uint8_t fPort, bool isConfirmed, LoRaWANEvent_t* eventUp, LoRaWANEvent_t* eventDown) {
// build a temporary buffer
// LoRaWAN downlinks can have 250 bytes at most with 1 extra byte for NULL
size_t lenDown = 0;
uint8_t dataDown[RADIOLIB_LORAWAN_MAX_DOWNLINK_SIZE + 1];
uint8_t dataDown[251];
return(this->sendReceive(dataUp, lenUp, fPort, dataDown, &lenDown, isConfirmed, eventUp, eventDown));
}
@ -67,6 +67,7 @@ int16_t LoRaWANNode::sendReceive(const uint8_t* dataUp, size_t lenUp, uint8_t fP
return(RADIOLIB_ERR_NULL_POINTER);
}
int16_t state = RADIOLIB_ERR_UNKNOWN;
Module* mod = this->phyLayer->getMod();
// if after (at) ADR_ACK_LIMIT frames no RekeyConf was received, revert to Join state
if(this->fCntUp == (1UL << this->adrLimitExp)) {
@ -146,7 +147,7 @@ int16_t LoRaWANNode::sendReceive(const uint8_t* dataUp, size_t lenUp, uint8_t fP
// RETRANSMIT_TIMEOUT is 2s +/- 1s (RP v1.0.4)
// must be present after any confirmed frame, so we force this here
if(isConfirmed) {
this->sleepDelay(this->phyLayer->random(1000, 3000));
mod->hal->delay(this->phyLayer->random(1000, 3000));
}
// if an error occured or a downlink was received, stop retransmission
@ -517,10 +518,10 @@ int16_t LoRaWANNode::setBufferSession(const uint8_t* persistentBuffer) {
// for dynamic bands, the additional channels must be restored per-channel
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) {
// all-zero buffer used for checking if MAC commands are set
const uint8_t bufferZeroes[RADIOLIB_LORAWAN_MAX_MAC_COMMAND_LEN_DOWN] = { 0 };
uint8_t bufferZeroes[RADIOLIB_LORAWAN_MAX_MAC_COMMAND_LEN_DOWN] = { 0 };
// restore the session channels
const uint8_t *startChannelsUp = &this->bufferSession[RADIOLIB_LORAWAN_SESSION_UL_CHANNELS];
uint8_t *startChannelsUp = &this->bufferSession[RADIOLIB_LORAWAN_SESSION_UL_CHANNELS];
cid = RADIOLIB_LORAWAN_MAC_NEW_CHANNEL;
(void)this->getMacLen(cid, &cLen, RADIOLIB_LORAWAN_DOWNLINK);
@ -531,7 +532,7 @@ int16_t LoRaWANNode::setBufferSession(const uint8_t* persistentBuffer) {
}
}
const uint8_t *startChannelsDown = &this->bufferSession[RADIOLIB_LORAWAN_SESSION_DL_CHANNELS];
uint8_t *startChannelsDown = &this->bufferSession[RADIOLIB_LORAWAN_SESSION_DL_CHANNELS];
cid = RADIOLIB_LORAWAN_MAC_DL_CHANNEL;
(void)this->getMacLen(cid, &cLen, RADIOLIB_LORAWAN_DOWNLINK);
@ -549,13 +550,12 @@ int16_t LoRaWANNode::setBufferSession(const uint8_t* persistentBuffer) {
memcpy(cOcts, &this->bufferSession[RADIOLIB_LORAWAN_SESSION_LINK_ADR], cLen);
(void)execMacCommand(cid, cOcts, cLen);
const uint8_t cids[6] = {
uint8_t cids[6] = {
RADIOLIB_LORAWAN_MAC_DUTY_CYCLE, RADIOLIB_LORAWAN_MAC_RX_PARAM_SETUP,
RADIOLIB_LORAWAN_MAC_RX_TIMING_SETUP, RADIOLIB_LORAWAN_MAC_TX_PARAM_SETUP,
RADIOLIB_LORAWAN_MAC_ADR_PARAM_SETUP, RADIOLIB_LORAWAN_MAC_REJOIN_PARAM_SETUP
};
const uint16_t locs[6] = {
uint16_t locs[6] = {
RADIOLIB_LORAWAN_SESSION_DUTY_CYCLE, RADIOLIB_LORAWAN_SESSION_RX_PARAM_SETUP,
RADIOLIB_LORAWAN_SESSION_RX_TIMING_SETUP, RADIOLIB_LORAWAN_SESSION_TX_PARAM_SETUP,
RADIOLIB_LORAWAN_SESSION_ADR_PARAM_SETUP, RADIOLIB_LORAWAN_SESSION_REJOIN_PARAM_SETUP
@ -905,51 +905,25 @@ int16_t LoRaWANNode::activateOTAA(uint8_t joinDr, LoRaWANJoinEvent_t *joinEvent)
RADIOLIB_ASSERT(state);
// calculate JoinRequest time-on-air in milliseconds
RadioLibTime_t toa = this->phyLayer->getTimeOnAir(RADIOLIB_LORAWAN_JOIN_REQUEST_LEN) / 1000;
if(this->dwellTimeUp) {
RadioLibTime_t toa = this->phyLayer->getTimeOnAir(RADIOLIB_LORAWAN_JOIN_REQUEST_LEN) / 1000;
if(toa > this->dwellTimeUp) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Dwell time exceeded: ToA = %lu, max = %d", (unsigned long)toa, this->dwellTimeUp);
return(RADIOLIB_ERR_DWELL_TIME_EXCEEDED);
}
}
RadioModeConfig_t modeCfg;
modeCfg.transmit.data = joinRequestMsg;
modeCfg.transmit.len = RADIOLIB_LORAWAN_JOIN_REQUEST_LEN;
modeCfg.transmit.addr = 0;
state = this->phyLayer->stageMode(RADIOLIB_RADIO_MODE_TX, &modeCfg);
RADIOLIB_ASSERT(state);
// if requested, delay until transmitting JoinRequest
RadioLibTime_t tNow = mod->hal->millis();
if(this->tUplink > tNow) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Delaying transmission by %lu ms", (unsigned long)(this->tUplink - tNow));
if(this->tUplink > mod->hal->millis()) {
this->sleepDelay(this->tUplink - mod->hal->millis());
mod->hal->delay(this->tUplink - mod->hal->millis());
}
}
// start transmission
state = this->phyLayer->launchMode();
RADIOLIB_ASSERT(state);
// sleep for the duration of the transmission
this->sleepDelay(toa);
RadioLibTime_t txEnd = mod->hal->millis();
// wait for an additional transmission duration as Tx timeout period
while(!mod->hal->digitalRead(mod->getIrq())) {
// yield for multi-threaded platforms
mod->hal->yield();
if(mod->hal->millis() > txEnd + toa) {
return(RADIOLIB_ERR_TX_TIMEOUT);
}
}
state = this->phyLayer->finishTransmit();
// set the timestamp so that we can measure when to start receiving
// send it
state = this->phyLayer->transmit(joinRequestMsg, RADIOLIB_LORAWAN_JOIN_REQUEST_LEN);
this->rxDelayStart = mod->hal->millis();
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("JoinRequest sent (DevNonce = %d) <-- Rx Delay start", this->devNonce);
@ -960,7 +934,7 @@ int16_t LoRaWANNode::activateOTAA(uint8_t joinDr, LoRaWANJoinEvent_t *joinEvent)
LoRaWANNode::hton<uint16_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_DEV_NONCE], this->devNonce);
// set the Time on Air of the JoinRequest
this->lastToA = toa;
this->lastToA = this->phyLayer->getTimeOnAir(RADIOLIB_LORAWAN_JOIN_REQUEST_LEN) / 1000;
// configure Rx1 and Rx2 delay for JoinAccept message - these are re-configured once a valid JoinAccept is received
this->rxDelays[1] = RADIOLIB_LORAWAN_JOIN_ACCEPT_DELAY_1_MS;
@ -1021,7 +995,7 @@ int16_t LoRaWANNode::activateABP(uint8_t initialDr) {
return(RADIOLIB_LORAWAN_NEW_SESSION);
}
void LoRaWANNode::processCFList(const uint8_t* cfList) {
void LoRaWANNode::processCFList(uint8_t* cfList) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Processing CFList");
uint8_t cOcts[14] = { 0 }; // TODO explain
@ -1041,7 +1015,7 @@ void LoRaWANNode::processCFList(const uint8_t* cfList) {
cid = RADIOLIB_LORAWAN_MAC_NEW_CHANNEL;
(void)this->getMacLen(cid, &cLen, RADIOLIB_LORAWAN_DOWNLINK);
const uint8_t freqZero[3] = { 0 };
uint8_t freqZero[3] = { 0 };
// datarate range for all new channels is equal to the default channels
cOcts[4] = (this->band->txFreqs[0].drMax << 4) | this->band->txFreqs[0].drMin;
@ -1290,11 +1264,12 @@ void LoRaWANNode::micUplink(uint8_t* inOut, uint8_t lenInOut) {
}
}
int16_t LoRaWANNode::transmitUplink(const LoRaWANChannel_t* chnl, uint8_t* in, uint8_t len, bool retrans) {
int16_t LoRaWANNode::transmitUplink(LoRaWANChannel_t* chnl, uint8_t* in, uint8_t len, bool retrans) {
int16_t state = RADIOLIB_ERR_UNKNOWN;
Module* mod = this->phyLayer->getMod();
// check if the Rx windows were closed after sending the previous uplink
// this FORCES a user to call downlink() after an uplink()
if(this->rxDelayEnd < this->rxDelayStart) {
// not enough time elapsed since the last uplink, we may still be in an Rx window
return(RADIOLIB_ERR_UPLINK_UNAVAILABLE);
@ -1320,56 +1295,23 @@ int16_t LoRaWANNode::transmitUplink(const LoRaWANChannel_t* chnl, uint8_t* in, u
this->txPowerMax - 2*this->txPowerSteps);
RADIOLIB_ASSERT(state);
// check whether dwell time limitation is exceeded
RadioLibTime_t toa = this->phyLayer->getTimeOnAir(len) / 1000;
if(this->dwellTimeUp) {
if(toa > this->dwellTimeUp) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Dwell time exceeded: ToA = %lu, max = %d", (unsigned long)toa, this->dwellTimeUp);
return(RADIOLIB_ERR_DWELL_TIME_EXCEEDED);
}
}
RadioModeConfig_t modeCfg;
modeCfg.transmit.data = in;
modeCfg.transmit.len = len;
modeCfg.transmit.addr = 0;
state = this->phyLayer->stageMode(RADIOLIB_RADIO_MODE_TX, &modeCfg);
RADIOLIB_ASSERT(state);
// if requested, wait until transmitting uplink
tNow = mod->hal->millis();
if(this->tUplink > tNow) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Delaying transmission by %lu ms", (unsigned long)(this->tUplink - tNow));
if(this->tUplink > mod->hal->millis()) {
this->sleepDelay(this->tUplink - mod->hal->millis());
mod->hal->delay(this->tUplink - mod->hal->millis());
}
}
// start transmission
state = this->phyLayer->launchMode();
RADIOLIB_ASSERT(state);
// sleep for the duration of the transmission
this->sleepDelay(toa);
RadioLibTime_t txEnd = mod->hal->millis();
// wait for an additional transmission duration as Tx timeout period
while(!mod->hal->digitalRead(mod->getIrq())) {
// yield for multi-threaded platforms
mod->hal->yield();
if(mod->hal->millis() > txEnd + toa) {
return(RADIOLIB_ERR_TX_TIMEOUT);
}
}
state = this->phyLayer->finishTransmit();
state = this->phyLayer->transmit(in, len);
// set the timestamp so that we can measure when to start receiving
this->rxDelayStart = mod->hal->millis();
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Uplink sent <-- Rx Delay start");
// increase Time on Air of the uplink sequence
this->lastToA += toa;
this->lastToA += this->phyLayer->getTimeOnAir(len) / 1000;
return(state);
}
@ -1397,7 +1339,7 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, const LoRaWANChannel_t* dlChanne
// if function was called while Rx windows are in progress,
// wait until last window closes to prevent very bad stuff
if(now < tReference + dlDelays[numWindows]) {
this->sleepDelay(dlDelays[numWindows] + tReference - now);
mod->hal->delay(dlDelays[numWindows] + tReference - now);
}
// update the end timestamp in case user got stuck between uplink and downlink
this->rxDelayEnd = mod->hal->millis();
@ -1421,18 +1363,9 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, const LoRaWANChannel_t* dlChanne
RADIOLIB_ASSERT(state);
// calculate the Rx timeout
RadioLibTime_t timeoutHost = this->phyLayer->getTimeOnAir(0) + this->scanGuard*1000;
RadioLibTime_t timeoutHost = this->phyLayer->getTimeOnAir(0) + 2*this->scanGuard*1000;
RadioLibTime_t timeoutMod = this->phyLayer->calculateRxTimeout(timeoutHost);
// TODO remove default arguments
RadioModeConfig_t modeCfg;
modeCfg.receive.timeout = timeoutMod;
modeCfg.receive.irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS;
modeCfg.receive.irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK;
modeCfg.receive.len = 0;
state = this->phyLayer->stageMode(RADIOLIB_RADIO_MODE_RX, &modeCfg);
RADIOLIB_ASSERT(state);
// wait for the start of the Rx window
RadioLibTime_t waitLen = tReference + dlDelays[window] - mod->hal->millis();
// make sure that no underflow occured; if so, clip the delay (although this will likely miss any downlink)
@ -1443,16 +1376,17 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, const LoRaWANChannel_t* dlChanne
if(waitLen > this->scanGuard) {
waitLen -= this->scanGuard;
}
this->sleepDelay(waitLen);
mod->hal->delay(waitLen);
// open Rx window by starting receive with specified timeout
state = this->phyLayer->launchMode();
// TODO remove default arguments
state = this->phyLayer->startReceive(timeoutMod, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
tOpen = mod->hal->millis();
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Opening Rx%d window (%d ms timeout)... <-- Rx Delay end ", window, (int)(timeoutHost / 1000 + 2));
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Opening Rx%d window (%d ms timeout)... <-- Rx Delay end ", window, (int)(timeoutHost / 1000 + scanGuard / 2));
// wait for the timeout to complete (and a small additional delay)
this->sleepDelay(timeoutHost / 1000 + this->scanGuard / 2);
mod->hal->delay(timeoutHost / 1000 + this->scanGuard / 2);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Closing Rx%d window", window);
// if the IRQ bit for Rx Timeout is not set, something is received, so stop the windows
@ -1773,7 +1707,12 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e
uint8_t fLen = 1;
uint8_t* mPtr = fOpts;
uint8_t procLen = 0;
uint8_t fOptsRe[RADIOLIB_LORAWAN_MAX_DOWNLINK_SIZE] = { 0 };
#if !RADIOLIB_STATIC_ONLY
uint8_t* fOptsRe = new uint8_t[250];
#else
uint8_t fOptsRe[RADIOLIB_STATIC_ARRAY_SIZE];
#endif
uint8_t fOptsReLen = 0;
// indication whether LinkAdr MAC command has been processed
@ -1783,14 +1722,14 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e
cid = *mPtr; // MAC id is the first byte
// fetch length of MAC downlink payload
state = this->getMacLen(cid, &fLen, RADIOLIB_LORAWAN_DOWNLINK, true, mPtr + 1);
state = this->getMacLen(cid, &fLen, RADIOLIB_LORAWAN_DOWNLINK, true);
if(state != RADIOLIB_ERR_NONE) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Unknown MAC CID %02x", cid);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Skipping remaining MAC commands");
break;
}
// already fetch length of MAC answer payload (if any), include CID
// already fetch length of MAC answer payload (if any)
uint8_t fLenRe = 0;
(void)this->getMacLen(cid, &fLenRe, RADIOLIB_LORAWAN_UPLINK, true);
// don't care about return value: the previous getMacLen() would have failed anyway
@ -1897,6 +1836,7 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e
#if !RADIOLIB_STATIC_ONLY
delete[] fOpts;
delete[] fOptsRe;
delete[] downlinkMsg;
#endif
@ -2172,7 +2112,7 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin
// check if the frequency is allowed and possible
if(macFreq >= this->band->freqMin && macFreq <= this->band->freqMax) {
if(this->phyLayer->setFrequency((float)macFreq / 10000.0f) == RADIOLIB_ERR_NONE) {
if(this->phyLayer->setFrequency((float)macFreq / 10000.0) == RADIOLIB_ERR_NONE) {
freqAck = 1;
}
// otherwise, if frequency is 0, disable the channel which is also a valid option
@ -2273,7 +2213,7 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin
if(delay == 0) {
delay = 1;
}
this->rxDelays[1] = (RadioLibTime_t)delay * (RadioLibTime_t)1000; // Rx1 delay
this->rxDelays[1] = delay * 1000; // Rx1 delay
this->rxDelays[2] = this->rxDelays[1] + 1000; // Rx2 delay
memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_RX_TIMING_SETUP], optIn, lenIn);
@ -2318,7 +2258,7 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin
// if not a valid server version, retransmit RekeyInd
uint8_t cLen = 0;
this->getMacLen(cid, &cLen, RADIOLIB_LORAWAN_UPLINK);
const uint8_t cOcts[1] = { this->rev };
uint8_t cOcts[1] = { this->rev };
(void)LoRaWANNode::pushMacCommand(cid, cOcts, this->fOptsUp, &this->fOptsUpLen, RADIOLIB_LORAWAN_UPLINK);
// discard RekeyConf, therefore return false so it doesn't send a reply
@ -2412,19 +2352,16 @@ void LoRaWANNode::preprocessMacLinkAdr(uint8_t* mPtr, uint8_t cLen, uint8_t* mAd
uint8_t chMaskCntl = (mPtr[opt * fLen + 4] & 0x70) >> 4;
uint16_t chMask = LoRaWANNode::ntoh<uint16_t>(&mPtr[opt * fLen + 2]);
switch(chMaskCntl) {
case 0:
case 1:
case 2:
case 3:
case 0 ... 3:
chMaskGrp0123 |= (uint64_t)chMask << (16 * chMaskCntl);
break;
case 4:
chMaskGrp45 |= (uint32_t)chMask;
break;
case 5:
// for CN470, this is just a normal channel mask
// for CN500, this is just a normal channel mask
// for all other bands, the first 10 bits enable banks of 8 125kHz channels
if(this->band->bandNum == BandCN470) {
if(this->band->bandNum == BandCN500) {
chMaskGrp45 |= (uint32_t)chMask << 16;
} else {
int bank = 0;
@ -2443,19 +2380,19 @@ void LoRaWANNode::preprocessMacLinkAdr(uint8_t* mPtr, uint8_t cLen, uint8_t* mAd
case 6:
// for dynamic bands: all channels ON (that are currently defined)
// for fixed bands: all 125kHz channels ON, channel mask similar to ChMask = 4
// except for CN470: all 125kHz channels ON
// except for CN500: all 125kHz channels ON
// for dynamic bands: retrieve all currently defined channels
// for fixed bands: cannot store all defined channels, so select a random one from each bank
this->getChannelPlanMask(&chMaskGrp0123, &chMaskGrp45);
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_FIXED && this->band->bandNum != BandCN470) {
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_FIXED && this->band->bandNum != BandCN500) {
chMaskGrp45 |= (uint32_t)chMask;
}
break;
case 7:
// for fixed bands: all 125kHz channels ON, channel mask similar to ChMask = 4
// except for CN470: RFU
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_FIXED && this->band->bandNum != BandCN470) {
// except for CN500: RFU
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_FIXED && this->band->bandNum != BandCN500) {
chMaskGrp0123 = 0;
chMaskGrp45 |= (uint32_t)chMask;
}
@ -2482,7 +2419,7 @@ void LoRaWANNode::postprocessMacLinkAdr(uint8_t* ack, uint8_t cLen) {
int16_t LoRaWANNode::getMacCommand(uint8_t cid, LoRaWANMacCommand_t* cmd) {
for(size_t i = 0; i < RADIOLIB_LORAWAN_NUM_MAC_COMMANDS; i++) {
if(MacTable[i].cid == cid) {
memcpy(reinterpret_cast<void*>(cmd), reinterpret_cast<void*>(const_cast<LoRaWANMacCommand_t*>(&MacTable[i])), sizeof(LoRaWANMacCommand_t));
memcpy((void*)cmd, (void*)&MacTable[i], sizeof(LoRaWANMacCommand_t));
return(RADIOLIB_ERR_NONE);
}
}
@ -2549,21 +2486,17 @@ int16_t LoRaWANNode::getMacDeviceTimeAns(uint32_t* gpsEpoch, uint8_t* fraction,
return(RADIOLIB_ERR_NONE);
}
int16_t LoRaWANNode::getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive, uint8_t* payload) {
(void)payload;
*len = 0;
if(inclusive) {
*len += 1; // add one byte for CID
}
int16_t LoRaWANNode::getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive) {
LoRaWANMacCommand_t cmd = RADIOLIB_LORAWAN_MAC_COMMAND_NONE;
int16_t state = this->getMacCommand(cid, &cmd);
RADIOLIB_ASSERT(state);
if(dir == RADIOLIB_LORAWAN_UPLINK) {
*len += cmd.lenUp;
*len = cmd.lenUp;
} else {
*len += cmd.lenDn;
*len = cmd.lenDn;
}
if(inclusive) {
*len += 1; // add one byte for CID
}
return(RADIOLIB_ERR_NONE);
}
@ -2585,7 +2518,7 @@ bool LoRaWANNode::isPersistentMacCommand(uint8_t cid, uint8_t dir) {
return(false);
}
int16_t LoRaWANNode::pushMacCommand(uint8_t cid, const uint8_t* cOcts, uint8_t* out, uint8_t* lenOut, uint8_t dir) {
int16_t LoRaWANNode::pushMacCommand(uint8_t cid, uint8_t* cOcts, uint8_t* out, uint8_t* lenOut, uint8_t dir) {
uint8_t fLen = 0;
int16_t state = this->getMacLen(cid, &fLen, dir, true);
RADIOLIB_ASSERT(state);
@ -2602,7 +2535,7 @@ int16_t LoRaWANNode::pushMacCommand(uint8_t cid, const uint8_t* cOcts, uint8_t*
return(RADIOLIB_ERR_NONE);
}
int16_t LoRaWANNode::getMacPayload(uint8_t cid, const uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t dir) {
int16_t LoRaWANNode::getMacPayload(uint8_t cid, uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t dir) {
size_t i = 0;
while(i < lenIn) {
@ -2665,8 +2598,7 @@ void LoRaWANNode::clearMacCommands(uint8_t* inOut, uint8_t* lenInOut, uint8_t di
uint8_t numDeleted = 0;
while(i < *lenInOut) {
uint8_t id = inOut[i];
uint8_t fLen = 0;
// include CID byte, so if command fails, we still move one byte forward
uint8_t fLen = 1; // if there is an incorrect MAC command, we should at least move forward by one byte
(void)this->getMacLen(id, &fLen, dir, true);
// only clear MAC command if it should not persist until a downlink is received
@ -2690,7 +2622,7 @@ int16_t LoRaWANNode::setDatarate(uint8_t drUp) {
// scan through all enabled channels and check if the requested datarate is available
bool isValidDR = false;
for(size_t i = 0; i < RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS; i++) {
const LoRaWANChannel_t *chnl = &(this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i]);
LoRaWANChannel_t *chnl = &(this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i]);
if(chnl->enabled) {
if(drUp >= chnl->drMin && drUp <= chnl->drMax) {
isValidDR = true;
@ -2935,7 +2867,7 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir,
syncWord[2] = (uint8_t)RADIOLIB_LORAWAN_GFSK_SYNC_WORD;
syncWordLen = 3;
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("FSK: BR = %4.1f, FD = %4.1f kHz",
(double)dr.fsk.bitRate, (double)dr.fsk.freqDev);
dr.fsk.bitRate, dr.fsk.freqDev);
} break;
case(ModemType_t::RADIOLIB_MODEM_LORA): {
@ -2943,7 +2875,7 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir,
syncWord[0] = RADIOLIB_LORAWAN_LORA_SYNC_WORD;
syncWordLen = 1;
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("LoRa: SF = %d, BW = %5.1f kHz, CR = 4/%d, IQ: %c",
dr.lora.spreadingFactor, (double)dr.lora.bandwidth, dr.lora.codingRate, dir ? 'D' : 'U');
dr.lora.spreadingFactor, dr.lora.bandwidth, dr.lora.codingRate, dir ? 'D' : 'U');
} break;
case(ModemType_t::RADIOLIB_MODEM_LRFHSS): {
@ -3028,11 +2960,11 @@ void LoRaWANNode::getChannelPlanMask(uint64_t* chMaskGrp0123, uint32_t* chMaskGr
// if a subband is set, we can set the channel indices straight from subband
if(this->subBand > 0 && this->subBand <= 8) {
// for sub band 1-8, set bank of 8 125kHz + single 500kHz channel
*chMaskGrp0123 |= (uint64_t)0xFF << ((this->subBand - 1) * 8);
*chMaskGrp45 |= (uint32_t)0x01 << (this->subBand - 1);
*chMaskGrp0123 |= 0xFF << ((this->subBand - 1) * 8);
*chMaskGrp45 |= 0x01 << ((this->subBand - 1) * 8);
} else if(this->subBand > 8 && this->subBand <= 12) {
// CN470 only: for sub band 9-12, set bank of 8 125kHz channels
*chMaskGrp45 |= (uint32_t)0xFF << ((this->subBand - 9) * 8);
// CN500 only: for sub band 9-12, set bank of 8 125kHz channels
*chMaskGrp45 |= 0xFF << ((this->subBand - 9) * 8);
} else {
// if subband is set to 0, all 125kHz channels are enabled.
// however, we can 'only' store 16 channels, so we don't use all channels at once.
@ -3049,8 +2981,8 @@ void LoRaWANNode::getChannelPlanMask(uint64_t* chMaskGrp0123, uint32_t* chMaskGr
}
}
// the 500 kHz channels are in the usual channel plan however
// these are the channel indices 64-71 for bands other than CN470
if(this->band->bandNum != BandCN470) {
// these are the channel indices 64-71 for bands other than CN500
if(this->band->bandNum != BandCN500) {
for(int i = 0; i < RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS; i++) {
uint8_t idx = this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i].idx;
if(idx != RADIOLIB_LORAWAN_CHANNEL_INDEX_NONE && idx >= 64) {
@ -3285,7 +3217,7 @@ void LoRaWANNode::printChannels() {
}
#endif
uint32_t LoRaWANNode::generateMIC(const uint8_t* msg, size_t len, uint8_t* key) {
uint32_t LoRaWANNode::generateMIC(uint8_t* msg, size_t len, uint8_t* key) {
if((msg == NULL) || (len == 0)) {
return(0);
}
@ -3375,10 +3307,6 @@ uint8_t LoRaWANNode::getMaxPayloadLen() {
return(curLen - 13 - this->fOptsUpLen);
}
void LoRaWANNode::setSleepFunction(SleepCb_t cb) {
this->sleepCb = cb;
}
int16_t LoRaWANNode::findDataRate(uint8_t dr, DataRate_t* dataRate) {
int16_t state = this->phyLayer->standby();
if(state != RADIOLIB_ERR_NONE) {
@ -3503,18 +3431,6 @@ void LoRaWANNode::processAES(const uint8_t* in, size_t len, uint8_t* key, uint8_
}
}
void LoRaWANNode::sleepDelay(RadioLibTime_t ms) {
// if the user did not provide sleep callback, or the duration is short, just call delay
if((this->sleepCb == nullptr) || (ms <= RADIOLIB_LORAWAN_DELAY_SLEEP_THRESHOLD)) {
Module* mod = this->phyLayer->getMod();
mod->hal->delay(ms);
return;
}
// otherwise, call the user-provided callback
this->sleepCb(ms);
}
int16_t LoRaWANNode::checkBufferCommon(const uint8_t *buffer, uint16_t size) {
// check if there are actually values in the buffer
size_t i = 0;

View file

@ -208,11 +208,6 @@
#define RADIOLIB_LORAWAN_MAX_MAC_COMMAND_LEN_UP (2)
#define RADIOLIB_LORAWAN_MAX_NUM_ADR_COMMANDS (8)
#define RADIOLIB_LORAWAN_MAX_DOWNLINK_SIZE (250)
// threshold at which sleeping via user callback enabled, in ms
#define RADIOLIB_LORAWAN_DELAY_SLEEP_THRESHOLD (50)
/*!
\struct LoRaWANMacCommand_t
\brief MAC command specification structure.
@ -435,7 +430,7 @@ extern const LoRaWANBand_t EU868;
extern const LoRaWANBand_t US915;
extern const LoRaWANBand_t EU433;
extern const LoRaWANBand_t AU915;
extern const LoRaWANBand_t CN470;
extern const LoRaWANBand_t CN500;
extern const LoRaWANBand_t AS923;
extern const LoRaWANBand_t AS923_2;
extern const LoRaWANBand_t AS923_3;
@ -452,7 +447,7 @@ enum LoRaWANBandNum_t {
BandUS915,
BandEU433,
BandAU915,
BandCN470,
BandCN500,
BandAS923,
BandAS923_2,
BandAS923_3,
@ -835,18 +830,6 @@ class LoRaWANNode {
*/
uint8_t getMaxPayloadLen();
/*! \brief Callback to a user-provided sleep function. */
typedef void (*SleepCb_t)(RadioLibTime_t ms);
/*!
\brief Set custom delay/sleep function callback. If set, LoRaWAN node will call
this function to wait for periods of time longer than RADIOLIB_LORAWAN_DELAY_SLEEP_THRESHOLD.
This can be used to lower the power consumption by putting the host microcontroller to sleep.
NOTE: Since this method will call a user-provided function, it is up to the user to ensure
that the time duration spent in that sleep function is accurate to at least 1 ms!
*/
void setSleepFunction(SleepCb_t cb);
/*!
\brief TS009 Protocol Specification Verification switch
(allows FPort 224 and cuts off uplink payload instead of rejecting if maximum length exceeded).
@ -865,7 +848,7 @@ class LoRaWANNode {
500 is the **maximum** value, but it is not a good idea to go anywhere near that.
If you have to go above 50 you probably have a bug somewhere. Check your device timing.
*/
RadioLibTime_t scanGuard = 5;
RadioLibTime_t scanGuard = 10;
#if !RADIOLIB_GODMODE
protected:
@ -988,8 +971,6 @@ class LoRaWANNode {
// allow port 226 for devices implementing TS011
bool TS011 = false;
SleepCb_t sleepCb = nullptr;
// this will reset the device credentials, so the device starts completely new
void clearNonces();
@ -1003,7 +984,7 @@ class LoRaWANNode {
int16_t processJoinAccept(LoRaWANJoinEvent_t *joinEvent);
// a join-accept can piggy-back a set of channels or channel masks
void processCFList(const uint8_t* cfList);
void processCFList(uint8_t* cfList);
// check whether payload length and fport are allowed
int16_t isValidUplink(uint8_t* len, uint8_t fPort);
@ -1018,7 +999,7 @@ class LoRaWANNode {
void micUplink(uint8_t* inOut, uint8_t lenInOut);
// transmit uplink buffer on a specified channel
int16_t transmitUplink(const LoRaWANChannel_t* chnl, uint8_t* in, uint8_t len, bool retrans);
int16_t transmitUplink(LoRaWANChannel_t* chnl, uint8_t* in, uint8_t len, bool retrans);
// wait for, open and listen during receive windows; only performs listening
int16_t receiveCommon(uint8_t dir, const LoRaWANChannel_t* dlChannels, const RadioLibTime_t* dlDelays, uint8_t numWindows, RadioLibTime_t tReference);
@ -1047,8 +1028,7 @@ class LoRaWANNode {
// get the length of a certain MAC command in a specific direction (up/down)
// if inclusive is true, add one for the CID byte
// include payload in case the MAC command has a dynamic length
virtual int16_t getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive = false, uint8_t* payload = NULL);
int16_t getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive = false);
// find out of a MAC command should persist destruction
// in uplink direction, some commands must persist if no downlink is received
@ -1056,10 +1036,10 @@ class LoRaWANNode {
bool isPersistentMacCommand(uint8_t cid, uint8_t dir);
// push MAC command to queue, done by copy
int16_t pushMacCommand(uint8_t cid, const uint8_t* cOcts, uint8_t* out, uint8_t* lenOut, uint8_t dir);
int16_t pushMacCommand(uint8_t cid, uint8_t* cOcts, uint8_t* out, uint8_t* lenOut, uint8_t dir);
// retrieve the payload of a certain MAC command, if present in the buffer
int16_t getMacPayload(uint8_t cid, const uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t dir);
int16_t getMacPayload(uint8_t cid, uint8_t* in, uint8_t lenIn, uint8_t* out, uint8_t dir);
// delete a specific MAC command from queue, indicated by the command ID
int16_t deleteMacCommand(uint8_t cid, uint8_t* inOut, uint8_t* lenInOut, uint8_t dir);
@ -1107,7 +1087,7 @@ class LoRaWANNode {
#endif
// method to generate message integrity code
uint32_t generateMIC(const uint8_t* msg, size_t len, uint8_t* key);
uint32_t generateMIC(uint8_t* msg, size_t len, uint8_t* key);
// method to verify message integrity code
// it assumes that the MIC is the last 4 bytes of the message
@ -1119,9 +1099,6 @@ class LoRaWANNode {
// function to encrypt and decrypt payloads (regular uplink/downlink)
void processAES(const uint8_t* in, size_t len, uint8_t* key, uint8_t* out, uint32_t fCnt, uint8_t dir, uint8_t ctrId, bool counter);
// function that allows sleeping via user-provided callback
void sleepDelay(RadioLibTime_t ms);
// 16-bit checksum method that takes a uint8_t array of even length and calculates the checksum
static uint16_t checkSum16(const uint8_t *key, uint16_t keyLen);

View file

@ -8,7 +8,7 @@ const LoRaWANBand_t* LoRaWANBands[RADIOLIB_LORAWAN_NUM_SUPPORTED_BANDS] = {
&US915,
&EU433,
&AU915,
&CN470,
&CN500,
&AS923,
&AS923_2,
&AS923_3,
@ -331,8 +331,8 @@ const LoRaWANBand_t AU915 = {
}
};
const LoRaWANBand_t CN470 = {
.bandNum = BandCN470,
const LoRaWANBand_t CN500 = {
.bandNum = BandCN500,
.bandType = RADIOLIB_LORAWAN_BAND_FIXED,
.freqMin = 4700000,
.freqMax = 5100000,
@ -356,7 +356,7 @@ const LoRaWANBand_t CN470 = {
.freqStep = 2000,
.drMin = 0,
.drMax = 5,
.drJoinRequest = 3
.drJoinRequest = 0
},
RADIOLIB_LORAWAN_CHANNEL_SPAN_NONE
},

View file

@ -23,7 +23,7 @@ MorseClient::MorseClient(AFSKClient* audio) {
int16_t MorseClient::begin(float base, uint8_t speed) {
// calculate 24-bit frequency
baseFreqHz = base;
baseFreq = (base * 1000000.0f) / phyLayer->freqStep;
baseFreq = (base * 1000000.0) / phyLayer->getFreqStep();
// calculate tone period for decoding
basePeriod = (1000000.0f/base)/2.0f;
@ -48,8 +48,7 @@ char MorseClient::decode(uint8_t symbol, uint8_t len) {
// iterate over the table
for(uint8_t i = 0; i < sizeof(MorseTable); i++) {
uint8_t* ptr = const_cast<uint8_t*>(&MorseTable[i]);
uint8_t code = RADIOLIB_NONVOLATILE_READ_BYTE(ptr);
uint8_t code = RADIOLIB_NONVOLATILE_READ_BYTE(&MorseTable[i]);
if(code == symbol) {
// match, return the index + ASCII offset
return((char)(i + RADIOLIB_MORSE_ASCII_OFFSET));
@ -57,7 +56,7 @@ char MorseClient::decode(uint8_t symbol, uint8_t len) {
}
// nothing found
return(RADIOLIB_MORSE_UNKNOWN_SYMBOL);
return(RADIOLIB_MORSE_UNSUPPORTED);
}
#if !RADIOLIB_EXCLUDE_AFSK
@ -86,7 +85,7 @@ int MorseClient::read(uint8_t* symbol, uint8_t* len, float low, float high) {
if((pauseLen >= low*(float)letterSpace) && (pauseLen <= high*(float)letterSpace)) {
return(RADIOLIB_MORSE_CHAR_COMPLETE);
} else if(pauseLen > wordSpace) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN(RADIOLIB_LINE_FEED "<space>");
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("\n<space>");
return(RADIOLIB_MORSE_WORD_COMPLETE);
}
@ -130,8 +129,7 @@ size_t MorseClient::write(uint8_t b) {
}
// get morse code from lookup table
uint8_t* ptr = const_cast<uint8_t*>(&MorseTable[(uint8_t)(toupper(b) - RADIOLIB_MORSE_ASCII_OFFSET)]);
uint8_t code = RADIOLIB_NONVOLATILE_READ_BYTE(ptr);
uint8_t code = RADIOLIB_NONVOLATILE_READ_BYTE(&MorseTable[(uint8_t)(toupper(b) - RADIOLIB_MORSE_ASCII_OFFSET)]);
// check unsupported characters
if(code == RADIOLIB_MORSE_UNSUPPORTED) {
@ -139,16 +137,15 @@ size_t MorseClient::write(uint8_t b) {
}
// iterate through codeword until guard bit is reached
RADIOLIB_DEBUG_PROTOCOL_PRINT("%c ", b);
while(code > RADIOLIB_MORSE_GUARDBIT) {
// send dot or dash
if (code & RADIOLIB_MORSE_DASH) {
RADIOLIB_DEBUG_PROTOCOL_PRINT_NOTAG("-");
RADIOLIB_DEBUG_PROTOCOL_PRINT("-");
transmitDirect(baseFreq, baseFreqHz);
mod->waitForMicroseconds(mod->hal->micros(), dashLength*1000);
} else {
RADIOLIB_DEBUG_PROTOCOL_PRINT_NOTAG(".");
RADIOLIB_DEBUG_PROTOCOL_PRINT(".");
transmitDirect(baseFreq, baseFreqHz);
mod->waitForMicroseconds(mod->hal->micros(), dotLength*1000);
}
@ -164,7 +161,7 @@ size_t MorseClient::write(uint8_t b) {
// letter space
standby();
mod->waitForMicroseconds(mod->hal->micros(), letterSpace*1000 - dotLength*1000);
RADIOLIB_DEBUG_PROTOCOL_PRINT_NOTAG(RADIOLIB_LINE_FEED);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN();
return(1);
}

View file

@ -14,7 +14,6 @@
#define RADIOLIB_MORSE_INTER_SYMBOL 0x00
#define RADIOLIB_MORSE_CHAR_COMPLETE 0x01
#define RADIOLIB_MORSE_WORD_COMPLETE 0x02
#define RADIOLIB_MORSE_UNKNOWN_SYMBOL '*'
// Morse character table: - using codes defined in ITU-R M.1677-1
// - Morse code representation is saved LSb first, using additional bit as guard
@ -172,6 +171,9 @@ class MorseClient: public RadioLibPrint {
uint32_t pauseCounter = 0;
RadioLibTime_t pauseStart = 0;
size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
int16_t transmitDirect(uint32_t freq = 0, uint32_t freqHz = 0);
int16_t standby();
};

View file

@ -39,10 +39,10 @@ int16_t PagerClient::begin(float base, uint16_t speed, bool invert, uint16_t shi
// calculate 24-bit frequency
baseFreq = base;
baseFreqRaw = (baseFreq * 1000000.0f) / phyLayer->freqStep;
baseFreqRaw = (baseFreq * 1000000.0) / phyLayer->getFreqStep();
// calculate module carrier frequency resolution
uint16_t step = round(phyLayer->freqStep);
uint16_t step = round(phyLayer->getFreqStep());
// calculate raw frequency shift
shiftFreqHz = shift;
@ -67,10 +67,10 @@ int16_t PagerClient::transmit(String& str, uint32_t addr, uint8_t encoding, uint
#endif
int16_t PagerClient::transmit(const char* str, uint32_t addr, uint8_t encoding, uint8_t function) {
return(PagerClient::transmit(reinterpret_cast<uint8_t*>(const_cast<char*>(str)), strlen(str), addr, encoding, function));
return(PagerClient::transmit((uint8_t*)str, strlen(str), addr, encoding, function));
}
int16_t PagerClient::transmit(const uint8_t* data, size_t len, uint32_t addr, uint8_t encoding, uint8_t function) {
int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t encoding, uint8_t function) {
if(addr > RADIOLIB_PAGER_ADDRESS_MAX) {
return(RADIOLIB_ERR_INVALID_ADDRESS_WIDTH);
}
@ -326,14 +326,14 @@ int16_t PagerClient::readData(String& str, size_t len, uint32_t* addr) {
// check tone-only transmissions
if(length == 0) {
length = 6;
strncpy(reinterpret_cast<char*>(data), "<tone>", length + 1);
strncpy((char*)data, "<tone>", length + 1);
}
// add null terminator
data[length] = 0;
// initialize Arduino String class
str = String(reinterpret_cast<char*>(data));
str = String((char*)data);
}
// deallocate temporary buffer
@ -494,7 +494,7 @@ bool PagerClient::addressMatched(uint32_t addr) {
return(false);
}
void PagerClient::write(const uint32_t* data, size_t len) {
void PagerClient::write(uint32_t* data, size_t len) {
// write code words from buffer
for(size_t i = 0; i < len; i++) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("POCSAG W\t%lu\t%08lX", (long unsigned int)i, (long unsigned int)data[i]);

View file

@ -117,7 +117,7 @@ class PagerClient {
\param function bits (NUMERIC, TONE, ACTIVATION, ALPHANUMERIC). Allowed values 0 to 3. Defaults to auto select by specified encoding
\returns \ref status_codes
*/
int16_t transmit(const uint8_t* data, size_t len, uint32_t addr, uint8_t encoding = RADIOLIB_PAGER_BCD, uint8_t function = RADIOLIB_PAGER_FUNC_AUTO);
int16_t transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t encoding = RADIOLIB_PAGER_BCD, uint8_t function = RADIOLIB_PAGER_FUNC_AUTO);
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
/*!
@ -190,7 +190,7 @@ class PagerClient {
size_t filterNumAddresses = 0;
bool inv = false;
void write(const uint32_t* data, size_t len);
void write(uint32_t* data, size_t len);
void write(uint32_t codeWord);
int16_t startReceiveCommon();
bool addressMatched(uint32_t addr);

Some files were not shown because too many files have changed in this diff Show more