Compare commits
No commits in common. "master" and "17.0.1" have entirely different histories.
110 changed files with 1636 additions and 2593 deletions
22
.github/workflows/main.yml
vendored
22
.github/workflows/main.yml
vendored
|
@ -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:
|
||||
|
|
25
.github/workflows/unit-test.yml
vendored
25
.github/workflows/unit-test.yml
vendored
|
@ -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
3
.gitignore
vendored
|
@ -11,6 +11,9 @@
|
|||
# Jetbrain IDEs
|
||||
.idea
|
||||
|
||||
# Spectrum scan
|
||||
extras/SX126x_Spectrum_Scan/out/*
|
||||
|
||||
# PlatformIO
|
||||
.pio*
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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 ...
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ...
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
RadioLib SX126x LR-FHSS Modem Example
|
||||
|
||||
This example shows how to use LR-FHSS modem in SX126x chips.
|
||||
This modem can only transmit data, and is not able to receive.
|
||||
|
||||
This example transmits packets using SX1262 LoRa radio module.
|
||||
Each packet contains up to 256 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Other modules from SX126x family can also be used.
|
||||
|
||||
Using blocking transmit is not recommended, as it will lead
|
||||
to inefficient use of processor time!
|
||||
Instead, interrupt transmit is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lr-fhss-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1262 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
SX1262 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1262 with default settings
|
||||
Serial.print(F("[SX1262] Initializing ... "));
|
||||
int state = radio.beginLRFHSS();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// some modules have an external RF switch
|
||||
// controlled via two pins (RX enable, TX enable)
|
||||
// to enable automatic control of the switch,
|
||||
// call the following method
|
||||
// RX enable: 4
|
||||
// TX enable: 5
|
||||
/*
|
||||
radio.setRfSwitchPins(4, 5);
|
||||
*/
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
// LR-FHSS modem can only transmit!
|
||||
Serial.print(F("[SX1262] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
int state = radio.transmit(str);
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print measured data rate
|
||||
Serial.print(F("[SX1262] Datarate:\t"));
|
||||
Serial.print(radio.getDataRate());
|
||||
Serial.println(F(" bps"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 256 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||
// timeout occurred while transmitting packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
RadioLib SX126x LR-FHSS Transmit with Interrupts Example
|
||||
|
||||
This example shows how to use LR-FHSS modem in SX126x chips.
|
||||
This modem can only transmit data, and is not able to receive.
|
||||
|
||||
This example transmits packets using SX1262 LoRa radio module.
|
||||
Each packet contains up to 256 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Other modules from SX126x family can also be used.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lr-fhss-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1262 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
SX1262 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// save transmission state between loops
|
||||
int transmissionState = RADIOLIB_ERR_NONE;
|
||||
|
||||
// flag to indicate that a packet was sent
|
||||
// or a frequency hop is needed
|
||||
volatile bool flag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is transmitted by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we sent a packet or need to hop, set the flag
|
||||
flag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1262 with default settings
|
||||
Serial.print(F("[SX1262] Initializing ... "));
|
||||
int state = radio.beginLRFHSS();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when packet transmission is finished
|
||||
radio.setPacketSentAction(setFlag);
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("[SX1262] Sending first packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
transmissionState = radio.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
// LR-FHSS modem can only transmit!
|
||||
|
||||
// check if the previous transmission finished
|
||||
if(flag) {
|
||||
// reset flag
|
||||
flag = false;
|
||||
|
||||
// check if this was caused by hopping or transmission finished
|
||||
if(radio.getIrqFlags() & RADIOLIB_SX126X_IRQ_LR_FHSS_HOP) {
|
||||
radio.hopLRFHSS();
|
||||
|
||||
} else {
|
||||
if (transmissionState == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully sent
|
||||
Serial.println(F("transmission finished!"));
|
||||
|
||||
// NOTE: when using interrupt-driven transmit method,
|
||||
// it is not possible to automatically measure
|
||||
// transmission data rate using getDataRate()
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(transmissionState);
|
||||
|
||||
}
|
||||
|
||||
// clean up after transmission is finished
|
||||
// this will ensure transmitter is disabled,
|
||||
// RF switch is powered down etc.
|
||||
radio.finishTransmit();
|
||||
|
||||
// wait a second before transmitting again
|
||||
delay(1000);
|
||||
|
||||
// send another one
|
||||
Serial.print(F("[SX1262] Sending another packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
transmissionState = radio.startTransmit(str);
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
transmissionState = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
2
extras/SX126x_Spectrum_Scan/out/.gitignore
vendored
2
extras/SX126x_Spectrum_Scan/out/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
# all output pictures
|
||||
*.png
|
|
@ -1,18 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 <path to check>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
path=$1
|
||||
|
||||
cppcheck --version
|
||||
cppcheck $path --enable=all \
|
||||
--force \
|
||||
--inline-suppr \
|
||||
--suppress=ConfigurationNotChecked \
|
||||
--suppress=unusedFunction \
|
||||
--suppress=missingIncludeSystem \
|
||||
--suppress=missingInclude \
|
||||
--quiet
|
|
@ -2,14 +2,7 @@
|
|||
|
||||
file=cppcheck.txt
|
||||
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)
|
||||
|
|
1
extras/test/unit/.gitignore
vendored
1
extras/test/unit/.gitignore
vendored
|
@ -1,2 +1 @@
|
|||
build/
|
||||
lcov*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
112
src/BuildOpt.h
112
src/BuildOpt.h
|
@ -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.
|
||||
|
|
12
src/Hal.cpp
12
src/Hal.cpp
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
12
src/Module.h
12
src/Module.h
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue