Merge branch 'jgromes:master' into Buffer-Pull
This commit is contained in:
commit
5ce49b9933
122 changed files with 78710 additions and 1984 deletions
3
.gitattributes
vendored
Normal file
3
.gitattributes
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# exclude binary patch files from language detection
|
||||
src/modules/SX126x/patches/*.h linguist-detectable=false
|
||||
src/modules/LR11x0/firmware/*.h linguist-detectable=false
|
2
.github/workflows/cppcheck.yml
vendored
2
.github/workflows/cppcheck.yml
vendored
|
@ -24,4 +24,4 @@ jobs:
|
|||
|
||||
- name: Run cppcheck
|
||||
run:
|
||||
cppcheck src --enable=all --force
|
||||
cppcheck src --enable=all --force --inline-suppr --quiet --suppress=ConfigurationNotChecked --suppress=unusedFunction
|
||||
|
|
15
.github/workflows/main.yml
vendored
15
.github/workflows/main.yml
vendored
|
@ -46,15 +46,16 @@ jobs:
|
|||
# platform-dependent settings - extra board options, board index URLs, skip patterns etc.
|
||||
include:
|
||||
- id: arduino:avr:uno
|
||||
run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN)" >> $GITHUB_OUTPUT
|
||||
run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
||||
- id: arduino:avr:mega
|
||||
run: echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT
|
||||
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
||||
- id: arduino:mbed:nano33ble
|
||||
- id: arduino:mbed:envie_m4
|
||||
- id: arduino:megaavr:uno2018
|
||||
run: |
|
||||
echo "options=':mode=on'" >> $GITHUB_OUTPUT
|
||||
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
|
||||
echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
||||
- id: arduino:sam:arduino_due_x
|
||||
- id: arduino:samd:arduino_zero_native
|
||||
- id: adafruit:samd:adafruit_feather_m0
|
||||
|
@ -110,7 +111,7 @@ jobs:
|
|||
echo "index-url=--additional-urls https://www.pjrc.com/teensy/package_teensy_index.json" >> $GITHUB_OUTPUT
|
||||
- id: arduino:renesas_uno:minima
|
||||
run: |
|
||||
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
|
||||
echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
name: ${{ matrix.id }}
|
||||
|
@ -170,7 +171,7 @@ jobs:
|
|||
else
|
||||
# apply special flags for LoRaWAN
|
||||
if [[ ${example} =~ "LoRaWAN" ]]; then
|
||||
flags="-DRADIOLIB_LORAWAN_DEV_ADDR=0 -DRADIOLIB_LORAWAN_NWKS_KEY=0 -DRADIOLIB_LORAWAN_SNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_NWKSENC_KEY=0 -DRADIOLIB_LORAWAN_APPS_KEY=0 -DRADIOLIB_LORAWAN_APP_KEY=0 -DRADIOLIB_LORAWAN_NWK_KEY=0 -DRADIOLIB_LORAWAN_DEV_EUI=0 -DARDUINO_TTGO_LORA32_V1"
|
||||
flags="-DRADIOLIB_LORAWAN_DEV_ADDR=0 -DRADIOLIB_LORAWAN_FNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_SNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_NWKSENC_KEY=0 -DRADIOLIB_LORAWAN_APPS_KEY=0 -DRADIOLIB_LORAWAN_APP_KEY=0 -DRADIOLIB_LORAWAN_NWK_KEY=0 -DRADIOLIB_LORAWAN_DEV_EUI=0 -DARDUINO_TTGO_LORA32_V1"
|
||||
fi
|
||||
|
||||
# build sketch
|
||||
|
@ -226,13 +227,15 @@ jobs:
|
|||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get install -y gcc-arm-none-eabi
|
||||
sudo apt-get install -y gcc-arm-none-eabi gcc-riscv64-unknown-elf
|
||||
cargo install elf2tab
|
||||
|
||||
- name: Build the example
|
||||
run: |
|
||||
cd $PWD/examples/NonArduino/Tock
|
||||
./build.sh
|
||||
git clone https://github.com/tock/libtock-c.git
|
||||
cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../
|
||||
LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
||||
|
||||
rpi-build:
|
||||
runs-on: [self-hosted, ARM64]
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
|||
[submodule "examples/NonArduino/Tock/libtock-c"]
|
||||
path = examples/NonArduino/Tock/libtock-c
|
||||
url = https://github.com/tock/libtock-c.git
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
RadioLib LR11x0 Firmware Update Example
|
||||
|
||||
This example updates the internal LR1110 firmware.
|
||||
Newer versions of the firmware introduce fixes
|
||||
and possibly even new features, so it is recommended
|
||||
to use the latest available firmware version
|
||||
when possible.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// select the firmware image you want to upload
|
||||
// WARNING: Make sure you select the correct firmware
|
||||
// for your device! Uploading incorrect firmware
|
||||
// (e.g. LR1110 firmware to LR1120 device)
|
||||
// may damage your hardware!
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0303
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0304
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0305
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0306
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0307
|
||||
#define RADIOLIB_LR1110_FIRMWARE_0401
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0101
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0102
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0201
|
||||
//#define RADIOLIB_LR1121_FIRMWARE_0102
|
||||
//#define RADIOLIB_LR1121_FIRMWARE_0103
|
||||
|
||||
// enable this macro if you want to store the image in host
|
||||
// MCU RAM instead of Flash.
|
||||
// NOTE: the firmware images are very large, up to 240 kB!
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_IN_RAM
|
||||
|
||||
// include the firmware image
|
||||
#include <modules/LR11x0/LR11x0_firmware.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//LR1110 radio = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// print the firmware versions before the update
|
||||
printVersions();
|
||||
|
||||
// prompt the user
|
||||
Serial.println(F("[LR1110] Send any character to start the update"));
|
||||
while(!Serial.available()) { yield(); }
|
||||
|
||||
// upload update into LR11x0 non-volatile memory
|
||||
Serial.print(F("[LR1110] Updating firmware, this may take several seconds ... "));
|
||||
state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE);
|
||||
/*
|
||||
use the following if you enabled RADIOLIB_LR1110_FIRMWARE_IN_RAM
|
||||
state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE, false);
|
||||
*/
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// print the firmware versions after the update
|
||||
printVersions();
|
||||
|
||||
}
|
||||
|
||||
void printVersions() {
|
||||
LR11x0VersionInfo_t version;
|
||||
Serial.print(F("[LR1110] Reading firmware versions ... "));
|
||||
int16_t state = radio.getVersionInfo(&version);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
Serial.print(F("[LR1110] Device: "));
|
||||
Serial.println(version.device);
|
||||
|
||||
Serial.print(F("[LR1110] Base firmware: "));
|
||||
Serial.print(version.fwMajor);
|
||||
Serial.print('.');
|
||||
Serial.println(version.fwMinor);
|
||||
|
||||
Serial.print(F("[LR1110] WiFi firmware: "));
|
||||
Serial.print(version.fwMajorWiFi);
|
||||
Serial.print('.');
|
||||
Serial.println(version.fwMinorWiFi);
|
||||
|
||||
Serial.print(F("[LR1110] GNSS firmware: "));
|
||||
Serial.print(version.fwGNSS);
|
||||
Serial.print('.');
|
||||
Serial.println(version.almanacGNSS);
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
RadioLib LR11x0 WiFi scan Blocking Example
|
||||
|
||||
This example performs a passive scan of WiFi networks.
|
||||
The scan shows basic information about the networks,
|
||||
such as the frequency, country code and SSID.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
Using blocking scan is not recommended, as depending
|
||||
on the scan settings, the program may be blocked
|
||||
for several seconds! Instead, interrupt scan is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//LR1110 radio = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[LR1110] Running WiFi scan ... "));
|
||||
|
||||
// scan all WiFi signals with default scan configuration
|
||||
uint8_t count = 0;
|
||||
int state = radio.wifiScan('*', &count);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the table header
|
||||
Serial.print(F("[LR1110] Reading "));
|
||||
Serial.print(count);
|
||||
Serial.println(F(" scan results:"));
|
||||
Serial.println(F(" # | WiFi type\t| Frequency\t| MAC Address\t | Country\t| RSSI [dBm]\t| SSID"));
|
||||
|
||||
// read all results one by one
|
||||
// this result type contains the most information, including the SSID
|
||||
LR11x0WifiResultExtended_t result;
|
||||
for(int i = 0; i < count; i++) {
|
||||
if(i < 10) { Serial.print(" "); } Serial.print(i); Serial.print(" | ");
|
||||
state = radio.getWifiScanResult(&result, i);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed to read result, code "));
|
||||
Serial.println(state);
|
||||
continue;
|
||||
}
|
||||
|
||||
// print the basic information
|
||||
Serial.print(F("802.11")); Serial.print(result.type); Serial.print("\t| ");
|
||||
Serial.print(result.channelFreq); Serial.print(" MHz\t| ");
|
||||
|
||||
// print MAC address
|
||||
for(int j = 0; j < 6; j++) {
|
||||
if(result.mac[j] < 0x10) { Serial.print("0"); }
|
||||
Serial.print(result.mac[j], HEX);
|
||||
if(j < 5) { Serial.print(":"); }
|
||||
}
|
||||
Serial.print(" | ");
|
||||
|
||||
// print the two-letter country code
|
||||
String country = result.countryCode;
|
||||
Serial.print(country);
|
||||
Serial.print(" \t| ");
|
||||
|
||||
// print the RSSI
|
||||
Serial.print(result.rssi);
|
||||
Serial.print("\t| ");
|
||||
|
||||
// print the network SSID
|
||||
Serial.println((char*)result.ssid);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before scanning again
|
||||
delay(1000);
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
RadioLib LR11x0 WiFi scan Interrupt Example
|
||||
|
||||
This example performs a passive scan of WiFi networks.
|
||||
The scan shows basic information about the networks,
|
||||
such as the frequency, country code and SSID.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
Using blocking scan is not recommended, as depending
|
||||
on the scan settings, the program may be blocked
|
||||
for several seconds! Instead, interrupt scan is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//LR1110 radio = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when WiFi scan is complete
|
||||
radio.setIrqAction(setFlag);
|
||||
|
||||
// scan all WiFi signals with default scan configuration
|
||||
Serial.print(F("[LR1110] Starting passive WiFi scan ... "));
|
||||
state = radio.startWifiScan('*');
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
// flag to indicate that a scan was completed
|
||||
volatile bool scanFlag = false;
|
||||
|
||||
// this function is called when a scan is completed
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// scan is complete, set the flag
|
||||
scanFlag = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(scanFlag) {
|
||||
// reset flag
|
||||
scanFlag = false;
|
||||
|
||||
// get the number of scan results
|
||||
uint8_t count = 0;
|
||||
Serial.print(F("[LR1110] Reading WiFi scan results ... "));
|
||||
int state = radio.getWifiScanResultsCount(&count);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the table header
|
||||
Serial.print(F("[LR1110] Reading "));
|
||||
Serial.print(count);
|
||||
Serial.println(F(" scan results:"));
|
||||
Serial.println(F(" # | WiFi type\t| Frequency\t| MAC Address\t | Country\t| RSSI [dBm]\t| SSID"));
|
||||
|
||||
// read all results one by one
|
||||
// this result type contains the most information, including the SSID
|
||||
LR11x0WifiResultExtended_t result;
|
||||
for(int i = 0; i < count; i++) {
|
||||
if(i < 10) { Serial.print(" "); } Serial.print(i); Serial.print(" | ");
|
||||
state = radio.getWifiScanResult(&result, i);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed to read result, code "));
|
||||
Serial.println(state);
|
||||
continue;
|
||||
}
|
||||
|
||||
// print the basic information
|
||||
Serial.print(F("802.11")); Serial.print(result.type); Serial.print("\t| ");
|
||||
Serial.print(result.channelFreq); Serial.print(" MHz\t| ");
|
||||
|
||||
// print MAC address
|
||||
for(int j = 0; j < 6; j++) {
|
||||
if(result.mac[j] < 0x10) { Serial.print("0"); }
|
||||
Serial.print(result.mac[j], HEX);
|
||||
if(j < 5) { Serial.print(":"); }
|
||||
}
|
||||
Serial.print(" | ");
|
||||
|
||||
// print the two-letter country code
|
||||
String country = result.countryCode;
|
||||
Serial.print(country);
|
||||
Serial.print(" \t| ");
|
||||
|
||||
// print the RSSI
|
||||
Serial.print(result.rssi);
|
||||
Serial.print("\t| ");
|
||||
|
||||
// print the network SSID
|
||||
Serial.println((char*)result.ssid);
|
||||
}
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// start scanning again
|
||||
Serial.print(F("[LR1110] Starting passive WiFi scan ... "));
|
||||
state = radio.startWifiScan('*');
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ void setup() {
|
|||
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
|
||||
|
||||
Serial.println(F("Initialise LoRaWAN Network credentials"));
|
||||
state = node.beginABP(devAddr, NwkSEncKey, AppSKey, NwkSKey, SNwkSIntKey, true);
|
||||
state = node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey, true);
|
||||
debug(state < RADIOLIB_ERR_NONE, F("Session setup failed"), state, true);
|
||||
|
||||
Serial.println(F("Ready!\n"));
|
||||
|
|
|
@ -12,8 +12,8 @@ const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
|||
#define RADIOLIB_LORAWAN_DEV_ADDR 0x------
|
||||
#endif
|
||||
|
||||
#ifndef RADIOLIB_LORAWAN_NWKS_KEY // Replace with your NwkS Key
|
||||
#define RADIOLIB_LORAWAN_NWKS_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#ifndef RADIOLIB_LORAWAN_FNWKSINT_KEY // Replace with your FNwkSInt Key
|
||||
#define RADIOLIB_LORAWAN_FNWKSINT_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_SNWKSINT_KEY // Replace with your SNwkSInt Key
|
||||
#define RADIOLIB_LORAWAN_SNWKSINT_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
|
@ -118,10 +118,10 @@ const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
|||
|
||||
// copy over the keys in to the something that will not compile if incorrectly formatted
|
||||
uint32_t devAddr = RADIOLIB_LORAWAN_DEV_ADDR;
|
||||
uint8_t NwkSKey[] = { RADIOLIB_LORAWAN_NWKS_KEY };
|
||||
uint8_t SNwkSIntKey[] = { RADIOLIB_LORAWAN_SNWKSINT_KEY }; // Previously sNwkSIntKey
|
||||
uint8_t NwkSEncKey[] = { RADIOLIB_LORAWAN_NWKSENC_KEY }; // Previously fNwkSIntKey
|
||||
uint8_t AppSKey[] = { RADIOLIB_LORAWAN_APPS_KEY };
|
||||
uint8_t fNwkSIntKey[] = { RADIOLIB_LORAWAN_FNWKSINT_KEY };
|
||||
uint8_t sNwkSIntKey[] = { RADIOLIB_LORAWAN_SNWKSINT_KEY };
|
||||
uint8_t nwkSEncKey[] = { RADIOLIB_LORAWAN_NWKSENC_KEY };
|
||||
uint8_t appSKey[] = { RADIOLIB_LORAWAN_APPS_KEY };
|
||||
|
||||
// create the LoRaWAN node
|
||||
LoRaWANNode node(&radio, &Region, subBand);
|
||||
|
|
|
@ -105,14 +105,14 @@ void loop() {
|
|||
uint8_t Port = 10;
|
||||
|
||||
// Retrieve the last uplink frame counter
|
||||
uint32_t fcntUp = node.getFcntUp();
|
||||
uint32_t fcntUp = node.getFCntUp();
|
||||
|
||||
// Send a confirmed uplink every 64th frame
|
||||
// and also request the LinkCheck and DeviceTime MAC commands
|
||||
if(fcntUp % 64 == 0) {
|
||||
Serial.println(F("[LoRaWAN] Requesting LinkCheck and DeviceTime"));
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
|
||||
node.sendMacCommandReq(RADIOLIB_LW_MAC_LINK_CHECK);
|
||||
node.sendMacCommandReq(RADIOLIB_LW_MAC_DEVICE_TIME);
|
||||
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), Port, downlinkPayload, &downlinkSize, true, &uplinkDetails, &downlinkDetails);
|
||||
} else {
|
||||
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), Port, downlinkPayload, &downlinkSize);
|
||||
|
@ -159,9 +159,9 @@ void loop() {
|
|||
Serial.print(downlinkDetails.power);
|
||||
Serial.println(F(" dBm"));
|
||||
Serial.print(F("[LoRaWAN] Frame count:\t"));
|
||||
Serial.println(downlinkDetails.fcnt);
|
||||
Serial.println(downlinkDetails.fCnt);
|
||||
Serial.print(F("[LoRaWAN] Port:\t\t"));
|
||||
Serial.println(downlinkDetails.port);
|
||||
Serial.println(downlinkDetails.fPort);
|
||||
|
||||
uint8_t margin = 0;
|
||||
uint8_t gwCnt = 0;
|
||||
|
|
|
@ -18,4 +18,5 @@ add_executable(${PROJECT_NAME} main.cpp)
|
|||
target_link_libraries(${PROJECT_NAME} RadioLib pigpio)
|
||||
|
||||
# you can also specify RadioLib compile-time flags here
|
||||
#target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_DEBUG RADIOLIB_VERBOSE)
|
||||
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI)
|
||||
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_PORT=stdout)
|
||||
|
|
2
examples/NonArduino/Tock/.gitignore
vendored
2
examples/NonArduino/Tock/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
|||
build/
|
||||
build-*
|
||||
TockApp.tab
|
||||
|
|
|
@ -27,9 +27,13 @@ cmake_minimum_required(VERSION 3.18)
|
|||
# create the project
|
||||
project(tock-sx1261)
|
||||
|
||||
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/userland_generic.ld)
|
||||
set(LINKER_SCRIPT $ENV{LIBTOCK_C_DIRECTORY}/userland_generic.ld)
|
||||
|
||||
include("tock.cmake")
|
||||
if (RISCV_BUILD)
|
||||
include("tock-riscv.cmake")
|
||||
else()
|
||||
include("tock-arm.cmake")
|
||||
endif()
|
||||
|
||||
# when using debuggers such as gdb, the following line can be used
|
||||
#set(CMAKE_BUILD_TYPE Debug)
|
||||
|
@ -43,18 +47,66 @@ add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CUR
|
|||
add_executable(${PROJECT_NAME} main.cpp)
|
||||
|
||||
# link with RadioLib and libtock-c
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/libtock/build/cortex-m4/libtock.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/libc++/cortex-m/libgcc.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/libc++/cortex-m/libstdc++.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/newlib/cortex-m/v7-m/libc.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/newlib/cortex-m/v7-m/libm.a
|
||||
)
|
||||
# The build system for libtock-c is a bit odd and the version of libraries
|
||||
# built changes based on compiler version.
|
||||
if (RISCV_BUILD)
|
||||
if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0")
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/riscv/lib/gcc/riscv64-unknown-elf/13.2.0/rv32i/ilp32/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
|
||||
)
|
||||
|
||||
target_include_directories(RadioLib AFTER PUBLIC
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/include/
|
||||
)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/riscv/lib/gcc/riscv64-unknown-elf/10.5.0/rv32i/ilp32/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
|
||||
)
|
||||
|
||||
target_include_directories(RadioLib AFTER PUBLIC
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/include/
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0")
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/arm/lib/gcc/arm-none-eabi/13.2.0/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/arm/arm-none-eabi/lib/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/lib/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/lib/libm.a
|
||||
)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/arm/lib/gcc/arm-none-eabi/10.5.0/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/arm/arm-none-eabi/lib/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/arm/arm-none-eabi/lib/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/arm/arm-none-eabi/lib/libm.a
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libtock-c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/
|
||||
$ENV{LIBTOCK_C_DIRECTORY}
|
||||
)
|
||||
|
||||
# you can also specify RadioLib compile-time flags here
|
||||
|
|
|
@ -13,16 +13,22 @@ This has been tested on the
|
|||
but will work on any LoRa compatible Tock board (currently only the
|
||||
expLoRaBLE board).
|
||||
|
||||
libtock-c by default is bulit for RISC-V and ARM. RadioLib is also built
|
||||
for both architectures by default. You can skip the RISC-V RadioLib build
|
||||
by setting the `SKIP_RISCV` varaible.
|
||||
|
||||
The RadioLib example can be built with:
|
||||
|
||||
```shell
|
||||
$ git clone https://github.com/jgromes/RadioLib.git
|
||||
$ cd RadioLib/examples/NonArduino/Tock/
|
||||
$ ./build.sh
|
||||
$ git clone https://github.com/tock/libtock-c.git
|
||||
$ cd libtock-c; git checkout dbee65a56d74b4bad166317f199e80b959f7c82c; cd ../
|
||||
$ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
||||
```
|
||||
|
||||
Then in the Tock repo you can flash the kernel and app with:
|
||||
|
||||
```shell
|
||||
$ make flash; APP=RadioLib/examples/NonArduino/Tock/build/tock-sx1261.tbf make flash-app
|
||||
$ make flash; APP=RadioLib/examples/NonArduino/Tock/build-arm/tock-sx1261.tbf make flash-app
|
||||
```
|
||||
|
|
|
@ -1,20 +1,30 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
rm -rf ./build
|
||||
rm -rf ./build-*
|
||||
|
||||
cd libtock-c/libtock
|
||||
cd libtock-c/examples/cxx_hello
|
||||
make -j4
|
||||
cd ../../
|
||||
cd ../../../
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
mkdir -p build-arm
|
||||
cd build-arm
|
||||
|
||||
cmake -G "CodeBlocks - Unix Makefiles" ..
|
||||
make -j4
|
||||
|
||||
cd ..
|
||||
|
||||
if ! env | grep SKIP_RISCV; then
|
||||
mkdir -p build-riscv
|
||||
cd build-riscv
|
||||
|
||||
cmake -G "CodeBlocks - Unix Makefiles" -DRISCV_BUILD=1 ..
|
||||
make -j4
|
||||
|
||||
cd ..
|
||||
fi
|
||||
|
||||
elf2tab -n radio-lib --stack 4096 --app-heap 2048 --kernel-heap 2048 \
|
||||
--kernel-major 2 --kernel-minor 1 \
|
||||
-v ./build/tock-sx1261
|
||||
-v ./build-arm/tock-sx1261
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 1c1f4c0810aa0fbd50aa91a11aaa7c05d2abb1bc
|
|
@ -31,10 +31,12 @@
|
|||
#include <RadioLib.h>
|
||||
|
||||
// include all the dependencies
|
||||
#include "libtock/lora_phy.h"
|
||||
#include "libtock/gpio.h"
|
||||
#include "libtock/timer.h"
|
||||
#include "libtock/read_only_state.h"
|
||||
#include "libtock/net/lora_phy.h"
|
||||
#include "libtock/net/syscalls/lora_phy_syscalls.h"
|
||||
#include "libtock-sync/net/lora_phy.h"
|
||||
#include "libtock/peripherals/gpio.h"
|
||||
#include "libtock-sync/services/alarm.h"
|
||||
#include "libtock/kernel/read_only_state.h"
|
||||
|
||||
#define RADIO_BUSY 1
|
||||
#define RADIO_DIO_1 2
|
||||
|
@ -99,9 +101,9 @@ class TockHal : public RadioLibHal {
|
|||
}
|
||||
|
||||
if (mode == PIN_OUTPUT) {
|
||||
lora_phy_gpio_enable_output(pin);
|
||||
libtock_lora_phy_gpio_enable_output(pin);
|
||||
} else if (mode == PIN_INPUT) {
|
||||
lora_phy_gpio_enable_input(pin, PullDown);
|
||||
libtock_lora_phy_gpio_enable_input(pin, libtock_pull_down);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,9 +113,9 @@ class TockHal : public RadioLibHal {
|
|||
}
|
||||
|
||||
if (value) {
|
||||
lora_phy_gpio_set(pin);
|
||||
libtock_lora_phy_gpio_set(pin);
|
||||
} else {
|
||||
lora_phy_gpio_clear(pin);
|
||||
libtock_lora_phy_gpio_clear(pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +126,7 @@ class TockHal : public RadioLibHal {
|
|||
return 0;
|
||||
}
|
||||
|
||||
lora_phy_gpio_read(pin, &value);
|
||||
libtock_lora_phy_gpio_read(pin, &value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -134,11 +136,11 @@ class TockHal : public RadioLibHal {
|
|||
return;
|
||||
}
|
||||
|
||||
lora_phy_gpio_interrupt_callback(lora_phy_gpio_Callback, &interruptCb);
|
||||
libtock_lora_phy_gpio_command_interrupt_callback(lora_phy_gpio_Callback, &interruptCb);
|
||||
|
||||
// set GPIO as input and enable interrupts on it
|
||||
lora_phy_gpio_enable_input(interruptNum, PullDown);
|
||||
lora_phy_gpio_enable_interrupt(interruptNum, Change);
|
||||
libtock_lora_phy_gpio_enable_input(interruptNum, libtock_pull_down);
|
||||
libtock_lora_phy_gpio_enable_interrupt(interruptNum, libtock_change);
|
||||
}
|
||||
|
||||
void detachInterrupt(uint32_t interruptNum) override {
|
||||
|
@ -146,15 +148,15 @@ class TockHal : public RadioLibHal {
|
|||
return;
|
||||
}
|
||||
|
||||
lora_phy_gpio_disable_interrupt(interruptNum);
|
||||
libtock_lora_phy_gpio_disable_interrupt(interruptNum);
|
||||
}
|
||||
|
||||
void delay(unsigned long ms) override {
|
||||
delay_ms( ms );
|
||||
libtocksync_alarm_delay_ms( ms );
|
||||
}
|
||||
|
||||
void delayMicroseconds(unsigned long us) override {
|
||||
delay_ms( us / 1000 );
|
||||
libtocksync_alarm_delay_ms( us / 1000 );
|
||||
}
|
||||
|
||||
unsigned long millis() override {
|
||||
|
@ -181,7 +183,7 @@ class TockHal : public RadioLibHal {
|
|||
}
|
||||
|
||||
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
|
||||
lora_phy_read_write_sync((const char*) out, (char*) in, len);
|
||||
libtocksync_lora_phy_read_write(out, in, len);
|
||||
}
|
||||
|
||||
void spiEndTransaction() {
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
# This is copied from https://github.com/Lora-net/LoRaMac-node/pull/1390
|
||||
# and has been relicensed by the original author
|
||||
|
||||
include("toolchain-arm-none-eabi.cmake")
|
||||
|
||||
if(NOT DEFINED LINKER_SCRIPT)
|
||||
message(FATAL_ERROR "No linker script defined")
|
||||
endif(NOT DEFINED LINKER_SCRIPT)
|
||||
|
@ -40,6 +38,22 @@ set(STACK_SIZE 4096)
|
|||
set(APP_HEAP_SIZE 2048)
|
||||
set(KERNEL_HEAP_SIZE 2048)
|
||||
|
||||
set(TOOLCHAIN arm-none-eabi)
|
||||
|
||||
find_program(TOOLCHAIN_PREFIX ${TOOLCHAIN}-gcc NO_CACHE)
|
||||
get_filename_component(TOOLCHAIN_PREFIX ${TOOLCHAIN_PREFIX} DIRECTORY)
|
||||
|
||||
set(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_PREFIX}/../bin)
|
||||
set(TOOLCHAIN_INC_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/include)
|
||||
set(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/lib)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compilers
|
||||
#---------------------------------------------------------------------------------------
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler")
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler")
|
||||
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler")
|
||||
|
||||
# Object build options
|
||||
set(OBJECT_GEN_FLAGS "-mthumb -g2 -fno-builtin -mcpu=cortex-m4 -Wall -Wextra -pedantic -Wno-unused-parameter -ffunction-sections -fdata-sections -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops -ffast-math -ftree-vectorize -frecord-gcc-switches -gdwarf-2 -Os -fdata-sections -ffunction-sections -fstack-usage -Wl,--emit-relocs -fPIC -mthumb -mfloat-abi=soft -msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative -D__TOCK__ -DSVCALL_AS_NORMAL_FUNCTION -DSOFTDEVICE_s130")
|
||||
|
76
examples/NonArduino/Tock/tock-riscv.cmake
Normal file
76
examples/NonArduino/Tock/tock-riscv.cmake
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Tock target specific CMake file
|
||||
#
|
||||
# Licensed under the MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# This is copied from https://github.com/Lora-net/LoRaMac-node/pull/1390
|
||||
# and has been relicensed by the original author
|
||||
|
||||
if(NOT DEFINED LINKER_SCRIPT)
|
||||
message(FATAL_ERROR "No linker script defined")
|
||||
endif(NOT DEFINED LINKER_SCRIPT)
|
||||
message("Linker script: ${LINKER_SCRIPT}")
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compiler/linker flags
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
set(STACK_SIZE 4096)
|
||||
set(APP_HEAP_SIZE 2048)
|
||||
set(KERNEL_HEAP_SIZE 2048)
|
||||
|
||||
find_program(TOOLCHAIN
|
||||
NAMES
|
||||
riscv64-none-elf-gcc
|
||||
riscv32-none-elf-gcc
|
||||
riscv64-elf-gcc
|
||||
riscv32-unknown-elf-gcc
|
||||
riscv64-unknown-elf-gcc
|
||||
riscv64-unknown-elf-clang
|
||||
riscv32-unknown-elf-clang
|
||||
NO_CACHE)
|
||||
|
||||
get_filename_component(TOOLCHAIN_PREFIX ${TOOLCHAIN} DIRECTORY)
|
||||
|
||||
get_filename_component(TOOLCHAIN ${TOOLCHAIN} NAME)
|
||||
string(REPLACE "-gcc" "" TOOLCHAIN ${TOOLCHAIN})
|
||||
|
||||
set(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_PREFIX}/../bin)
|
||||
set(TOOLCHAIN_INC_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/include)
|
||||
set(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/lib)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compilers
|
||||
#---------------------------------------------------------------------------------------
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler")
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler")
|
||||
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler")
|
||||
|
||||
# Object build options
|
||||
set(OBJECT_GEN_FLAGS "-march=rv32i -mabi=ilp32 -mcmodel=medlow -g2 -fno-builtin -Wall -Wextra -pedantic -Wno-unused-parameter -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-unroll-loops -ffast-math -ftree-vectorize -frecord-gcc-switches -gdwarf-2 -Os -fdata-sections -ffunction-sections -fstack-usage -Wl,--emit-relocs -D__TOCK__ -DSVCALL_AS_NORMAL_FUNCTION -DSOFTDEVICE_s130")
|
||||
|
||||
set(CMAKE_C_FLAGS "${OBJECT_GEN_FLAGS} -std=gnu99 " CACHE INTERNAL "C Compiler options")
|
||||
set(CMAKE_CXX_FLAGS "${OBJECT_GEN_FLAGS} -std=c++20 " CACHE INTERNAL "C++ Compiler options")
|
||||
set(CMAKE_ASM_FLAGS "${OBJECT_GEN_FLAGS} -x assembler-with-cpp " CACHE INTERNAL "ASM Compiler options")
|
||||
|
||||
# Linker flags
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections -march=rv32i -mabi=ilp32 -mcmodel=medlow -T${LINKER_SCRIPT} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Xlinker --defsym=STACK_SIZE=${STACK_SIZE} -Xlinker --defsym=APP_HEAP_SIZE=${APP_HEAP_SIZE} -Xlinker --defsym=KERNEL_HEAP_SIZE=${KERNEL_HEAP_SIZE} -nostdlib -Wl,--start-group" CACHE INTERNAL "Linker options")
|
|
@ -1,90 +0,0 @@
|
|||
# Arm specific CMake file
|
||||
#
|
||||
# This is copied from:
|
||||
# https://github.com/Lora-net/LoRaMac-node/blob/2bf36bde72f68257eb96b5c00900619546bedca8/cmake/toolchain-arm-none-eabi.cmake
|
||||
#
|
||||
# The below file is licensed as Revised BSD License
|
||||
# See https://github.com/Lora-net/LoRaMac-node/blob/master/LICENSE for details
|
||||
|
||||
##
|
||||
## ______ _
|
||||
## / _____) _ | |
|
||||
## ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
## \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
## _____) ) ____| | | || |_| ____( (___| | | |
|
||||
## (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
## (C)2013-2017 Semtech
|
||||
## ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
## / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
## \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
## |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
## embedded.connectivity.solutions.==============
|
||||
##
|
||||
## License: Revised BSD License, see LICENSE.TXT file included in the project
|
||||
## Authors: Johannes Bruder ( STACKFORCE ), Miguel Luis ( Semtech )
|
||||
##
|
||||
##
|
||||
## CMake arm-none-eabi toolchain file
|
||||
##
|
||||
|
||||
# Append current directory to CMAKE_MODULE_PATH for making device specific cmake modules visible
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Target definition
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR ARM)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set toolchain paths
|
||||
#---------------------------------------------------------------------------------------
|
||||
set(TOOLCHAIN arm-none-eabi)
|
||||
|
||||
find_program(TOOLCHAIN_PREFIX ${TOOLCHAIN}-gcc NO_CACHE)
|
||||
get_filename_component(TOOLCHAIN_PREFIX ${TOOLCHAIN_PREFIX} DIRECTORY)
|
||||
|
||||
set(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_PREFIX}/../bin)
|
||||
set(TOOLCHAIN_INC_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/include)
|
||||
set(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/lib)
|
||||
|
||||
# Set system depended extensions
|
||||
if(WIN32)
|
||||
set(TOOLCHAIN_EXT ".exe" )
|
||||
else()
|
||||
set(TOOLCHAIN_EXT "" )
|
||||
endif()
|
||||
|
||||
# Perform compiler test with static library
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Preset some general GCC Options
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
# Options for DEBUG build
|
||||
# -Og enables optimizations that do not interfere with debugging
|
||||
# -g produce debugging information in the operating system's native format
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Og -g -DDEBUG" CACHE INTERNAL "C Compiler options for debug build type")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -DDEBUG" CACHE INTERNAL "C++ Compiler options for debug build type")
|
||||
set(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "ASM Compiler options for debug build type")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "Linker options for debug build type")
|
||||
|
||||
# Options for RELEASE build
|
||||
# -Os Optimize for size. -Os enables all -O2 optimizations
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Os" CACHE INTERNAL "C Compiler options for release build type")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Os" CACHE INTERNAL "C++ Compiler options for release build type")
|
||||
set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "ASM Compiler options for release build type")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Linker options for release build type")
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compilers
|
||||
#---------------------------------------------------------------------------------------
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc${TOOLCHAIN_EXT} CACHE INTERNAL "C Compiler")
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++${TOOLCHAIN_EXT} CACHE INTERNAL "C++ Compiler")
|
||||
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc${TOOLCHAIN_EXT} CACHE INTERNAL "ASM Compiler")
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_PREFIX}/${${TOOLCHAIN}} ${CMAKE_PREFIX_PATH})
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
RadioLib SX128x Channel Activity Detection Example
|
||||
|
||||
This example uses SX1280 to scan the current LoRa
|
||||
channel and detect ongoing LoRa transmissions.
|
||||
|
||||
Other modules from SX128x family can also be used.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1280 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
SX1280 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//SX1280 radio = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1280 with default settings
|
||||
Serial.print(F("[SX1280] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when LoRa packet or timeout is detected
|
||||
radio.setDio1Action(setFlag);
|
||||
|
||||
// start scanning the channel
|
||||
Serial.print(F("[SX1280] Starting scan for LoRa preamble ... "));
|
||||
state = radio.startChannelScan();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
// flag to indicate that a packet was detected or CAD timed out
|
||||
volatile bool scanFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// something happened, set the flag
|
||||
scanFlag = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(scanFlag) {
|
||||
// reset flag
|
||||
scanFlag = false;
|
||||
|
||||
// check CAD result
|
||||
int state = radio.getChannelScanResult();
|
||||
|
||||
if (state == RADIOLIB_LORA_DETECTED) {
|
||||
// LoRa packet was detected
|
||||
Serial.println(F("[SX1280] Packet detected!"));
|
||||
|
||||
} else if (state == RADIOLIB_CHANNEL_FREE) {
|
||||
// channel is free
|
||||
Serial.println(F("[SX1280] Channel is free!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("[SX1280] Failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// start scanning the channel again
|
||||
Serial.print(F("[SX1280] Starting scan for LoRa preamble ... "));
|
||||
state = radio.startChannelScan();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
}
|
4
extras/SSTV_Image_Converter/.gitignore
vendored
Normal file
4
extras/SSTV_Image_Converter/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
# ignore all output files
|
||||
*.h
|
||||
*.png
|
||||
!radiolib.png
|
50
extras/SSTV_Image_Converter/ImageConverter.py
Executable file
50
extras/SSTV_Image_Converter/ImageConverter.py
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
from argparse import RawTextHelpFormatter
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
|
||||
RadioLib image to array conversion tool.
|
||||
|
||||
Input is a PNG image to be transmitted via RadioLib SSTV.
|
||||
The image must have correct size for the chose SSTV mode!
|
||||
|
||||
Output is a file (by default named "img.h") which can be included and transmitted.
|
||||
The resulting array will be very large (typically 320 kB),
|
||||
make sure your platform has sufficient Flash/RAM space.
|
||||
''')
|
||||
parser.add_argument('input',
|
||||
type=str,
|
||||
help='Input PNG file')
|
||||
parser.add_argument('output',
|
||||
type=str,
|
||||
nargs='?',
|
||||
default='img',
|
||||
help='Output header file')
|
||||
args = parser.parse_args()
|
||||
outfile = f'{args.output}.h'
|
||||
print(f'Converting "{args.input}" to "{outfile}"')
|
||||
|
||||
# open the image as numpy array
|
||||
img = Image.open(args.input)
|
||||
arr = np.array(img)
|
||||
|
||||
# open the output file
|
||||
with open(outfile, 'w') as f:
|
||||
print(f'const uint32_t img[{arr.shape[0]}][{arr.shape[1]}] = {{', file=f)
|
||||
for row in arr:
|
||||
print(' { ', end='', file=f)
|
||||
for pix in row:
|
||||
rgb = pix[0] << 16 | pix[1] << 8 | pix[2]
|
||||
print(hex(rgb), end=', ', file=f)
|
||||
print(' },', file=f)
|
||||
print('};', file=f)
|
||||
|
||||
print('Done!')
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
BIN
extras/SSTV_Image_Converter/radiolib.png
Normal file
BIN
extras/SSTV_Image_Converter/radiolib.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
39
keywords.txt
39
keywords.txt
|
@ -91,6 +91,12 @@ AS923 KEYWORD1
|
|||
KR920 KEYWORD1
|
||||
IN865 KEYWORD1
|
||||
|
||||
# LR11x0 structures
|
||||
LR11x0WifiResult_t KEYWORD1
|
||||
LR11x0WifiResultFull_t KEYWORD1
|
||||
LR11x0WifiResultExtended_t KEYWORD1
|
||||
LR11x0VersionInfo_t KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
@ -127,6 +133,7 @@ setCodingRate KEYWORD2
|
|||
setFrequency KEYWORD2
|
||||
setSyncWord KEYWORD2
|
||||
setOutputPower KEYWORD2
|
||||
checkOutputPower KEYWORD2
|
||||
setCurrentLimit KEYWORD2
|
||||
setPreambleLength KEYWORD2
|
||||
setGain KEYWORD2
|
||||
|
@ -242,6 +249,14 @@ setAutoAck KEYWORD2
|
|||
# LR11x0
|
||||
beginLRFHSS KEYWORD2
|
||||
setLrFhssConfig KEYWORD2
|
||||
startWifiScan KEYWORD2
|
||||
getWifiScanResultsCount KEYWORD2
|
||||
getWifiScanResult KEYWORD2
|
||||
wifiScan KEYWORD2
|
||||
setWiFiScanAction KEYWORD2
|
||||
clearWiFiScanAction KEYWORD2
|
||||
getVersionInfo KEYWORD2
|
||||
updateFirmware KEYWORD2
|
||||
|
||||
# RTTY
|
||||
idle KEYWORD2
|
||||
|
@ -316,10 +331,10 @@ uplink KEYWORD2
|
|||
downlink KEYWORD2
|
||||
sendReceive KEYWORD2
|
||||
setDeviceStatus KEYWORD2
|
||||
getFcntUp KEYWORD2
|
||||
getNFcntDown KEYWORD2
|
||||
getAFcntDown KEYWORD2
|
||||
resetFcntDown KEYWORD2
|
||||
getFCntUp KEYWORD2
|
||||
getNFCntDown KEYWORD2
|
||||
getAFCntDown KEYWORD2
|
||||
resetFCntDown KEYWORD2
|
||||
setDatarate KEYWORD2
|
||||
setADR KEYWORD2
|
||||
setDutyCycle KEYWORD2
|
||||
|
@ -328,10 +343,10 @@ timeUntilUplink KEYWORD2
|
|||
setDwellTime KEYWORD2
|
||||
maxPayloadDwellTime KEYWORD2
|
||||
setTxPower KEYWORD2
|
||||
setCSMA KEYWORD2
|
||||
getMacLinkCheckAns KEYWORD2
|
||||
getMacDeviceTimeAns KEYWORD2
|
||||
getDevAddr KEYWORD2
|
||||
getLastToA KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
|
@ -447,3 +462,17 @@ RADIOLIB_ERR_DATA_RATE_INVALID LITERAL1
|
|||
RADIOLIB_ERR_DWELL_TIME_EXCEEDED LITERAL1
|
||||
RADIOLIB_ERR_CHECKSUM_MISMATCH LITERAL1
|
||||
RADIOLIB_LORAWAN_NO_DOWNLINK LITERAL1
|
||||
|
||||
RADIOLIB_LR1110_FIRMWARE_IN_RAM LITERAL1
|
||||
RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0303 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0304 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0305 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0306 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0307 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0401 LITERAL1
|
||||
RADIOLIB_LR1120_FIRMWARE_0101 LITERAL1
|
||||
RADIOLIB_LR1120_FIRMWARE_0102 LITERAL1
|
||||
RADIOLIB_LR1120_FIRMWARE_0201 LITERAL1
|
||||
RADIOLIB_LR1121_FIRMWARE_0102 LITERAL1
|
||||
RADIOLIB_LR1121_FIRMWARE_0103 LITERAL1
|
||||
|
|
|
@ -32,7 +32,7 @@ class ArduinoHal : public RadioLibHal {
|
|||
\param spi SPI interface to be used, can also use software SPI implementations.
|
||||
\param spiSettings SPI interface settings.
|
||||
*/
|
||||
ArduinoHal(SPIClass& spi, SPISettings spiSettings = RADIOLIB_DEFAULT_SPI_SETTINGS);
|
||||
explicit ArduinoHal(SPIClass& spi, SPISettings spiSettings = RADIOLIB_DEFAULT_SPI_SETTINGS);
|
||||
|
||||
// implementations of pure virtual RadioLibHal methods
|
||||
void pinMode(uint32_t pin, uint32_t mode) override;
|
||||
|
|
|
@ -76,13 +76,18 @@ int16_t Module::SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb, uint8_t
|
|||
// check register value each millisecond until check interval is reached
|
||||
// some registers need a bit of time to process the change (e.g. SX127X_REG_OP_MODE)
|
||||
RadioLibTime_t start = this->hal->micros();
|
||||
#if RADIOLIB_DEBUG_SPI
|
||||
uint8_t readValue = 0x00;
|
||||
#endif
|
||||
while(this->hal->micros() - start < (checkInterval * 1000)) {
|
||||
readValue = SPIreadRegister(reg);
|
||||
if((readValue & checkMask) == (newValue & checkMask)) {
|
||||
uint8_t val = SPIreadRegister(reg);
|
||||
if((val & checkMask) == (newValue & checkMask)) {
|
||||
// check passed, we can stop the loop
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
#if RADIOLIB_DEBUG_SPI
|
||||
readValue = val;
|
||||
#endif
|
||||
}
|
||||
|
||||
// check failed, print debug info
|
||||
|
@ -113,7 +118,7 @@ void Module::SPIreadRegisterBurst(uint32_t reg, size_t numBytes, uint8_t* inByte
|
|||
for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
|
||||
*(cmdPtr++) = (reg >> 8*i) & 0xFF;
|
||||
}
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, false, NULL, inBytes, numBytes, true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, false, NULL, inBytes, numBytes, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +135,7 @@ uint8_t Module::SPIreadRegister(uint32_t reg) {
|
|||
for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
|
||||
*(cmdPtr++) = (reg >> 8*i) & 0xFF;
|
||||
}
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, false, NULL, &resp, 1, true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, false, NULL, &resp, 1, true);
|
||||
}
|
||||
return(resp);
|
||||
}
|
||||
|
@ -147,7 +152,7 @@ void Module::SPIwriteRegisterBurst(uint32_t reg, uint8_t* data, size_t numBytes)
|
|||
for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
|
||||
*(cmdPtr++) = (reg >> 8*i) & 0xFF;
|
||||
}
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, true, data, NULL, numBytes, true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, true, data, NULL, numBytes, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +168,7 @@ void Module::SPIwriteRegister(uint32_t reg, uint8_t data) {
|
|||
for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
|
||||
*(cmdPtr++) = (reg >> 8*i) & 0xFF;
|
||||
}
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, true, &data, NULL, 1, true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, true, &data, NULL, 1, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,7 +245,7 @@ int16_t Module::SPIreadStream(uint16_t cmd, uint8_t* data, size_t numBytes, bool
|
|||
|
||||
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_MODULE_SPI_TIMEOUT);
|
||||
int16_t state = this->SPItransferStream(cmd, cmdLen, false, NULL, data, numBytes, waitForGpio);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
#if !RADIOLIB_SPI_PARANOID
|
||||
|
@ -268,7 +273,7 @@ int16_t Module::SPIwriteStream(uint16_t cmd, uint8_t* data, size_t numBytes, boo
|
|||
|
||||
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_MODULE_SPI_TIMEOUT);
|
||||
int16_t state = this->SPItransferStream(cmd, cmdLen, true, data, NULL, numBytes, waitForGpio);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
#if !RADIOLIB_SPI_PARANOID
|
||||
|
@ -296,7 +301,7 @@ int16_t Module::SPIcheckStream() {
|
|||
for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
|
||||
*(cmdPtr++) = ( this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] >> 8*i) & 0xFF;
|
||||
}
|
||||
state = this->SPItransferStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, false, NULL, &spiStatus, 1, true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
state = this->SPItransferStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, false, NULL, &spiStatus, 1, true);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// translate to RadioLib status code
|
||||
|
@ -308,18 +313,16 @@ int16_t Module::SPIcheckStream() {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t Module::SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio, RadioLibTime_t timeout) {
|
||||
// prepare the buffers
|
||||
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
|
||||
size_t buffLen = cmdLen + numBytes;
|
||||
if(!write) {
|
||||
buffLen += (this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] / 8);
|
||||
}
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
uint8_t buffOut[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
uint8_t buffIn[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* buffOut = new uint8_t[buffLen];
|
||||
uint8_t* buffIn = new uint8_t[buffLen];
|
||||
#endif
|
||||
uint8_t* buffOutPtr = buffOut;
|
||||
|
||||
|
@ -342,17 +345,23 @@ int16_t Module::SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint
|
|||
RadioLibTime_t start = this->hal->millis();
|
||||
while(this->hal->digitalRead(this->gpioPin)) {
|
||||
this->hal->yield();
|
||||
if(this->hal->millis() - start >= timeout) {
|
||||
if(this->hal->millis() - start >= this->spiConfig.timeout) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO pre-transfer timeout, is it connected?");
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] buffOut;
|
||||
delete[] buffIn;
|
||||
#endif
|
||||
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prepare the input buffer
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
uint8_t buffIn[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* buffIn = new uint8_t[buffLen];
|
||||
#endif
|
||||
|
||||
// do the transfer
|
||||
this->hal->spiBeginTransaction();
|
||||
this->hal->digitalWrite(this->csPin, this->hal->GpioLevelLow);
|
||||
|
@ -369,7 +378,7 @@ int16_t Module::SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint
|
|||
RadioLibTime_t start = this->hal->millis();
|
||||
while(this->hal->digitalRead(this->gpioPin)) {
|
||||
this->hal->yield();
|
||||
if(this->hal->millis() - start >= timeout) {
|
||||
if(this->hal->millis() - start >= this->spiConfig.timeout) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO post-transfer timeout, is it connected?");
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] buffOut;
|
||||
|
@ -462,8 +471,8 @@ uint32_t Module::reflect(uint32_t in, uint8_t bits) {
|
|||
void Module::hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset, uint8_t width, bool be) {
|
||||
size_t rem_len = len;
|
||||
for(size_t i = 0; i < len; i+=16) {
|
||||
char str[80];
|
||||
sprintf(str, "%07" PRIx32 " ", i+offset);
|
||||
char str[120];
|
||||
sprintf(str, "%07" PRIx32 " ", (uint32_t)i+offset);
|
||||
size_t line_len = 16;
|
||||
if(rem_len < line_len) {
|
||||
line_len = rem_len;
|
||||
|
@ -488,15 +497,21 @@ void Module::hexdump(const char* level, uint8_t* data, size_t len, uint32_t offs
|
|||
}
|
||||
str[56] = '|';
|
||||
str[57] = ' ';
|
||||
|
||||
// at this point we need to start escaping "%" characters
|
||||
char* strPtr = &str[58];
|
||||
for(size_t j = 0; j < line_len; j++) {
|
||||
char c = data[i+j];
|
||||
if((c < ' ') || (c > '~')) {
|
||||
c = '.';
|
||||
} else if(c == '%') {
|
||||
*strPtr++ = '%';
|
||||
}
|
||||
sprintf(&str[58 + j], "%c", c);
|
||||
sprintf(strPtr++, "%c", c);
|
||||
|
||||
}
|
||||
for(size_t j = line_len; j < 16; j++) {
|
||||
sprintf(&str[58 + j], " ");
|
||||
sprintf(strPtr++, " ");
|
||||
}
|
||||
if(level) {
|
||||
RADIOLIB_DEBUG_PRINT(level);
|
||||
|
@ -539,7 +554,7 @@ size_t Module::serialPrintf(const char* format, ...) {
|
|||
vsnprintf(buffer, len + 1, format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
len = RADIOLIB_DEBUG_PORT.write((const uint8_t*)buffer, len);
|
||||
len = RADIOLIB_DEBUG_PORT.write(reinterpret_cast<const uint8_t*>(buffer), len);
|
||||
if (buffer != temp) {
|
||||
delete[] buffer;
|
||||
}
|
||||
|
|
10
src/Module.h
10
src/Module.h
|
@ -18,9 +18,6 @@
|
|||
*/
|
||||
#define END_OF_MODE_TABLE { Module::MODE_END_OF_TABLE, {} }
|
||||
|
||||
// default timeout for SPI transfers
|
||||
#define RADIOLIB_MODULE_SPI_TIMEOUT (1000)
|
||||
|
||||
/*!
|
||||
\defgroup module_spi_command_pos Position of commands in Module::spiConfig command array.
|
||||
\{
|
||||
|
@ -200,6 +197,9 @@ class Module {
|
|||
|
||||
/*! \brief Callback for validation SPI status. */
|
||||
SPIcheckStatusCb_t checkStatusCb;
|
||||
|
||||
/*! \brief Timeout in ms when waiting for GPIO signals. */
|
||||
RadioLibTime_t timeout;
|
||||
};
|
||||
|
||||
/*! \brief SPI configuration structure. The default configuration corresponds to register-access modules, such as SX127x. */
|
||||
|
@ -211,6 +211,7 @@ class Module {
|
|||
.statusPos = 0,
|
||||
.parseStatusCb = nullptr,
|
||||
.checkStatusCb = nullptr,
|
||||
.timeout = 1000,
|
||||
};
|
||||
|
||||
#if RADIOLIB_INTERRUPT_TIMING
|
||||
|
@ -368,10 +369,9 @@ class Module {
|
|||
\param dataIn Data that was transferred from slave to master.
|
||||
\param numBytes Number of bytes to transfer.
|
||||
\param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
|
||||
\param timeout GPIO wait period timeout in milliseconds.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio, RadioLibTime_t timeout);
|
||||
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
|
||||
|
||||
|
|
|
@ -563,6 +563,13 @@
|
|||
*/
|
||||
#define RADIOLIB_LORAWAN_NO_DOWNLINK (-1116)
|
||||
|
||||
// LR11x0-specific status codes
|
||||
|
||||
/*!
|
||||
\brief The selected 802.11 WiFi type is invalid.
|
||||
*/
|
||||
#define RADIOLIB_ERR_INVALID_WIFI_TYPE (-1200)
|
||||
|
||||
/*!
|
||||
\}
|
||||
*/
|
||||
|
|
|
@ -361,7 +361,7 @@ int16_t CC1101::startReceive() {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t CC1101::startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len) {
|
||||
int16_t CC1101::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)timeout;
|
||||
(void)irqFlags;
|
||||
(void)irqMask;
|
||||
|
@ -560,6 +560,62 @@ int16_t CC1101::getFrequencyDeviation(float *freqDev) {
|
|||
}
|
||||
|
||||
int16_t CC1101::setOutputPower(int8_t pwr) {
|
||||
// check if power value is configurable
|
||||
uint8_t powerRaw = 0;
|
||||
int16_t state = checkOutputPower(pwr, NULL, &powerRaw);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// store the value
|
||||
this->power = pwr;
|
||||
|
||||
if(this->modulation == RADIOLIB_CC1101_MOD_FORMAT_ASK_OOK){
|
||||
// Amplitude modulation:
|
||||
// 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)
|
||||
|
||||
uint8_t paValues[2] = {0x00, powerRaw};
|
||||
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_PATABLE, paValues, 2);
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
|
||||
} else {
|
||||
// Freq modulation:
|
||||
// PA_TABLE[0] is the power to be used when transmitting.
|
||||
return(SPIsetRegValue(RADIOLIB_CC1101_REG_PATABLE, powerRaw));
|
||||
}
|
||||
}
|
||||
|
||||
int16_t CC1101::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
return(checkOutputPower(power, clipped, NULL));
|
||||
}
|
||||
|
||||
int16_t CC1101::checkOutputPower(int8_t power, int8_t* clipped, uint8_t* raw) {
|
||||
constexpr int8_t allowedPwrs[8] = { -30, -20, -15, -10, 0, 5, 7, 10 };
|
||||
|
||||
if(clipped) {
|
||||
if(power <= -30) {
|
||||
*clipped = -30;
|
||||
} else if(power >= 10) {
|
||||
*clipped = 10;
|
||||
} else {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(allowedPwrs[i] > power) {
|
||||
break;
|
||||
}
|
||||
*clipped = allowedPwrs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if just a check occurs (and not requesting the raw power value), return now
|
||||
if(!raw) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(allowedPwrs[i] == power) {
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
}
|
||||
return(RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
|
||||
// round to the known frequency settings
|
||||
uint8_t f;
|
||||
if(this->frequency < 374.0) {
|
||||
|
@ -586,53 +642,35 @@ int16_t CC1101::setOutputPower(int8_t pwr) {
|
|||
{0xCB, 0xC8, 0xCB, 0xC7},
|
||||
{0xC2, 0xC0, 0xC2, 0xC0}};
|
||||
|
||||
uint8_t powerRaw;
|
||||
switch(pwr) {
|
||||
case -30:
|
||||
powerRaw = paTable[0][f];
|
||||
switch(power) {
|
||||
case allowedPwrs[0]: // -30
|
||||
*raw = paTable[0][f];
|
||||
break;
|
||||
case -20:
|
||||
powerRaw = paTable[1][f];
|
||||
case allowedPwrs[1]: // -20
|
||||
*raw = paTable[1][f];
|
||||
break;
|
||||
case -15:
|
||||
powerRaw = paTable[2][f];
|
||||
case allowedPwrs[2]: // -15
|
||||
*raw = paTable[2][f];
|
||||
break;
|
||||
case -10:
|
||||
powerRaw = paTable[3][f];
|
||||
case allowedPwrs[3]: // -10
|
||||
*raw = paTable[3][f];
|
||||
break;
|
||||
case 0:
|
||||
powerRaw = paTable[4][f];
|
||||
case allowedPwrs[4]: // 0
|
||||
*raw = paTable[4][f];
|
||||
break;
|
||||
case 5:
|
||||
powerRaw = paTable[5][f];
|
||||
case allowedPwrs[5]: // 5
|
||||
*raw = paTable[5][f];
|
||||
break;
|
||||
case 7:
|
||||
powerRaw = paTable[6][f];
|
||||
case allowedPwrs[6]: // 7
|
||||
*raw = paTable[6][f];
|
||||
break;
|
||||
case 10:
|
||||
powerRaw = paTable[7][f];
|
||||
case allowedPwrs[7]: // 10
|
||||
*raw = paTable[7][f];
|
||||
break;
|
||||
default:
|
||||
return(RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
|
||||
// store the value
|
||||
this->power = pwr;
|
||||
|
||||
if(this->modulation == RADIOLIB_CC1101_MOD_FORMAT_ASK_OOK){
|
||||
// Amplitude modulation:
|
||||
// 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)
|
||||
|
||||
uint8_t paValues[2] = {0x00, powerRaw};
|
||||
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_PATABLE, paValues, 2);
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
|
||||
} else {
|
||||
// Freq modulation:
|
||||
// PA_TABLE[0] is the power to be used when transmitting.
|
||||
return(SPIsetRegValue(RADIOLIB_CC1101_REG_PATABLE, powerRaw));
|
||||
}
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t CC1101::setSyncWord(uint8_t* syncWord, uint8_t len, uint8_t maxErrBits, bool requireCarrierSense) {
|
||||
|
|
|
@ -539,6 +539,7 @@ class CC1101: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param module Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
CC1101(Module* module);
|
||||
|
||||
// basic methods
|
||||
|
@ -660,23 +661,23 @@ class CC1101: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method.
|
||||
|
@ -698,7 +699,7 @@ class CC1101: public PhysicalLayer {
|
|||
\brief Interrupt-driven receive method. GDO0 will be activated when full packet is received.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer.
|
||||
|
@ -708,7 +709,7 @@ class CC1101: public PhysicalLayer {
|
|||
\param len Ignored.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len);
|
||||
int16_t startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Reads data received after calling startReceive method. When the packet length is not known in advance,
|
||||
|
@ -728,14 +729,14 @@ class CC1101: public PhysicalLayer {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets bit rate. Allowed values range from 0.025 to 600.0 kbps.
|
||||
\param br Bit rate to be set in kbps.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
/*!
|
||||
\brief Sets receiver bandwidth. Allowed values are 58, 68, 81, 102, 116, 135, 162,
|
||||
|
@ -772,7 +773,25 @@ class CC1101: public PhysicalLayer {
|
|||
\param pwr Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t pwr);
|
||||
int16_t setOutputPower(int8_t pwr) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\param raw Raw internal value.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped, uint8_t* raw);
|
||||
|
||||
/*!
|
||||
\brief Sets 16-bit sync word as a two byte value.
|
||||
|
@ -829,7 +848,7 @@ class CC1101: public PhysicalLayer {
|
|||
In asynchronous direct mode, returns the current RSSI level.
|
||||
\returns RSSI in dBm.
|
||||
*/
|
||||
float getRSSI();
|
||||
float getRSSI() override;
|
||||
|
||||
/*!
|
||||
\brief Gets LQI (Link Quality Indicator) of the last received packet.
|
||||
|
@ -921,7 +940,7 @@ class CC1101: public PhysicalLayer {
|
|||
\brief Get one truly random byte from RSSI noise.
|
||||
\returns TRNG byte.
|
||||
*/
|
||||
uint8_t randomByte();
|
||||
uint8_t randomByte() override;
|
||||
|
||||
/*!
|
||||
\brief Read version SPI register. Should return CC1101_VERSION_LEGACY (0x04) or
|
||||
|
@ -935,13 +954,13 @@ class CC1101: public PhysicalLayer {
|
|||
\brief Set interrupt service routine function to call when data bit is receveid in direct mode.
|
||||
\param func Pointer to interrupt service routine.
|
||||
*/
|
||||
void setDirectAction(void (*func)(void));
|
||||
void setDirectAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Function to read and process data bit in direct reception mode.
|
||||
\param pin Pin on which to read.
|
||||
*/
|
||||
void readBit(uint32_t pin);
|
||||
void readBit(uint32_t pin) override;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -950,12 +969,12 @@ class CC1101: public PhysicalLayer {
|
|||
\param value The value that indicates which function to place on that pin. See chip datasheet for details.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setDIOMapping(uint32_t pin, uint32_t value);
|
||||
int16_t setDIOMapping(uint32_t pin, uint32_t value) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
// SPI read overrides to set bit for burst write and status registers access
|
||||
int16_t SPIgetRegValue(uint8_t reg, uint8_t msb = 7, uint8_t lsb = 0);
|
||||
|
|
|
@ -21,7 +21,7 @@ class LLCC68: public SX1262 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
LLCC68(Module* mod);
|
||||
LLCC68(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
/*!
|
||||
\brief Initialization method for LoRa modem.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#if !RADIOLIB_EXCLUDE_LR11X0
|
||||
|
||||
LR1110::LR1110(Module* mod) : LR11x0(mod) {
|
||||
chipType = RADIOLIB_LR11X0_HW_LR1110;
|
||||
chipType = RADIOLIB_LR11X0_DEVICE_LR1110;
|
||||
}
|
||||
|
||||
int16_t LR1110::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) {
|
||||
|
|
|
@ -18,7 +18,7 @@ class LR1110: public LR11x0 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
LR1110(Module* mod);
|
||||
LR1110(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -74,7 +74,7 @@ class LR1110: public LR11x0 {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#if !RADIOLIB_EXCLUDE_LR11X0
|
||||
|
||||
LR1120::LR1120(Module* mod) : LR11x0(mod) {
|
||||
chipType = RADIOLIB_LR11X0_HW_LR1120;
|
||||
chipType = RADIOLIB_LR11X0_DEVICE_LR1120;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -18,7 +18,7 @@ class LR1120: public LR11x0 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
LR1120(Module* mod);
|
||||
LR1120(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -74,7 +74,7 @@ class LR1120: public LR11x0 {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#if !RADIOLIB_EXCLUDE_LR11X0
|
||||
|
||||
LR1121::LR1121(Module* mod) : LR1120(mod) {
|
||||
chipType = RADIOLIB_LR11X0_HW_LR1121;
|
||||
chipType = RADIOLIB_LR11X0_DEVICE_LR1121;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,7 +19,7 @@ class LR1121: public LR1120 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
LR1121(Module* mod);
|
||||
LR1121(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// TODO this is where overrides to disable GNSS+WiFi scanning methods on LR1121
|
||||
// will be put once those are implemented
|
||||
|
|
|
@ -143,6 +143,7 @@ int16_t LR11x0::transmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
// get currently active modem
|
||||
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
state = getPacketType(&modem);
|
||||
RADIOLIB_ASSERT(state);
|
||||
RadioLibTime_t timeout = getTimeOnAir(len);
|
||||
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||
// calculate timeout (150% of expected time-on-air)
|
||||
|
@ -189,6 +190,7 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
|
|||
// get currently active modem
|
||||
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
state = getPacketType(&modem);
|
||||
RADIOLIB_ASSERT(state);
|
||||
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;
|
||||
|
@ -312,6 +314,10 @@ int16_t LR11x0::standby(uint8_t mode, bool wakeup) {
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_STANDBY, true, buff, 1));
|
||||
}
|
||||
|
||||
int16_t LR11x0::sleep() {
|
||||
return(LR11x0::sleep(true, 0));
|
||||
}
|
||||
|
||||
int16_t LR11x0::sleep(bool retainConfig, uint32_t sleepTime) {
|
||||
// set RF switch (if present)
|
||||
this->mod->setRfSwitchState(Module::MODE_IDLE);
|
||||
|
@ -396,6 +402,7 @@ int16_t LR11x0::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
// in LR-FHSS mode, the packet is built by the device
|
||||
// TODO add configurable grid step and device offset
|
||||
state = lrFhssBuildFrame(this->lrFhssHdrCount, this->lrFhssCr, RADIOLIB_LR11X0_LR_FHSS_GRID_STEP_FCC, true, this->lrFhssBw, this->lrFhssHopSeq, 0, data, len);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
} else {
|
||||
// write packet to buffer
|
||||
|
@ -432,10 +439,11 @@ int16_t LR11x0::finishTransmit() {
|
|||
}
|
||||
|
||||
int16_t LR11x0::startReceive() {
|
||||
return(this->startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_LR11X0_IRQ_RX_DONE, 0));
|
||||
return(this->startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_LR11X0_IRQ_RX_DONE, 0, 0));
|
||||
}
|
||||
|
||||
int16_t LR11x0::startReceive(uint32_t timeout, uint32_t irqFlags, size_t len) {
|
||||
int16_t LR11x0::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)irqMask;
|
||||
(void)len;
|
||||
|
||||
// check active modem
|
||||
|
@ -481,7 +489,7 @@ 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 };
|
||||
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_0;
|
||||
mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true);
|
||||
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_8;
|
||||
uint32_t irq = ((uint32_t)(buff[2]) << 24) | ((uint32_t)(buff[3]) << 16) | ((uint32_t)(buff[4]) << 8) | (uint32_t)buff[5];
|
||||
return(irq);
|
||||
|
@ -593,22 +601,17 @@ int16_t LR11x0::setOutputPower(int8_t power) {
|
|||
}
|
||||
|
||||
int16_t LR11x0::setOutputPower(int8_t power, bool forceHighPower) {
|
||||
// check if power value is configurable
|
||||
int16_t state = checkOutputPower(power, NULL, forceHighPower);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// determine whether to use HP or LP PA and check range accordingly
|
||||
bool useHp = forceHighPower || (power > 14);
|
||||
if(useHp) {
|
||||
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
useHp = true;
|
||||
|
||||
} else {
|
||||
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
useHp = false;
|
||||
|
||||
}
|
||||
|
||||
// TODO how and when to configure OCP?
|
||||
|
||||
// update PA config - always use VBAT for high-power PA
|
||||
int16_t state = setPaConfig((uint8_t)useHp, (uint8_t)useHp, 0x04, 0x07);
|
||||
state = setPaConfig((uint8_t)useHp, (uint8_t)useHp, 0x04, 0x07);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set output power
|
||||
|
@ -616,6 +619,27 @@ int16_t LR11x0::setOutputPower(int8_t power, bool forceHighPower) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
return(checkOutputPower(power, clipped, false));
|
||||
}
|
||||
|
||||
int16_t LR11x0::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower) {
|
||||
if(forceHighPower || (power > 14)) {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
|
||||
} else {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
|
||||
}
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t LR11x0::setBandwidth(float bw) {
|
||||
// check active modem
|
||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
|
@ -833,8 +857,16 @@ int16_t LR11x0::setSyncWord(uint8_t* syncWord, size_t len) {
|
|||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
int16_t state = getPacketType(&type);
|
||||
RADIOLIB_ASSERT(state);
|
||||
if(type != RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||
if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||
// with length set to 1 and LoRa modem active, assume it is the LoRa sync word
|
||||
if(len > 1) {
|
||||
return(RADIOLIB_ERR_INVALID_SYNC_WORD);
|
||||
}
|
||||
return(setSyncWord(syncWord[0]));
|
||||
|
||||
} else if(type != RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
}
|
||||
|
||||
// update sync word length
|
||||
|
@ -1177,12 +1209,12 @@ float LR11x0::getRSSI() {
|
|||
|
||||
// check active modem
|
||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
getPacketType(&type);
|
||||
(void)getPacketType(&type);
|
||||
if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||
getPacketStatusLoRa(&val, NULL, NULL);
|
||||
(void)getPacketStatusLoRa(&val, NULL, NULL);
|
||||
|
||||
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
|
||||
getPacketStatusGFSK(NULL, &val, NULL, NULL);
|
||||
(void)getPacketStatusGFSK(NULL, &val, NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1194,9 +1226,9 @@ float LR11x0::getSNR() {
|
|||
|
||||
// check active modem
|
||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
getPacketType(&type);
|
||||
(void)getPacketType(&type);
|
||||
if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||
getPacketStatusLoRa(NULL, &val, NULL);
|
||||
(void)getPacketStatusLoRa(NULL, &val, NULL);
|
||||
}
|
||||
|
||||
return(val);
|
||||
|
@ -1229,7 +1261,7 @@ size_t LR11x0::getPacketLength(bool update, uint8_t* offset) {
|
|||
RadioLibTime_t LR11x0::getTimeOnAir(size_t len) {
|
||||
// check active modem
|
||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
getPacketType(&type);
|
||||
(void)getPacketType(&type);
|
||||
if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||
// calculate number of symbols
|
||||
float N_symbol = 0;
|
||||
|
@ -1294,6 +1326,39 @@ RadioLibTime_t LR11x0::getTimeOnAir(size_t len) {
|
|||
return(0);
|
||||
}
|
||||
|
||||
RadioLibTime_t LR11x0::calculateRxTimeout(RadioLibTime_t timeoutUs) {
|
||||
// the timeout value is given in units of 30.52 microseconds
|
||||
// the calling function should provide some extra width, as this number of units is truncated to integer
|
||||
RadioLibTime_t timeout = timeoutUs / 30.52;
|
||||
return(timeout);
|
||||
}
|
||||
|
||||
int16_t LR11x0::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) {
|
||||
irqFlags = RADIOLIB_LR11X0_IRQ_RX_DONE | RADIOLIB_LR11X0_IRQ_TIMEOUT; // flags that can appear in the IRQ register
|
||||
irqMask = irqFlags; // on LR11x0, these are the same
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
bool LR11x0::isRxTimeout() {
|
||||
uint32_t irq = getIrqStatus();
|
||||
bool rxTimedOut = irq & RADIOLIB_LR11X0_IRQ_TIMEOUT;
|
||||
return(rxTimedOut);
|
||||
}
|
||||
|
||||
uint8_t LR11x0::randomByte() {
|
||||
uint32_t num = 0;
|
||||
(void)getRandomNumber(&num);
|
||||
return((uint8_t)num);
|
||||
}
|
||||
|
||||
int16_t LR11x0::implicitHeader(size_t len) {
|
||||
return(this->setHeaderType(RADIOLIB_LR11X0_LORA_HEADER_IMPLICIT, len));
|
||||
}
|
||||
|
||||
int16_t LR11x0::explicitHeader() {
|
||||
return(this->setHeaderType(RADIOLIB_LR11X0_LORA_HEADER_EXPLICIT));
|
||||
}
|
||||
|
||||
float LR11x0::getDataRate() const {
|
||||
return(this->dataRateMeasured);
|
||||
}
|
||||
|
@ -1319,6 +1384,240 @@ int16_t LR11x0::setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount, uint16
|
|||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t LR11x0::startWifiScan(char wifiType, uint8_t mode, uint16_t chanMask, uint8_t numScans, uint16_t timeout) {
|
||||
uint8_t type;
|
||||
switch(wifiType) {
|
||||
case('b'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_802_11_B;
|
||||
break;
|
||||
case('g'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_802_11_G;
|
||||
break;
|
||||
case('n'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_802_11_N;
|
||||
break;
|
||||
case('*'):
|
||||
type = RADIOLIB_LR11X0_WIFI_SCAN_ALL;
|
||||
break;
|
||||
default:
|
||||
return(RADIOLIB_ERR_INVALID_WIFI_TYPE);
|
||||
}
|
||||
|
||||
// go to standby
|
||||
int16_t state = standby();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// reset cumulative timings
|
||||
state = wifiResetCumulTimings();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set DIO mapping
|
||||
state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_WIFI_DONE, 0);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// start scan with the maximum number of results and abort on timeout
|
||||
this->wifiScanMode = mode;
|
||||
state = wifiScan(type, chanMask, this->wifiScanMode, RADIOLIB_LR11X0_WIFI_MAX_NUM_RESULTS, numScans, timeout, RADIOLIB_LR11X0_WIFI_ABORT_ON_TIMEOUT_ENABLED);
|
||||
return(state);
|
||||
}
|
||||
|
||||
void LR11x0::setWiFiScanAction(void (*func)(void)) {
|
||||
this->setIrqAction(func);
|
||||
}
|
||||
|
||||
void LR11x0::clearWiFiScanAction() {
|
||||
this->clearIrqAction();
|
||||
}
|
||||
|
||||
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 = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
uint8_t buff[1] = { 0 };
|
||||
state = this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_GET_NB_RESULTS, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(count) { *count = buff[0]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::getWifiScanResult(LR11x0WifiResult_t* result, uint8_t index, bool brief) {
|
||||
if(!result) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
// read a single result
|
||||
uint8_t format = brief ? RADIOLIB_LR11X0_WIFI_RESULT_TYPE_BASIC : RADIOLIB_LR11X0_WIFI_RESULT_TYPE_COMPLETE;
|
||||
uint8_t raw[RADIOLIB_LR11X0_WIFI_RESULT_MAX_LEN] = { 0 };
|
||||
int16_t state = wifiReadResults(index, 1, format, raw);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// parse the information
|
||||
switch(raw[0] & 0x03) {
|
||||
case(RADIOLIB_LR11X0_WIFI_SCAN_802_11_B):
|
||||
result->type = 'b';
|
||||
break;
|
||||
case(RADIOLIB_LR11X0_WIFI_SCAN_802_11_G):
|
||||
result->type = 'g';
|
||||
break;
|
||||
case(RADIOLIB_LR11X0_WIFI_SCAN_802_11_N):
|
||||
result->type = 'n';
|
||||
break;
|
||||
}
|
||||
result->dataRateId = (raw[0] & 0xFC) >> 2;
|
||||
result->channelFreq = 2407 + (raw[1] & 0x0F)*5;
|
||||
result->origin = (raw[1] & 0x30) >> 4;
|
||||
result->ap = (raw[1] & 0x40) != 0;
|
||||
result->rssi = (float)raw[2] / -2.0f;;
|
||||
memcpy(result->mac, &raw[3], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
|
||||
if(!brief) {
|
||||
if(this->wifiScanMode == RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON) {
|
||||
LR11x0WifiResultExtended_t* resultExtended = reinterpret_cast<LR11x0WifiResultExtended_t*>(result);
|
||||
resultExtended->rate = raw[3];
|
||||
resultExtended->service = (((uint16_t)raw[4] << 8) | ((uint16_t)raw[5]));
|
||||
resultExtended->length = (((uint16_t)raw[6] << 8) | ((uint16_t)raw[7]));
|
||||
resultExtended->frameType = raw[9] & 0x03;
|
||||
resultExtended->frameSubType = (raw[9] & 0x3C) >> 2;
|
||||
resultExtended->toDistributionSystem = (raw[9] & 0x40) != 0;
|
||||
resultExtended->fromDistributionSystem = (raw[9] & 0x80) != 0;
|
||||
memcpy(resultExtended->mac0, &raw[10], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
memcpy(resultExtended->mac, &raw[16], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
memcpy(resultExtended->mac2, &raw[22], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
resultExtended->timestamp = (((uint64_t)raw[28] << 56) | ((uint64_t)raw[29] << 48)) |
|
||||
(((uint64_t)raw[30] << 40) | ((uint64_t)raw[31] << 32)) |
|
||||
(((uint64_t)raw[32] << 24) | ((uint64_t)raw[33] << 16)) |
|
||||
(((uint64_t)raw[34] << 8) | (uint64_t)raw[35]);
|
||||
resultExtended->periodBeacon = (((uint16_t)raw[36] << 8) | ((uint16_t)raw[37])) * 1024UL;
|
||||
resultExtended->seqCtrl = (((uint16_t)raw[38] << 8) | ((uint16_t)raw[39]));
|
||||
memcpy(resultExtended->ssid, &raw[40], RADIOLIB_LR11X0_WIFI_RESULT_SSID_LEN);
|
||||
resultExtended->currentChannel = raw[72];
|
||||
memcpy(resultExtended->countryCode, &raw[73], 2);
|
||||
resultExtended->countryCode[2] = '\0';
|
||||
resultExtended->ioReg = raw[75];
|
||||
resultExtended->fcsCheckOk = (raw[76] != 0);
|
||||
resultExtended->phiOffset = (((uint16_t)raw[77] << 8) | ((uint16_t)raw[78]));
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
LR11x0WifiResultFull_t* resultFull = reinterpret_cast<LR11x0WifiResultFull_t*>(result);
|
||||
resultFull->frameType = raw[3] & 0x03;
|
||||
resultFull->frameSubType = (raw[3] & 0x3C) >> 2;
|
||||
resultFull->toDistributionSystem = (raw[3] & 0x40) != 0;
|
||||
resultFull->fromDistributionSystem = (raw[3] & 0x80) != 0;
|
||||
memcpy(resultFull->mac, &raw[4], RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN);
|
||||
resultFull->phiOffset = (((uint16_t)raw[10] << 8) | ((uint16_t)raw[11]));
|
||||
resultFull->timestamp = (((uint64_t)raw[12] << 56) | ((uint64_t)raw[13] << 48)) |
|
||||
(((uint64_t)raw[14] << 40) | ((uint64_t)raw[15] << 32)) |
|
||||
(((uint64_t)raw[16] << 24) | ((uint64_t)raw[17] << 16)) |
|
||||
(((uint64_t)raw[18] << 8) | (uint64_t)raw[19]);
|
||||
resultFull->periodBeacon = (((uint16_t)raw[20] << 8) | ((uint16_t)raw[21])) * 1024UL;
|
||||
}
|
||||
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiScan(uint8_t wifiType, uint8_t* count, uint8_t mode, uint16_t chanMask, uint8_t numScans, uint16_t timeout) {
|
||||
if(!count) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
// start scan
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi scan start");
|
||||
int16_t state = startWifiScan(wifiType, mode, chanMask, numScans, timeout);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// wait for scan finished or timeout
|
||||
RadioLibTime_t softTimeout = 30UL * 1000UL;
|
||||
RadioLibTime_t start = this->mod->hal->millis();
|
||||
while(!this->mod->hal->digitalRead(this->mod->getIrq())) {
|
||||
this->mod->hal->yield();
|
||||
if(this->mod->hal->millis() - start > softTimeout) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout waiting for IRQ");
|
||||
this->standby();
|
||||
return(RADIOLIB_ERR_RX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi scan done in %lu ms", (long unsigned int)(this->mod->hal->millis() - start));
|
||||
|
||||
// read number of results
|
||||
return(getWifiScanResultsCount(count));
|
||||
}
|
||||
|
||||
int16_t LR11x0::getVersionInfo(LR11x0VersionInfo_t* info) {
|
||||
if(!info) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
int16_t state = this->getVersion(&info->hardware, &info->device, &info->fwMajor, &info->fwMinor);
|
||||
RADIOLIB_ASSERT(state);
|
||||
state = this->wifiReadVersion(&info->fwMajorWiFi, &info->fwMinorWiFi);
|
||||
RADIOLIB_ASSERT(state);
|
||||
return(this->gnssReadVersion(&info->fwGNSS, &info->almanacGNSS));
|
||||
}
|
||||
|
||||
int16_t LR11x0::updateFirmware(const uint32_t* image, size_t size, bool nonvolatile) {
|
||||
if(!image) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
// put the device to bootloader mode
|
||||
int16_t state = this->reboot(true);
|
||||
RADIOLIB_ASSERT(state);
|
||||
this->mod->hal->delay(500);
|
||||
|
||||
// check we're in bootloader
|
||||
uint8_t device = 0xFF;
|
||||
state = this->getVersion(NULL, &device, NULL, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
if(device != RADIOLIB_LR11X0_DEVICE_BOOT) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Failed to put device to bootloader mode, %02x != %02x", device, RADIOLIB_LR11X0_DEVICE_BOOT);
|
||||
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// erase the image
|
||||
state = this->bootEraseFlash();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// wait for BUSY to go low
|
||||
RadioLibTime_t start = this->mod->hal->millis();
|
||||
while(this->mod->hal->digitalRead(this->mod->getGpio())) {
|
||||
this->mod->hal->yield();
|
||||
if(this->mod->hal->millis() - start >= 3000) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("BUSY pin timeout after erase!");
|
||||
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
// upload the new image
|
||||
const size_t maxLen = 64;
|
||||
size_t rem = size % maxLen;
|
||||
size_t numWrites = (rem == 0) ? (size / maxLen) : ((size / maxLen) + 1);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Writing image in %lu chunks, last chunk size is %lu words", (unsigned long)numWrites, (unsigned long)rem);
|
||||
for(size_t i = 0; i < numWrites; i ++) {
|
||||
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), (uint32_t*)&image[offset], len, nonvolatile);
|
||||
}
|
||||
|
||||
// kick the device from bootloader
|
||||
state = this->reset();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// verify we are no longer in bootloader
|
||||
state = this->getVersion(NULL, &device, NULL, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
if(device == RADIOLIB_LR11X0_DEVICE_BOOT) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Failed to kick device from bootloader mode, %02x == %02x", device, RADIOLIB_LR11X0_DEVICE_BOOT);
|
||||
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1374,7 +1673,7 @@ int16_t LR11x0::SPIcheckStatus(Module* mod) {
|
|||
// it also seems to ignore the actual command, and just sending in bunch of NOPs will work
|
||||
uint8_t buff[6] = { 0 };
|
||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_0;
|
||||
int16_t state = mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
int16_t state = mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true);
|
||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_8;
|
||||
RADIOLIB_ASSERT(state);
|
||||
return(LR11x0::SPIparseStatus(buff[0]));
|
||||
|
@ -1410,12 +1709,16 @@ bool LR11x0::findChip(uint8_t ver) {
|
|||
reset();
|
||||
|
||||
// read the version
|
||||
uint8_t device = 0xFF;
|
||||
if((this->getVersion(NULL, &device, NULL, NULL) == RADIOLIB_ERR_NONE) && (device == ver)) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Found LR11x0: RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", device);
|
||||
LR11x0VersionInfo_t info;
|
||||
int16_t state = getVersionInfo(&info);
|
||||
if((state == RADIOLIB_ERR_NONE) && (info.device == ver)) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Found LR11x0: RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", info.device);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Base FW version: %d.%d", (int)info.fwMajor, (int)info.fwMinor);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi FW version: %d.%d", (int)info.fwMajorWiFi, (int)info.fwMinorWiFi);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("GNSS FW version: %d.%d", (int)info.fwGNSS, (int)info.almanacGNSS);
|
||||
flagFound = true;
|
||||
} else {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("LR11x0 not found! (%d of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", i + 1, device);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("LR11x0 not found! (%d of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", i + 1, info.device);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Expected: 0x%02x", ver);
|
||||
this->mod->hal->delay(10);
|
||||
i++;
|
||||
|
@ -1438,7 +1741,7 @@ int16_t LR11x0::config(uint8_t modem) {
|
|||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// calibrate all blocks
|
||||
state = this->calibrate(RADIOLIB_LR11X0_CALIBRATE_ALL);
|
||||
(void)this->calibrate(RADIOLIB_LR11X0_CALIBRATE_ALL);
|
||||
|
||||
// wait for calibration completion
|
||||
this->mod->hal->delay(5);
|
||||
|
@ -1496,7 +1799,7 @@ int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
|
|||
num = 2;
|
||||
}
|
||||
|
||||
uint8_t detPeakValues[8] = { 48, 48, 50, 55, 55, 59, 61, 65 };
|
||||
const uint8_t detPeakValues[8] = { 48, 48, 50, 55, 55, 59, 61, 65 };
|
||||
uint8_t peak = detPeak;
|
||||
if(peak == RADIOLIB_LR11X0_CAD_PARAM_DEFAULT) {
|
||||
peak = detPeakValues[this->spreadingFactor - 5];
|
||||
|
@ -1516,6 +1819,26 @@ int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
|
|||
return(setCad());
|
||||
}
|
||||
|
||||
int16_t LR11x0::setHeaderType(uint8_t hdrType, size_t len) {
|
||||
// check active modem
|
||||
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
|
||||
int16_t state = getPacketType(&type);
|
||||
RADIOLIB_ASSERT(state);
|
||||
if(type != RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// set requested packet mode
|
||||
state = setPacketParamsLoRa(this->preambleLengthLoRa, hdrType, len, this->crcTypeLoRa, this->invertIQEnabled);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// update cached value
|
||||
this->headerType = hdrType;
|
||||
this->implicitLen = len;
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
Module* LR11x0::getMod() {
|
||||
return(this->mod);
|
||||
}
|
||||
|
@ -1525,7 +1848,7 @@ int16_t LR11x0::writeRegMem32(uint32_t addr, uint32_t* data, size_t len) {
|
|||
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||
}
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_WRITE_REG_MEM, addr, data, len));
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_WRITE_REG_MEM, addr, data, len, false));
|
||||
}
|
||||
|
||||
int16_t LR11x0::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
|
||||
|
@ -1618,7 +1941,7 @@ int16_t LR11x0::getStatus(uint8_t* stat1, uint8_t* stat2, uint32_t* irq) {
|
|||
// the status check command doesn't return status in the same place as other read commands
|
||||
// but only as the first byte (as with any other command), hence LR11x0::SPIcommand can't be used
|
||||
// it also seems to ignore the actual command, and just sending in bunch of NOPs will work
|
||||
int16_t state = this->mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
int16_t state = this->mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true);
|
||||
|
||||
// pass the replies
|
||||
if(stat1) { *stat1 = buff[0]; }
|
||||
|
@ -1671,8 +1994,8 @@ int16_t LR11x0::calibImage(float freq1, float freq2) {
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CALIB_IMAGE, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::setDioAsRfSwitch(uint8_t en, uint8_t stbyCfg, uint8_t rxCfg, uint8_t txCfg, uint8_t txHpCfg, uint8_t gnssCfg, uint8_t wifiCfg) {
|
||||
uint8_t buff[7] = { en, stbyCfg, rxCfg, txCfg, txHpCfg, gnssCfg, wifiCfg };
|
||||
int16_t LR11x0::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) {
|
||||
uint8_t buff[8] = { en, stbyCfg, rxCfg, txCfg, txHpCfg, txHfCfg, gnssCfg, wifiCfg };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_DIO_AS_RF_SWITCH, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
|
@ -1703,8 +2026,8 @@ int16_t LR11x0::setTcxoMode(uint8_t tune, uint32_t delay) {
|
|||
}
|
||||
|
||||
int16_t LR11x0::reboot(bool stay) {
|
||||
uint8_t buff[1] = { (uint8_t)stay };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_REBOOT, true, buff, sizeof(buff)));
|
||||
uint8_t buff[1] = { (uint8_t)(stay*3) };
|
||||
return(this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_REBOOT, buff, sizeof(buff), true, false));
|
||||
}
|
||||
|
||||
int16_t LR11x0::getVbat(float* vbat) {
|
||||
|
@ -1750,7 +2073,7 @@ int16_t LR11x0::eraseInfoPage(void) {
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_ERASE_INFO_PAGE, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::writeInfoPage(uint16_t addr, uint32_t* data, size_t len) {
|
||||
int16_t LR11x0::writeInfoPage(uint16_t addr, const 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);
|
||||
|
@ -1779,7 +2102,7 @@ int16_t LR11x0::writeInfoPage(uint16_t addr, uint32_t* data, size_t len) {
|
|||
}
|
||||
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_WRITE_INFO_PAGE, true, dataBuff, buffLen);
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] dataBuff;
|
||||
#endif
|
||||
return(state);
|
||||
|
@ -2112,7 +2435,7 @@ int16_t LR11x0::setRangingReqAddr(uint32_t addr) {
|
|||
int16_t LR11x0::getRangingResult(uint8_t type, float* res) {
|
||||
uint8_t reqBuff[1] = { type };
|
||||
uint8_t rplBuff[4] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_NOP, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_RANGING_RESULT, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
if(res) {
|
||||
|
@ -2164,6 +2487,22 @@ int16_t LR11x0::setRangingParameter(uint8_t symbolNum) {
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RANGING_PARAMETER, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::setRssiCalibration(int8_t* tune, int16_t gainOffset) {
|
||||
uint8_t buff[11] = {
|
||||
(uint8_t)((tune[0] & 0x0F) | (uint8_t)(tune[1] & 0x0F) << 4),
|
||||
(uint8_t)((tune[2] & 0x0F) | (uint8_t)(tune[3] & 0x0F) << 4),
|
||||
(uint8_t)((tune[4] & 0x0F) | (uint8_t)(tune[5] & 0x0F) << 4),
|
||||
(uint8_t)((tune[6] & 0x0F) | (uint8_t)(tune[7] & 0x0F) << 4),
|
||||
(uint8_t)((tune[8] & 0x0F) | (uint8_t)(tune[9] & 0x0F) << 4),
|
||||
(uint8_t)((tune[10] & 0x0F) | (uint8_t)(tune[11] & 0x0F) << 4),
|
||||
(uint8_t)((tune[12] & 0x0F) | (uint8_t)(tune[13] & 0x0F) << 4),
|
||||
(uint8_t)((tune[14] & 0x0F) | (uint8_t)(tune[15] & 0x0F) << 4),
|
||||
(uint8_t)((tune[16] & 0x0F) | (uint8_t)(tune[17] & 0x0F) << 4),
|
||||
(uint8_t)(((uint16_t)gainOffset >> 8) & 0xFF), (uint8_t)(gainOffset & 0xFF),
|
||||
};
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RSSI_CALIBRATION, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::setLoRaSyncWord(uint8_t sync) {
|
||||
uint8_t buff[1] = { sync };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_LORA_SYNC_WORD, true, buff, sizeof(buff)));
|
||||
|
@ -2202,7 +2541,7 @@ int16_t LR11x0::lrFhssBuildFrame(uint8_t hdrCount, uint8_t cr, uint8_t grid, boo
|
|||
memcpy(&dataBuff[9], payload, len);
|
||||
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_LR_FHSS_BUILD_FRAME, true, dataBuff, buffLen);
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] dataBuff;
|
||||
#endif
|
||||
return(state);
|
||||
|
@ -2253,7 +2592,7 @@ int16_t LR11x0::bleBeaconCommon(uint16_t cmd, uint8_t chan, uint8_t* payload, si
|
|||
memcpy(&dataBuff[1], payload, len);
|
||||
|
||||
int16_t state = this->SPIcommand(cmd, true, dataBuff, sizeof(uint8_t) + len);
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] dataBuff;
|
||||
#endif
|
||||
return(state);
|
||||
|
@ -2266,7 +2605,9 @@ int16_t LR11x0::wifiScan(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t n
|
|||
(uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
|
||||
abortOnTimeout
|
||||
};
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_SCAN, true, buff, sizeof(buff)));
|
||||
|
||||
// call the SPI write stream directly to skip waiting for BUSY - it will be set to high once the scan starts
|
||||
return(this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_WIFI_SCAN, buff, sizeof(buff), false, false));
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiScanTimeLimit(uint8_t type, uint16_t mask, uint8_t acqMode, uint8_t nbMaxRes, uint16_t timePerChan, uint16_t timeout) {
|
||||
|
@ -2299,19 +2640,9 @@ int16_t LR11x0::wifiCountryCodeTimeLimit(uint16_t mask, uint8_t nbMaxRes, uint16
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_COUNTRY_CODE_TIME_LIMIT, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiGetNbResults(uint8_t* nbResults) {
|
||||
uint8_t buff[1] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_GET_NB_RESULTS, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(nbResults) { *nbResults = buff[0]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiReadResults(uint8_t index, uint8_t nbResults, uint8_t format, uint8_t* results) {
|
||||
uint8_t reqBuff[3] = { index, nbResults, format };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_READ_RESULTS, false, results, nbResults, reqBuff, sizeof(reqBuff)));
|
||||
uint8_t buff[3] = { index, nbResults, format };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WIFI_READ_RESULTS, false, results, RADIOLIB_LR11X0_WIFI_RESULT_MAX_LEN, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::wifiResetCumulTimings(void) {
|
||||
|
@ -2481,7 +2812,7 @@ int16_t LR11x0::gnssGetContextStatus(uint8_t* fwVersion, uint32_t* almanacCrc, u
|
|||
// read the result - this requires some magic bytes first, that's why LR11x0::SPIcommand cannot be used
|
||||
uint8_t cmd_buff[3] = { 0x00, 0x02, 0x18 };
|
||||
uint8_t buff[9] = { 0 };
|
||||
state = this->mod->SPItransferStream(cmd_buff, sizeof(cmd_buff), false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
state = this->mod->SPItransferStream(cmd_buff, sizeof(cmd_buff), false, NULL, buff, sizeof(buff), true);
|
||||
|
||||
// pass the replies
|
||||
if(fwVersion) { *fwVersion = buff[0]; }
|
||||
|
@ -2526,7 +2857,7 @@ int16_t LR11x0::gnssGetSvDetected(uint8_t* svId, uint8_t* snr, uint16_t* doppler
|
|||
}
|
||||
}
|
||||
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] dataBuff;
|
||||
#endif
|
||||
return(state);
|
||||
|
@ -2589,6 +2920,196 @@ int16_t LR11x0::gnssGetSvVisible(uint32_t time, float lat, float lon, uint8_t co
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_GET_SV_VISIBLE, false, nbSv, 1, reqBuff, sizeof(reqBuff)));
|
||||
}
|
||||
|
||||
// TODO check version > 02.01
|
||||
int16_t LR11x0::gnssScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax) {
|
||||
uint8_t buff[3] = { effort, resMask, nbSvMax };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_SCAN, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadLastScanModeLaunched(uint8_t* lastScanMode) {
|
||||
uint8_t buff[1] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_LAST_SCAN_MODE_LAUNCHED, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(lastScanMode) { *lastScanMode = buff[0]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssFetchTime(uint8_t effort, uint8_t opt) {
|
||||
uint8_t buff[2] = { effort, opt };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_FETCH_TIME, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadTime(uint8_t* err, uint32_t* time, uint32_t* nbUs, uint32_t* timeAccuracy) {
|
||||
uint8_t buff[12] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_TIME, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(err) { *err = buff[0]; }
|
||||
if(time) { *time = ((uint32_t)(buff[1]) << 24) | ((uint32_t)(buff[2]) << 16) | ((uint32_t)(buff[3]) << 8) | (uint32_t)buff[4]; }
|
||||
if(nbUs) { *nbUs = ((uint32_t)(buff[5]) << 16) | ((uint32_t)(buff[6]) << 8) | (uint32_t)buff[7]; }
|
||||
if(timeAccuracy) { *timeAccuracy = ((uint32_t)(buff[8]) << 24) | ((uint32_t)(buff[9]) << 16) | ((uint32_t)(buff[10]) << 8) | (uint32_t)buff[11]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssResetTime(void) {
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_RESET_TIME, true, NULL, 0));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssResetPosition(void) {
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_RESET_POSITION, true, NULL, 0));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadDemodStatus(int8_t* status, uint8_t* info) {
|
||||
uint8_t buff[2] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_DEMOD_STATUS, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(status) { *status = (int8_t)buff[0]; }
|
||||
if(info) { *info = buff[1]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadCumulTiming(uint32_t* timing, uint8_t* constDemod) {
|
||||
uint8_t rplBuff[125] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_READ_REG_MEM, false, rplBuff, 125);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// convert endians
|
||||
if(timing) {
|
||||
for(size_t i = 0; i < 31; i++) {
|
||||
timing[i] = ((uint32_t)rplBuff[i*sizeof(uint32_t)] << 24) | ((uint32_t)rplBuff[1 + i*sizeof(uint32_t)] << 16) | ((uint32_t)rplBuff[2 + i*sizeof(uint32_t)] << 8) | (uint32_t)rplBuff[3 + i*sizeof(uint32_t)];
|
||||
}
|
||||
}
|
||||
|
||||
if(constDemod) { *constDemod = rplBuff[124]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssSetTime(uint32_t time, uint16_t accuracy) {
|
||||
uint8_t buff[6] = {
|
||||
(uint8_t)((time >> 24) & 0xFF), (uint8_t)((time >> 16) & 0xFF),
|
||||
(uint8_t)((time >> 8) & 0xFF), (uint8_t)(time & 0xFF),
|
||||
(uint8_t)((accuracy >> 8) & 0xFF), (uint8_t)(accuracy & 0xFF),
|
||||
};
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_SET_TIME, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadDopplerSolverRes(uint8_t* error, uint8_t* nbSvUsed, float* lat, float* lon, uint16_t* accuracy, uint16_t* xtal, float* latFilt, float* lonFilt, uint16_t* accuracyFilt, uint16_t* xtalFilt) {
|
||||
uint8_t buff[18] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_DOPPLER_SOLVER_RES, false, buff, sizeof(buff));
|
||||
|
||||
// pass the replies
|
||||
if(error) { *error = buff[0]; }
|
||||
if(nbSvUsed) { *nbSvUsed = buff[1]; }
|
||||
if(lat) {
|
||||
uint16_t latRaw = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3];
|
||||
*lat = ((float)latRaw * 90.0f)/2048.0f;
|
||||
}
|
||||
if(lon) {
|
||||
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) {
|
||||
uint16_t latRaw = ((uint16_t)(buff[10]) << 8) | (uint16_t)buff[11];
|
||||
*latFilt = ((float)latRaw * 90.0f)/2048.0f;
|
||||
}
|
||||
if(lonFilt) {
|
||||
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]; }
|
||||
if(xtalFilt) { *xtalFilt = ((uint16_t)(buff[16]) << 8) | (uint16_t)buff[17]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadDelayResetAP(uint32_t* delay) {
|
||||
uint8_t buff[3] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_DELAY_RESET_AP, false, buff, sizeof(buff));
|
||||
|
||||
if(delay) { *delay = ((uint32_t)(buff[0]) << 16) | ((uint32_t)(buff[1]) << 8) | (uint32_t)buff[2]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssAlmanacUpdateFromSat(uint8_t effort, uint8_t bitMask) {
|
||||
uint8_t buff[2] = { effort, bitMask };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_UPDATE_FROM_SAT, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadAlmanacStatus(uint8_t* status) {
|
||||
// TODO parse the reply into some structure
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_STATUS, false, status, 53));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssConfigAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t period) {
|
||||
uint8_t buff[4] = { bitMask, svType, (uint8_t)((period >> 8) & 0xFF), (uint8_t)(period & 0xFF) };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_CONFIG_ALMANAC_UPDATE_PERIOD, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t* period) {
|
||||
uint8_t reqBuff[2] = { bitMask, svType };
|
||||
uint8_t rplBuff[2] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_UPDATE_PERIOD, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
if(period) { *period = ((uint16_t)(rplBuff[0]) << 8) | (uint16_t)rplBuff[1]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssConfigDelayResetAP(uint32_t delay) {
|
||||
uint8_t buff[3] = { (uint8_t)((delay >> 16) & 0xFF), (uint8_t)((delay >> 8) & 0xFF), (uint8_t)(delay & 0xFF) };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_CONFIG_DELAY_RESET_AP, true, buff, sizeof(buff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssGetSvWarmStart(uint8_t bitMask, uint8_t* sv, uint8_t nbVisSat) {
|
||||
uint8_t reqBuff[1] = { bitMask };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_GET_SV_WARM_START, false, sv, nbVisSat, reqBuff, sizeof(reqBuff)));
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadWNRollover(uint8_t* status, uint8_t* rollover) {
|
||||
uint8_t buff[2] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_WN_ROLLOVER, false, buff, sizeof(buff));
|
||||
|
||||
if(status) { *status = buff[0]; }
|
||||
if(rollover) { *rollover = buff[1]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssReadWarmStartStatus(uint8_t bitMask, uint8_t* nbVisSat, uint32_t* timeElapsed) {
|
||||
uint8_t reqBuff[1] = { bitMask };
|
||||
uint8_t rplBuff[5] = { 0 };
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_WARM_START_STATUS, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
if(nbVisSat) { *nbVisSat = rplBuff[0]; }
|
||||
if(timeElapsed) { *timeElapsed = ((uint32_t)(rplBuff[1]) << 24) | ((uint32_t)(rplBuff[2]) << 16) | ((uint32_t)(rplBuff[3]) << 8) | (uint32_t)rplBuff[4]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::gnssWriteBitMaskSatActivated(uint8_t bitMask, uint32_t* bitMaskActivated0, uint32_t* bitMaskActivated1) {
|
||||
uint8_t reqBuff[1] = { bitMask };
|
||||
uint8_t rplBuff[8] = { 0 };
|
||||
size_t rplLen = (bitMask & 0x01) ? 8 : 4; // GPS only has the first bit mask
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GNSS_READ_WARM_START_STATUS, false, rplBuff, rplLen, reqBuff, sizeof(reqBuff));
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
if(bitMaskActivated0) { *bitMaskActivated0 = ((uint32_t)(rplBuff[0]) << 24) | ((uint32_t)(rplBuff[1]) << 16) | ((uint32_t)(rplBuff[2]) << 8) | (uint32_t)rplBuff[3]; }
|
||||
if(bitMaskActivated1) { *bitMaskActivated1 = ((uint32_t)(rplBuff[4]) << 24) | ((uint32_t)(rplBuff[5]) << 16) | ((uint32_t)(rplBuff[6]) << 8) | (uint32_t)rplBuff[7]; }
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::cryptoSetKey(uint8_t keyId, uint8_t* key) {
|
||||
if(!key) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
|
@ -2670,7 +3191,7 @@ int16_t LR11x0::cryptoComputeAesCmac(uint8_t keyId, uint8_t* data, size_t len, u
|
|||
memcpy(&reqBuff[1], data, len);
|
||||
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_CRYPTO_COMPUTE_AES_CMAC, false, rplBuff, sizeof(rplBuff), reqBuff, reqLen);
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] reqBuff;
|
||||
#endif
|
||||
|
||||
|
@ -2701,7 +3222,7 @@ int16_t LR11x0::cryptoVerifyAesCmac(uint8_t keyId, uint32_t micExp, uint8_t* dat
|
|||
memcpy(&reqBuff[5], data, len);
|
||||
|
||||
int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_CRYPTO_VERIFY_AES_CMAC, false, rplBuff, sizeof(rplBuff), reqBuff, reqLen);
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] reqBuff;
|
||||
#endif
|
||||
|
||||
|
@ -2753,13 +3274,12 @@ int16_t LR11x0::cryptoGetParam(uint8_t id, uint32_t* value) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::cryptoCheckEncryptedFirmwareImage(uint32_t offset, uint32_t* data, size_t len) {
|
||||
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);
|
||||
}
|
||||
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_CRYPTO_CHECK_ENCRYPTED_FIRMWARE_IMAGE, offset, data, len));
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_CRYPTO_CHECK_ENCRYPTED_FIRMWARE_IMAGE, offset, data, len, nonvolatile));
|
||||
}
|
||||
|
||||
int16_t LR11x0::cryptoCheckEncryptedFirmwareImageResult(bool* result) {
|
||||
|
@ -2773,12 +3293,20 @@ int16_t LR11x0::cryptoCheckEncryptedFirmwareImageResult(bool* result) {
|
|||
}
|
||||
|
||||
int16_t LR11x0::bootEraseFlash(void) {
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_ERASE_FLASH, true, NULL, 0));
|
||||
// erasing flash takes about 2.5 seconds, temporarily tset SPI timeout to 3 seconds
|
||||
RadioLibTime_t timeout = this->mod->spiConfig.timeout;
|
||||
this->mod->spiConfig.timeout = 3000;
|
||||
int16_t state = this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_BOOT_ERASE_FLASH, NULL, 0, false, false);
|
||||
this->mod->spiConfig.timeout = timeout;
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::bootWriteFlashEncrypted(uint32_t offset, uint32_t* data, size_t len) {
|
||||
RADIOLIB_CHECK_RANGE(len, 1, 32, RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_BOOT_WRITE_FLASH_ENCRYPTED, offset, data, len));
|
||||
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);
|
||||
}
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_BOOT_WRITE_FLASH_ENCRYPTED, offset, data, len, nonvolatile));
|
||||
}
|
||||
|
||||
int16_t LR11x0::bootReboot(bool stay) {
|
||||
|
@ -2807,7 +3335,7 @@ int16_t LR11x0::bootGetJoinEui(uint8_t* eui) {
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_GET_JOIN_EUI, false, eui, RADIOLIB_LR11X0_EUI_LEN));
|
||||
}
|
||||
|
||||
int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, uint32_t* data, size_t len) {
|
||||
int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile) {
|
||||
// build buffers - later we need to ensure endians are correct,
|
||||
// so there is probably no way to do this without copying buffers and iterating
|
||||
size_t buffLen = sizeof(uint32_t) + len*sizeof(uint32_t);
|
||||
|
@ -2825,14 +3353,20 @@ int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, uint32_t* data, s
|
|||
|
||||
// convert endians
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
dataBuff[4 + i] = (uint8_t)((data[i] >> 24) & 0xFF);
|
||||
dataBuff[5 + i] = (uint8_t)((data[i] >> 16) & 0xFF);
|
||||
dataBuff[6 + i] = (uint8_t)((data[i] >> 8) & 0xFF);
|
||||
dataBuff[7 + i] = (uint8_t)(data[i] & 0xFF);
|
||||
uint32_t bin = 0;
|
||||
if(nonvolatile) {
|
||||
bin = RADIOLIB_NONVOLATILE_READ_DWORD(data + i);
|
||||
} else {
|
||||
bin = data[i];
|
||||
}
|
||||
dataBuff[4 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 24) & 0xFF);
|
||||
dataBuff[5 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 16) & 0xFF);
|
||||
dataBuff[6 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 8) & 0xFF);
|
||||
dataBuff[7 + i*sizeof(uint32_t)] = (uint8_t)(bin & 0xFF);
|
||||
}
|
||||
|
||||
int16_t state = this->SPIcommand(cmd, true, dataBuff, buffLen);
|
||||
#if RADIOLIB_STATIC_ONLY
|
||||
int16_t state = this->mod->SPIwriteStream(cmd, dataBuff, buffLen, true, false);
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] dataBuff;
|
||||
#endif
|
||||
return(state);
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#define RADIOLIB_LR11X0_CMD_SET_GFSK_WHIT_PARAMS (0x0225)
|
||||
#define RADIOLIB_LR11X0_CMD_SET_RX_BOOSTED (0x0227)
|
||||
#define RADIOLIB_LR11X0_CMD_SET_RANGING_PARAMETER (0x0228)
|
||||
#define RADIOLIB_LR11X0_CMD_SET_RSSI_CALIBRATION (0x0229)
|
||||
#define RADIOLIB_LR11X0_CMD_SET_LORA_SYNC_WORD (0x022B)
|
||||
#define RADIOLIB_LR11X0_CMD_LR_FHSS_BUILD_FRAME (0x022C)
|
||||
#define RADIOLIB_LR11X0_CMD_LR_FHSS_SET_SYNC_WORD (0x022D)
|
||||
|
@ -111,6 +112,10 @@
|
|||
#define RADIOLIB_LR11X0_CMD_GNSS_SET_MODE (0x0408)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_AUTONOMOUS (0x0409)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_ASSISTED (0x040A)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_SCAN (0x040B)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_GET_RESULT_SIZE (0x040C)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_RESULTS (0x040D)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE (0x040E)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_SET_ASSISTANCE_POSITION (0x0410)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_ASSISTANCE_POSITION (0x0411)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_PUSH_SOLVER_MSG (0x0414)
|
||||
|
@ -119,10 +124,26 @@
|
|||
#define RADIOLIB_LR11X0_CMD_GNSS_GET_NB_SV_DETECTED (0x0417)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_GET_SV_DETECTED (0x0418)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_GET_CONSUMPTION (0x0419)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_GET_RESULT_SIZE (0x040C)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_RESULTS (0x040D)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_FULL_UPDATE (0x040E)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_GET_SV_VISIBLE (0x041F)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_LAST_SCAN_MODE_LAUNCHED (0x0426)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_FETCH_TIME (0x0432)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_TIME (0x0434)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_RESET_TIME (0x0435)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_RESET_POSITION (0x0437)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_DEMOD_STATUS (0x0439)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_CUMUL_TIMING (0x044A)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_SET_TIME (0x044B)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_DOPPLER_SOLVER_RES (0x044F)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_DELAY_RESET_AP (0x0453)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_ALMANAC_UPDATE_FROM_SAT (0x0455)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_STATUS (0x0457)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_CONFIG_ALMANAC_UPDATE_PERIOD (0x0463)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_ALMANAC_UPDATE_PERIOD (0x0464)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_CONFIG_DELAY_RESET_AP (0x0465)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_GET_SV_WARM_START (0x0466)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_WN_ROLLOVER (0x0467)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_READ_WARM_START_STATUS (0x0469)
|
||||
#define RADIOLIB_LR11X0_CMD_GNSS_WRITE_BIT_MASK_SAT_ACTIVATED (0x0472)
|
||||
#define RADIOLIB_LR11X0_CMD_CRYPTO_SET_KEY (0x0502)
|
||||
#define RADIOLIB_LR11X0_CMD_CRYPTO_DERIVE_KEY (0x0503)
|
||||
#define RADIOLIB_LR11X0_CMD_CRYPTO_PROCESS_JOIN_ACCEPT (0x0504)
|
||||
|
@ -147,6 +168,7 @@
|
|||
// LR11X0 register map
|
||||
#define RADIOLIB_LR11X0_REG_SF6_SX127X_COMPAT (0x00F20414)
|
||||
#define RADIOLIB_LR11X0_REG_LORA_HIGH_POWER_FIX (0x00F30054)
|
||||
// TODO add fix for br 600/1200 bps
|
||||
|
||||
// LR11X0 SPI command variables
|
||||
|
||||
|
@ -178,10 +200,10 @@
|
|||
#define RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN (256) // 7 0 maximum length of read/write SPI payload in bytes
|
||||
|
||||
// RADIOLIB_LR11X0_CMD_GET_VERSION
|
||||
#define RADIOLIB_LR11X0_HW_LR1110 (0x01UL << 0) // 7 0 HW version: LR1110
|
||||
#define RADIOLIB_LR11X0_HW_LR1120 (0x02UL << 0) // 7 0 LR1120
|
||||
#define RADIOLIB_LR11X0_HW_LR1121 (0x03UL << 0) // 7 0 LR1121
|
||||
#define RADIOLIB_LR11X0_HW_BOOT (0xDFUL << 0) // 7 0 bootloader mode
|
||||
#define RADIOLIB_LR11X0_DEVICE_LR1110 (0x01UL << 0) // 7 0 HW device: LR1110
|
||||
#define RADIOLIB_LR11X0_DEVICE_LR1120 (0x02UL << 0) // 7 0 LR1120
|
||||
#define RADIOLIB_LR11X0_DEVICE_LR1121 (0x03UL << 0) // 7 0 LR1121
|
||||
#define RADIOLIB_LR11X0_DEVICE_BOOT (0xDFUL << 0) // 7 0 bootloader mode
|
||||
|
||||
// RADIOLIB_LR11X0_CMD_GET_ERRORS
|
||||
#define RADIOLIB_LR11X0_ERROR_STAT_LF_RC_CALIB_ERR (0x01UL << 0) // 15 0 error: low frequency RC not calibrated
|
||||
|
@ -472,10 +494,15 @@
|
|||
#define RADIOLIB_LR11X0_WIFI_ACQ_MODE_SSID_BEACON (0x05UL << 0) // 7 0 SSID beacon
|
||||
#define RADIOLIB_LR11X0_WIFI_ABORT_ON_TIMEOUT_ENABLED (0x01UL << 0) // 7 0 abort scanning on preamble timeout: enabled
|
||||
#define RADIOLIB_LR11X0_WIFI_ABORT_ON_TIMEOUT_DISABLED (0x00UL << 0) // 7 0 disabled
|
||||
#define RADIOLIB_LR11X0_WIFI_MAX_NUM_RESULTS (32) // 7 0 maximum possible number of Wi-Fi scan results
|
||||
#define RADIOLIB_LR11X0_WIFI_ALL_CHANNELS (0x3FFFUL) // 16 0 scan all channels
|
||||
|
||||
// RADIOLIB_LR11X0_CMD_WIFI_READ_RESULTS
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_TYPE_COMPLETE (0x01UL << 0) // 7 0 Wi-Fi scan result type: complete
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_TYPE_BASIC (0x04UL << 0) // 7 0 basic
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_MAX_LEN (79) // 7 0 maximum possible Wi-Fi scan size
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN (6) // 7 0 MAC address length in bytes
|
||||
#define RADIOLIB_LR11X0_WIFI_RESULT_SSID_LEN (32) // 7 0 SSID length in bytes
|
||||
|
||||
// RADIOLIB_LR11X0_CMD_GNSS_SET_CONSTELLATION_TO_USE
|
||||
#define RADIOLIB_LR11X0_GNSS_CONSTELLATION_GPS (0x01UL << 0) // 7 0 GNSS constellation to use: GPS
|
||||
|
@ -536,10 +563,138 @@
|
|||
// RADIOLIB_LR11X0_REG_LORA_HIGH_POWER_FIX
|
||||
#define RADIOLIB_LR11X0_LORA_HIGH_POWER_FIX (0x00UL << 30) // 30 30 fix for errata
|
||||
|
||||
/*!
|
||||
\struct LR11x0WifiResult_t
|
||||
\brief Structure to save result of passive WiFi scan.
|
||||
This result only saves the basic information.
|
||||
*/
|
||||
struct LR11x0WifiResult_t {
|
||||
/*! \brief WiFi (802.11) signal type, 'b', 'n' or 'g' */
|
||||
char type;
|
||||
|
||||
/*! \brief Data rate ID holding information about modulation and coding rate. See LR11x0 user manual for details. */
|
||||
uint8_t dataRateId;
|
||||
|
||||
/*! \brief Channel frequency in MHz */
|
||||
uint16_t channelFreq;
|
||||
|
||||
/*! \brief MAC address origin: from gateway (1), phone (2) or undetermined (3) */
|
||||
uint8_t origin;
|
||||
|
||||
/*! \brief Whether this signal was sent by an access point (true) or end device (false) */
|
||||
bool ap;
|
||||
|
||||
/*! \brief RSSI in dBm */
|
||||
float rssi;
|
||||
|
||||
/*! \brief MAC address */
|
||||
uint8_t mac[RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN];
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LR11x0WifiResultFull_t
|
||||
\brief Structure to save result of passive WiFi scan.
|
||||
This result saves additional information alongside that in LR11x0WifiResult_t.
|
||||
*/
|
||||
struct LR11x0WifiResultFull_t: public LR11x0WifiResult_t {
|
||||
/*! \brief Frame type. See LR11x0 user manual for details. */
|
||||
uint8_t frameType;
|
||||
|
||||
/*! \brief Frame sub type. See LR11x0 user manual for details. */
|
||||
uint8_t frameSubType;
|
||||
|
||||
/*! \brief Frame sent from client station to distribution system. */
|
||||
bool toDistributionSystem;
|
||||
|
||||
/*! \brief Frame sent from distribution system to client station. */
|
||||
bool fromDistributionSystem;
|
||||
|
||||
/*! \brief See LR11x0 user manual for details. */
|
||||
uint16_t phiOffset;
|
||||
|
||||
/*! \brief Number of microseconds the AP has been active. */
|
||||
uint64_t timestamp;
|
||||
|
||||
/*! \brief Beacon period in microseconds. */
|
||||
uint32_t periodBeacon;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LR11x0WifiResultExtended_t
|
||||
\brief Structure to save result of passive WiFi scan.
|
||||
This result saves additional information alongside that in LR11x0WifiResultFull_t.
|
||||
Only scans performed with RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON acquisition mode
|
||||
can yield this result!
|
||||
*/
|
||||
struct LR11x0WifiResultExtended_t: public LR11x0WifiResultFull_t {
|
||||
/*! \brief Data rate. See LR11x0 user manual for details. */
|
||||
uint8_t rate;
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint16_t service;
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint16_t length;
|
||||
|
||||
/*! \brief MAC address 0 */
|
||||
uint8_t mac0[RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN];
|
||||
|
||||
/*! \brief MAC address 2 */
|
||||
uint8_t mac2[RADIOLIB_LR11X0_WIFI_RESULT_MAC_LEN];
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint16_t seqCtrl;
|
||||
|
||||
/*! \brief SSID */
|
||||
uint8_t ssid[RADIOLIB_LR11X0_WIFI_RESULT_SSID_LEN];
|
||||
|
||||
/*! \brief WiFi channel number */
|
||||
uint8_t currentChannel;
|
||||
|
||||
/*! \brief Two-letter country code (null-terminated string). */
|
||||
char countryCode[3];
|
||||
|
||||
/*! \brief Refer to IEEE Std 802.11, 2016, Part 11: Wireless LAN MAC and PHY Spec. */
|
||||
uint8_t ioReg;
|
||||
|
||||
/*! \brief True if frame check sequences is valid, false otherwise. */
|
||||
bool fcsCheckOk;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LR11x0VersionInfo_t
|
||||
\brief Structure to report information about versions of the LR11x0 hardware and firmware.
|
||||
*/
|
||||
struct LR11x0VersionInfo_t {
|
||||
/*! \brief Hardware revision. */
|
||||
uint8_t hardware;
|
||||
|
||||
/*! \brief Which device this is - one of RADIOLIB_LR11X0_DEVICE_* macros. */
|
||||
uint8_t device;
|
||||
|
||||
/*! \brief Major revision of the base firmware. */
|
||||
uint8_t fwMajor;
|
||||
|
||||
/*! \brief Minor revision of the base firmware. */
|
||||
uint8_t fwMinor;
|
||||
|
||||
/*! \brief Major revision of the WiFi firmware. */
|
||||
uint8_t fwMajorWiFi;
|
||||
|
||||
/*! \brief Minor revision of the WiFi firmware. */
|
||||
uint8_t fwMinorWiFi;
|
||||
|
||||
/*! \brief Revision of the GNSS firmware. */
|
||||
uint8_t fwGNSS;
|
||||
|
||||
/*! \brief Almanac revision of the GNSS firmware. */
|
||||
uint8_t almanacGNSS;
|
||||
};
|
||||
|
||||
/*!
|
||||
\class LR11x0
|
||||
\brief
|
||||
\brief Base class for %LR11x0 series. All derived classes for %LR11x0 (e.g. LR1110 or LR1120) inherit from this base class.
|
||||
This class should not be instantiated directly from user code, only from its derived classes.
|
||||
*/
|
||||
class LR11x0: public PhysicalLayer {
|
||||
public:
|
||||
|
@ -553,7 +708,7 @@ class LR11x0: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
LR11x0(Module* mod);
|
||||
explicit LR11x0(Module* mod);
|
||||
|
||||
/*!
|
||||
\brief Whether the module has an XTAL (true) or TCXO (false). Defaults to false.
|
||||
|
@ -664,6 +819,13 @@ class LR11x0: public PhysicalLayer {
|
|||
*/
|
||||
int16_t standby(uint8_t mode, bool wakeup = true);
|
||||
|
||||
/*!
|
||||
\brief Sets the module to sleep mode. To wake the device up, call standby().
|
||||
Overload with warm start enabled for PhysicalLayer compatibility.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep();
|
||||
|
||||
/*!
|
||||
\brief Sets the module to sleep mode. To wake the device up, call standby().
|
||||
\param retainConfig Set to true to retain configuration of the currently active modem ("warm start")
|
||||
|
@ -671,7 +833,7 @@ class LR11x0: public PhysicalLayer {
|
|||
\param sleepTime Sleep duration (enables automatic wakeup), in multiples of 30.52 us. Ignored if set to 0.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep(bool retainConfig = true, uint32_t sleepTime = 0);
|
||||
int16_t sleep(bool retainConfig, uint32_t sleepTime);
|
||||
|
||||
// interrupt methods
|
||||
|
||||
|
@ -690,23 +852,23 @@ class LR11x0: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method.
|
||||
|
@ -730,7 +892,7 @@ class LR11x0: public PhysicalLayer {
|
|||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method. IRQ1 will be activated when full packet is received.
|
||||
|
@ -740,10 +902,11 @@ class LR11x0: public PhysicalLayer {
|
|||
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, size_t len = 0);
|
||||
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.
|
||||
|
@ -791,7 +954,7 @@ class LR11x0: public PhysicalLayer {
|
|||
\param power Output power to be set in dBm, output PA is determined automatically preferring the low-power PA.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setOutputPower(int8_t power) override;
|
||||
|
||||
/*!
|
||||
\brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA).
|
||||
|
@ -802,6 +965,25 @@ class LR11x0: public PhysicalLayer {
|
|||
*/
|
||||
int16_t setOutputPower(int8_t power, bool forceHighPower);
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
|
||||
\param power Output power in dBm, PA will be determined automatically.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically
|
||||
based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower);
|
||||
|
||||
/*!
|
||||
\brief Sets LoRa bandwidth. Allowed values are 62.5, 125.0, 250.0 and 500.0 kHz.
|
||||
\param bw LoRa bandwidth to be set in kHz.
|
||||
|
@ -838,7 +1020,7 @@ class LR11x0: public PhysicalLayer {
|
|||
\param br FSK bit rate to be set in kbps.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
/*!
|
||||
\brief Sets GFSK frequency deviation. Allowed values range from 0.0 to 200.0 kHz.
|
||||
|
@ -984,13 +1166,13 @@ class LR11x0: public PhysicalLayer {
|
|||
\brief Gets RSSI (Recorded Signal Strength Indicator) of the last received packet. Only available for LoRa or GFSK modem.
|
||||
\returns RSSI of the last received packet in dBm.
|
||||
*/
|
||||
float getRSSI();
|
||||
float getRSSI() override;
|
||||
|
||||
/*!
|
||||
\brief Gets SNR (Signal to Noise Ratio) of the last received packet. Only available for LoRa modem.
|
||||
\returns SNR of the last received packet in dB.
|
||||
*/
|
||||
float getSNR();
|
||||
float getSNR() override;
|
||||
|
||||
/*!
|
||||
\brief Gets frequency error of the latest received packet.
|
||||
|
@ -1019,6 +1201,46 @@ class LR11x0: public PhysicalLayer {
|
|||
*/
|
||||
RadioLibTime_t getTimeOnAir(size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Calculate the timeout value for this specific module / series (in number of symbols or units of time)
|
||||
\param timeoutUs Timeout in microseconds to listen for
|
||||
\returns Timeout value in a unit that is specific for the used module
|
||||
*/
|
||||
RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs) override;
|
||||
|
||||
/*!
|
||||
\brief Create the flags that make up RxDone and RxTimeout used for receiving downlinks
|
||||
\param irqFlags The flags for which IRQs must be triggered
|
||||
\param irqMask Mask indicating which IRQ triggers a DIO
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override;
|
||||
|
||||
/*!
|
||||
\brief Check whether the IRQ bit for RxTimeout is set
|
||||
\returns Whether RxTimeout IRQ is set
|
||||
*/
|
||||
bool isRxTimeout() override;
|
||||
|
||||
/*!
|
||||
\brief Get one truly random byte from RSSI noise.
|
||||
\returns TRNG byte.
|
||||
*/
|
||||
uint8_t randomByte() override;
|
||||
|
||||
/*!
|
||||
\brief Set implicit header mode for future reception/transmission.
|
||||
\param len Payload length in bytes.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t implicitHeader(size_t len);
|
||||
|
||||
/*!
|
||||
\brief Set explicit header mode for future reception/transmission.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t explicitHeader();
|
||||
|
||||
/*!
|
||||
\brief Gets effective data rate for the last transmitted packet. The value is calculated only for payload bytes.
|
||||
\returns Effective data rate in bps.
|
||||
|
@ -1035,10 +1257,92 @@ class LR11x0: public PhysicalLayer {
|
|||
*/
|
||||
int16_t setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount = 3, uint16_t hopSeed = 0x13A);
|
||||
|
||||
/*!
|
||||
\brief Start passive WiFi scan. BUSY pin will be de-activated when the scan is finished.
|
||||
\param wifiType Type of WiFi (802.11) signals to scan, 'b', 'n', 'g' or '*' for all signals.
|
||||
\param mode Scan acquisition mode, one of RADIOLIB_LR11X0_WIFI_ACQ_MODE_*.
|
||||
The type of results available after the scan depends on this mode.
|
||||
Defaults to RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, which provides the most information.
|
||||
\param chanMask Bit mask of WiFi channels to scan, defaults to all channels.
|
||||
More channels leads to longer overall scan duration.
|
||||
\param numScans Number of scans to perform per each enabled channel. Defaults to 16 scans.
|
||||
More scans leads to longer overall scan duration.
|
||||
\param timeout Timeout of each scan in milliseconds. Defaults to 100 ms
|
||||
Longer timeout leads to longer overall scan duration.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startWifiScan(char wifiType, uint8_t mode = RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, uint16_t chanMask = RADIOLIB_LR11X0_WIFI_ALL_CHANNELS, uint8_t numScans = 16, uint16_t timeout = 100);
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a WiFi scan is completed.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setWiFiScanAction(void (*func)(void));
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a WiFi scan is completed.
|
||||
*/
|
||||
void clearWiFiScanAction();
|
||||
|
||||
/*!
|
||||
\brief Get number of WiFi scan results after the scan is finished.
|
||||
\param count Pointer to a variable that will hold the number of scan results.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t getWifiScanResultsCount(uint8_t* count);
|
||||
|
||||
/*!
|
||||
\brief Retrieve passive WiFi scan result.
|
||||
\param result Pointer to structure to hold the result data.
|
||||
\param index Result index, starting from 0. The number of scan results can be retrieved by calling getWifiScanResultsCount.
|
||||
\param brief Whether to only retrieve the results in brief format. If set to false, only information in LR11x0WifiResult_t
|
||||
will be retrieved. If set to true, information in LR11x0WifiResultFull_t will be retrieved. In addition, if WiFi scan mode
|
||||
was set to RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, all information in LR11x0WifiResultExtended_t will be retrieved.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t getWifiScanResult(LR11x0WifiResult_t* result, uint8_t index, bool brief = false);
|
||||
|
||||
/*!
|
||||
\brief Blocking WiFi scan method. Performs a full passive WiFi scan.
|
||||
This method may block for several seconds!
|
||||
\param wifiType Type of WiFi (802.11) signals to scan, 'b', 'n', 'g' or '*' for all signals.
|
||||
\param count Pointer to a variable that will hold the number of scan results.
|
||||
\param mode Scan acquisition mode, one of RADIOLIB_LR11X0_WIFI_ACQ_MODE_*.
|
||||
The type of results available after the scan depends on this mode.
|
||||
Defaults to RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, which provides the most information.
|
||||
\param chanMask Bit mask of WiFi channels to scan, defaults to all channels.
|
||||
More channels leads to longer overall scan duration.
|
||||
\param numScans Number of scans to perform per each enabled channel. Defaults to 16 scans.
|
||||
More scans leads to longer overall scan duration.
|
||||
\param timeout Timeout of each scan in milliseconds. Defaults to 100 ms
|
||||
Longer timeout leads to longer overall scan duration.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t wifiScan(uint8_t wifiType, uint8_t* count, uint8_t mode = RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, uint16_t chanMask = RADIOLIB_LR11X0_WIFI_ALL_CHANNELS, uint8_t numScans = 16, uint16_t timeout = 100);
|
||||
|
||||
/*!
|
||||
\brief Retrieve LR11x0 hardware, device and firmware version information.
|
||||
\param info Pointer to LR11x0VersionInfo_t structure to populate.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t getVersionInfo(LR11x0VersionInfo_t* info);
|
||||
|
||||
/*!
|
||||
\brief Method to upload new firmware image to the device.
|
||||
The device will be automatically erased, a new firmware will be uploaded,
|
||||
written to flash and executed.
|
||||
\param image Pointer to the image to upload.
|
||||
\param size Size of the image in 32-bit words.
|
||||
\param nonvolatile Set to true when the image is saved in non-volatile memory of the host processor,
|
||||
or to false when the patch is in its RAM. Defaults to true.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t updateFirmware(const uint32_t* image, size_t size, bool nonvolatile = true);
|
||||
|
||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
// LR11x0 SPI command implementations
|
||||
int16_t writeRegMem32(uint32_t addr, uint32_t* data, size_t len);
|
||||
|
@ -1055,7 +1359,7 @@ class LR11x0: public PhysicalLayer {
|
|||
int16_t calibrate(uint8_t params);
|
||||
int16_t setRegMode(uint8_t mode);
|
||||
int16_t calibImage(float freq1, float freq2);
|
||||
int16_t setDioAsRfSwitch(uint8_t en, uint8_t stbyCfg, uint8_t rxCfg, uint8_t txCfg, uint8_t txHpCfg, uint8_t gnssCfg, uint8_t wifiCfg);
|
||||
int16_t setDioAsRfSwitch(uint8_t en, uint8_t stbyCfg, uint8_t rxCfg, uint8_t txCfg, uint8_t txHpCfg, uint8_t txHfCfg, uint8_t gnssCfg, uint8_t wifiCfg);
|
||||
int16_t setDioIrqParams(uint32_t irq1, uint32_t irq2);
|
||||
int16_t clearIrq(uint32_t irq);
|
||||
int16_t configLfClock(uint8_t setup);
|
||||
|
@ -1066,7 +1370,7 @@ class LR11x0: public PhysicalLayer {
|
|||
int16_t setFs(void);
|
||||
int16_t getRandomNumber(uint32_t* rnd);
|
||||
int16_t eraseInfoPage(void);
|
||||
int16_t writeInfoPage(uint16_t addr, uint32_t* data, size_t len);
|
||||
int16_t writeInfoPage(uint16_t addr, const uint32_t* data, size_t len);
|
||||
int16_t readInfoPage(uint16_t addr, uint32_t* data, size_t len);
|
||||
int16_t getChipEui(uint8_t* eui);
|
||||
int16_t getSemtechJoinEui(uint8_t* eui);
|
||||
|
@ -1114,6 +1418,7 @@ class LR11x0: public PhysicalLayer {
|
|||
int16_t setGfskWhitParams(uint16_t seed);
|
||||
int16_t setRxBoosted(bool en);
|
||||
int16_t setRangingParameter(uint8_t symbolNum);
|
||||
int16_t setRssiCalibration(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, uint8_t* payload, size_t len);
|
||||
int16_t lrFhssSetSyncWord(uint32_t sync);
|
||||
|
@ -1156,6 +1461,26 @@ class LR11x0: public PhysicalLayer {
|
|||
int16_t gnssAlmanacFullUpdateHeader(uint16_t date, uint32_t globalCrc);
|
||||
int16_t gnssAlmanacFullUpdateSV(uint8_t svn, uint8_t* svnAlmanac);
|
||||
int16_t gnssGetSvVisible(uint32_t time, float lat, float lon, uint8_t constellation, uint8_t* nbSv);
|
||||
int16_t gnssScan(uint8_t effort, uint8_t resMask, uint8_t nbSvMax);
|
||||
int16_t gnssReadLastScanModeLaunched(uint8_t* lastScanMode);
|
||||
int16_t gnssFetchTime(uint8_t effort, uint8_t opt);
|
||||
int16_t gnssReadTime(uint8_t* err, uint32_t* time, uint32_t* nbUs, uint32_t* timeAccuracy);
|
||||
int16_t gnssResetTime(void);
|
||||
int16_t gnssResetPosition(void);
|
||||
int16_t gnssReadDemodStatus(int8_t* status, uint8_t* info);
|
||||
int16_t gnssReadCumulTiming(uint32_t* timing, uint8_t* constDemod);
|
||||
int16_t gnssSetTime(uint32_t time, uint16_t accuracy);
|
||||
int16_t gnssReadDopplerSolverRes(uint8_t* error, uint8_t* nbSvUsed, float* lat, float* lon, uint16_t* accuracy, uint16_t* xtal, float* latFilt, float* lonFilt, uint16_t* accuracyFilt, uint16_t* xtalFilt);
|
||||
int16_t gnssReadDelayResetAP(uint32_t* delay);
|
||||
int16_t gnssAlmanacUpdateFromSat(uint8_t effort, uint8_t bitMask);
|
||||
int16_t gnssReadAlmanacStatus(uint8_t* status);
|
||||
int16_t gnssConfigAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t period);
|
||||
int16_t gnssReadAlmanacUpdatePeriod(uint8_t bitMask, uint8_t svType, uint16_t* period);
|
||||
int16_t gnssConfigDelayResetAP(uint32_t delay);
|
||||
int16_t gnssGetSvWarmStart(uint8_t bitMask, uint8_t* sv, uint8_t nbVisSat);
|
||||
int16_t gnssReadWNRollover(uint8_t* status, uint8_t* rollover);
|
||||
int16_t gnssReadWarmStartStatus(uint8_t bitMask, uint8_t* nbVisSat, uint32_t* timeElapsed);
|
||||
int16_t gnssWriteBitMaskSatActivated(uint8_t bitMask, uint32_t* bitMaskActivated0, uint32_t* bitMaskActivated1);
|
||||
|
||||
int16_t cryptoSetKey(uint8_t keyId, uint8_t* key);
|
||||
int16_t cryptoDeriveKey(uint8_t srcKeyId, uint8_t dstKeyId, uint8_t* key);
|
||||
|
@ -1169,11 +1494,11 @@ class LR11x0: public PhysicalLayer {
|
|||
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, uint32_t* data, size_t len);
|
||||
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, uint32_t* data, size_t len);
|
||||
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);
|
||||
|
@ -1184,7 +1509,7 @@ class LR11x0: public PhysicalLayer {
|
|||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
#endif
|
||||
uint8_t chipType;
|
||||
uint8_t chipType = 0;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
@ -1210,6 +1535,8 @@ class LR11x0: public PhysicalLayer {
|
|||
|
||||
float dataRateMeasured = 0;
|
||||
|
||||
uint8_t wifiScanMode = 0;
|
||||
|
||||
int16_t modSetup(float tcxoVoltage, uint8_t modem);
|
||||
static int16_t SPIparseStatus(uint8_t in);
|
||||
static int16_t SPIcheckStatus(Module* mod);
|
||||
|
@ -1217,10 +1544,11 @@ class LR11x0: public PhysicalLayer {
|
|||
int16_t config(uint8_t modem);
|
||||
int16_t setPacketMode(uint8_t mode, uint8_t len);
|
||||
int16_t startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin);
|
||||
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, uint8_t* payload, size_t len);
|
||||
int16_t writeCommon(uint16_t cmd, uint32_t addrOffset, uint32_t* data, 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, uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
||||
};
|
||||
|
||||
|
|
38
src/modules/LR11x0/LR11x0_firmware.h
Normal file
38
src/modules/LR11x0/LR11x0_firmware.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#if !defined(_RADIOLIB_LR11X0_FIRMWARE_H)
|
||||
#define _RADIOLIB_LR11X0_FIRMWARE_H
|
||||
|
||||
#if defined(RADIOLIB_LR1110_FIRMWARE_IN_RAM)
|
||||
#define RADIOLIB_LR1110_FIRMWARE_ATTR
|
||||
#else
|
||||
#define RADIOLIB_LR1110_FIRMWARE_ATTR RADIOLIB_NONVOLATILE
|
||||
#endif
|
||||
|
||||
#define RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE LR11XX_FIRMWARE_IMAGE_SIZE
|
||||
|
||||
#if defined(RADIOLIB_LR1110_FIRMWARE_0303)
|
||||
#include "firmware/lr1110_transceiver_0303.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0304)
|
||||
#include "firmware/lr1110_transceiver_0304.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0305)
|
||||
#include "firmware/lr1110_transceiver_0305.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0306)
|
||||
#include "firmware/lr1110_transceiver_0306.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0307)
|
||||
#include "firmware/lr1110_transceiver_0307.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0401)
|
||||
#include "firmware/lr1110_transceiver_0401.h"
|
||||
#elif defined(RADIOLIB_LR1120_FIRMWARE_0101)
|
||||
#include "firmware/lr1120_transceiver_0101.h"
|
||||
#elif defined(RADIOLIB_LR1120_FIRMWARE_0102)
|
||||
#include "firmware/lr1120_transceiver_0102.h"
|
||||
#elif defined(RADIOLIB_LR1120_FIRMWARE_0201)
|
||||
#include "firmware/lr1120_transceiver_0201.h"
|
||||
#elif defined(RADIOLIB_LR1121_FIRMWARE_0102)
|
||||
#include "firmware/lr1121_transceiver_0102.h"
|
||||
#elif defined(RADIOLIB_LR1121_FIRMWARE_0103)
|
||||
#include "firmware/lr1121_transceiver_0103.h"
|
||||
#else
|
||||
#error "No LR11x0 firmware image selected!"
|
||||
#endif
|
||||
|
||||
#endif
|
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0303.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0303.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0304.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0304.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0305.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0305.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0306.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0306.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0307.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0307.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0308.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0308.h
Normal file
File diff suppressed because it is too large
Load diff
7741
src/modules/LR11x0/firmware/lr1110_transceiver_0401.h
Normal file
7741
src/modules/LR11x0/firmware/lr1110_transceiver_0401.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0101.h
Normal file
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0101.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0102.h
Normal file
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0102.h
Normal file
File diff suppressed because it is too large
Load diff
7741
src/modules/LR11x0/firmware/lr1120_transceiver_0201.h
Normal file
7741
src/modules/LR11x0/firmware/lr1120_transceiver_0201.h
Normal file
File diff suppressed because it is too large
Load diff
1921
src/modules/LR11x0/firmware/lr1121_transceiver_0102.h
Normal file
1921
src/modules/LR11x0/firmware/lr1121_transceiver_0102.h
Normal file
File diff suppressed because it is too large
Load diff
2157
src/modules/LR11x0/firmware/lr1121_transceiver_0103.h
Normal file
2157
src/modules/LR11x0/firmware/lr1121_transceiver_0103.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -259,7 +259,7 @@ int16_t RF69::startReceive() {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t RF69::startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len) {
|
||||
int16_t RF69::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)timeout;
|
||||
(void)irqFlags;
|
||||
(void)irqMask;
|
||||
|
@ -566,9 +566,9 @@ int16_t RF69::setBitRate(float br) {
|
|||
setMode(RADIOLIB_RF69_STANDBY);
|
||||
|
||||
// set bit rate
|
||||
uint16_t bitRate = 32000 / br;
|
||||
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0);
|
||||
state |= this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0);
|
||||
uint16_t bitRateRaw = 32000 / br;
|
||||
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_MSB, (bitRateRaw & 0xFF00) >> 8, 7, 0);
|
||||
state |= this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_LSB, bitRateRaw & 0x00FF, 7, 0);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
this->bitRate = br;
|
||||
}
|
||||
|
|
|
@ -488,7 +488,7 @@ class RF69: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param module Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
RF69(Module* module);
|
||||
RF69(Module* module); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -538,7 +538,7 @@ class RF69: public PhysicalLayer {
|
|||
\brief Sets the module to sleep mode.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep();
|
||||
int16_t sleep() override;
|
||||
|
||||
/*!
|
||||
\brief Sets the module to standby mode.
|
||||
|
@ -619,23 +619,23 @@ class RF69: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Set interrupt service routine function to call when FIFO is empty.
|
||||
|
@ -697,7 +697,7 @@ class RF69: public PhysicalLayer {
|
|||
\brief Interrupt-driven receive method. GDO0 will be activated when full packet is received.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer.
|
||||
|
@ -707,7 +707,7 @@ class RF69: public PhysicalLayer {
|
|||
\param len Ignored.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len);
|
||||
int16_t startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Reads data received after calling startReceive method. When the packet length is not known in advance,
|
||||
|
@ -727,7 +727,7 @@ class RF69: public PhysicalLayer {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Gets carrier frequency.
|
||||
|
@ -741,7 +741,7 @@ class RF69: public PhysicalLayer {
|
|||
\param br Bit rate to be set in kbps.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
/*!
|
||||
\brief Sets receiver bandwidth. Allowed values are 2.6, 3.1, 3.9, 5.2, 6.3, 7.8, 10.4, 12.5, 15.6,
|
||||
|
@ -944,7 +944,7 @@ class RF69: public PhysicalLayer {
|
|||
\brief Gets RSSI (Recorded Signal Strength Indicator) of the last received packet.
|
||||
\returns Last packet RSSI in dBm.
|
||||
*/
|
||||
float getRSSI();
|
||||
float getRSSI() override;
|
||||
|
||||
/*!
|
||||
\brief Sets the RSSI value above which the RSSI interrupt is signaled
|
||||
|
@ -963,7 +963,7 @@ class RF69: public PhysicalLayer {
|
|||
\brief Get one truly random byte from RSSI noise.
|
||||
\returns TRNG byte.
|
||||
*/
|
||||
uint8_t randomByte();
|
||||
uint8_t randomByte() override;
|
||||
|
||||
/*!
|
||||
\brief Read version SPI register. Should return RF69_CHIP_VERSION (0x24) if SX127x is connected and working.
|
||||
|
@ -976,13 +976,13 @@ class RF69: public PhysicalLayer {
|
|||
\brief Set interrupt service routine function to call when data bit is received in direct mode.
|
||||
\param func Pointer to interrupt service routine.
|
||||
*/
|
||||
void setDirectAction(void (*func)(void));
|
||||
void setDirectAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Function to read and process data bit in direct reception mode.
|
||||
\param pin Pin on which to read.
|
||||
*/
|
||||
void readBit(uint32_t pin);
|
||||
void readBit(uint32_t pin) override;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -991,12 +991,12 @@ class RF69: public PhysicalLayer {
|
|||
\param value The value that indicates which function to place on that pin. See chip datasheet for details.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setDIOMapping(uint32_t pin, uint32_t value);
|
||||
int16_t setDIOMapping(uint32_t pin, uint32_t value) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
|
|
|
@ -96,7 +96,7 @@ class SX1231: public RF69 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1231(Module* mod);
|
||||
SX1231(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
@ -111,7 +111,7 @@ class SX1231: public RF69 {
|
|||
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
|
||||
private:
|
||||
protected:
|
||||
#endif
|
||||
uint8_t chipRevision = 0;
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@ class SX1233: public SX1231 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1233(Module* mod);
|
||||
SX1233(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
@ -48,12 +48,12 @@ class SX1233: public SX1231 {
|
|||
\param br Bit rate to be set in kbps.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
uint8_t chipRevision = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -87,14 +87,14 @@ int16_t STM32WLx::setOutputPower(int8_t power) {
|
|||
return(RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
|
||||
}
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// Apply workaround for HP only
|
||||
state = SX126x::fixPaClamping(use_hp);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set output power
|
||||
/// \todo power ramp time configuration
|
||||
state = SX126x::setTxParams(power);
|
||||
// set output power with default 200us ramp
|
||||
state = SX126x::setTxParams(power, RADIOLIB_SX126X_PA_RAMP_200U);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// restore OCP configuration
|
||||
|
|
|
@ -39,7 +39,7 @@ class STM32WLx : public SX1262 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of STM32WLx_Module that will be used to communicate with the radio.
|
||||
*/
|
||||
STM32WLx(STM32WLx_Module* mod);
|
||||
STM32WLx(STM32WLx_Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
/*!
|
||||
\brief Custom operation modes for STMWLx.
|
||||
|
@ -124,34 +124,34 @@ class STM32WLx : public SX1262 {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a channel scan is finished.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setChannelScanAction(void (*func)(void));
|
||||
void setChannelScanAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a channel scan is finished.
|
||||
*/
|
||||
void clearChannelScanAction();
|
||||
void clearChannelScanAction() override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
|
|
|
@ -6,11 +6,13 @@ SX1261::SX1261(Module* mod): SX1262(mod) {
|
|||
}
|
||||
|
||||
int16_t SX1261::setOutputPower(int8_t power) {
|
||||
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
// check if power value is configurable
|
||||
int16_t state = checkOutputPower(power, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// get current OCP configuration
|
||||
uint8_t ocp = 0;
|
||||
int16_t state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
|
||||
state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set PA config
|
||||
|
@ -25,4 +27,12 @@ int16_t SX1261::setOutputPower(int8_t power) {
|
|||
return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1));
|
||||
}
|
||||
|
||||
int16_t SX1261::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,14 +25,22 @@ class SX1261 : public SX1262 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1261(Module* mod);
|
||||
SX1261(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
/*!
|
||||
\brief Sets output power. Allowed values are in range from -17 to 14 dBm.
|
||||
\param power Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setOutputPower(int8_t power) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -98,11 +98,13 @@ int16_t SX1262::setFrequency(float freq, bool calibrate) {
|
|||
}
|
||||
|
||||
int16_t SX1262::setOutputPower(int8_t power) {
|
||||
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
// check if power value is configurable
|
||||
int16_t state = checkOutputPower(power, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// get current OCP configuration
|
||||
uint8_t ocp = 0;
|
||||
int16_t state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
|
||||
state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set PA config
|
||||
|
@ -117,4 +119,12 @@ int16_t SX1262::setOutputPower(int8_t power) {
|
|||
return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1));
|
||||
}
|
||||
|
||||
int16_t SX1262::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@ class SX1262: public SX126x {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1262(Module* mod);
|
||||
SX1262(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -69,7 +69,7 @@ class SX1262: public SX126x {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz.
|
||||
|
@ -85,7 +85,15 @@ class SX1262: public SX126x {
|
|||
\param power Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
virtual int16_t setOutputPower(int8_t power);
|
||||
virtual int16_t setOutputPower(int8_t power) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -93,11 +93,13 @@ int16_t SX1268::setFrequency(float freq, bool calibrate) {
|
|||
}
|
||||
|
||||
int16_t SX1268::setOutputPower(int8_t power) {
|
||||
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
// check if power value is configurable
|
||||
int16_t state = checkOutputPower(power, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// get current OCP configuration
|
||||
uint8_t ocp = 0;
|
||||
int16_t state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
|
||||
state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set PA config
|
||||
|
@ -112,4 +114,12 @@ int16_t SX1268::setOutputPower(int8_t power) {
|
|||
return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1));
|
||||
}
|
||||
|
||||
int16_t SX1268::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@ class SX1268: public SX126x {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1268(Module* mod);
|
||||
SX1268(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -68,7 +68,7 @@ class SX1268: public SX126x {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz.
|
||||
|
@ -83,7 +83,15 @@ class SX1268: public SX126x {
|
|||
\param power Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setOutputPower(int8_t power) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -76,10 +76,11 @@ int16_t SX126x::begin(uint8_t cr, uint8_t syncWord, uint16_t preambleLength, flo
|
|||
RADIOLIB_ASSERT(state);
|
||||
|
||||
if (useRegulatorLDO) {
|
||||
state = setRegulatorLDO();
|
||||
state = setRegulatorLDO();
|
||||
} else {
|
||||
state = setRegulatorDCDC();
|
||||
state = setRegulatorDCDC();
|
||||
}
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set publicly accessible settings that are not a part of begin method
|
||||
state = setCurrentLimit(60.0);
|
||||
|
@ -441,6 +442,11 @@ int16_t SX126x::scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin)
|
|||
return(getChannelScanResult());
|
||||
}
|
||||
|
||||
|
||||
int16_t SX126x::sleep() {
|
||||
return(SX126x::sleep(true));
|
||||
}
|
||||
|
||||
int16_t SX126x::sleep(bool retainConfig) {
|
||||
// set RF switch (if present)
|
||||
this->mod->setRfSwitchState(Module::MODE_IDLE);
|
||||
|
@ -580,7 +586,7 @@ int16_t SX126x::startReceive() {
|
|||
return(this->startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF, RADIOLIB_SX126X_IRQ_RX_DEFAULT, RADIOLIB_SX126X_IRQ_RX_DONE, 0));
|
||||
}
|
||||
|
||||
int16_t SX126x::startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len) {
|
||||
int16_t SX126x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)len;
|
||||
int16_t state = startReceiveCommon(timeout, irqFlags, irqMask);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
@ -638,7 +644,7 @@ int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_
|
|||
|
||||
uint32_t symbolLength = ((uint32_t)(10 * 1000) << this->spreadingFactor) / (10 * this->bandwidthKhz);
|
||||
uint32_t sleepPeriod = symbolLength * sleepSymbols;
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Auto sleep period: %lu", sleepPeriod);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Auto sleep period: %lu", (long unsigned int)sleepPeriod);
|
||||
|
||||
// when the unit detects a preamble, it starts a timer that will timeout if it doesn't receive a header in time.
|
||||
// the duration is sleepPeriod + 2 * wakePeriod.
|
||||
|
@ -649,7 +655,7 @@ int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_
|
|||
uint32_t wakePeriod = RADIOLIB_MAX(
|
||||
(symbolLength * (senderPreambleLength + 1) - (sleepPeriod - 1000)) / 2, // (A)
|
||||
symbolLength * (minSymbols + 1)); //(B)
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Auto wake period: %lu", wakePeriod);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Auto wake period: %lu", (long unsigned int)wakePeriod);
|
||||
|
||||
// If our sleep period is shorter than our transition time, just use the standard startReceive
|
||||
if(sleepPeriod < this->tcxoDelay + 1016) {
|
||||
|
@ -1173,15 +1179,7 @@ int16_t SX126x::setSyncBits(uint8_t *syncWord, uint8_t bitsLen) {
|
|||
bytesLen++;
|
||||
}
|
||||
|
||||
// write sync word
|
||||
int16_t state = writeRegister(RADIOLIB_SX126X_REG_SYNC_WORD_0, syncWord, bytesLen);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// update packet parameters
|
||||
this->syncWordLength = bitsLen;
|
||||
state = setPacketParamsFSK(this->preambleLengthFSK, this->crcTypeFSK, this->syncWordLength, this->addrComp, this->whitening, this->packetType);
|
||||
|
||||
return(state);
|
||||
return(setSyncWord(syncWord, bytesLen));
|
||||
}
|
||||
|
||||
int16_t SX126x::setNodeAddress(uint8_t nodeAddr) {
|
||||
|
@ -1455,7 +1453,7 @@ RadioLibTime_t SX126x::calculateRxTimeout(RadioLibTime_t timeoutUs) {
|
|||
return(timeout);
|
||||
}
|
||||
|
||||
int16_t SX126x::irqRxDoneRxTimeout(uint16_t &irqFlags, uint16_t &irqMask) {
|
||||
int16_t SX126x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) {
|
||||
irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT; // flags that can appear in the IRQ register
|
||||
irqMask = RADIOLIB_SX126X_IRQ_RX_DONE | RADIOLIB_SX126X_IRQ_TIMEOUT; // flags that will trigger DIO0
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
|
@ -1577,7 +1575,7 @@ int16_t SX126x::uploadPatch(const uint32_t* patch, size_t len, bool nonvolatile)
|
|||
// check the version
|
||||
#if RADIOLIB_DEBUG_BASIC
|
||||
char ver_pre[16];
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, (uint8_t*)ver_pre);
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, reinterpret_cast<uint8_t*>(ver_pre));
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Pre-update version string: %s", ver_pre);
|
||||
#endif
|
||||
|
||||
|
@ -1609,7 +1607,7 @@ int16_t SX126x::uploadPatch(const uint32_t* patch, size_t len, bool nonvolatile)
|
|||
// check the version again
|
||||
#if RADIOLIB_DEBUG_BASIC
|
||||
char ver_post[16];
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, (uint8_t*)ver_post);
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, reinterpret_cast<uint8_t*>(ver_post));
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Post-update version string: %s", ver_post);
|
||||
#endif
|
||||
|
||||
|
@ -1736,7 +1734,7 @@ int16_t SX126x::setRx(uint32_t timeout) {
|
|||
|
||||
int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
|
||||
// default CAD parameters are shown in Semtech AN1200.48, page 41.
|
||||
uint8_t detPeakValues[6] = { 22, 22, 24, 25, 26, 30};
|
||||
const uint8_t detPeakValues[6] = { 22, 22, 24, 25, 26, 30};
|
||||
|
||||
// CAD parameters aren't available for SF-6. Just to be safe.
|
||||
if(this->spreadingFactor < 7) {
|
||||
|
@ -1850,6 +1848,8 @@ int16_t SX126x::setRfFrequency(uint32_t frf) {
|
|||
int16_t SX126x::calibrateImageRejection(float freqMin, float freqMax) {
|
||||
// calculate the calibration coefficients and calibrate image
|
||||
uint8_t data[] = { (uint8_t)floor((freqMin - 1.0f) / 4.0f), (uint8_t)ceil((freqMax + 1.0f) / 4.0f) };
|
||||
data[0] = (data[0] % 2) ? data[0] : data[0] - 1;
|
||||
data[1] = (data[1] % 2) ? data[1] : data[1] + 1;
|
||||
return(this->calibrateImage(data));
|
||||
}
|
||||
|
||||
|
@ -2163,18 +2163,18 @@ bool SX126x::findChip(const char* verStr) {
|
|||
|
||||
// read the version string
|
||||
char version[16];
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, (uint8_t*)version);
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, reinterpret_cast<uint8_t*>(version));
|
||||
|
||||
// check version register
|
||||
if(strncmp(verStr, version, 6) == 0) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:");
|
||||
RADIOLIB_DEBUG_BASIC_HEXDUMP((uint8_t*)version, 16, RADIOLIB_SX126X_REG_VERSION_STRING);
|
||||
RADIOLIB_DEBUG_BASIC_HEXDUMP(reinterpret_cast<uint8_t*>(version), 16, RADIOLIB_SX126X_REG_VERSION_STRING);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN();
|
||||
flagFound = true;
|
||||
} else {
|
||||
#if RADIOLIB_DEBUG_BASIC
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("SX126x not found! (%d of 10 tries) RADIOLIB_SX126X_REG_VERSION_STRING:", i + 1);
|
||||
RADIOLIB_DEBUG_BASIC_HEXDUMP((uint8_t*)version, 16, RADIOLIB_SX126X_REG_VERSION_STRING);
|
||||
RADIOLIB_DEBUG_BASIC_HEXDUMP(reinterpret_cast<uint8_t*>(version), 16, RADIOLIB_SX126X_REG_VERSION_STRING);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Expected string: %s", verStr);
|
||||
#endif
|
||||
this->mod->hal->delay(10);
|
||||
|
|
|
@ -452,7 +452,7 @@ class SX126x: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX126x(Module* mod);
|
||||
explicit SX126x(Module* mod);
|
||||
|
||||
/*!
|
||||
\brief Whether the module has an XTAL (true) or TCXO (false). Defaults to false.
|
||||
|
@ -546,13 +546,20 @@ class SX126x: public PhysicalLayer {
|
|||
*/
|
||||
int16_t scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin);
|
||||
|
||||
/*!
|
||||
\brief Sets the module to sleep mode. To wake the device up, call standby().
|
||||
Overload with warm start enabled for PhysicalLayer compatibility.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep();
|
||||
|
||||
/*!
|
||||
\brief Sets the module to sleep mode. To wake the device up, call standby().
|
||||
\param retainConfig Set to true to retain configuration of the currently active modem ("warm start")
|
||||
or to false to discard current configuration ("cold start"). Defaults to true.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep(bool retainConfig = true);
|
||||
int16_t sleep(bool retainConfig);
|
||||
|
||||
/*!
|
||||
\brief Sets the module to standby mode (overload for PhysicalLayer compatibility, uses 13 MHz RC oscillator).
|
||||
|
@ -586,34 +593,34 @@ class SX126x: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a channel scan is finished.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setChannelScanAction(void (*func)(void));
|
||||
void setChannelScanAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a channel scan is finished.
|
||||
*/
|
||||
void clearChannelScanAction();
|
||||
void clearChannelScanAction() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method.
|
||||
|
@ -637,7 +644,7 @@ class SX126x: public PhysicalLayer {
|
|||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method. DIO1 will be activated when full packet is received.
|
||||
|
@ -654,7 +661,7 @@ class SX126x: public PhysicalLayer {
|
|||
\param len Only for PhysicalLayer compatibility, not used.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive(uint32_t timeout, uint16_t irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT, uint16_t irqMask = RADIOLIB_SX126X_IRQ_RX_DONE, size_t len = 0);
|
||||
int16_t startReceive(uint32_t timeout, uint32_t irqFlags = RADIOLIB_SX126X_IRQ_RX_DEFAULT, uint32_t irqMask = RADIOLIB_SX126X_IRQ_RX_DONE, size_t len = 0);
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method where the device mostly sleeps and periodically wakes to listen.
|
||||
|
@ -786,7 +793,7 @@ class SX126x: public PhysicalLayer {
|
|||
\param br FSK bit rate to be set in kbps.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
/*!
|
||||
\brief Set data.
|
||||
|
@ -920,7 +927,7 @@ class SX126x: public PhysicalLayer {
|
|||
\brief Gets SNR (Signal to Noise Ratio) of the last received packet. Only available for LoRa modem.
|
||||
\returns SNR of the last received packet in dB.
|
||||
*/
|
||||
float getSNR();
|
||||
float getSNR() override;
|
||||
|
||||
/*!
|
||||
\brief Gets frequency error of the latest received packet.
|
||||
|
@ -964,7 +971,7 @@ class SX126x: public PhysicalLayer {
|
|||
\param timeoutUs Timeout in microseconds to listen for
|
||||
\returns Timeout value in a unit that is specific for the used module
|
||||
*/
|
||||
RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs);
|
||||
RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs) override;
|
||||
|
||||
/*!
|
||||
\brief Create the flags that make up RxDone and RxTimeout used for receiving downlinks
|
||||
|
@ -972,13 +979,13 @@ class SX126x: public PhysicalLayer {
|
|||
\param irqMask Mask indicating which IRQ triggers a DIO
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t irqRxDoneRxTimeout(uint16_t &irqFlags, uint16_t &irqMask);
|
||||
int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override;
|
||||
|
||||
/*!
|
||||
\brief Check whether the IRQ bit for RxTimeout is set
|
||||
\returns Whether RxTimeout IRQ is set
|
||||
*/
|
||||
bool isRxTimeout();
|
||||
bool isRxTimeout() override;
|
||||
|
||||
/*!
|
||||
\brief Set implicit header mode for future reception/transmission.
|
||||
|
@ -1040,7 +1047,7 @@ class SX126x: public PhysicalLayer {
|
|||
\brief Get one truly random byte from RSSI noise.
|
||||
\returns TRNG byte.
|
||||
*/
|
||||
uint8_t randomByte();
|
||||
uint8_t randomByte() override;
|
||||
|
||||
/*!
|
||||
\brief Enable/disable inversion of the I and Q signals
|
||||
|
@ -1054,13 +1061,13 @@ class SX126x: public PhysicalLayer {
|
|||
\brief Set interrupt service routine function to call when data bit is received in direct mode.
|
||||
\param func Pointer to interrupt service routine.
|
||||
*/
|
||||
void setDirectAction(void (*func)(void));
|
||||
void setDirectAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Function to read and process data bit in direct reception mode.
|
||||
\param pin Pin on which to read.
|
||||
*/
|
||||
void readBit(uint32_t pin);
|
||||
void readBit(uint32_t pin) override;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -1132,7 +1139,7 @@ class SX126x: public PhysicalLayer {
|
|||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
// SX126x SPI command implementations
|
||||
int16_t setFs();
|
||||
|
@ -1163,7 +1170,7 @@ class SX126x: public PhysicalLayer {
|
|||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
#endif
|
||||
const char* chipType;
|
||||
const char* chipType = NULL;
|
||||
uint8_t bandwidth = 0;
|
||||
|
||||
// Allow subclasses to define different TX modes
|
||||
|
|
|
@ -280,15 +280,12 @@ int16_t SX1272::setOutputPower(int8_t power) {
|
|||
}
|
||||
|
||||
int16_t SX1272::setOutputPower(int8_t power, bool useRfo) {
|
||||
// check allowed power range
|
||||
if(useRfo) {
|
||||
RADIOLIB_CHECK_RANGE(power, -1, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
} else {
|
||||
RADIOLIB_CHECK_RANGE(power, 2, 20, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
// check if power value is configurable
|
||||
int16_t state = checkOutputPower(power, NULL, useRfo);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
state = SX127x::standby();
|
||||
Module* mod = this->getMod();
|
||||
|
||||
if(useRfo) {
|
||||
|
@ -317,6 +314,26 @@ int16_t SX1272::setOutputPower(int8_t power, bool useRfo) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
return(checkOutputPower(power, clipped, false));
|
||||
}
|
||||
|
||||
int16_t SX1272::checkOutputPower(int8_t power, int8_t* clipped, bool useRfo) {
|
||||
// check allowed power range
|
||||
if(useRfo) {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-1, RADIOLIB_MIN(14, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -1, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
} else {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(2, RADIOLIB_MIN(20, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, 2, 20, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX1272::setGain(uint8_t gain) {
|
||||
// check allowed range
|
||||
if(gain > 6) {
|
||||
|
|
|
@ -100,7 +100,7 @@ class SX1272: public SX127x {
|
|||
\brief Default constructor. Called from Arduino sketch when creating new LoRa instance.
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
SX1272(Module* mod);
|
||||
SX1272(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -146,7 +146,7 @@ class SX1272: public SX127x {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets %LoRa link bandwidth. Allowed values are 125, 250 and 500 kHz. Only available in %LoRa mode.
|
||||
|
@ -206,6 +206,24 @@ class SX1272: public SX127x {
|
|||
*/
|
||||
int16_t setOutputPower(int8_t power, bool useRfo);
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
|
||||
\param power Output power in dBm, assumes PA_BOOST pin.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\param useRfo Whether to use the RFO (true) or the PA_BOOST (false) pin for the RF output.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped, bool useRfo);
|
||||
|
||||
/*!
|
||||
\brief Sets gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest gain.
|
||||
Set to 0 to enable automatic gain control (recommended).
|
||||
|
@ -236,7 +254,7 @@ class SX1272: public SX127x {
|
|||
Overload with packet mode enabled for PhysicalLayer compatibility.
|
||||
\returns RSSI value in dBm.
|
||||
*/
|
||||
float getRSSI();
|
||||
float getRSSI() override;
|
||||
|
||||
/*!
|
||||
\brief Gets recorded signal strength indicator.
|
||||
|
@ -293,7 +311,7 @@ class SX1272: public SX127x {
|
|||
int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF);
|
||||
|
||||
int16_t configFSK();
|
||||
void errataFix(bool rx);
|
||||
void errataFix(bool rx) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -20,7 +20,7 @@ class SX1273: public SX1272 {
|
|||
\brief Default constructor. Called from Arduino sketch when creating new LoRa instance.
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
SX1273(Module* mod);
|
||||
SX1273(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class SX1276: public SX1278 {
|
|||
\brief Default constructor. Called from Arduino sketch when creating new LoRa instance.
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
SX1276(Module* mod);
|
||||
SX1276(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -61,7 +61,7 @@ class SX1276: public SX1278 {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -20,7 +20,7 @@ class SX1277: public SX1278 {
|
|||
\brief Default constructor. Called from Arduino sketch when creating new LoRa instance.
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
SX1277(Module* mod);
|
||||
SX1277(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -61,7 +61,7 @@ class SX1277: public SX1278 {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets %LoRa link spreading factor. Allowed values range from 6 to 9. Only available in %LoRa mode.
|
||||
|
|
|
@ -294,19 +294,12 @@ int16_t SX1278::setOutputPower(int8_t power) {
|
|||
}
|
||||
|
||||
int16_t SX1278::setOutputPower(int8_t power, bool useRfo) {
|
||||
// check allowed power range
|
||||
if(useRfo) {
|
||||
// RFO output
|
||||
RADIOLIB_CHECK_RANGE(power, -3, 15, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
} else {
|
||||
// PA_BOOST output, check high-power operation
|
||||
if(power != 20) {
|
||||
RADIOLIB_CHECK_RANGE(power, 2, 17, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
}
|
||||
// check if power value is configurable
|
||||
int16_t state = checkOutputPower(power, NULL, useRfo);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
state = SX127x::standby();
|
||||
Module* mod = this->getMod();
|
||||
|
||||
if(useRfo) {
|
||||
|
@ -342,6 +335,34 @@ int16_t SX1278::setOutputPower(int8_t power, bool useRfo) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
return(checkOutputPower(power, clipped, false));
|
||||
}
|
||||
|
||||
int16_t SX1278::checkOutputPower(int8_t power, int8_t* clipped, bool useRfo) {
|
||||
// check allowed power range
|
||||
if(useRfo) {
|
||||
// RFO output
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-3, RADIOLIB_MIN(15, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -3, 15, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
} else {
|
||||
// PA_BOOST output, check high-power operation
|
||||
if(clipped) {
|
||||
if(power != 20) {
|
||||
*clipped = RADIOLIB_MAX(2, RADIOLIB_MIN(17, power));
|
||||
} else {
|
||||
*clipped = 20;
|
||||
}
|
||||
}
|
||||
if(power != 20) {
|
||||
RADIOLIB_CHECK_RANGE(power, 2, 17, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
}
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX1278::setGain(uint8_t gain) {
|
||||
// check allowed range
|
||||
if(gain > 6) {
|
||||
|
|
|
@ -111,7 +111,7 @@ class SX1278: public SX127x {
|
|||
\brief Default constructor. Called from Arduino sketch when creating new LoRa instance.
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
SX1278(Module* mod);
|
||||
SX1278(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -157,7 +157,7 @@ class SX1278: public SX127x {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\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.
|
||||
|
@ -218,6 +218,24 @@ class SX1278: public SX127x {
|
|||
*/
|
||||
int16_t setOutputPower(int8_t power, bool useRfo);
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
This method is needed for compatibility with PhysicalLayer::checkOutputPower.
|
||||
\param power Output power in dBm, assumes PA_BOOST pin.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\param useRfo Whether to use the RFO (true) or the PA_BOOST (false) pin for the RF output.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped, bool useRfo);
|
||||
|
||||
/*!
|
||||
\brief Sets gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest gain.
|
||||
Set to 0 to enable automatic gain control (recommended).
|
||||
|
@ -248,7 +266,7 @@ class SX1278: public SX127x {
|
|||
Overload with packet mode enabled for PhysicalLayer compatibility.
|
||||
\returns RSSI value in dBm.
|
||||
*/
|
||||
float getRSSI();
|
||||
float getRSSI() override;
|
||||
|
||||
/*!
|
||||
\brief Gets recorded signal strength indicator.
|
||||
|
@ -305,7 +323,7 @@ class SX1278: public SX127x {
|
|||
int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF);
|
||||
|
||||
int16_t configFSK();
|
||||
void errataFix(bool rx);
|
||||
void errataFix(bool rx) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -20,7 +20,7 @@ class SX1279: public SX1278 {
|
|||
\brief Default constructor. Called from Arduino sketch when creating new LoRa instance.
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
SX1279(Module* mod);
|
||||
SX1279(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -61,7 +61,7 @@ class SX1279: public SX1278 {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -419,7 +419,7 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) {
|
|||
return(setMode(mode));
|
||||
}
|
||||
|
||||
int16_t SX127x::startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len) {
|
||||
int16_t SX127x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)irqFlags;
|
||||
(void)irqMask;
|
||||
uint8_t mode = RADIOLIB_SX127X_RXCONTINUOUS;
|
||||
|
@ -905,13 +905,13 @@ int16_t SX127x::setBitRateCommon(float br, uint8_t fracRegAddr) {
|
|||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set bit rate
|
||||
uint16_t bitRate = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0) / br;
|
||||
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0);
|
||||
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0);
|
||||
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.0) / (float)br) - (float)bitRate;
|
||||
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);
|
||||
}
|
||||
|
@ -1289,7 +1289,7 @@ RadioLibTime_t SX127x::calculateRxTimeout(RadioLibTime_t timeoutUs) {
|
|||
return(numSymbols);
|
||||
}
|
||||
|
||||
int16_t SX127x::irqRxDoneRxTimeout(uint16_t &irqFlags, uint16_t &irqMask) {
|
||||
int16_t SX127x::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) {
|
||||
// IRQ flags/masks are inverted to what seems logical for SX127x (0 being activated, 1 being deactivated)
|
||||
irqFlags = RADIOLIB_SX127X_MASK_IRQ_FLAG_RX_DEFAULT;
|
||||
irqMask = RADIOLIB_SX127X_MASK_IRQ_FLAG_RX_DONE & RADIOLIB_SX127X_MASK_IRQ_FLAG_RX_TIMEOUT;
|
||||
|
@ -1335,8 +1335,14 @@ int16_t SX127x::setRSSIConfig(uint8_t smoothingSamples, int8_t offset) {
|
|||
|
||||
RADIOLIB_CHECK_RANGE(offset, -16, 15, RADIOLIB_ERR_INVALID_RSSI_OFFSET);
|
||||
|
||||
// calculate the two's complement
|
||||
uint8_t offsetRaw = RADIOLIB_ABS(offset);
|
||||
offsetRaw ^= 0x1F;
|
||||
offsetRaw += 1;
|
||||
offsetRaw &= 0x1F;
|
||||
|
||||
// set new register values
|
||||
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_CONFIG, offset << 3, 7, 3);
|
||||
state = this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_CONFIG, offsetRaw << 3, 7, 3);
|
||||
state |= this->mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_CONFIG, smoothingSamples, 2, 0);
|
||||
return(state);
|
||||
}
|
||||
|
@ -1538,7 +1544,7 @@ int16_t SX127x::setPacketMode(uint8_t mode, uint8_t len) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
bool SX127x::findChip(uint8_t* vers, uint8_t num) {
|
||||
bool SX127x::findChip(const uint8_t* vers, uint8_t num) {
|
||||
uint8_t i = 0;
|
||||
bool flagFound = false;
|
||||
while((i < 10) && !flagFound) {
|
||||
|
@ -1547,8 +1553,8 @@ bool SX127x::findChip(uint8_t* vers, uint8_t num) {
|
|||
|
||||
// check version register
|
||||
int16_t version = getChipVersion();
|
||||
for(uint8_t i = 0; i < num; i++) {
|
||||
if(version == vers[i]) {
|
||||
for(uint8_t j = 0; j < num; j++) {
|
||||
if(version == vers[j]) {
|
||||
flagFound = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -594,7 +594,7 @@ class SX127x: public PhysicalLayer {
|
|||
\brief Default constructor. Called internally when creating new LoRa instance.
|
||||
\param mod Instance of Module that will be used to communicate with the %LoRa chip.
|
||||
*/
|
||||
SX127x(Module* mod);
|
||||
explicit SX127x(Module* mod);
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -655,7 +655,7 @@ class SX127x: public PhysicalLayer {
|
|||
%Module will wake up automatically when methods like transmit or receive are called.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep();
|
||||
int16_t sleep() override;
|
||||
|
||||
/*!
|
||||
\brief Sets the %LoRa module to standby.
|
||||
|
@ -721,34 +721,34 @@ class SX127x: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a channel scan is finished.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setChannelScanAction(void (*func)(void));
|
||||
void setChannelScanAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a channel scan is finished.
|
||||
*/
|
||||
void clearChannelScanAction();
|
||||
void clearChannelScanAction() override;
|
||||
|
||||
/*!
|
||||
\brief Set interrupt service routine function to call when FIFO is empty.
|
||||
|
@ -810,7 +810,7 @@ class SX127x: public PhysicalLayer {
|
|||
Implemented for compatibility with PhysicalLayer.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method. DIO0 will be activated when full valid packet is received.
|
||||
|
@ -832,7 +832,7 @@ class SX127x: public PhysicalLayer {
|
|||
\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, uint16_t irqFlags, uint16_t irqMask, size_t len);
|
||||
int16_t startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Reads data that was received after calling startReceive method. When the packet length is not known in advance,
|
||||
|
@ -904,7 +904,7 @@ class SX127x: public PhysicalLayer {
|
|||
\brief Gets signal-to-noise ratio of the latest received packet. Only available in LoRa mode.
|
||||
\returns Last packet signal-to-noise ratio (SNR).
|
||||
*/
|
||||
float getSNR();
|
||||
float getSNR() override;
|
||||
|
||||
/*!
|
||||
\brief Get data rate of the latest transmitted packet.
|
||||
|
@ -1062,7 +1062,7 @@ class SX127x: public PhysicalLayer {
|
|||
\param timeoutUs Timeout in microseconds to listen for
|
||||
\returns Timeout value in a unit that is specific for the used module
|
||||
*/
|
||||
RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs);
|
||||
RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs) override;
|
||||
|
||||
/*!
|
||||
\brief Create the flags that make up RxDone and RxTimeout used for receiving downlinks
|
||||
|
@ -1070,13 +1070,13 @@ class SX127x: public PhysicalLayer {
|
|||
\param irqMask Mask indicating which IRQ triggers a DIO
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t irqRxDoneRxTimeout(uint16_t &irqFlags, uint16_t &irqMask);
|
||||
int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override;
|
||||
|
||||
/*!
|
||||
\brief Check whether the IRQ bit for RxTimeout is set
|
||||
\returns Whether RxTimeout IRQ is set
|
||||
*/
|
||||
bool isRxTimeout();
|
||||
bool isRxTimeout() override;
|
||||
|
||||
/*!
|
||||
\brief Enable CRC filtering and generation.
|
||||
|
@ -1133,7 +1133,7 @@ class SX127x: public PhysicalLayer {
|
|||
\brief Get one truly random byte from RSSI noise.
|
||||
\returns TRNG byte.
|
||||
*/
|
||||
uint8_t randomByte();
|
||||
uint8_t randomByte() override;
|
||||
|
||||
/*!
|
||||
\brief Read version SPI register. Should return SX1278_CHIP_VERSION (0x12) or SX1272_CHIP_VERSION (0x22) if SX127x is connected and working.
|
||||
|
@ -1153,13 +1153,13 @@ class SX127x: public PhysicalLayer {
|
|||
\brief Set interrupt service routine function to call when data bit is received in direct mode.
|
||||
\param func Pointer to interrupt service routine.
|
||||
*/
|
||||
void setDirectAction(void (*func)(void));
|
||||
void setDirectAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Function to read and process data bit in direct reception mode.
|
||||
\param pin Pin on which to read.
|
||||
*/
|
||||
void readBit(uint32_t pin);
|
||||
void readBit(uint32_t pin) override;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -1192,7 +1192,7 @@ class SX127x: public PhysicalLayer {
|
|||
\param value The value that indicates which function to place on that pin. See chip datasheet for details.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setDIOMapping(uint32_t pin, uint32_t value);
|
||||
int16_t setDIOMapping(uint32_t pin, uint32_t value) override;
|
||||
|
||||
/*!
|
||||
\brief Configure DIO mapping to use RSSI or Preamble Detect for pins that support it.
|
||||
|
@ -1221,7 +1221,7 @@ class SX127x: public PhysicalLayer {
|
|||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
|
@ -1254,7 +1254,7 @@ class SX127x: public PhysicalLayer {
|
|||
int16_t config();
|
||||
int16_t directMode();
|
||||
int16_t setPacketMode(uint8_t mode, uint8_t len);
|
||||
bool findChip(uint8_t* vers, uint8_t num);
|
||||
bool findChip(const uint8_t* vers, uint8_t num);
|
||||
int16_t setMode(uint8_t mode);
|
||||
int16_t setActiveModem(uint8_t modem);
|
||||
void clearIRQFlags();
|
||||
|
|
|
@ -19,7 +19,7 @@ class SX1280: public SX1281 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1280(Module* mod);
|
||||
SX1280(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
/*!
|
||||
\brief Blocking ranging method.
|
||||
|
|
|
@ -18,7 +18,7 @@ class SX1281: public SX128x {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1281(Module* mod);
|
||||
SX1281(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -19,7 +19,7 @@ class SX1282: public SX1280 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX1282(Module* mod);
|
||||
SX1282(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
|
|
|
@ -411,28 +411,8 @@ int16_t SX128x::receiveDirect() {
|
|||
}
|
||||
|
||||
int16_t SX128x::scanChannel() {
|
||||
// check active modem
|
||||
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = standby();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set DIO pin mapping
|
||||
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE, RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// clear interrupt flags
|
||||
state = clearIrqStatus();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set RF switch (if present)
|
||||
this->mod->setRfSwitchState(Module::MODE_RX);
|
||||
|
||||
// set mode to CAD
|
||||
state = setCad();
|
||||
int16_t state = startChannelScan();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// wait for channel activity detected or timeout
|
||||
|
@ -441,18 +421,11 @@ int16_t SX128x::scanChannel() {
|
|||
}
|
||||
|
||||
// check CAD result
|
||||
uint16_t cadResult = getIrqStatus();
|
||||
if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DETECTED) {
|
||||
// detected some LoRa activity
|
||||
clearIrqStatus();
|
||||
return(RADIOLIB_LORA_DETECTED);
|
||||
} else if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DONE) {
|
||||
// channel is free
|
||||
clearIrqStatus();
|
||||
return(RADIOLIB_CHANNEL_FREE);
|
||||
}
|
||||
return(getChannelScanResult());
|
||||
}
|
||||
|
||||
return(RADIOLIB_ERR_UNKNOWN);
|
||||
int16_t SX128x::sleep() {
|
||||
return(SX128x::sleep(true));
|
||||
}
|
||||
|
||||
int16_t SX128x::sleep(bool retainConfig) {
|
||||
|
@ -588,7 +561,7 @@ int16_t SX128x::startReceive() {
|
|||
return(this->startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_SX128X_IRQ_RX_DEFAULT, RADIOLIB_SX128X_IRQ_RX_DONE, 0));
|
||||
}
|
||||
|
||||
int16_t SX128x::startReceive(uint16_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len) {
|
||||
int16_t SX128x::startReceive(uint16_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)len;
|
||||
|
||||
// check active modem
|
||||
|
@ -664,6 +637,52 @@ int16_t SX128x::readData(uint8_t* data, size_t len) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX128x::startChannelScan() {
|
||||
// check active modem
|
||||
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = standby();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set DIO pin mapping
|
||||
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE, RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// clear interrupt flags
|
||||
state = clearIrqStatus();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set RF switch (if present)
|
||||
this->mod->setRfSwitchState(Module::MODE_RX);
|
||||
|
||||
// set mode to CAD
|
||||
return(setCad());
|
||||
}
|
||||
|
||||
int16_t SX128x::getChannelScanResult() {
|
||||
// check active modem
|
||||
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// check CAD result
|
||||
uint16_t cadResult = getIrqStatus();
|
||||
int16_t state = RADIOLIB_ERR_UNKNOWN;
|
||||
if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DETECTED) {
|
||||
// detected some LoRa activity
|
||||
state = RADIOLIB_LORA_DETECTED;
|
||||
} else if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DONE) {
|
||||
// channel is free
|
||||
state = RADIOLIB_CHANNEL_FREE;
|
||||
}
|
||||
|
||||
clearIrqStatus();
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX128x::setFrequency(float freq) {
|
||||
RADIOLIB_CHECK_RANGE(freq, 2400.0, 2500.0, RADIOLIB_ERR_INVALID_FREQUENCY);
|
||||
|
||||
|
@ -765,11 +784,22 @@ int16_t SX128x::setCodingRate(uint8_t cr, bool longInterleaving) {
|
|||
}
|
||||
|
||||
int16_t SX128x::setOutputPower(int8_t pwr) {
|
||||
RADIOLIB_CHECK_RANGE(pwr, -18, 13, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
// check if power value is configurable
|
||||
int16_t state = checkOutputPower(power, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
this->power = pwr + 18;
|
||||
return(setTxParams(this->power));
|
||||
}
|
||||
|
||||
int16_t SX128x::checkOutputPower(int8_t power, int8_t* clipped) {
|
||||
if(clipped) {
|
||||
*clipped = RADIOLIB_MAX(-18, RADIOLIB_MIN(13, power));
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(power, -18, 13, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX128x::setPreambleLength(uint32_t preambleLength) {
|
||||
uint8_t modem = getPacketType();
|
||||
if((modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) || (modem == RADIOLIB_SX128X_PACKET_TYPE_RANGING)) {
|
||||
|
@ -898,13 +928,13 @@ int16_t SX128x::setFrequencyDeviation(float freqDev) {
|
|||
}
|
||||
|
||||
// update modulation parameters
|
||||
uint8_t modIndex = (uint8_t)((8.0 * (newFreqDev / (float)this->bitRateKbps)) - 1.0);
|
||||
if(modIndex > RADIOLIB_SX128X_BLE_GFSK_MOD_IND_4_00) {
|
||||
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);
|
||||
}
|
||||
|
||||
// update modulation parameters
|
||||
this->modIndex = modIndex;
|
||||
this->modIndex = modInd;
|
||||
return(setModulationParams(this->bitRate, this->modIndex, this->shaping));
|
||||
}
|
||||
|
||||
|
@ -938,7 +968,7 @@ int16_t SX128x::setDataShaping(uint8_t sh) {
|
|||
}
|
||||
}
|
||||
|
||||
int16_t SX128x::setSyncWord(uint8_t* syncWord, uint8_t len) {
|
||||
int16_t SX128x::setSyncWord(const uint8_t* syncWord, uint8_t len) {
|
||||
// check active modem
|
||||
uint8_t modem = getPacketType();
|
||||
if(!((modem == RADIOLIB_SX128X_PACKET_TYPE_GFSK) || (modem == RADIOLIB_SX128X_PACKET_TYPE_FLRC))) {
|
||||
|
|
|
@ -359,7 +359,7 @@ class SX128x: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
SX128x(Module* mod);
|
||||
explicit SX128x(Module* mod);
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -455,7 +455,14 @@ class SX128x: public PhysicalLayer {
|
|||
\brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t scanChannel();
|
||||
int16_t scanChannel() override;
|
||||
|
||||
/*!
|
||||
\brief Sets the module to sleep mode. To wake the device up, call standby().
|
||||
Overload for PhysicalLayer compatibility.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep();
|
||||
|
||||
/*!
|
||||
\brief Sets the module to sleep mode. To wake the device up, call standby().
|
||||
|
@ -463,7 +470,7 @@ class SX128x: public PhysicalLayer {
|
|||
to discard current configuration and data buffer. Defaults to true.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep(bool retainConfig = true);
|
||||
int16_t sleep(bool retainConfig);
|
||||
|
||||
/*!
|
||||
\brief Sets the module to standby mode (overload for PhysicalLayer compatibility, uses 13 MHz RC oscillator).
|
||||
|
@ -497,23 +504,23 @@ class SX128x: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method.
|
||||
|
@ -537,7 +544,7 @@ class SX128x: public PhysicalLayer {
|
|||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method. DIO1 will be activated when full packet is received.
|
||||
|
@ -551,7 +558,7 @@ class SX128x: public PhysicalLayer {
|
|||
\param len Only for PhysicalLayer compatibility, not used.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive(uint16_t timeout, uint16_t irqFlags = RADIOLIB_SX128X_IRQ_RX_DEFAULT, uint16_t irqMask = RADIOLIB_SX128X_IRQ_RX_DONE, size_t len = 0);
|
||||
int16_t startReceive(uint16_t timeout, uint32_t irqFlags = RADIOLIB_SX128X_IRQ_RX_DEFAULT, uint32_t irqMask = RADIOLIB_SX128X_IRQ_RX_DONE, size_t len = 0);
|
||||
|
||||
/*!
|
||||
\brief Reads the current IRQ status.
|
||||
|
@ -569,6 +576,19 @@ class SX128x: public PhysicalLayer {
|
|||
*/
|
||||
int16_t readData(uint8_t* data, size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven channel activity detection method. DIO1 will be activated
|
||||
when LoRa preamble is detected, or upon timeout. Defaults to CAD parameter values recommended by AN1200.48.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startChannelScan() override;
|
||||
|
||||
/*!
|
||||
\brief Read the channel scan result
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t getChannelScanResult() override;
|
||||
|
||||
// configuration methods
|
||||
|
||||
/*!
|
||||
|
@ -576,7 +596,7 @@ class SX128x: public PhysicalLayer {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets LoRa bandwidth. Allowed values are 203.125, 406.25, 812.5 and 1625.0 kHz.
|
||||
|
@ -606,7 +626,15 @@ class SX128x: public PhysicalLayer {
|
|||
\param pwr Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t pwr);
|
||||
int16_t setOutputPower(int8_t pwr) override;
|
||||
|
||||
/*!
|
||||
\brief Check if output power is configurable.
|
||||
\param power Output power in dBm.
|
||||
\param clipped Clipped output power value to what is possible within the module's range.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t checkOutputPower(int8_t power, int8_t* clipped) override;
|
||||
|
||||
/*!
|
||||
\brief Sets preamble length for currently active modem. Allowed values range from 1 to 65535.
|
||||
|
@ -621,7 +649,7 @@ class SX128x: public PhysicalLayer {
|
|||
\param br FSK/FLRC bit rate to be set in kbps.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
/*!
|
||||
\brief Sets FSK frequency deviation. Allowed values range from 0.0 to 3200.0 kHz.
|
||||
|
@ -645,7 +673,7 @@ class SX128x: public PhysicalLayer {
|
|||
\param len Sync word length in bytes.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setSyncWord(uint8_t* syncWord, uint8_t len);
|
||||
int16_t setSyncWord(const uint8_t* syncWord, uint8_t len);
|
||||
|
||||
/*!
|
||||
\brief Sets LoRa sync word.
|
||||
|
@ -696,13 +724,13 @@ class SX128x: public PhysicalLayer {
|
|||
\brief Gets RSSI (Recorded Signal Strength Indicator) of the last received packet.
|
||||
\returns RSSI of the last received packet in dBm.
|
||||
*/
|
||||
float getRSSI();
|
||||
float getRSSI() override;
|
||||
|
||||
/*!
|
||||
\brief Gets SNR (Signal to Noise Ratio) of the last received packet. Only available for LoRa or ranging modem.
|
||||
\returns SNR of the last received packet in dB.
|
||||
*/
|
||||
float getSNR();
|
||||
float getSNR() override;
|
||||
|
||||
/*!
|
||||
\brief Gets frequency error of the latest received packet.
|
||||
|
@ -722,7 +750,7 @@ class SX128x: public PhysicalLayer {
|
|||
\param len Payload length in bytes.
|
||||
\returns Expected time-on-air in microseconds.
|
||||
*/
|
||||
RadioLibTime_t getTimeOnAir(size_t len);
|
||||
RadioLibTime_t getTimeOnAir(size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Set implicit header mode for future reception/transmission.
|
||||
|
@ -754,33 +782,33 @@ class SX128x: public PhysicalLayer {
|
|||
\brief Dummy random method, to ensure PhysicalLayer compatibility.
|
||||
\returns Always returns 0.
|
||||
*/
|
||||
uint8_t randomByte();
|
||||
uint8_t randomByte() override;
|
||||
|
||||
/*!
|
||||
\brief Enable/disable inversion of the I and Q signals
|
||||
\param enable QI inversion enabled (true) or disabled (false);
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t invertIQ(bool enable);
|
||||
int16_t invertIQ(bool enable) override;
|
||||
|
||||
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
|
||||
/*!
|
||||
\brief Dummy method, to ensure PhysicalLayer compatibility.
|
||||
\param func Ignored.
|
||||
*/
|
||||
void setDirectAction(void (*func)(void));
|
||||
void setDirectAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Dummy method, to ensure PhysicalLayer compatibility.
|
||||
\param pin Ignored.
|
||||
*/
|
||||
void readBit(uint32_t pin);
|
||||
void readBit(uint32_t pin) override;
|
||||
#endif
|
||||
|
||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
// cached LoRa parameters
|
||||
float bandwidthKhz = 0;
|
||||
|
|
|
@ -21,7 +21,7 @@ class Si4430: public Si4432 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio chip.
|
||||
*/
|
||||
Si4430(Module* mod);
|
||||
Si4430(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -44,14 +44,14 @@ class Si4430: public Si4432 {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets output power. Allowed values range from -8 to 13 dBm in 3 dBm steps.
|
||||
\param power Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setOutputPower(int8_t power) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
|
|
|
@ -21,7 +21,7 @@ class Si4431: public Si4432 {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio chip.
|
||||
*/
|
||||
Si4431(Module* mod);
|
||||
Si4431(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -44,7 +44,7 @@ class Si4431: public Si4432 {
|
|||
\param power Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setOutputPower(int8_t power) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
|
|
|
@ -21,7 +21,7 @@ class Si4432: public Si443x {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio chip.
|
||||
*/
|
||||
Si4432(Module* mod);
|
||||
Si4432(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -44,14 +44,14 @@ class Si4432: public Si443x {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets output power. Allowed values range from -1 to 20 dBm in 3 dBm steps.
|
||||
\param power Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setOutputPower(int8_t power) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
|
|
|
@ -300,7 +300,7 @@ int16_t Si443x::startReceive() {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t Si443x::startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len) {
|
||||
int16_t Si443x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)timeout;
|
||||
(void)irqFlags;
|
||||
(void)irqMask;
|
||||
|
@ -558,11 +558,11 @@ int16_t Si443x::setEncoding(uint8_t encoding) {
|
|||
/// \todo - add inverted Manchester?
|
||||
switch(encoding) {
|
||||
case RADIOLIB_ENCODING_NRZ:
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_INVERTED_OFF | RADIOLIB_SI443X_MANCHESTER_OFF | RADIOLIB_SI443X_WHITENING_OFF, 2, 0));
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_OFF | RADIOLIB_SI443X_WHITENING_OFF, 2, 0));
|
||||
case RADIOLIB_ENCODING_MANCHESTER:
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_INVERTED_OFF | RADIOLIB_SI443X_MANCHESTER_ON | RADIOLIB_SI443X_WHITENING_OFF, 2, 0));
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_ON | RADIOLIB_SI443X_WHITENING_OFF, 2, 0));
|
||||
case RADIOLIB_ENCODING_WHITENING:
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_INVERTED_OFF | RADIOLIB_SI443X_MANCHESTER_OFF | RADIOLIB_SI443X_WHITENING_ON, 2, 0));
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_OFF | RADIOLIB_SI443X_WHITENING_ON, 2, 0));
|
||||
default:
|
||||
return(RADIOLIB_ERR_INVALID_ENCODING);
|
||||
}
|
||||
|
@ -577,12 +577,8 @@ int16_t Si443x::setDataShaping(uint8_t sh) {
|
|||
switch(sh) {
|
||||
case RADIOLIB_SHAPING_NONE:
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_INVERTED_OFF | RADIOLIB_SI443X_MANCHESTER_OFF | RADIOLIB_SI443X_WHITENING_OFF, 2, 0));
|
||||
case RADIOLIB_SHAPING_0_3:
|
||||
return(RADIOLIB_ERR_INVALID_ENCODING);
|
||||
case RADIOLIB_SHAPING_0_5:
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_2, RADIOLIB_SI443X_MODULATION_GFSK, 1, 0));
|
||||
case RADIOLIB_SHAPING_1_0:
|
||||
return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_MODULATION_MODE_CONTROL_1, RADIOLIB_SI443X_MANCHESTER_INVERTED_OFF | RADIOLIB_SI443X_MANCHESTER_OFF | RADIOLIB_SI443X_WHITENING_ON, 2, 0));
|
||||
default:
|
||||
return(RADIOLIB_ERR_INVALID_ENCODING);
|
||||
}
|
||||
|
@ -771,7 +767,7 @@ int16_t Si443x::updateClockRecovery() {
|
|||
// print that whole mess
|
||||
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, ncoOff, ncoOff, crGain, crGain);
|
||||
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);
|
||||
|
|
|
@ -564,7 +564,7 @@ class Si443x: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
Si443x(Module* mod);
|
||||
explicit Si443x(Module* mod);
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -607,7 +607,7 @@ class Si443x: public PhysicalLayer {
|
|||
%Module will wake up automatically when methods like transmit or receive are called.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep();
|
||||
int16_t sleep() override;
|
||||
|
||||
/*!
|
||||
\brief Sets the module to standby (with XTAL on).
|
||||
|
@ -658,23 +658,23 @@ class Si443x: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method. Will start transmitting arbitrary binary data up to 64 bytes long.
|
||||
|
@ -695,7 +695,7 @@ class Si443x: public PhysicalLayer {
|
|||
\brief Interrupt-driven receive method. IRQ will be activated when full valid packet is received.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer.
|
||||
|
@ -705,7 +705,7 @@ class Si443x: public PhysicalLayer {
|
|||
\param len Ignored.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len);
|
||||
int16_t startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Reads data that was received after calling startReceive method. When the packet length is not known in advance,
|
||||
|
@ -724,7 +724,7 @@ class Si443x: public PhysicalLayer {
|
|||
\param br Bit rate to be set (in kbps).
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
/*!
|
||||
\brief Sets FSK frequency deviation from carrier frequency. Allowed values range from 0.625 to 320.0 kHz.
|
||||
|
@ -745,7 +745,7 @@ class Si443x: public PhysicalLayer {
|
|||
\param syncWord Pointer to the array of sync word bytes.
|
||||
\param len Sync word length in bytes.
|
||||
*/
|
||||
int16_t setSyncWord(uint8_t* syncWord, size_t len);
|
||||
int16_t setSyncWord(uint8_t* syncWord, size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Sets preamble length.
|
||||
|
@ -787,7 +787,7 @@ class Si443x: public PhysicalLayer {
|
|||
\brief Get one truly random byte from RSSI noise.
|
||||
\returns TRNG byte.
|
||||
*/
|
||||
uint8_t randomByte();
|
||||
uint8_t randomByte() override;
|
||||
|
||||
/*!
|
||||
\brief Read version SPI register. Should return RADIOLIB_SI443X_DEVICE_VERSION (0x06) if Si443x is connected and working.
|
||||
|
@ -800,13 +800,13 @@ class Si443x: public PhysicalLayer {
|
|||
\brief Set interrupt service routine function to call when data bit is received in direct mode.
|
||||
\param func Pointer to interrupt service routine.
|
||||
*/
|
||||
void setDirectAction(void (*func)(void));
|
||||
void setDirectAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Function to read and process data bit in direct reception mode.
|
||||
\param pin Pin on which to read.
|
||||
*/
|
||||
void readBit(uint32_t pin);
|
||||
void readBit(uint32_t pin) override;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -826,7 +826,7 @@ class Si443x: public PhysicalLayer {
|
|||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
protected:
|
||||
|
|
|
@ -249,7 +249,7 @@ int16_t nRF24::startReceive() {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t nRF24::startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len) {
|
||||
int16_t nRF24::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) {
|
||||
(void)timeout;
|
||||
(void)irqFlags;
|
||||
(void)irqMask;
|
||||
|
@ -298,14 +298,14 @@ int16_t nRF24::setBitRate(float br) {
|
|||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set data rate
|
||||
uint16_t dataRate = (uint16_t)br;
|
||||
if(dataRate == 250) {
|
||||
uint16_t bitRate = (uint16_t)br;
|
||||
if(bitRate == 250) {
|
||||
state = this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, RADIOLIB_NRF24_DR_250_KBPS, 5, 5);
|
||||
state |= this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, RADIOLIB_NRF24_DR_250_KBPS, 3, 3);
|
||||
} else if(dataRate == 1000) {
|
||||
} else if(bitRate == 1000) {
|
||||
state = this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, RADIOLIB_NRF24_DR_1_MBPS, 5, 5);
|
||||
state |= this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, RADIOLIB_NRF24_DR_1_MBPS, 3, 3);
|
||||
} else if(dataRate == 2000) {
|
||||
} else if(bitRate == 2000) {
|
||||
state = this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, RADIOLIB_NRF24_DR_2_MBPS, 5, 5);
|
||||
state |= this->mod->SPIsetRegValue(RADIOLIB_NRF24_REG_RF_SETUP, RADIOLIB_NRF24_DR_2_MBPS, 3, 3);
|
||||
} else {
|
||||
|
@ -313,7 +313,7 @@ int16_t nRF24::setBitRate(float br) {
|
|||
}
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
this->dataRate = dataRate;
|
||||
this->dataRate = bitRate;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ class nRF24: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
nRF24(Module* mod);
|
||||
nRF24(Module* mod); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
// basic methods
|
||||
|
||||
|
@ -215,7 +215,7 @@ class nRF24: public PhysicalLayer {
|
|||
\brief Sets the module to sleep mode.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t sleep();
|
||||
int16_t sleep() override;
|
||||
|
||||
/*!
|
||||
\brief Sets the module to standby mode.
|
||||
|
@ -279,23 +279,23 @@ class nRF24: public PhysicalLayer {
|
|||
\brief Sets interrupt service routine to call when a packet is received.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketReceivedAction(void (*func)(void));
|
||||
void setPacketReceivedAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is received.
|
||||
*/
|
||||
void clearPacketReceivedAction();
|
||||
void clearPacketReceivedAction() override;
|
||||
|
||||
/*!
|
||||
\brief Sets interrupt service routine to call when a packet is sent.
|
||||
\param func ISR to call.
|
||||
*/
|
||||
void setPacketSentAction(void (*func)(void));
|
||||
void setPacketSentAction(void (*func)(void)) override;
|
||||
|
||||
/*!
|
||||
\brief Clears interrupt service routine to call when a packet is sent.
|
||||
*/
|
||||
void clearPacketSentAction();
|
||||
void clearPacketSentAction() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method. IRQ will be activated when full packet is transmitted.
|
||||
|
@ -317,7 +317,7 @@ class nRF24: public PhysicalLayer {
|
|||
\brief Interrupt-driven receive method. IRQ will be activated when full packet is received.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive();
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method, implemented for compatibility with PhysicalLayer.
|
||||
|
@ -327,7 +327,7 @@ class nRF24: public PhysicalLayer {
|
|||
\param len Ignored.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMask, size_t len);
|
||||
int16_t startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMask, size_t len) override;
|
||||
|
||||
/*!
|
||||
\brief Reads data received after calling startReceive method. When the packet length is not known in advance,
|
||||
|
@ -345,21 +345,21 @@ class nRF24: public PhysicalLayer {
|
|||
\param freq Carrier frequency to be set in MHz.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFrequency(float freq);
|
||||
int16_t setFrequency(float freq) override;
|
||||
|
||||
/*!
|
||||
\brief Sets bit rate. Allowed values are 2000, 1000 or 250 kbps.
|
||||
\param br Bit rate to be set in kbps.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBitRate(float br);
|
||||
int16_t setBitRate(float br) override;
|
||||
|
||||
/*!
|
||||
\brief Sets output power. Allowed values are -18, -12, -6 or 0 dBm.
|
||||
\param pwr Output power to be set in dBm.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setOutputPower(int8_t pwr);
|
||||
int16_t setOutputPower(int8_t pwr) override;
|
||||
|
||||
/*!
|
||||
\brief Sets address width of transmit and receive pipes in bytes. Allowed values are 3, 4 or 5 bytes.
|
||||
|
@ -468,7 +468,7 @@ class nRF24: public PhysicalLayer {
|
|||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
void SPIreadRxPayload(uint8_t* data, uint8_t numBytes);
|
||||
void SPIwriteTxPayload(uint8_t* data, uint8_t numBytes);
|
||||
|
|
|
@ -26,7 +26,7 @@ class AFSKClient {
|
|||
\brief Copy contructor.
|
||||
\param aud Pointer to the AFSKClient instance to copy.
|
||||
*/
|
||||
AFSKClient(AFSKClient* aud);
|
||||
explicit AFSKClient(AFSKClient* aud);
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
|
|
@ -49,22 +49,28 @@ int16_t APRSClient::sendPosition(char* destCallsign, uint8_t destSSID, char* lat
|
|||
#endif
|
||||
|
||||
// build the info field
|
||||
if((msg == NULL) && (time == NULL)) {
|
||||
// no message, no timestamp
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_NO_TIME_NO_MSG "%s%c%s%c", lat, table, lon, symbol);
|
||||
} else if((msg != NULL) && (time == NULL)) {
|
||||
// message, no timestamp
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_NO_TIME_MSG "%s%c%s%c%s", lat, table, lon, symbol, msg);
|
||||
} else if((msg == NULL) && (time != NULL)) {
|
||||
// timestamp, no message
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_TIME_NO_MSG "%s%s%c%s%c", time, lat, table, lon, symbol);
|
||||
if(msg != NULL) {
|
||||
if(time != NULL) {
|
||||
// timestamp and message
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_TIME_MSG "%s%s%c%s%c%s", time, lat, table, lon, symbol, msg);
|
||||
} else {
|
||||
// message, no timestamp
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_NO_TIME_MSG "%s%c%s%c%s", lat, table, lon, symbol, msg);
|
||||
}
|
||||
|
||||
} else {
|
||||
// timestamp and message
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_TIME_MSG "%s%s%c%s%c%s", time, lat, table, lon, symbol, msg);
|
||||
if(time != NULL) {
|
||||
// timestamp, no message
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_TIME_NO_MSG "%s%s%c%s%c", time, lat, table, lon, symbol);
|
||||
} else {
|
||||
// no message, no timestamp
|
||||
sprintf(info, RADIOLIB_APRS_DATA_TYPE_POSITION_NO_TIME_NO_MSG "%s%c%s%c", lat, table, lon, symbol);
|
||||
}
|
||||
|
||||
}
|
||||
info[len] = '\0';
|
||||
|
||||
// send the frame
|
||||
info[len] = '\0';
|
||||
int16_t state = sendFrame(destCallsign, destSSID, info);
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] info;
|
||||
|
@ -244,9 +250,9 @@ int16_t APRSClient::sendFrame(char* destCallsign, uint8_t destSSID, char* info)
|
|||
char srcCallsign[RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1];
|
||||
axClient->getCallsign(srcCallsign);
|
||||
|
||||
AX25Frame frameUI(destCallsign, destSSID, srcCallsign, axClient->getSSID(), RADIOLIB_AX25_CONTROL_U_UNNUMBERED_INFORMATION |
|
||||
RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED | RADIOLIB_AX25_CONTROL_UNNUMBERED_FRAME,
|
||||
RADIOLIB_AX25_PID_NO_LAYER_3, (const char*)info);
|
||||
AX25Frame frameUI(destCallsign, destSSID, srcCallsign, axClient->getSSID(),
|
||||
RADIOLIB_AX25_CONTROL_UNNUMBERED_FRAME,
|
||||
RADIOLIB_AX25_PID_NO_LAYER_3, const_cast<char*>(info));
|
||||
|
||||
return(axClient->sendFrame(&frameUI));
|
||||
|
||||
|
@ -256,7 +262,7 @@ int16_t APRSClient::sendFrame(char* destCallsign, uint8_t destSSID, char* info)
|
|||
char* buff = new char[len];
|
||||
snprintf(buff, len, RADIOLIB_APRS_LORA_HEADER "%s-%d>%s,WIDE%d-%d:%s", this->src, this->id, destCallsign, destSSID, destSSID, info);
|
||||
|
||||
int16_t res = this->phyLayer->transmit((uint8_t*)buff, strlen(buff));
|
||||
int16_t res = this->phyLayer->transmit(reinterpret_cast<uint8_t*>(buff), strlen(buff));
|
||||
delete[] buff;
|
||||
return(res);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,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 char* info)
|
||||
: AX25Frame(destCallsign, destSSID, srcCallsign, srcSSID, control, protocolID, (uint8_t*)info, strlen(info)) {
|
||||
: AX25Frame(destCallsign, destSSID, srcCallsign, srcSSID, control, protocolID, reinterpret_cast<uint8_t*>(const_cast<char*>(info)), strlen(info)) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,41 @@ AX25Frame::AX25Frame(const char* destCallsign, uint8_t destSSID, const char* src
|
|||
}
|
||||
}
|
||||
|
||||
AX25Frame::AX25Frame(const AX25Frame& frame) {
|
||||
*this = frame;
|
||||
AX25Frame::AX25Frame(const AX25Frame& frame)
|
||||
: destSSID(frame.destSSID),
|
||||
srcSSID(frame.srcSSID),
|
||||
numRepeaters(frame.numRepeaters),
|
||||
control(frame.control),
|
||||
protocolID(frame.protocolID),
|
||||
infoLen(frame.infoLen),
|
||||
rcvSeqNumber(frame.rcvSeqNumber),
|
||||
sendSeqNumber(frame.sendSeqNumber) {
|
||||
strncpy(this->destCallsign, frame.destCallsign, RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1);
|
||||
strncpy(this->srcCallsign, frame.srcCallsign, RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1);
|
||||
|
||||
if(frame.infoLen) {
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
this->info = new uint8_t[frame.infoLen];
|
||||
#endif
|
||||
memcpy(this->info, frame.info, frame.infoLen);
|
||||
}
|
||||
|
||||
if(frame.numRepeaters) {
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
this->repeaterCallsigns = new char*[frame.numRepeaters];
|
||||
for(uint8_t i = 0; i < frame.numRepeaters; i++) {
|
||||
this->repeaterCallsigns[i] = new char[strlen(frame.repeaterCallsigns[i]) + 1];
|
||||
}
|
||||
this->repeaterSSIDs = new uint8_t[frame.numRepeaters];
|
||||
#endif
|
||||
|
||||
this->numRepeaters = frame.numRepeaters;
|
||||
for(uint8_t i = 0; i < frame.numRepeaters; i++) {
|
||||
memcpy(this->repeaterCallsigns[i], frame.repeaterCallsigns[i], strlen(frame.repeaterCallsigns[i]));
|
||||
this->repeaterCallsigns[i][strlen(frame.repeaterCallsigns[i])] = '\0';
|
||||
}
|
||||
memcpy(this->repeaterSSIDs, frame.repeaterSSIDs, frame.numRepeaters);
|
||||
}
|
||||
}
|
||||
|
||||
AX25Frame::~AX25Frame() {
|
||||
|
@ -154,17 +187,46 @@ void AX25Frame::setSendSequence(uint8_t seqNumber) {
|
|||
AX25Client::AX25Client(PhysicalLayer* phy) {
|
||||
phyLayer = phy;
|
||||
#if !RADIOLIB_EXCLUDE_AFSK
|
||||
audio = nullptr;
|
||||
bellModem = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !RADIOLIB_EXCLUDE_AFSK
|
||||
AX25Client::AX25Client(AFSKClient* audio) {
|
||||
phyLayer = audio->phyLayer;
|
||||
bellModem = new BellClient(audio);
|
||||
AX25Client::AX25Client(AFSKClient* aud)
|
||||
: audio(aud) {
|
||||
phyLayer = this->audio->phyLayer;
|
||||
bellModem = new BellClient(this->audio);
|
||||
bellModem->setModem(Bell202);
|
||||
}
|
||||
|
||||
AX25Client::AX25Client(const AX25Client& ax25)
|
||||
: phyLayer(ax25.phyLayer),
|
||||
sourceSSID(ax25.sourceSSID),
|
||||
preambleLen(ax25.preambleLen) {
|
||||
strncpy(sourceCallsign, ax25.sourceCallsign, RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1);
|
||||
#if !RADIOLIB_EXCLUDE_AFSK
|
||||
if(ax25.bellModem) {
|
||||
this->audio = ax25.audio;
|
||||
this->bellModem = new BellClient(ax25.audio);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
AX25Client& AX25Client::operator=(const AX25Client& ax25) {
|
||||
this->phyLayer = ax25.phyLayer;
|
||||
this->sourceSSID = ax25.sourceSSID;
|
||||
this->preambleLen = ax25.preambleLen;
|
||||
strncpy(sourceCallsign, ax25.sourceCallsign, RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1);
|
||||
#if !RADIOLIB_EXCLUDE_AFSK
|
||||
if(ax25.bellModem) {
|
||||
this->audio = ax25.audio;
|
||||
this->bellModem = new BellClient(ax25.audio);
|
||||
}
|
||||
#endif
|
||||
return(*this);
|
||||
}
|
||||
|
||||
int16_t AX25Client::setCorrection(int16_t mark, int16_t space, float length) {
|
||||
BellModem_t modem;
|
||||
modem.freqMark = Bell202.freqMark + mark;
|
||||
|
@ -205,10 +267,12 @@ int16_t AX25Client::transmit(String& str, const char* destCallsign, uint8_t dest
|
|||
|
||||
int16_t AX25Client::transmit(const char* str, const char* destCallsign, uint8_t destSSID) {
|
||||
// create control field
|
||||
uint8_t controlField = RADIOLIB_AX25_CONTROL_U_UNNUMBERED_INFORMATION | RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED | RADIOLIB_AX25_CONTROL_UNNUMBERED_FRAME;
|
||||
uint8_t controlField = RADIOLIB_AX25_CONTROL_UNNUMBERED_FRAME;
|
||||
|
||||
// build the frame
|
||||
AX25Frame frame(destCallsign, destSSID, sourceCallsign, sourceSSID, controlField, RADIOLIB_AX25_PID_NO_LAYER_3, (uint8_t*)str, strlen(str));
|
||||
AX25Frame frame(destCallsign, destSSID, sourceCallsign, sourceSSID, controlField,
|
||||
RADIOLIB_AX25_PID_NO_LAYER_3,
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(str)), strlen(str));
|
||||
|
||||
// send Unnumbered Information frame
|
||||
return(sendFrame(&frame));
|
||||
|
|
|
@ -246,9 +246,21 @@ class AX25Client {
|
|||
#if !RADIOLIB_EXCLUDE_AFSK
|
||||
/*!
|
||||
\brief Constructor for AFSK mode.
|
||||
\param audio Pointer to the AFSK instance providing audio.
|
||||
\param aud Pointer to the AFSK instance providing audio.
|
||||
*/
|
||||
explicit AX25Client(AFSKClient* audio);
|
||||
explicit AX25Client(AFSKClient* aud);
|
||||
|
||||
/*!
|
||||
\brief Copy constructor.
|
||||
\param ax25 AX25Client instance to copy.
|
||||
*/
|
||||
AX25Client(const AX25Client& ax25);
|
||||
|
||||
/*!
|
||||
\brief Overload for assignment operator.
|
||||
\param ax25 rvalue AX25Client.
|
||||
*/
|
||||
AX25Client& operator=(const AX25Client& ax25);
|
||||
|
||||
/*!
|
||||
\brief Set AFSK tone correction offset. On some platforms, this is required to get the audio produced
|
||||
|
@ -310,10 +322,11 @@ class AX25Client {
|
|||
|
||||
PhysicalLayer* phyLayer;
|
||||
#if !RADIOLIB_EXCLUDE_AFSK
|
||||
AFSKClient* audio;
|
||||
BellClient* bellModem;
|
||||
#endif
|
||||
|
||||
char sourceCallsign[RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1] = {0, 0, 0, 0, 0, 0, 0};
|
||||
char sourceCallsign[RADIOLIB_AX25_MAX_CALLSIGN_LEN + 1] = { 0 };
|
||||
uint8_t sourceSSID = 0;
|
||||
uint16_t preambleLen = 0;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ size_t BellClient::write(uint8_t b) {
|
|||
uint16_t toneSpace = this->modemType.freqSpace;
|
||||
if(this->reply) {
|
||||
toneMark = this->modemType.freqMarkReply;
|
||||
toneMark = this->modemType.freqSpaceReply;
|
||||
toneSpace = this->modemType.freqSpaceReply;
|
||||
}
|
||||
|
||||
// get the Module pointer to access HAL
|
||||
|
|
|
@ -75,7 +75,7 @@ class BellClient: public AFSKClient, public RadioLibPrint {
|
|||
\brief Audio-client constructor. Can be used when AFSKClient instance already exists.
|
||||
\param aud Audio client to use.
|
||||
*/
|
||||
BellClient(AFSKClient* aud);
|
||||
explicit BellClient(AFSKClient* aud);
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
@ -104,7 +104,7 @@ class BellClient: public AFSKClient, public RadioLibPrint {
|
|||
\param b Byte to write.
|
||||
\returns 1 if the byte was written, 0 otherwise.
|
||||
*/
|
||||
size_t write(uint8_t b);
|
||||
size_t write(uint8_t b) override;
|
||||
|
||||
/*!
|
||||
\brief Set the modem to idle (ready to transmit).
|
||||
|
@ -119,7 +119,7 @@ class BellClient: public AFSKClient, public RadioLibPrint {
|
|||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
BellModem_t modemType;
|
||||
BellModem_t modemType = Bell101;
|
||||
float correction = 1.0;
|
||||
uint16_t toneLen = 0;
|
||||
bool autoStart = true;
|
||||
|
|
|
@ -14,6 +14,27 @@ ExternalRadio::ExternalRadio(RadioLibHal *hal, uint32_t pin) : PhysicalLayer(1,
|
|||
this->prevFrf = 0;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
ExternalRadio& ExternalRadio::operator=(const ExternalRadio& ext) {
|
||||
this->prevFrf = ext.prevFrf;
|
||||
if(ext.mod) {
|
||||
this->mod = new Module(ext.mod->hal, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, ext.mod->getGpio());
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
ExternalRadio::~ExternalRadio() {
|
||||
if(this->mod) {
|
||||
delete this->mod;
|
||||
}
|
||||
}
|
||||
|
||||
Module* ExternalRadio::getMod() {
|
||||
return(mod);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class ExternalRadio: public PhysicalLayer {
|
|||
\brief Default constructor.
|
||||
\param pin Output pin when using direct transmission, defaults to unused pin.
|
||||
*/
|
||||
ExternalRadio(uint32_t pin = RADIOLIB_NC);
|
||||
ExternalRadio(uint32_t pin = RADIOLIB_NC); // cppcheck-suppress noExplicitConstructor
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -28,13 +28,30 @@ class ExternalRadio: public PhysicalLayer {
|
|||
\param hal Pointer to the hardware abstraction layer to use.
|
||||
\param pin Output pin when using direct transmission, defaults to unused pin.
|
||||
*/
|
||||
ExternalRadio(RadioLibHal *hal, uint32_t pin = RADIOLIB_NC);
|
||||
ExternalRadio(RadioLibHal *hal, uint32_t pin = RADIOLIB_NC); // cppcheck-suppress noExplicitConstructor
|
||||
|
||||
/*!
|
||||
\brief Copy constructor.
|
||||
\param ext ExternalRadio instance to copy.
|
||||
*/
|
||||
ExternalRadio(const ExternalRadio& ext);
|
||||
|
||||
/*!
|
||||
\brief Overload for assignment operator.
|
||||
\param ext rvalue ExternalRadio.
|
||||
*/
|
||||
ExternalRadio& operator=(const ExternalRadio& ext);
|
||||
|
||||
/*!
|
||||
\brief Default destructor.
|
||||
*/
|
||||
~ExternalRadio();
|
||||
|
||||
/*!
|
||||
\brief Method to retrieve pointer to the underlying Module instance.
|
||||
\returns Pointer to the Module instance.
|
||||
*/
|
||||
Module* getMod();
|
||||
Module* getMod() override;
|
||||
|
||||
/*!
|
||||
\brief Dummy implementation overriding PhysicalLayer.
|
||||
|
@ -63,7 +80,7 @@ class ExternalRadio: public PhysicalLayer {
|
|||
the output pin will be set to logic high. Otherwise it will be set to logic low.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t transmitDirect(uint32_t frf = 0);
|
||||
int16_t transmitDirect(uint32_t frf = 0) override;
|
||||
|
||||
private:
|
||||
Module* mod;
|
||||
|
|
|
@ -112,12 +112,12 @@ int32_t FSK4Client::getRawShift(int32_t shift) {
|
|||
int32_t step = round(phyLayer->getFreqStep());
|
||||
|
||||
// check minimum shift value
|
||||
if(abs(shift) < step / 2) {
|
||||
if(RADIOLIB_ABS(shift) < step / 2) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
// round shift to multiples of frequency step size
|
||||
if(abs(shift) % step < (step / 2)) {
|
||||
if(RADIOLIB_ABS(shift) % step < (step / 2)) {
|
||||
return(shift / step);
|
||||
}
|
||||
if(shift < 0) {
|
||||
|
|
|
@ -85,8 +85,8 @@ class FSK4Client {
|
|||
uint32_t baseFreq = 0, baseFreqHz = 0;
|
||||
uint32_t shiftFreq = 0, shiftFreqHz = 0;
|
||||
RadioLibTime_t bitDuration = 0;
|
||||
uint32_t tones[4];
|
||||
uint32_t tonesHz[4];
|
||||
uint32_t tones[4] = { 0 };
|
||||
uint32_t tonesHz[4] = { 0 };
|
||||
|
||||
void tone(uint8_t i);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ int16_t HellClient::begin(float base, float rate) {
|
|||
return(phyLayer->startDirect());
|
||||
}
|
||||
|
||||
size_t HellClient::printGlyph(uint8_t* buff) {
|
||||
size_t HellClient::printGlyph(const uint8_t* buff) {
|
||||
// print the character
|
||||
Module* mod = phyLayer->getMod();
|
||||
bool transmitting = false;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue