Porównaj commity

...

19 Commity

Autor SHA1 Wiadomość Data
HeadBoffin ff5ade2aa1
Merge pull request #1 from jgromes/master
LoRaWAN examples update
2024-03-25 11:17:57 +00:00
Nick McCloud 5bc97550ec Clean up prior named directories plus neglected Reference is included 2024-03-23 17:03:21 +00:00
Nick McCloud 0182a123fb Update of examples to latest API, testing, repeat 2024-03-23 17:00:13 +00:00
Jan Gromeš cfc425970c
[LoRaWAN] Resolve warnings, fix bugs for fixed bands (#1021)
* [LoRaWAN] Resolve warnings

* [LoRaWAN] Fixed bands: improve initial datarate, fix CFList bug

* [LoRaWAN] Improve MAC debug output formatting

* Fix hexdump debug level

* Remove unnecessary error, add new ones to keywords

* [LoRaWAN] Discard useless check

---------

Co-authored-by: StevenCellist <steven@boonstoppel.nu>
2024-03-18 16:39:55 +01:00
jgromes 44f6c1d432 [CI] Enable LoRaWAN builds for previously disabled platforms 2024-03-18 09:37:16 +01:00
StevenCellist ca2a3073b9
[LoRaWAN] Change and upgrade persistence handling (#1017)
* [LoRaWAN] Change and upgrade persistence handling

* [BuildOpt] Patch to upstream

* [LoRaWAN] Fix #1018

* [LoRaWAN] Remove outdated parts

* [LoRaWAN] Resolve feedback

Warning: untested - am not at my desk

* [LoRaWAN] Small bugfixes
2024-03-18 08:51:38 +01:00
Jan Gromeš 3d5f05b963
Static check (#1019)
* Update CodeQL action

* [CI] Added workflow dispatch for codeql

* [CI] Use v4 checkout action

* [CI] Add cppcheck action (#1018)
2024-03-17 18:10:54 +01:00
jgromes 0b11d101aa [CC1101] Clarify direct methods are synchronous (#1016) 2024-03-15 19:32:57 +01:00
jgromes 9fd7db4d13 [SX126x] Fix rx/tx fallback mode (#1008) 2024-03-13 07:00:20 +01:00
jgromes b288485d6c [SX126x] Added option to select standby mode (#1008) 2024-03-12 21:52:17 +01:00
jgromes 24ffbfc284 Added ESP IRAM attribute to examples (#1010) 2024-03-10 20:40:41 +01:00
jgromes 4993ac7c9d Added links to troubleshooting guide 2024-03-10 12:44:04 +01:00
jgromes 4ee17cc168 Debugging rework 2024-03-10 11:07:23 +01:00
jgromes 9774a2299b Update issue template for new debug levels 2024-03-10 09:56:23 +01:00
jgromes cf561733d2 [Pager] Minor fixes 2024-03-02 18:09:56 +01:00
Jan Szumiec 268e2d704f
Receive messages for multiple POCSAG RICs (#998)
* Make it possible to supply a list of addresses for POCSAG reception.

* Initialize some instance variables to sensible values.
2024-03-02 18:01:32 +01:00
jgromes 744834509f Merge branch 'master' of https://github.com/jgromes/RadioLib 2024-02-28 18:09:26 +01:00
jgromes 10acb6d9ca Added ESP-IDF badge to readme 2024-02-28 18:09:24 +01:00
Nicklas Börjesson a52920bcb2
IDF Component Registry manifest (#990)
* Add idf_component.yxml

* Fix URL, add compote dist to .gitignore
2024-02-28 17:50:04 +01:00
55 zmienionych plików z 1743 dodań i 1507 usunięć

Wyświetl plik

@ -8,10 +8,10 @@ assignees: ''
---
**IMPORTANT: Check the wiki**
Before submitting new issue, please check the [Wiki](https://github.com/jgromes/RadioLib/wiki) and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
**Describe the bug**
A clear and concise description of what the bug is. When applicable, please include [debug mode output](https://github.com/jgromes/RadioLib/wiki/Debug-mode).
A clear and concise description of what the bug is. When applicable, please include [debug mode output](https://github.com/jgromes/RadioLib/wiki/Debug-mode) **using the appropriate debug mode**.
**To Reproduce**
Minimal Arduino sketch to reproduce the behavior. Please use Markdown to style the code to make it readable (see [Markdown Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)).

Wyświetl plik

@ -8,7 +8,7 @@ assignees: ''
---
**IMPORTANT: Check the wiki**
Before submitting new issue, please check the [Wiki](https://github.com/jgromes/RadioLib/wiki) and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Wyświetl plik

@ -9,7 +9,7 @@ assignees: ''
**IMPORTANT: Before submitting an issue, please check the following:**
1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored.
2. RadioLib has a [Wiki](https://github.com/jgromes/RadioLib/wiki) and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases).
4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib!
5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html).
@ -24,7 +24,7 @@ paste the sketch here, even if it is an unmodified example code
Wiring diagram, schematic, pictures etc.
**Debug mode output**
Enable all [debug levels](https://github.com/jgromes/RadioLib/wiki/Debug-mode) and paste the Serial monitor output here.
Enable the appropriate [debug levels](https://github.com/jgromes/RadioLib/wiki/Debug-mode) and paste the Serial monitor output here. For debugging protocols, enable `RADIOLIB_DEBUG_PROTOCOL`. For debugging issues with the radio module itself, enable `RADIOLIB_DEBUG_SPI`.
**Additional info (please complete):**
- MCU: [e.g. Arduino Uno, ESP8266 etc.]

Wyświetl plik

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

Wyświetl plik

@ -5,11 +5,14 @@ on:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
security-events: write
strategy:
fail-fast: false
@ -18,20 +21,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
@ -63,4 +57,4 @@ jobs:
arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn arduino:avr:uno $PWD/examples/SX126x/SX126x_Transmit_Blocking/SX126x_Transmit_Blocking.ino --warnings=all
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v3

27
.github/workflows/cppcheck.yml vendored 100644
Wyświetl plik

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

Wyświetl plik

@ -13,7 +13,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y doxygen
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Generate docs
run: doxygen Doxyfile

Wyświetl plik

@ -50,22 +50,17 @@ jobs:
- id: arduino:avr:mega
run: echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT
- id: arduino:mbed:nano33ble
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: arduino:mbed:envie_m4
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: arduino:megaavr:uno2018
run: |
echo "options=':mode=on'" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
- id: arduino:sam:arduino_due_x
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: arduino:samd:arduino_zero_native
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: adafruit:samd:adafruit_feather_m0
run: |
echo "options=':usbstack=arduino,debug=off'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: adafruit:nrf52:feather52832
run: |
sudo apt-get update
@ -75,7 +70,6 @@ jobs:
echo "/home/runner/.local/bin" >> $GITHUB_PATH
echo "options=':softdevice=s132v6,debug=l0'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: esp32:esp32:esp32
run: |
python -m pip install pyserial
@ -102,10 +96,8 @@ jobs:
echo "index-url=--additional-urls http://dan.drown.org/stm32duino/package_STM32duino_index.json" >> $GITHUB_OUTPUT
- id: MegaCoreX:megaavr:4809
run: |
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://mcudude.github.io/MegaCoreX/package_MCUdude_MegaCoreX_index.json" >> $GITHUB_OUTPUT
- id: arduino:mbed_rp2040:pico
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: rp2040:rp2040:rpipico
run: echo "index-url=--additional-urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json" >> $GITHUB_OUTPUT
- id: CubeCell:CubeCell:CubeCell-Board
@ -158,7 +150,7 @@ jobs:
- name: Checkout repository
if: ${{ env.run-build == 'true' }}
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Build examples
if: ${{ env.run-build == 'true' }}
@ -186,7 +178,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install dependencies
run: |
@ -214,7 +206,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: recursive
@ -235,7 +227,7 @@ jobs:
runs-on: [self-hosted, ARM64]
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install dependencies
run: |
@ -270,7 +262,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install dependencies
run: |

3
.gitignore vendored
Wyświetl plik

@ -23,3 +23,6 @@ extras/SX126x_Spectrum_Scan/out/*
# cmake
build/
# Compote build output
dist

Wyświetl plik

@ -1,4 +1,4 @@
# RadioLib ![Build Status](https://github.com/jgromes/RadioLib/workflows/CI/badge.svg) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/jgromes/library/RadioLib.svg)](https://registry.platformio.org/libraries/jgromes/RadioLib)
# RadioLib ![Build Status](https://github.com/jgromes/RadioLib/workflows/CI/badge.svg) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/jgromes/library/RadioLib.svg)](https://registry.platformio.org/libraries/jgromes/RadioLib) [![Component Registry](https://components.espressif.com/components/jgromes/radiolib/badge.svg)](https://components.espressif.com/components/jgromes/radiolib)
### _One radio library to rule them all!_

Wyświetl plik

@ -0,0 +1,130 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#include <RadioLib.h>
// How often to send an uplink - consider legal & FUP constraints - see notes
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
// JoinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
// The Device EUI & two keys can be generated on the TTN console
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
// For the curious, the #ifndef blocks allow for automated testing &/or you can
// put your EUI & keys in to your platformio.ini - see wiki for more tips
// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500
const LoRaWANBand_t Region = EU868;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
// Auto select MCU <-> radio connections
// If you get an error message when compiling, it may be that the
// pinmap could not be determined - see the notes for more info
// Adafruit
#if defined(ARDUINO_SAMD_FEATHER_M0)
#pragma message ("Adafruit Feather M0 with RFM95")
#pragma message ("Link required on board")
SX1276 radio = new Module(8, 3, 4, 6);
// LilyGo
#elif defined(ARDUINO_TTGO_LORA32_V1)
#pragma message ("TTGO LoRa32 v1 - no Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TTGO_LORA32_V2)
#pragma error ("ARDUINO_TTGO_LORA32_V2 awaiting pin map")
#elif defined(ARDUINO_TTGO_LoRa32_v21new) // T3_V1.6.1
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1262)
#pragma error ("ARDUINO_TBEAM_USE_RADIO_SX1262 awaiting pin map")
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1276)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 23, 33);
// Heltec
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
#pragma error ("ARDUINO_HELTEC_WIFI_LORA_32 awaiting pin map")
#elif defined(ARDUINO_heltec_wifi_kit_32_V2)
#pragma message ("ARDUINO_heltec_wifi_kit_32_V2 awaiting pin map")
SX1276 radio = new Module(18, 26, 14, 35);
#elif defined(ARDUINO_heltec_wifi_kit_32_V3)
#pragma message ("Using Heltec WiFi LoRa32 v3 - Display + USB-C")
SX1262 radio = new Module(8, 14, 12, 13);
#elif defined(ARDUINO_CUBECELL_BOARD)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE);
#elif defined(ARDUINO_CUBECELL_BOARD_V2)
#pragma error ("ARDUINO_CUBECELL_BOARD_V2 awaiting pin map")
#else
#pragma message ("Unknown board - no automagic pinmap available")
// SX1262 pin order: Module(NSS/CS, DIO1, RESET, BUSY);
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 pin order: Module(NSS/CS, DIO0, RESET, DIO1);
// SX1278 radio = new Module(10, 2, 9, 3);
#endif
// Copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
// Create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);
// Helper function to display any issues
void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) {
if (isFail) {
Serial.print(message);
Serial.print("(");
Serial.print(state);
Serial.println(")");
while (Freeze);
}
}
// Helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
for (uint16_t c; c < len; c++) {
Serial.printf("%02X", buffer[c]);
}
Serial.println();
}
#endif

Wyświetl plik

@ -0,0 +1,196 @@
/*
This demonstrates how to save the join information in to permanent memory
so that if the power fails, batteries run out or are changed, the rejoin
is more efficient & happens sooner due to the way that LoRaWAN secures
the join process - see the wiki for more details.
This is typically useful for devices that need more power than a battery
driven sensor - something like a air quality monitor or GPS based device that
is likely to use up it's power source resulting in loss of the session.
The relevant code is flagged with a ##### comment
Saving the entire session is possible but not demonstrated here - it has
implications for flash wearing and complications with which parts of the
session may have changed after an uplink. So it is assumed that the device
is going in to deep-sleep, as below, between normal uplinks.
*/
#if !defined(ESP32)
#pragma error ("This is not the example your device is looking for - ESP32 only")
#endif
// ##### Load the ESP32 preferences facilites
#include <Preferences.h>
Preferences store;
// LoRaWAN config, credentials & pinmap
#include "config.h"
#include <RadioLib.h>
// Utilities & vars to support ESP32 deep-sleep. The RTC_DATA_ATTR attribute
// puts these in to the RTC memory which is preserved during deep-sleep
RTC_DATA_ATTR uint16_t bootCount = 1;
RTC_DATA_ATTR uint16_t bootCountSinceUnsuccessfulJoin = 0;
RTC_DATA_ATTR uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE];
// Abbreviated version from the Arduino-ESP32 package, see
// https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/deepsleep.html
// for the complete set of options
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
if (wakeup_reason == ESP_SLEEP_WAKEUP_TIMER) {
Serial.println(F("Wake from sleep"));
} else {
Serial.print(F("Wake not caused by deep sleep: "));
Serial.println(wakeup_reason);
}
Serial.print(F("Boot count: "));
Serial.println(bootCount++);
}
// Put device in to lowest power deep-sleep mode
void gotoSleep(uint32_t seconds) {
esp_sleep_enable_timer_wakeup(seconds * 1000UL * 1000UL); // Function uses uS
Serial.println(F("Sleeping\n"));
Serial.flush();
esp_deep_sleep_start();
// If this appears in the serial debug, we didn't go to sleep!
// So take defensive action so we don't continually uplink
Serial.println(F("\n\n### Sleep failed, delay of 5 minutes & then restart ###\n"));
delay(5UL * 60UL * 1000UL);
ESP.restart();
}
// Setup & execute all device functions ...
void setup() {
Serial.begin(115200);
while (!Serial); // Wait for serial to be initalised
delay(2000); // Give time to switch to the serial monitor
Serial.println(F("\nSetup"));
print_wakeup_reason();
int16_t state = 0; // return value for calls to RadioLib
// Setup the radio based on the pinmap (connections) in config.h
Serial.println(F("Initalise the radio"));
state = radio.begin();
debug(state != RADIOLIB_ERR_NONE, F("Initalise radio failed"), state, true);
Serial.println(F("Recalling LoRaWAN nonces & session"));
// ##### Setup the flash storage
store.begin("radiolib");
// ##### If we have previously saved nonces, restore them
if (store.isKey("nonces")) {
uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE];// Create somewhere to store nonces
store.getBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);// Get them to the store
state = node.setBufferNonces(buffer); // Send them to LoRaWAN
debug(state != RADIOLIB_ERR_NONE, F("Restoring nonces buffer failed"), state, false);
}
// Recall session from RTC deep-sleep preserved variable
state = node.setBufferSession(LWsession); // Send them to LoRaWAN stack
// If we have booted at least once we should have a session to restore, so report any failure
// Otherwise no point saying there's been a failure when it was bound to fail with an empty
// LWsession var. At this point, bootCount has already been incremented, hence the > 2
debug((state != RADIOLIB_ERR_NONE) && (bootCount > 2), F("Restoring session buffer failed"), state, false);
// Process the restored session or failing that, create a new one &
// return flag to indicate a fresh join is required
Serial.println(F("Setup LoRaWAN session"));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, false);
// See comment above, no need to report a failure that is bound to occur on first boot
debug((state != RADIOLIB_ERR_NONE) && (bootCount > 2), F("Restore session failed"), state, false);
// Loop until successful join
while (state != RADIOLIB_ERR_NONE) {
Serial.println(F("Join ('login') to the LoRaWAN Network"));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, true);
if (state < RADIOLIB_ERR_NONE) {
Serial.print(F("Join failed: "));
Serial.println(state);
// How long to wait before join attenpts. This is an interim solution pending
// implementation of TS001 LoRaWAN Specification section #7 - this doc applies to v1.0.4 & v1.1
// It sleeps for longer & longer durations to give time for any gateway issues to resolve
// or whatever is interfering with the device <-> gateway airwaves.
uint32_t sleepForSeconds = min((bootCountSinceUnsuccessfulJoin++ + 1UL) * 60UL, 3UL * 60UL);
Serial.print(F("Boots since unsuccessful join: "));
Serial.println(bootCountSinceUnsuccessfulJoin);
Serial.print(F("Retrying join in "));
Serial.print(sleepForSeconds);
Serial.println(F(" seconds"));
gotoSleep(sleepForSeconds);
} else { // Join was successful
Serial.println(F("Joined"));
// ##### Save the join counters (nonces) to permanent store
Serial.println(F("Saving nonces to flash"));
uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE]; // Create somewhere to store nonces
uint8_t *persist = node.getBufferNonces(); // Get pointer to nonces
memcpy(buffer, persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); // Copy in to buffer
store.putBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); // Send them to the store
// We'll save the session after the uplink
// Reset the failed join count
bootCountSinceUnsuccessfulJoin = 0;
delay(1000); // Hold off off hitting the airwaves again too soon - an issue in the US
} // if beginOTAA state
} // while join
// ##### Close the store
store.end();
// ----- And now for the main event -----
Serial.println(F("Sending uplink"));
// Read some inputs
uint8_t Digital2 = digitalRead(2);
uint16_t Analog1 = analogRead(A1);
// Build payload byte array
uint8_t uplinkPayload[3];
uplinkPayload[0] = Digital2;
uplinkPayload[1] = highByte(Analog1); // See notes for high/lowByte functions
uplinkPayload[2] = lowByte(Analog1);
// Perform an uplink
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
debug((state != RADIOLIB_ERR_RX_TIMEOUT) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false);
Serial.print(F("FcntUp: "));
Serial.println(node.getFcntUp());
// Now save session to RTC memory
uint8_t *persist = node.getBufferSession();
memcpy(LWsession, persist, RADIOLIB_LORAWAN_SESSION_BUF_SIZE);
// Wait until next uplink - observing legal & TTN FUP constraints
gotoSleep(uplinkIntervalSeconds);
}
// The ESP32 wakes from deep-sleep and starts from the very beginning
// which is a very good place to start, as any singing nun knows.
// It then goes back to sleep, so loop() is never called and which is
// why it is empty.
void loop() {}

Wyświetl plik

@ -0,0 +1,130 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#include <RadioLib.h>
// How often to send an uplink - consider legal & FUP constraints - see notes
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
// JoinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
// The Device EUI & two keys can be generated on the TTN console
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
// For the curious, the #ifndef blocks allow for automated testing &/or you can
// put your EUI & keys in to your platformio.ini - see wiki for more tips
// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500
const LoRaWANBand_t Region = EU868;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
// Auto select MCU <-> radio connections
// If you get an error message when compiling, it may be that the
// pinmap could not be determined - see the notes for more info
// Adafruit
#if defined(ARDUINO_SAMD_FEATHER_M0)
#pragma message ("Adafruit Feather M0 with RFM95")
#pragma message ("Link required on board")
SX1276 radio = new Module(8, 3, 4, 6);
// LilyGo
#elif defined(ARDUINO_TTGO_LORA32_V1)
#pragma message ("TTGO LoRa32 v1 - no Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TTGO_LORA32_V2)
#pragma error ("ARDUINO_TTGO_LORA32_V2 awaiting pin map")
#elif defined(ARDUINO_TTGO_LoRa32_v21new) // T3_V1.6.1
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1262)
#pragma error ("ARDUINO_TBEAM_USE_RADIO_SX1262 awaiting pin map")
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1276)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 23, 33);
// Heltec
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
#pragma error ("ARDUINO_HELTEC_WIFI_LORA_32 awaiting pin map")
#elif defined(ARDUINO_heltec_wifi_kit_32_V2)
#pragma message ("ARDUINO_heltec_wifi_kit_32_V2 awaiting pin map")
SX1276 radio = new Module(18, 26, 14, 35);
#elif defined(ARDUINO_heltec_wifi_kit_32_V3)
#pragma message ("Using Heltec WiFi LoRa32 v3 - Display + USB-C")
SX1262 radio = new Module(8, 14, 12, 13);
#elif defined(ARDUINO_CUBECELL_BOARD)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE);
#elif defined(ARDUINO_CUBECELL_BOARD_V2)
#pragma error ("ARDUINO_CUBECELL_BOARD_V2 awaiting pin map")
#else
#pragma message ("Unknown board - no automagic pinmap available")
// SX1262 pin order: Module(NSS/CS, DIO1, RESET, BUSY);
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 pin order: Module(NSS/CS, DIO0, RESET, DIO1);
// SX1278 radio = new Module(10, 2, 9, 3);
#endif
// Copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
// Create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);
// Helper function to display any issues
void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) {
if (isFail) {
Serial.print(message);
Serial.print("(");
Serial.print(state);
Serial.println(")");
while (Freeze);
}
}
// Helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
for (uint16_t c; c < len; c++) {
Serial.printf("%02X", buffer[c]);
}
Serial.println();
}
#endif

Wyświetl plik

@ -1,161 +0,0 @@
/*
RadioLib LoRaWAN End Device Example
This example joins a LoRaWAN network and will send
uplink packets. Before you start, you will have to
register your device at https://www.thethingsnetwork.org/
After your device is registered, you can run this example.
The device will join the network and start uploading data.
NOTE: LoRaWAN v1.1 requires storing parameters persistently!
RadioLib does this by using EEPROM (persistent storage),
by default starting at address 0 and using 448 bytes.
If you already use EEPROM in your application,
you will have to either avoid this range, or change it
by setting a different start address by changing the value of
RADIOLIB_HAL_PERSISTENT_STORAGE_BASE macro, either
during build or in src/BuildOpt.h.
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
For LoRaWAN details, see the wiki page
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
Last updated 1st March 2024 for RadioLib 6.4.2
*/
// include the library
#include <RadioLib.h>
// SX1262 has the following pin order:
// Module(NSS/CS, DIO1, RESET, BUSY)
SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 has the following pin order:
// Module(NSS/CS, DIO0, RESET, DIO1)
// SX1278 radio = new Module(10, 2, 9, 3);
// create the node instance on the EU-868 band
// using the radio module and the encryption key
// make sure you are using the correct band
// based on your geographical location!
LoRaWANNode node(&radio, &EU868);
// for fixed bands with subband selection
// such as US915 and AU915, you must specify
// the subband that matches the Frequency Plan
// that you selected on your LoRaWAN console
// LoRaWANNode node(&radio, &US915, 2);
void setup() {
Serial.begin(9600);
// initialize radio (SX1262 / SX1278 / ... ) with default settings
Serial.print(F("[Radio] 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);
}
// JoinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
uint64_t joinEUI = 0x0000000000000000;
// DevEUI - The device's Extended Unique Identifier
// TTN will generate one for you
uint64_t devEUI = 0x----------------;
// encryption keys used to secure the communication
// TTN will generate them for you
// see wiki for details on copying & pasting them
uint8_t nwkKey[] = { 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- };
uint8_t appKey[] = { 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- };
// Manages uplink intervals to the TTN Fair Use Policy
node.setDutyCycle(true, 1250);
// Begin the join to the network
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
if(state >= RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
delay(2000); // small delay between joining and uplink
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
} // setup
// counter to keep track of transmitted packets
int count = 0;
void loop() {
// send uplink to port 10
Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
String strUp = "Hello! " + String(count++);
String strDown;
int state = node.sendReceive(strUp, 10, strDown);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("received a downlink!"));
// print data of the packet (if there are any)
Serial.print(F("[LoRaWAN] Data:\t\t"));
if(strDown.length() > 0) {
Serial.println(strDown);
} else {
Serial.println(F("<MAC commands only>"));
}
// print RSSI (Received Signal Strength Indicator)
Serial.print(F("[LoRaWAN] RSSI:\t\t"));
Serial.print(radio.getRSSI());
Serial.println(F(" dBm"));
// print SNR (Signal-to-Noise Ratio)
Serial.print(F("[LoRaWAN] SNR:\t\t"));
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
// print frequency error
Serial.print(F("[LoRaWAN] Frequency error:\t"));
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F(""));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// on boards that can save to Flash or EEPROM this saves the session
// which allows recall of the session after reboot or deepsleep
node.saveSession();
// wait before sending another packet
uint32_t minimumDelay = 300000; // try to send once every 3 minutes
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per FUP & law!)
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
Serial.print(F("[LoRaWAN] Next uplink in "));
Serial.print(delayMs/60);
Serial.println(F("s"));
delay(delayMs);
} // loop

Wyświetl plik

@ -27,99 +27,54 @@
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
Last updated 1st March 2024 for RadioLib 6.4.2
*/
#include "config.h"
// include the library
#include <RadioLib.h>
// SX1262 has the following pin order:
// Module(NSS/CS, DIO1, RESET, BUSY)
SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 has the following pin order:
// Module(NSS/CS, DIO0, RESET, DIO1)
// SX1278 radio = new Module(10, 2, 9, 3);
// create the node instance on the EU-868 band
// using the radio module and the encryption key
// make sure you are using the correct band
// based on your geographical location!
LoRaWANNode node(&radio, &EU868);
// for fixed bands with subband selection
// such as US915 and AU915, you must specify
// the subband that matches the Frequency Plan
// that you selected on your LoRaWAN console
// LoRaWANNode node(&radio, &US915, 2);
void setup() {
Serial.begin(9600);
Serial.begin(115200);
while (!Serial); // Wait for serial to be initalised
delay(2000); // Give time to switch to the serial monitor
Serial.println(F("\nSetup"));
// initialize radio (SX1262 / SX1278 / ... ) with default settings
Serial.print(F("[Radio] 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);
}
// JoinEUI - previous versions of LoRaWAN this was AppEUI
// for development purposes you can use all zeros - see wiki for details
uint64_t joinEUI = 0x0000000000000000;
// DevEUI - The device's Extended Unique Identifier
// TTN will generate one for you
uint64_t devEUI = 0x----------------;
// encryption keys used to secure the communication
// TTN will generate them for you
// see wiki for details on copying & pasting them
uint8_t nwkKey[] = { 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- };
uint8_t appKey[] = { 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- };
int16_t state = 0; // return value for calls to RadioLib
Serial.println(F("Initalise the radio"));
state = radio.begin();
debug(state != RADIOLIB_ERR_NONE, F("Initalise radio failed"), state, true);
// Override the default join rate
uint8_t joinDR = 3;
// uint8_t joinDR = 3;
// Begin the join to the network
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, joinDR);
if(state >= RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
delay(2000); // small delay between joining and uplink
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
Serial.println(F("Join ('login') to the LoRaWAN Network"));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, true);
debug(state < RADIOLIB_ERR_NONE, F("Join failed"), state, true);
// Print the DevAddr
Serial.print("[LoRaWAN] DevAddr: ");
Serial.println(node.getDevAddr(), HEX);
// disable the ADR algorithm (on by default which is preferable)
// Disable the ADR algorithm (on by default which is preferable)
node.setADR(false);
// set a fixed datarate & make it persistent (not normal)
node.setDatarate(5, true);
// Set a fixed datarate & make it persistent (not normal)
node.setDatarate(4);
// enable CSMA which tries to minimize packet loss by searching
// Enable CSMA which tries to minimize packet loss by searching
// for a free channel before actually sending an uplink
node.setCSMA(6, 2, true);
// manages uplink intervals to the TTN Fair Use Policy
node.setDutyCycle(true, 1250);
// Manages uplink intervals to the TTN Fair Use Policy
node.setDutyCycle(true, 1250);
// enable the dwell time limits - 400ms is the limit for the US
// Enable the dwell time limits - 400ms is the limit for the US
node.setDwellTime(true, 400);
Serial.println(F("Ready!\n"));
} // setup
@ -135,48 +90,46 @@ void loop() {
uint8_t battLevel = 146;
node.setDeviceStatus(battLevel);
// retrieve the last uplink frame counter
uint32_t fcntUp = node.getFcntUp();
Serial.print(F("[LoRaWAN] Sending uplink packet #"));
Serial.println(fcntUp);
String strUp = "Hello! " + String(fcntUp);
// send a confirmed uplink to port 10 every 64th frame
// and also request the LinkCheck and DeviceTime MAC commands
if(fcntUp % 64 == 0) {
Serial.print(F("[LoRaWAN] Requesting LinkCheck and DeviceTime"));
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
state = node.uplink(strUp, 10, true);
} else {
state = node.uplink(strUp, 10);
}
if(state != RADIOLIB_ERR_NONE) {
Serial.print(F("failed, code "));
Serial.println(state);
}
// Read some inputs
uint8_t Digital1 = digitalRead(2);
uint16_t Analog1 = analogRead(A0);
// after uplink, you must call downlink() to receive any possible reply
// from the server. This function must be called before the Rx1 delay
// for the network. Typically this is 5s after end of uplink.
Serial.println(F("[LoRaWAN] Waiting for downlink ... "));
String strDown;
// Build payload byte array
uint8_t uplinkPayload[3];
uplinkPayload[0] = Digital1;
uplinkPayload[1] = highByte(Analog1); // See notes for high/lowByte functions
uplinkPayload[2] = lowByte(Analog1);
uint8_t downlinkPayload[10]; // Make sure this fits your plans!
size_t downlinkSize; // To hold the actual payload size rec'd
// you can also retrieve additional information about an uplink or
// downlink by passing a reference to LoRaWANEvent_t structure
LoRaWANEvent_t uplinkDetails;
LoRaWANEvent_t downlinkDetails;
state = node.downlink(strDown, &downlinkDetails);
uint8_t Port = 10;
// Retrieve the last uplink frame counter
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);
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), Port, downlinkPayload, &downlinkSize, true, &uplinkDetails, &downlinkDetails);
} else {
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), Port, downlinkPayload, &downlinkSize);
}
debug((state != RADIOLIB_ERR_RX_TIMEOUT) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false);
if(state == RADIOLIB_ERR_NONE) {
// print data of the packet
Serial.print(F("[LoRaWAN] Data:\t\t"));
if(strDown.length() > 0) {
for (uint8_t c = 0; c < strDown.length(); c++) {
uint8_t value = strDown[c];
if (value < 10) Serial.print(F("0"));
Serial.print(value, HEX);
}
Serial.println();
// Did we get a downlink with data for us
if (downlinkSize > 0) {
Serial.println(F("Downlink data: "));
arrayDump(downlinkPayload, downlinkSize);
} else {
Serial.println(F("<MAC commands only>"));
}
@ -233,20 +186,10 @@ void loop() {
Serial.println(fracSecond);
}
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
// Not really necessary to report normal operation
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// on boards that can save to Flash or EEPROM this saves the session
// which allows recall of the session after reboot or deepsleep
node.saveSession();
// wait before sending another packet
uint32_t minimumDelay = 3 * 60 * 1000; // try to send once every 3 minutes
uint32_t minimumDelay = uplinkIntervalSeconds * 1000UL;
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per FUP & law!)
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows

Wyświetl plik

@ -0,0 +1,130 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#include <RadioLib.h>
// How often to send an uplink - consider legal & FUP constraints - see notes
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
// JoinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
// The Device EUI & two keys can be generated on the TTN console
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
// For the curious, the #ifndef blocks allow for automated testing &/or you can
// put your EUI & keys in to your platformio.ini - see wiki for more tips
// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500
const LoRaWANBand_t Region = EU868;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
// Auto select MCU <-> radio connections
// If you get an error message when compiling, it may be that the
// pinmap could not be determined - see the notes for more info
// Adafruit
#if defined(ARDUINO_SAMD_FEATHER_M0)
#pragma message ("Adafruit Feather M0 with RFM95")
#pragma message ("Link required on board")
SX1276 radio = new Module(8, 3, 4, 6);
// LilyGo
#elif defined(ARDUINO_TTGO_LORA32_V1)
#pragma message ("TTGO LoRa32 v1 - no Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TTGO_LORA32_V2)
#pragma error ("ARDUINO_TTGO_LORA32_V2 awaiting pin map")
#elif defined(ARDUINO_TTGO_LoRa32_v21new) // T3_V1.6.1
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1262)
#pragma error ("ARDUINO_TBEAM_USE_RADIO_SX1262 awaiting pin map")
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1276)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 23, 33);
// Heltec
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
#pragma error ("ARDUINO_HELTEC_WIFI_LORA_32 awaiting pin map")
#elif defined(ARDUINO_heltec_wifi_kit_32_V2)
#pragma message ("ARDUINO_heltec_wifi_kit_32_V2 awaiting pin map")
SX1276 radio = new Module(18, 26, 14, 35);
#elif defined(ARDUINO_heltec_wifi_kit_32_V3)
#pragma message ("Using Heltec WiFi LoRa32 v3 - Display + USB-C")
SX1262 radio = new Module(8, 14, 12, 13);
#elif defined(ARDUINO_CUBECELL_BOARD)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE);
#elif defined(ARDUINO_CUBECELL_BOARD_V2)
#pragma error ("ARDUINO_CUBECELL_BOARD_V2 awaiting pin map")
#else
#pragma message ("Unknown board - no automagic pinmap available")
// SX1262 pin order: Module(NSS/CS, DIO1, RESET, BUSY);
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 pin order: Module(NSS/CS, DIO0, RESET, DIO1);
// SX1278 radio = new Module(10, 2, 9, 3);
#endif
// Copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
// Create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);
// Helper function to display any issues
void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) {
if (isFail) {
Serial.print(message);
Serial.print("(");
Serial.print(state);
Serial.println(")");
while (Freeze);
}
}
// Helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
for (uint16_t c; c < len; c++) {
Serial.printf("%02X", buffer[c]);
}
Serial.println();
}
#endif

Wyświetl plik

@ -12,7 +12,7 @@ void setup() {
debug(state != RADIOLIB_ERR_NONE, F("Initalise radio failed"), state, true);
Serial.println(F("Join ('login') to the LoRaWAN Network"));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, true);
debug(state < RADIOLIB_ERR_NONE, F("Join failed"), state, true);
Serial.println(F("Ready!\n"));
@ -37,5 +37,5 @@ void loop() {
debug((state != RADIOLIB_ERR_RX_TIMEOUT) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false);
// Wait until next uplink - observing legal & TTN FUP constraints
delay(uplinkInterval);
delay(uplinkIntervalSeconds * 1000UL);
}

Wyświetl plik

@ -0,0 +1,130 @@
#ifndef _CONFIG_H
#define _CONFIG_H
#include <RadioLib.h>
// How often to send an uplink - consider legal & FUP constraints - see notes
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
// JoinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
// The Device EUI & two keys can be generated on the TTN console
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
// For the curious, the #ifndef blocks allow for automated testing &/or you can
// put your EUI & keys in to your platformio.ini - see wiki for more tips
// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500
const LoRaWANBand_t Region = EU868;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
// Auto select MCU <-> radio connections
// If you get an error message when compiling, it may be that the
// pinmap could not be determined - see the notes for more info
// Adafruit
#if defined(ARDUINO_SAMD_FEATHER_M0)
#pragma message ("Adafruit Feather M0 with RFM95")
#pragma message ("Link required on board")
SX1276 radio = new Module(8, 3, 4, 6);
// LilyGo
#elif defined(ARDUINO_TTGO_LORA32_V1)
#pragma message ("TTGO LoRa32 v1 - no Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TTGO_LORA32_V2)
#pragma error ("ARDUINO_TTGO_LORA32_V2 awaiting pin map")
#elif defined(ARDUINO_TTGO_LoRa32_v21new) // T3_V1.6.1
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 14, 33);
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1262)
#pragma error ("ARDUINO_TBEAM_USE_RADIO_SX1262 awaiting pin map")
#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1276)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 23, 33);
// Heltec
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
#pragma error ("ARDUINO_HELTEC_WIFI_LORA_32 awaiting pin map")
#elif defined(ARDUINO_heltec_wifi_kit_32_V2)
#pragma message ("ARDUINO_heltec_wifi_kit_32_V2 awaiting pin map")
SX1276 radio = new Module(18, 26, 14, 35);
#elif defined(ARDUINO_heltec_wifi_kit_32_V3)
#pragma message ("Using Heltec WiFi LoRa32 v3 - Display + USB-C")
SX1262 radio = new Module(8, 14, 12, 13);
#elif defined(ARDUINO_CUBECELL_BOARD)
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE);
#elif defined(ARDUINO_CUBECELL_BOARD_V2)
#pragma error ("ARDUINO_CUBECELL_BOARD_V2 awaiting pin map")
#else
#pragma message ("Unknown board - no automagic pinmap available")
// SX1262 pin order: Module(NSS/CS, DIO1, RESET, BUSY);
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 pin order: Module(NSS/CS, DIO0, RESET, DIO1);
// SX1278 radio = new Module(10, 2, 9, 3);
#endif
// Copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
// Create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);
// Helper function to display any issues
void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) {
if (isFail) {
Serial.print(message);
Serial.print("(");
Serial.print(state);
Serial.println(")");
while (Freeze);
}
}
// Helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
for (uint16_t c; c < len; c++) {
Serial.printf("%02X", buffer[c]);
}
Serial.println();
}
#endif

Wyświetl plik

@ -1,85 +0,0 @@
#include <RadioLib.h>
// How often to send an uplink - consider legal & FUP constraints - see notes
uint32_t uplinkInterval = 3 * 60 * 1000; // minutes x seconds x milliseconds
uint64_t joinEUI = 0x0000000000000000;
uint64_t devEUI = 0x0000000000000000;
uint8_t appKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t nwkKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// Regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500
const LoRaWANBand_t Region = EU868;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
// Auto select MCU <-> radio connections
// If you get an error message when compiling, it may be that the
// pinmap could not be determined - see the notes for more info
#if defined(ARDUINO_TTGO_LORA32_V1)
#pragma message ("TTGO LoRa32 v1 - no Display")
SX1276 radio = new Module(18, 26, 14, 33);
// #elif defined(ARDUINO_TTGO_LORA32_V2)
// #pragma error ("ARDUINO_TTGO_LORA32_V2 awaiting pin map")
#elif defined(ARDUINO_TTGO_LoRa32_v21new) // T3_V1.6.1
#pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
SX1276 radio = new Module(18, 26, 14, 33);
// #elif defined(ARDUINO_TBEAM_USE_RADIO_SX1262)
// #pragma error ("ARDUINO_TBEAM_USE_RADIO_SX1262 awaiting pin map")
// #elif defined(ARDUINO_TBEAM_USE_RADIO_SX1276)
// #pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
// SX1276 radio = new Module(18, 26, 23, 33);
// #elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
// #pragma error ("ARDUINO_HELTEC_WIFI_LORA_32 awaiting pin map")
#elif defined(ARDUINO_heltec_wifi_kit_32_V2)
#pragma message ("ARDUINO_heltec_wifi_kit_32_V2 awaiting pin map")
SX1276 radio = new Module(18, 26, 14, 35);
#elif defined(ARDUINO_heltec_wifi_kit_32_V3)
#pragma message ("Using Heltec WiFi LoRa32 v3 - Display + USB-C")
SX1262 radio = new Module(8, 14, 12, 13);
// #elif defined(ARDUINO_CUBECELL_BOARD)
// #pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
// SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE);
// #elif defined(ARDUINO_CUBECELL_BOARD_V2)
// #pragma error ("ARDUINO_CUBECELL_BOARD_V2 awaiting pin map")
#elif defined(ARDUINO_SAMD_FEATHER_M0)
#pragma message ("Adafruit Feather M0 with RFM95")
#pragma message ("Link required on board")
SX1276 radio = new Module(8, 3, 4, 6);
#else
#pragma message ("Unknown board - no pinmap")
SX1262 radio = new Module(8, 14, 12, 13);
#endif
LoRaWANNode node(&radio, &Region, subBand);
// Helper function to display any issues
void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) {
if (isFail) {
Serial.print(message);
Serial.print("(");
Serial.print(state);
Serial.println(")");
while (Freeze);
}
}

Wyświetl plik

@ -42,6 +42,9 @@ volatile bool operationDone = false;
// is transmitted or received by the module
// IMPORTANT: this function MUST be 'void' type
// and MUST NOT have any arguments!
#if defined(ESP8266) || defined(ESP32)
ICACHE_RAM_ATTR
#endif
void setFlag(void) {
// we sent or received a packet, set the flag
operationDone = true;

Wyświetl plik

@ -39,6 +39,9 @@ volatile bool operationDone = false;
// is transmitted or received by the module
// IMPORTANT: this function MUST be 'void' type
// and MUST NOT have any arguments!
#if defined(ESP8266) || defined(ESP32)
ICACHE_RAM_ATTR
#endif
void setFlag(void) {
// we sent or received packet, set the flag
operationDone = true;

11
idf_component.yml 100644
Wyświetl plik

@ -0,0 +1,11 @@
version: "6.4.2"
description: "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.) and other protocols (Pagers, LoRaWAN)."
tags: "radio, communication, morse, cc1101, aprs, sx1276, sx1278, sx1272, rtty, ax25, afsk, nrf24, rfm96, sx1231, rfm96, rfm98, sstv, sx1278, sx1272, sx1276, sx1280, sx1281, sx1282, sx1261, sx1262, sx1268, si4432, rfm22, llcc68, pager, pocsag, lorawan"
url: "https://github.com/jgromes/RadioLib"
repository: "https://github.com/jgromes/RadioLib.git"
license: "MIT"
dependencies:
# Required IDF version
idf: ">=4.1"
maintainers:
"Jan Gromeš <gromes.jan@gmail.com>"

Wyświetl plik

@ -293,6 +293,10 @@ setModem KEYWORD2
# LoRaWAN
wipe KEYWORD2
getBufferNonces KEYWORD2
setBufferNonces KEYWORD2
getBufferSession KEYWORD2
setBufferSession KEYWORD2
restore KEYWORD2
beginOTAA KEYWORD2
beginABP KEYWORD2
@ -426,9 +430,10 @@ RADIOLIB_ERR_INVALID_CHANNEL LITERAL1
RADIOLIB_ERR_INVALID_CID LITERAL1
RADIOLIB_ERR_UPLINK_UNAVAILABLE LITERAL1
RADIOLIB_ERR_COMMAND_QUEUE_FULL LITERAL1
RADIOLIB_ERR_COMMAND_QUEUE_EMPTY LITERAL1
RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND LITERAL1
RADIOLIB_ERR_JOIN_NONCE_INVALID LITERAL1
RADIOLIB_ERR_N_FCNT_DOWN_INVALID LITERAL1
RADIOLIB_ERR_A_FCNT_DOWN_INVALID LITERAL1
RADIOLIB_ERR_DATA_RATE_INVALID LITERAL1
RADIOLIB_ERR_DATA_RATE_INVALID LITERAL1
RADIOLIB_ERR_DWELL_TIME_EXCEEDED LITERAL1
RADIOLIB_ERR_CHECKSUM_MISMATCH LITERAL1

Wyświetl plik

@ -2,10 +2,6 @@
#if defined(RADIOLIB_BUILD_ARDUINO)
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
#include <EEPROM.h>
#endif
ArduinoHal::ArduinoHal(): RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING), spi(&RADIOLIB_DEFAULT_SPI), initInterface(true) {}
ArduinoHal::ArduinoHal(SPIClass& spi, SPISettings spiSettings): RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING), spi(&spi), spiSettings(spiSettings) {}
@ -118,49 +114,6 @@ void inline ArduinoHal::spiEnd() {
spi->end();
}
void ArduinoHal::readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
EEPROM.begin(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE);
#elif defined(ARDUINO_ARCH_APOLLO3)
EEPROM.init();
#endif
for(size_t i = 0; i < len; i++) {
buff[i] = EEPROM.read(addr + i);
}
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
EEPROM.end();
#endif
#else
(void)addr;
(void)buff;
(void)len;
#endif
}
void ArduinoHal::writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
EEPROM.begin(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE);
#elif defined(ARDUINO_ARCH_APOLLO3)
EEPROM.init();
#endif
for(size_t i = 0; i < len; i++) {
if(EEPROM.read(addr + i) != buff[i]) { // only write if value is new
EEPROM.write(addr + i, buff[i]);
}
}
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
EEPROM.commit();
EEPROM.end();
#endif
#else
(void)addr;
(void)buff;
(void)len;
#endif
}
void inline ArduinoHal::tone(uint32_t pin, unsigned int frequency, unsigned long duration) {
#if !defined(RADIOLIB_TONE_UNSUPPORTED)
if(pin == RADIOLIB_NC) {

Wyświetl plik

@ -51,9 +51,6 @@ class ArduinoHal : public RadioLibHal {
void spiEndTransaction() override;
void spiEnd() override;
void readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) override;
void writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) override;
// implementations of virtual RadioLibHal methods
void init() override;
void term() override;

Wyświetl plik

@ -7,14 +7,18 @@
* Debug output enable.
* Warning: Debug output will slow down the whole system significantly.
* Also, it will result in larger compiled binary.
* Levels: debug - only main info
* verbose - full transcript of all SPI communication
* Levels: basic - only main info
* protocol - mainly LoRaWAN stuff, but other protocols as well
* SPI - full transcript of all SPI communication
*/
#if !defined(RADIOLIB_DEBUG)
#define RADIOLIB_DEBUG (0)
#if !defined(RADIOLIB_DEBUG_BASIC)
#define RADIOLIB_DEBUG_BASIC (0)
#endif
#if !defined(RADIOLIB_VERBOSE)
#define RADIOLIB_VERBOSE (0)
#if !defined(RADIOLIB_DEBUG_PROTOCOL)
#define RADIOLIB_DEBUG_PROTOCOL (0)
#endif
#if !defined(RADIOLIB_DEBUG_SPI)
#define RADIOLIB_DEBUG_SPI (0)
#endif
// set which output port should be used for debug output
@ -100,21 +104,6 @@
#define RADIOLIB_STATIC_ARRAY_SIZE (256)
#endif
// the base address for persistent storage
// some protocols (e.g. LoRaWAN) require a method
// to store some data persistently
// on Arduino, this will use EEPROM, on non-Arduino platform,
// it will use anything provided by the hardware abstraction layer
// RadioLib will place these starting at this address
#if !defined(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE)
#define RADIOLIB_HAL_PERSISTENT_STORAGE_BASE (0)
#endif
// the amount of space allocated to the persistent storage
#if !defined(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE)
#define RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE (0x01C0)
#endif
/*
* Uncomment on boards whose clock runs too slow or too fast
* Set the value according to the following scheme:
@ -234,7 +223,6 @@
#elif defined(SAMD_SERIES)
// Adafruit SAMD boards (M0 and M4)
#define RADIOLIB_PLATFORM "Adafruit SAMD"
#define RADIOLIB_EEPROM_UNSUPPORTED
#elif defined(ARDUINO_ARCH_SAMD)
// Arduino SAMD (Zero, MKR, etc.)
@ -242,18 +230,15 @@
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
#define RADIOLIB_EEPROM_UNSUPPORTED
#elif defined(__SAM3X8E__)
// Arduino Due
#define RADIOLIB_PLATFORM "Arduino Due"
#define RADIOLIB_TONE_UNSUPPORTED
#define RADIOLIB_EEPROM_UNSUPPORTED
#elif (defined(NRF52832_XXAA) || defined(NRF52840_XXAA)) && !defined(ARDUINO_ARDUINO_NANO33BLE)
// Adafruit nRF52 boards
#define RADIOLIB_PLATFORM "Adafruit nRF52"
#define RADIOLIB_EEPROM_UNSUPPORTED
#elif defined(ARDUINO_ARC32_TOOLS)
// Intel Curie
@ -276,7 +261,6 @@
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
#define RADIOLIB_EEPROM_UNSUPPORTED
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
#define RADIOLIB_TONE_UNSUPPORTED
@ -288,7 +272,6 @@
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
#define RADIOLIB_EEPROM_UNSUPPORTED
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
#define RADIOLIB_TONE_UNSUPPORTED
@ -310,7 +293,6 @@
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
#define RADIOLIB_EEPROM_UNSUPPORTED
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
#define RADIOLIB_TONE_UNSUPPORTED
@ -469,23 +451,35 @@
#define RADIOLIB_EXCLUDE_STM32WLX (1)
#endif
// set the global debug mode flag
#if RADIOLIB_DEBUG_BASIC || RADIOLIB_DEBUG_PROTOCOL || RADIOLIB_DEBUG_SPI
#define RADIOLIB_DEBUG (1)
#else
#define RADIOLIB_DEBUG (0)
#endif
#if RADIOLIB_DEBUG
#if defined(RADIOLIB_BUILD_ARDUINO)
#define RADIOLIB_DEBUG_PRINT(...) Module::serialPrintf(__VA_ARGS__)
#define RADIOLIB_DEBUG_PRINTLN(M, ...) Module::serialPrintf(M "\n", ##__VA_ARGS__)
#define RADIOLIB_DEBUG_PRINT_LVL(LEVEL, M, ...) Module::serialPrintf(LEVEL "" M, ##__VA_ARGS__)
#define RADIOLIB_DEBUG_PRINTLN_LVL(LEVEL, M, ...) Module::serialPrintf(LEVEL "" M "\n", ##__VA_ARGS__)
// some platforms do not support printf("%f"), so it has to be done this way
#define RADIOLIB_DEBUG_PRINT_FLOAT(VAL, DECIMALS) RADIOLIB_DEBUG_PORT.print(VAL, DECIMALS)
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL); RADIOLIB_DEBUG_PORT.print(VAL, DECIMALS)
#else
#if !defined(RADIOLIB_DEBUG_PRINT)
#define RADIOLIB_DEBUG_PRINT(...) fprintf(RADIOLIB_DEBUG_PORT, __VA_ARGS__)
#define RADIOLIB_DEBUG_PRINT_LVL(LEVEL, M, ...) fprintf(RADIOLIB_DEBUG_PORT, LEVEL "" M, ##__VA_ARGS__)
#endif
#if !defined(RADIOLIB_DEBUG_PRINTLN)
#define RADIOLIB_DEBUG_PRINTLN(M, ...) fprintf(RADIOLIB_DEBUG_PORT, M "\n", ##__VA_ARGS__)
#define RADIOLIB_DEBUG_PRINTLN_LVL(LEVEL, M, ...) fprintf(RADIOLIB_DEBUG_PORT, LEVEL "" M "\n", ##__VA_ARGS__)
#endif
#define RADIOLIB_DEBUG_PRINT_FLOAT(VAL, DECIMALS) RADIOLIB_DEBUG_PRINT("%.3f", VAL)
#define RADIOLIB_DEBUG_PRINT_FLOAT(LEVEL, VAL, DECIMALS) RADIOLIB_DEBUG_PRINT(LEVEL "%.3f", VAL)
#endif
#define RADIOLIB_DEBUG_HEXDUMP(...) Module::hexdump(__VA_ARGS__)
#define RADIOLIB_DEBUG_HEXDUMP(LEVEL, ...) Module::hexdump(LEVEL, __VA_ARGS__)
#else
#define RADIOLIB_DEBUG_PRINT(...) {}
#define RADIOLIB_DEBUG_PRINTLN(...) {}
@ -493,14 +487,49 @@
#define RADIOLIB_DEBUG_HEXDUMP(...) {}
#endif
#if RADIOLIB_VERBOSE
#define RADIOLIB_VERBOSE_PRINT(...) RADIOLIB_DEBUG_PRINT(__VA_ARGS__)
#define RADIOLIB_VERBOSE_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN(__VA_ARGS__)
#if RADIOLIB_DEBUG_BASIC
#define RADIOLIB_DEBUG_BASIC_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_DBG: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT_LVL("", __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_DBG: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_DBG: ", __VA_ARGS__);
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_DBG: ", __VA_ARGS__);
#else
#define RADIOLIB_VERBOSE_PRINT(...) {}
#define RADIOLIB_VERBOSE_PRINTLN(...) {}
#define RADIOLIB_DEBUG_BASIC_PRINT(...) {}
#define RADIOLIB_DEBUG_BASIC_PRINT_NOTAG(...) {}
#define RADIOLIB_DEBUG_BASIC_PRINTLN(...) {}
#define RADIOLIB_DEBUG_BASIC_PRINT_FLOAT(...) {}
#define RADIOLIB_DEBUG_BASIC_HEXDUMP(...) {}
#endif
#if RADIOLIB_DEBUG_PROTOCOL
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_PRO: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_PRO: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_PRO: ", __VA_ARGS__);
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_PRO: ", __VA_ARGS__);
#else
#define RADIOLIB_DEBUG_PROTOCOL_PRINT(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_PRINTLN(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_PRINT_FLOAT(...) {}
#define RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(...) {}
#endif
#if RADIOLIB_DEBUG_SPI
#define RADIOLIB_DEBUG_SPI_PRINT(...) RADIOLIB_DEBUG_PRINT_LVL("RLB_SPI: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) RADIOLIB_DEBUG_PRINT_LVL("", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) RADIOLIB_DEBUG_PRINTLN_LVL("RLB_SPI: ", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) RADIOLIB_DEBUG_PRINTLN_LVL("", __VA_ARGS__)
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) RADIOLIB_DEBUG_PRINT_FLOAT("RLB_SPI: ", __VA_ARGS__);
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) RADIOLIB_DEBUG_HEXDUMP("RLB_SPI: ", __VA_ARGS__);
#else
#define RADIOLIB_DEBUG_SPI_PRINT(...) {}
#define RADIOLIB_DEBUG_SPI_PRINT_NOTAG(...) {}
#define RADIOLIB_DEBUG_SPI_PRINTLN(...) {}
#define RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG(...) {}
#define RADIOLIB_DEBUG_SPI_PRINT_FLOAT(...) {}
#define RADIOLIB_DEBUG_SPI_HEXDUMP(...) {}
#endif
/*!
\brief A simple assert macro, will return on error.
*/
@ -534,4 +563,4 @@
#define RADIOLIB_VERSION (((RADIOLIB_VERSION_MAJOR) << 24) | ((RADIOLIB_VERSION_MINOR) << 16) | ((RADIOLIB_VERSION_PATCH) << 8) | (RADIOLIB_VERSION_EXTRA))
#endif
#endif

Wyświetl plik

@ -5,7 +5,8 @@
// most commonly, RADIOLIB_EXCLUDE_* macros
// or enabling debug output
//#define RADIOLIB_DEBUG (1)
//#define RADIOLIB_VERBOSE (1)
//#define RADIOLIB_DEBUG_BASIC (1) // basic debugging (e.g. reporting GPIO timeouts or module not being found)
//#define RADIOLIB_DEBUG_PROTOCOL (1) // protocol information (e.g. LoRaWAN internal information)
//#define RADIOLIB_DEBUG_SPI (1) // verbose transcription of all SPI communication - produces large debug logs!
#endif

Wyświetl plik

@ -33,50 +33,3 @@ void RadioLibHal::yield() {
uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) {
return(pin);
}
void RadioLibHal::readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
// these are only needed for some protocols, so it's not needed to have them by default
(void)addr;
(void)buff;
(void)len;
}
void RadioLibHal::writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
// these are only needed for some protocols, so it's not needed to have them by default
(void)addr;
(void)buff;
(void)len;
}
void RadioLibHal::wipePersistentStorage() {
uint8_t dummy = 0;
for(size_t i = 0; i < RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE; i++) {
this->writePersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + i, &dummy, sizeof(uint8_t));
}
}
uint32_t RadioLibHal::getPersistentAddr(uint32_t id) {
return(RadioLibPersistentParamTable[id]);
}
template<typename T>
void RadioLibHal::setPersistentParameter(uint32_t id, T val, uint32_t offset) {
uint8_t *ptr = (uint8_t*)&val;
this->writePersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + RadioLibPersistentParamTable[id] + offset, ptr, sizeof(T));
}
template void RadioLibHal::setPersistentParameter(uint32_t id, uint8_t val, uint32_t offset);
template void RadioLibHal::setPersistentParameter(uint32_t id, uint16_t val, uint32_t offset);
template void RadioLibHal::setPersistentParameter(uint32_t id, uint32_t val, uint32_t offset);
template<typename T>
T RadioLibHal::getPersistentParameter(uint32_t id) {
T val = 0;
uint8_t *ptr = (uint8_t*)&val;
this->readPersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + RadioLibPersistentParamTable[id], ptr, sizeof(T));
return(val);
}
template uint8_t RadioLibHal::getPersistentParameter(uint32_t id);
template uint16_t RadioLibHal::getPersistentParameter(uint32_t id);
template uint32_t RadioLibHal::getPersistentParameter(uint32_t id);

132
src/Hal.h
Wyświetl plik

@ -6,88 +6,6 @@
#include "BuildOpt.h"
#define RADIOLIB_EEPROM_TABLE_VERSION (0x0002)
// list of persistent parameters
enum RADIOLIB_EEPROM_PARAMS {
RADIOLIB_EEPROM_TABLE_VERSION_ID, // table layout version
RADIOLIB_EEPROM_LORAWAN_CLASS_ID, // class A, B or C
RADIOLIB_EEPROM_LORAWAN_MODE_ID, // none, OTAA or ABP
RADIOLIB_EEPROM_LORAWAN_CHECKSUM_ID, // checksum of keys used for device activation
RADIOLIB_EEPROM_LORAWAN_VERSION_ID, // LoRaWAN version
RADIOLIB_EEPROM_LORAWAN_LAST_TIME_ID, // last heard time through DeviceTimeReq or Beacon
RADIOLIB_EEPROM_LORAWAN_DEV_ADDR_ID,
RADIOLIB_EEPROM_LORAWAN_APP_S_KEY_ID,
RADIOLIB_EEPROM_LORAWAN_FNWK_SINT_KEY_ID,
RADIOLIB_EEPROM_LORAWAN_SNWK_SINT_KEY_ID,
RADIOLIB_EEPROM_LORAWAN_NWK_SENC_KEY_ID,
RADIOLIB_EEPROM_LORAWAN_DEV_NONCE_ID,
RADIOLIB_EEPROM_LORAWAN_JOIN_NONCE_ID,
RADIOLIB_EEPROM_LORAWAN_HOME_NET_ID,
RADIOLIB_EEPROM_LORAWAN_A_FCNT_DOWN_ID,
RADIOLIB_EEPROM_LORAWAN_N_FCNT_DOWN_ID,
RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_UP_ID,
RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_DOWN_ID,
RADIOLIB_EEPROM_LORAWAN_ADR_FCNT_ID,
RADIOLIB_EEPROM_LORAWAN_RJ_COUNT0_ID,
RADIOLIB_EEPROM_LORAWAN_RJ_COUNT1_ID,
RADIOLIB_EEPROM_LORAWAN_FCNT_UP_ID,
RADIOLIB_EEPROM_LORAWAN_LINK_ADR_ID,
RADIOLIB_EEPROM_LORAWAN_DUTY_CYCLE_ID,
RADIOLIB_EEPROM_LORAWAN_RX_PARAM_SETUP_ID,
RADIOLIB_EEPROM_LORAWAN_RX_TIMING_SETUP_ID,
RADIOLIB_EEPROM_LORAWAN_TX_PARAM_SETUP_ID,
RADIOLIB_EEPROM_LORAWAN_ADR_PARAM_SETUP_ID,
RADIOLIB_EEPROM_LORAWAN_REJOIN_PARAM_SETUP_ID,
RADIOLIB_EEPROM_LORAWAN_BEACON_FREQ_ID,
RADIOLIB_EEPROM_LORAWAN_PING_SLOT_CHANNEL_ID,
RADIOLIB_EEPROM_LORAWAN_PERIODICITY_ID,
RADIOLIB_EEPROM_LORAWAN_NUM_ADR_MASKS_ID,
RADIOLIB_EEPROM_LORAWAN_MAC_QUEUE_UL_ID,
RADIOLIB_EEPROM_LORAWAN_UL_CHANNELS_ID,
RADIOLIB_EEPROM_LORAWAN_DL_CHANNELS_ID
};
static const uint32_t RadioLibPersistentParamTable[] = {
0x00, // RADIOLIB_EEPROM_TABLE_VERSION_ID
0x02, // RADIOLIB_EEPROM_LORAWAN_CLASS_ID
0x03, // RADIOLIB_EEPROM_LORAWAN_MODE_ID
0x05, // RADIOLIB_EEPROM_LORAWAN_CHECKSUM_ID
0x07, // RADIOLIB_EEPROM_LORAWAN_VERSION_ID
0x08, // RADIOLIB_EEPROM_LORAWAN_LAST_TIME_ID
0x0C, // RADIOLIB_EEPROM_LORAWAN_DEV_ADDR_ID
0x10, // RADIOLIB_EEPROM_LORAWAN_APP_S_KEY_ID
0x20, // RADIOLIB_EEPROM_LORAWAN_FNWK_SINT_KEY_ID
0x30, // RADIOLIB_EEPROM_LORAWAN_SNWK_SINT_KEY_ID
0x40, // RADIOLIB_EEPROM_LORAWAN_NWK_SENC_KEY_ID
0x50, // RADIOLIB_EEPROM_LORAWAN_DEV_NONCE_ID
0x54, // RADIOLIB_EEPROM_LORAWAN_JOIN_NONCE_ID
0x58, // RADIOLIB_EEPROM_LORAWAN_HOME_NET_ID
0x5C, // RADIOLIB_EEPROM_LORAWAN_A_FCNT_DOWN_ID
0x60, // RADIOLIB_EEPROM_LORAWAN_N_FCNT_DOWN_ID
0x64, // RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_UP_ID
0x68, // RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_DOWN_ID
0x6C, // RADIOLIB_EEPROM_LORAWAN_ADR_FCNT_ID
0x70, // RADIOLIB_EEPROM_LORAWAN_RJ_COUNT0_ID
0x72, // RADIOLIB_EEPROM_LORAWAN_RJ_COUNT1_ID
0x74, // RADIOLIB_EEPROM_LORAWAN_FCNT_UP_ID
0xA0, // RADIOLIB_EEPROM_LORAWAN_LINK_ADR_ID
0xA4, // RADIOLIB_EEPROM_LORAWAN_DUTY_CYCLE_ID
0xA5, // RADIOLIB_EEPROM_LORAWAN_RX_PARAM_SETUP_ID
0xA9, // RADIOLIB_EEPROM_LORAWAN_RX_TIMING_SETUP_ID
0xAA, // RADIOLIB_EEPROM_LORAWAN_TX_PARAM_SETUP_ID
0xAB, // RADIOLIB_EEPROM_LORAWAN_ADR_PARAM_SETUP_ID
0xAC, // RADIOLIB_EEPROM_LORAWAN_REJOIN_PARAM_SETUP_ID
0xAD, // RADIOLIB_EEPROM_LORAWAN_BEACON_FREQ_ID
0xB0, // RADIOLIB_EEPROM_LORAWAN_PING_SLOT_CHANNEL_ID
0xB4, // RADIOLIB_EEPROM_LORAWAN_PERIODICITY_ID
0xB5, // RADIOLIB_EEPROM_LORAWAN_NUM_ADR_MASKS_ID
0xB6, // RADIOLIB_EEPROM_LORAWAN_MAC_QUEUE_UL_ID
0x0100, // RADIOLIB_EEPROM_LORAWAN_UL_CHANNELS_ID
0x0180, // RADIOLIB_EEPROM_LORAWAN_DL_CHANNELS_ID
0x01C0, // end
};
/*!
\class RadioLibHal
\brief Hardware abstraction library base interface.
@ -289,56 +207,6 @@ class RadioLibHal {
\returns The interrupt number of a given pin.
*/
virtual uint32_t pinToInterrupt(uint32_t pin);
/*!
\brief Method to read from persistent storage (e.g. EEPROM).
\param addr Address to start reading at.
\param buff Buffer to read into.
\param len Number of bytes to read.
*/
virtual void readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len);
/*!
\brief Method to write to persistent storage (e.g. EEPROM).
\param addr Address to start writing to.
\param buff Buffer to write.
\param len Number of bytes to write.
*/
virtual void writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len);
/*!
\brief Method to wipe the persistent storage by writing to 0.
Will write at most RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE bytes.
*/
void wipePersistentStorage();
/*!
\brief Method to convert from persistent parameter ID to its physical address.
\param id Parameter ID.
\returns Parameter physical address.
*/
uint32_t getPersistentAddr(uint32_t id);
/*!
\brief Method to set arbitrary parameter to persistent storage.
This method DOES NOT perform any endianness conversion, so the value
will be stored in the system endian!
\param id Parameter ID to save at.
\param val Value to set.
\param offset An additional offset added to the address.
*/
template<typename T>
void setPersistentParameter(uint32_t id, T val, uint32_t offset = 0);
/*!
\brief Method to get arbitrary parameter from persistent storage.
This method DOES NOT perform any endianness conversion, so the value
will be retrieved in the system endian!
\param id Parameter ID to load from.
\returns The loaded value.
*/
template<typename T>
T getPersistentParameter(uint32_t id);
};
#endif

Wyświetl plik

@ -44,10 +44,10 @@ void Module::init() {
this->hal->init();
this->hal->pinMode(csPin, this->hal->GpioModeOutput);
this->hal->digitalWrite(csPin, this->hal->GpioLevelHigh);
RADIOLIB_DEBUG_PRINTLN("\nRadioLib Debug Info");
RADIOLIB_DEBUG_PRINTLN("Version: %d.%d.%d.%d", RADIOLIB_VERSION_MAJOR, RADIOLIB_VERSION_MINOR, RADIOLIB_VERSION_PATCH, RADIOLIB_VERSION_EXTRA);
RADIOLIB_DEBUG_PRINTLN("Platform: " RADIOLIB_PLATFORM);
RADIOLIB_DEBUG_PRINTLN("Compiled: " __DATE__ " " __TIME__ "\n");
RADIOLIB_DEBUG_BASIC_PRINTLN("RadioLib Debug Info");
RADIOLIB_DEBUG_BASIC_PRINTLN("Version: %d.%d.%d.%d", RADIOLIB_VERSION_MAJOR, RADIOLIB_VERSION_MINOR, RADIOLIB_VERSION_PATCH, RADIOLIB_VERSION_EXTRA);
RADIOLIB_DEBUG_BASIC_PRINTLN("Platform: " RADIOLIB_PLATFORM);
RADIOLIB_DEBUG_BASIC_PRINTLN("Compiled: " __DATE__ " " __TIME__ "\n");
}
void Module::term() {
@ -89,14 +89,14 @@ int16_t Module::SPIsetRegValue(uint16_t reg, uint8_t value, uint8_t msb, uint8_t
}
// check failed, print debug info
RADIOLIB_DEBUG_PRINTLN();
RADIOLIB_DEBUG_PRINTLN("address:\t0x%X", reg);
RADIOLIB_DEBUG_PRINTLN("bits:\t\t%d %d", msb, lsb);
RADIOLIB_DEBUG_PRINTLN("value:\t\t0x%X", value);
RADIOLIB_DEBUG_PRINTLN("current:\t0x%X", currentValue);
RADIOLIB_DEBUG_PRINTLN("mask:\t\t0x%X", mask);
RADIOLIB_DEBUG_PRINTLN("new:\t\t0x%X", newValue);
RADIOLIB_DEBUG_PRINTLN("read:\t\t0x%X", readValue);
RADIOLIB_DEBUG_SPI_PRINTLN();
RADIOLIB_DEBUG_SPI_PRINTLN("address:\t0x%X", reg);
RADIOLIB_DEBUG_SPI_PRINTLN("bits:\t\t%d %d", msb, lsb);
RADIOLIB_DEBUG_SPI_PRINTLN("value:\t\t0x%X", value);
RADIOLIB_DEBUG_SPI_PRINTLN("current:\t0x%X", currentValue);
RADIOLIB_DEBUG_SPI_PRINTLN("mask:\t\t0x%X", mask);
RADIOLIB_DEBUG_SPI_PRINTLN("new:\t\t0x%X", newValue);
RADIOLIB_DEBUG_SPI_PRINTLN("read:\t\t0x%X", readValue);
return(RADIOLIB_ERR_SPI_WRITE_FAILED);
#else
@ -182,19 +182,19 @@ void Module::SPItransfer(uint8_t cmd, uint16_t reg, uint8_t* dataOut, uint8_t* d
}
// print debug information
#if RADIOLIB_VERBOSE
#if RADIOLIB_DEBUG_SPI
uint8_t* debugBuffPtr = NULL;
if(cmd == SPIwriteCommand) {
RADIOLIB_VERBOSE_PRINT("W\t%X\t", reg);
RADIOLIB_DEBUG_SPI_PRINT("W\t%X\t", reg);
debugBuffPtr = &buffOut[this->SPIaddrWidth/8];
} else if(cmd == SPIreadCommand) {
RADIOLIB_VERBOSE_PRINT("R\t%X\t", reg);
RADIOLIB_DEBUG_SPI_PRINT("R\t%X\t", reg);
debugBuffPtr = &buffIn[this->SPIaddrWidth/8];
}
for(size_t n = 0; n < numBytes; n++) {
RADIOLIB_VERBOSE_PRINT("%X\t", debugBuffPtr[n]);
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", debugBuffPtr[n]);
}
RADIOLIB_VERBOSE_PRINTLN();
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
#endif
#if !RADIOLIB_STATIC_ONLY
@ -291,7 +291,7 @@ int16_t Module::SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint
while(this->hal->digitalRead(this->gpioPin)) {
this->hal->yield();
if(this->hal->millis() - start >= timeout) {
RADIOLIB_DEBUG_PRINTLN("GPIO pre-transfer timeout, is it connected?");
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO pre-transfer timeout, is it connected?");
#if !RADIOLIB_STATIC_ONLY
delete[] buffOut;
delete[] buffIn;
@ -318,7 +318,7 @@ int16_t Module::SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint
while(this->hal->digitalRead(this->gpioPin)) {
this->hal->yield();
if(this->hal->millis() - start >= timeout) {
RADIOLIB_DEBUG_PRINTLN("GPIO post-transfer timeout, is it connected?");
RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO post-transfer timeout, is it connected?");
#if !RADIOLIB_STATIC_ONLY
delete[] buffOut;
delete[] buffIn;
@ -342,31 +342,34 @@ int16_t Module::SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint
}
// print debug information
#if RADIOLIB_VERBOSE
#if RADIOLIB_DEBUG_SPI
// print command byte(s)
RADIOLIB_VERBOSE_PRINT("CMD");
RADIOLIB_DEBUG_SPI_PRINT("CMD");
if(write) {
RADIOLIB_VERBOSE_PRINT("W\t");
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("W\t");
} else {
RADIOLIB_VERBOSE_PRINT("R\t");
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("R\t");
}
size_t n = 0;
for(; n < cmdLen; n++) {
RADIOLIB_VERBOSE_PRINT("%X\t", cmd[n]);
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", cmd[n]);
}
RADIOLIB_VERBOSE_PRINTLN();
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
// print data bytes
RADIOLIB_VERBOSE_PRINT("SI\t");
RADIOLIB_DEBUG_SPI_PRINT("SI\t");
for(n = 0; n < cmdLen; n++) {
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("\t");
}
for(; n < buffLen; n++) {
RADIOLIB_VERBOSE_PRINT("%X\t", buffOut[n]);
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffOut[n]);
}
RADIOLIB_VERBOSE_PRINTLN();
RADIOLIB_VERBOSE_PRINT("SO\t");
for(n = cmdLen; n < buffLen; n++) {
RADIOLIB_VERBOSE_PRINT("%X\t", buffIn[n]);
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
RADIOLIB_DEBUG_SPI_PRINT("SO\t");
for(n = 0; n < buffLen; n++) {
RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffIn[n]);
}
RADIOLIB_VERBOSE_PRINTLN();
RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG();
#endif
#if !RADIOLIB_STATIC_ONLY
@ -404,7 +407,7 @@ uint32_t Module::reflect(uint32_t in, uint8_t bits) {
}
#if RADIOLIB_DEBUG
void Module::hexdump(uint8_t* data, size_t len, uint32_t offset, uint8_t width, bool be) {
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];
@ -443,20 +446,23 @@ void Module::hexdump(uint8_t* data, size_t len, uint32_t offset, uint8_t width,
for(size_t j = line_len; j < 16; j++) {
sprintf(&str[58 + j], " ");
}
if(level) {
RADIOLIB_DEBUG_PRINT(level);
}
RADIOLIB_DEBUG_PRINT(str);
RADIOLIB_DEBUG_PRINTLN();
rem_len -= 16;
}
}
void Module::regdump(uint16_t start, size_t len) {
void Module::regdump(const char* level, uint16_t start, size_t len) {
#if RADIOLIB_STATIC_ONLY
uint8_t buff[RADIOLIB_STATIC_ARRAY_SIZE];
#else
uint8_t* buff = new uint8_t[len];
#endif
SPIreadRegisterBurst(start, len, buff);
hexdump(buff, len, start);
hexdump(level, buff, len, start);
#if !RADIOLIB_STATIC_ONLY
delete[] buff;
#endif

Wyświetl plik

@ -471,19 +471,21 @@ class Module {
#if RADIOLIB_DEBUG
/*!
\brief Function to dump data as hex into the debug port.
\param level RadioLib debug level, set to NULL to not print.
\param data Data to dump.
\param len Number of bytes to dump.
\param width Word width (1 for uint8_t, 2 for uint16_t, 4 for uint32_t).
\param be Print multi-byte data as big endian. Defaults to false.
*/
static void hexdump(uint8_t* data, size_t len, uint32_t offset = 0, uint8_t width = 1, bool be = false);
static void hexdump(const char* level, uint8_t* data, size_t len, uint32_t offset = 0, uint8_t width = 1, bool be = false);
/*!
\brief Function to dump device registers as hex into the debug port.
\param level RadioLib debug level, set to NULL to not print.
\param start First address to dump.
\param len Number of bytes to dump.
*/
void regdump(uint16_t start, size_t len);
void regdump(const char* level, uint16_t start, size_t len);
#endif
#if RADIOLIB_DEBUG and defined(RADIOLIB_BUILD_ARDUINO)

Wyświetl plik

@ -528,35 +528,35 @@
*/
#define RADIOLIB_ERR_COMMAND_QUEUE_FULL (-1109)
/*!
\brief Unable to pop existing MAC command because the queue is empty.
*/
#define RADIOLIB_ERR_COMMAND_QUEUE_EMPTY (-1110)
/*!
\brief Unable to delete MAC command because it was not found in the queue.
*/
#define RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND (-1111)
#define RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND (-1110)
/*!
\brief Unable to join network because JoinNonce is not higher than saved value.
*/
#define RADIOLIB_ERR_JOIN_NONCE_INVALID (-1112)
#define RADIOLIB_ERR_JOIN_NONCE_INVALID (-1111)
/*!
\brief Received downlink Network frame counter is invalid (lower than last heard value).
*/
#define RADIOLIB_ERR_N_FCNT_DOWN_INVALID (-1113)
#define RADIOLIB_ERR_N_FCNT_DOWN_INVALID (-1112)
/*!
\brief Received downlink Application frame counter is invalid (lower than last heard value).
*/
#define RADIOLIB_ERR_A_FCNT_DOWN_INVALID (-1114)
#define RADIOLIB_ERR_A_FCNT_DOWN_INVALID (-1113)
/*!
\brief Uplink payload length at this datarate exceeds the active dwell time limitations.
*/
#define RADIOLIB_ERR_DWELL_TIME_EXCEEDED (-1115)
#define RADIOLIB_ERR_DWELL_TIME_EXCEEDED (-1114)
/*!
\brief The buffer integrity check did not match the supplied checksum value.
*/
#define RADIOLIB_ERR_CHECKSUM_MISMATCH (-1115)
/*!
\}

Wyświetl plik

@ -21,18 +21,18 @@ int16_t CC1101::begin(float freq, float br, float freqDev, float rxBw, int8_t pw
if((version == RADIOLIB_CC1101_VERSION_CURRENT) || (version == RADIOLIB_CC1101_VERSION_LEGACY) || (version == RADIOLIB_CC1101_VERSION_CLONE)) {
flagFound = true;
} else {
RADIOLIB_DEBUG_PRINTLN("CC1101 not found! (%d of 10 tries) RADIOLIB_CC1101_REG_VERSION == 0x%04X, expected 0x0004/0x0014", i + 1, version);
RADIOLIB_DEBUG_BASIC_PRINTLN("CC1101 not found! (%d of 10 tries) RADIOLIB_CC1101_REG_VERSION == 0x%04X, expected 0x0004/0x0014", i + 1, version);
this->mod->hal->delay(10);
i++;
}
}
if(!flagFound) {
RADIOLIB_DEBUG_PRINTLN("No CC1101 found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No CC1101 found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
} else {
RADIOLIB_DEBUG_PRINTLN("M\tCC1101");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tCC1101");
}
// configure settings not accessible by API
@ -916,7 +916,6 @@ void CC1101::setRfSwitchTable(const uint32_t (&pins)[Module::RFSWITCH_MAX_PINS],
uint8_t CC1101::randomByte() {
// set mode to Rx
SPIsendCommand(RADIOLIB_CC1101_CMD_RX);
RADIOLIB_DEBUG_PRINTLN("CC1101::randomByte");
// wait a bit for the RSSI reading to stabilise
this->mod->hal->delay(10);
@ -1113,7 +1112,7 @@ void CC1101::SPIsendCommand(uint8_t cmd) {
// stop transfer
this->mod->hal->spiEndTransaction();
this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelHigh);
RADIOLIB_VERBOSE_PRINTLN("CMD\tW\t%02X\t%02X", cmd, status);
RADIOLIB_DEBUG_SPI_PRINTLN("CMD\tW\t%02X\t%02X", cmd, status);
(void)status;
}

Wyświetl plik

@ -599,14 +599,14 @@ class CC1101: public PhysicalLayer {
int16_t standby(uint8_t mode) override;
/*!
\brief Starts direct mode transmission.
\brief Starts synchronous direct mode transmission.
\param frf Raw RF frequency value. Defaults to 0, required for quick frequency shifts in RTTY.
\returns \ref status_codes
*/
int16_t transmitDirect(uint32_t frf = 0) override;
/*!
\brief Starts direct mode reception.
\brief Starts synchronous direct mode reception.
\returns \ref status_codes
*/
int16_t receiveDirect() override;

Wyświetl plik

@ -23,18 +23,18 @@ int16_t RF69::begin(float freq, float br, float freqDev, float rxBw, int8_t pwr,
if(version == RADIOLIB_RF69_CHIP_VERSION) {
flagFound = true;
} else {
RADIOLIB_DEBUG_PRINTLN("RF69 not found! (%d of 10 tries) RADIOLIB_RF69_REG_VERSION == 0x%04X, expected 0x0024", i + 1, version);
RADIOLIB_DEBUG_BASIC_PRINTLN("RF69 not found! (%d of 10 tries) RADIOLIB_RF69_REG_VERSION == 0x%04X, expected 0x0024", i + 1, version);
this->mod->hal->delay(10);
i++;
}
}
if(!flagFound) {
RADIOLIB_DEBUG_PRINTLN("No RF69 found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No RF69 found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
} else {
RADIOLIB_DEBUG_PRINTLN("M\tRF69");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tRF69");
}
// configure settings not accessible by API

Wyświetl plik

@ -21,23 +21,23 @@ int16_t SX1231::begin(float freq, float br, float freqDev, float rxBw, int8_t po
flagFound = true;
this->chipRevision = version;
} else {
RADIOLIB_DEBUG_PRINTLN("SX1231 not found! (%d of 10 tries) RF69_REG_VERSION == 0x%04X, expected 0x0021 / 0x0022 / 0x0023", i + 1, version);
RADIOLIB_DEBUG_BASIC_PRINTLN("SX1231 not found! (%d of 10 tries) RF69_REG_VERSION == 0x%04X, expected 0x0021 / 0x0022 / 0x0023", i + 1, version);
mod->hal->delay(10);
i++;
}
}
if(!flagFound) {
RADIOLIB_DEBUG_PRINTLN("No SX1231 found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No SX1231 found!");
mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_PRINTLN("M\tSX1231");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX1231");
// configure settings not accessible by API
int16_t state = config();
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PRINTLN("M\tRF69");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tRF69");
// configure publicly accessible settings
state = setFrequency(freq);

Wyświetl plik

@ -22,23 +22,23 @@ int16_t SX1233::begin(float freq, float br, float freqDev, float rxBw, int8_t po
flagFound = true;
this->chipRevision = version;
} else {
RADIOLIB_DEBUG_PRINTLN("SX1231 not found! (%d of 10 tries) RF69_REG_VERSION == 0x%04X, expected 0x0021 / 0x0022 / 0x0023", i + 1, version);
RADIOLIB_DEBUG_BASIC_PRINTLN("SX1231 not found! (%d of 10 tries) RF69_REG_VERSION == 0x%04X, expected 0x0021 / 0x0022 / 0x0023", i + 1, version);
mod->hal->delay(10);
i++;
}
}
if(!flagFound) {
RADIOLIB_DEBUG_PRINTLN("No SX1233 found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No SX1233 found!");
mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_PRINTLN("M\tSX1233");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX1233");
// configure settings not accessible by API
int16_t state = config();
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PRINTLN("M\tRF69");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tRF69");
// configure publicly accessible settings
state = setFrequency(freq);

Wyświetl plik

@ -6,6 +6,7 @@
SX126x::SX126x(Module* mod) : PhysicalLayer(RADIOLIB_SX126X_FREQUENCY_STEP_SIZE, RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
this->mod = mod;
this->XTAL = false;
this->standbyXOSC = false;
}
int16_t SX126x::begin(uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) {
@ -22,11 +23,11 @@ int16_t SX126x::begin(uint8_t cr, uint8_t syncWord, uint16_t preambleLength, flo
// try to find the SX126x chip
if(!SX126x::findChip(this->chipType)) {
RADIOLIB_DEBUG_PRINTLN("No SX126x found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No SX126x found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_PRINTLN("M\tSX126x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX126x");
// BW in kHz and SF are required in order to calculate LDRO for setModulationParams
// set the defaults, this will get overwritten later anyway
@ -107,11 +108,11 @@ int16_t SX126x::beginFSK(float br, float freqDev, float rxBw, uint16_t preambleL
// try to find the SX126x chip
if(!SX126x::findChip(this->chipType)) {
RADIOLIB_DEBUG_PRINTLN("No SX126x found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No SX126x found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_PRINTLN("M\tSX126x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX126x");
// initialize configuration variables (will be overwritten during public settings configuration)
this->bitRate = 21333; // 48.0 kbps
@ -246,7 +247,7 @@ int16_t SX126x::transmit(uint8_t* data, size_t len, uint8_t addr) {
return(RADIOLIB_ERR_UNKNOWN);
}
RADIOLIB_DEBUG_PRINTLN("Timeout in %lu us", timeout);
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout);
// start transmission
state = startTransmit(data, len, addr);
@ -295,7 +296,7 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
return(RADIOLIB_ERR_UNKNOWN);
}
RADIOLIB_DEBUG_PRINTLN("Timeout in %lu us", timeout);
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout);
// start reception
uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625);
@ -463,7 +464,7 @@ int16_t SX126x::sleep(bool retainConfig) {
}
int16_t SX126x::standby() {
return(SX126x::standby(RADIOLIB_SX126X_STANDBY_RC));
return(SX126x::standby(this->standbyXOSC ? RADIOLIB_SX126X_STANDBY_XOSC : RADIOLIB_SX126X_STANDBY_RC));
}
int16_t SX126x::standby(uint8_t mode, bool wakeup) {
@ -643,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_PRINTLN("Auto sleep period: %lu", sleepPeriod);
RADIOLIB_DEBUG_BASIC_PRINTLN("Auto sleep period: %lu", 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.
@ -654,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_PRINTLN("Auto wake period: %lu", wakePeriod);
RADIOLIB_DEBUG_BASIC_PRINTLN("Auto wake period: %lu", wakePeriod);
// If our sleep period is shorter than our transition time, just use the standard startReceive
if(sleepPeriod < this->tcxoDelay + 1016) {
@ -1580,10 +1581,10 @@ int16_t SX126x::uploadPatch(const uint32_t* patch, size_t len, bool nonvolatile)
RADIOLIB_ASSERT(state);
// check the version
#if RADIOLIB_DEBUG
#if RADIOLIB_DEBUG_BASIC
char ver_pre[16];
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, (uint8_t*)ver_pre);
RADIOLIB_DEBUG_PRINTLN("Pre-update version string: %s", ver_pre);
RADIOLIB_DEBUG_BASIC_PRINTLN("Pre-update version string: %s", ver_pre);
#endif
// enable patch update
@ -1612,10 +1613,10 @@ int16_t SX126x::uploadPatch(const uint32_t* patch, size_t len, bool nonvolatile)
this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_PRAM_UPDATE, NULL, 0);
// check the version again
#if RADIOLIB_DEBUG
#if RADIOLIB_DEBUG_BASIC
char ver_post[16];
this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, (uint8_t*)ver_post);
RADIOLIB_DEBUG_PRINTLN("Post-update version string: %s", ver_post);
RADIOLIB_DEBUG_BASIC_PRINTLN("Post-update version string: %s", ver_post);
#endif
return(state);
@ -1857,12 +1858,12 @@ int16_t SX126x::calibrateImage(float freqMin, float freqMax) {
int16_t state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE_IMAGE, data, 2);
// if something failed, show the device errors
#if RADIOLIB_DEBUG
#if RADIOLIB_DEBUG_BASIC
if(state != RADIOLIB_ERR_NONE) {
// unless mode is forced to standby, device errors will be 0
standby();
uint16_t errors = getDeviceErrors();
RADIOLIB_DEBUG_PRINTLN("Calibration failed, device errors: 0x%X", errors);
RADIOLIB_DEBUG_BASIC_PRINTLN("Calibration failed, device errors: 0x%X", errors);
}
#endif
return(state);
@ -2086,7 +2087,7 @@ int16_t SX126x::config(uint8_t modem) {
RADIOLIB_ASSERT(state);
// set Rx/Tx fallback mode to STDBY_RC
data[0] = RADIOLIB_SX126X_RX_TX_FALLBACK_MODE_STDBY_RC;
data[0] = this->standbyXOSC ? RADIOLIB_SX126X_RX_TX_FALLBACK_MODE_STDBY_XOSC : RADIOLIB_SX126X_RX_TX_FALLBACK_MODE_STDBY_RC;
state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_RX_TX_FALLBACK_MODE, data, 1);
RADIOLIB_ASSERT(state);
@ -2121,12 +2122,12 @@ int16_t SX126x::config(uint8_t modem) {
state = this->mod->SPIcheckStream();
// if something failed, show the device errors
#if RADIOLIB_DEBUG
#if RADIOLIB_DEBUG_BASIC
if(state != RADIOLIB_ERR_NONE) {
// unless mode is forced to standby, device errors will be 0
standby();
uint16_t errors = getDeviceErrors();
RADIOLIB_DEBUG_PRINTLN("Calibration failed, device errors: 0x%X", errors);
RADIOLIB_DEBUG_BASIC_PRINTLN("Calibration failed, device errors: 0x%X", errors);
}
#endif
@ -2159,15 +2160,15 @@ bool SX126x::findChip(const char* verStr) {
// check version register
if(strncmp(verStr, version, 6) == 0) {
RADIOLIB_DEBUG_PRINTLN("Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:");
RADIOLIB_DEBUG_HEXDUMP((uint8_t*)version, 16, RADIOLIB_SX126X_REG_VERSION_STRING);
RADIOLIB_DEBUG_PRINTLN();
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_PRINTLN();
flagFound = true;
} else {
#if RADIOLIB_DEBUG
RADIOLIB_DEBUG_PRINTLN("SX126x not found! (%d of 10 tries) RADIOLIB_SX126X_REG_VERSION_STRING:", i + 1);
RADIOLIB_DEBUG_HEXDUMP((uint8_t*)version, 16, RADIOLIB_SX126X_REG_VERSION_STRING);
RADIOLIB_DEBUG_PRINTLN("Expected string: %s", verStr);
#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_PRINTLN("Expected string: %s", verStr);
#endif
this->mod->hal->delay(10);
i++;

Wyświetl plik

@ -447,6 +447,11 @@ class SX126x: public PhysicalLayer {
*/
bool XTAL;
/*!
\brief Whether to use XOSC (true) or RC (false) oscillator in standby mode. Defaults to false.
*/
bool standbyXOSC;
// basic methods
/*!

Wyświetl plik

@ -14,11 +14,11 @@ int16_t SX127x::begin(uint8_t* chipVersions, uint8_t numVersions, uint8_t syncWo
// try to find the SX127x chip
if(!SX127x::findChip(chipVersions, numVersions)) {
RADIOLIB_DEBUG_PRINTLN("No SX127x found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No SX127x found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_PRINTLN("M\tSX127x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX127x");
// set mode to standby
int16_t state = standby();
@ -65,11 +65,11 @@ int16_t SX127x::beginFSK(uint8_t* chipVersions, uint8_t numVersions, float freqD
// try to find the SX127x chip
if(!SX127x::findChip(chipVersions, numVersions)) {
RADIOLIB_DEBUG_PRINTLN("No SX127x found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No SX127x found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_PRINTLN("M\tSX127x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX127x");
// set mode to standby
int16_t state = standby();
@ -1554,7 +1554,7 @@ bool SX127x::findChip(uint8_t* vers, uint8_t num) {
}
if(!flagFound) {
RADIOLIB_DEBUG_PRINTLN("SX127x not found! (%d of 10 tries) RADIOLIB_SX127X_REG_VERSION == 0x%04X", i + 1, version);
RADIOLIB_DEBUG_BASIC_PRINTLN("SX127x not found! (%d of 10 tries) RADIOLIB_SX127X_REG_VERSION == 0x%04X", i + 1, version);
this->mod->hal->delay(10);
i++;
}

Wyświetl plik

@ -17,7 +17,7 @@ int16_t SX128x::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
this->mod->SPIstatusCommand = RADIOLIB_SX128X_CMD_GET_STATUS;
this->mod->SPIstreamType = true;
this->mod->SPIparseStatusCb = SPIparseStatus;
RADIOLIB_DEBUG_PRINTLN("M\tSX128x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX128x");
// initialize LoRa modulation variables
this->bandwidthKhz = bw;
@ -78,7 +78,7 @@ int16_t SX128x::beginGFSK(float freq, uint16_t br, float freqDev, int8_t pwr, ui
this->mod->SPIstatusCommand = RADIOLIB_SX128X_CMD_GET_STATUS;
this->mod->SPIstreamType = true;
this->mod->SPIparseStatusCb = SPIparseStatus;
RADIOLIB_DEBUG_PRINTLN("M\tSX128x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX128x");
// initialize GFSK modulation variables
this->bitRateKbps = br;
@ -147,7 +147,7 @@ int16_t SX128x::beginBLE(float freq, uint16_t br, float freqDev, int8_t pwr, uin
this->mod->SPIstatusCommand = RADIOLIB_SX128X_CMD_GET_STATUS;
this->mod->SPIstreamType = true;
this->mod->SPIparseStatusCb = SPIparseStatus;
RADIOLIB_DEBUG_PRINTLN("M\tSX128x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX128x");
// initialize BLE modulation variables
this->bitRateKbps = br;
@ -202,7 +202,7 @@ int16_t SX128x::beginFLRC(float freq, uint16_t br, uint8_t cr, int8_t pwr, uint1
this->mod->SPIstatusCommand = RADIOLIB_SX128X_CMD_GET_STATUS;
this->mod->SPIstreamType = true;
this->mod->SPIparseStatusCb = SPIparseStatus;
RADIOLIB_DEBUG_PRINTLN("M\tSX128x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSX128x");
// initialize FLRC modulation variables
this->bitRateKbps = br;
@ -308,7 +308,7 @@ int16_t SX128x::transmit(uint8_t* data, size_t len, uint8_t addr) {
// calculate timeout (500% of expected time-on-air)
uint32_t timeout = getTimeOnAir(len) * 5;
RADIOLIB_DEBUG_PRINTLN("Timeout in %lu us", timeout);
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout);
// start transmission
state = startTransmit(data, len, addr);
@ -341,7 +341,7 @@ int16_t SX128x::receive(uint8_t* data, size_t len) {
// calculate timeout (1000% of expected time-on-air)
uint32_t timeout = getTimeOnAir(len) * 10;
RADIOLIB_DEBUG_PRINTLN("Timeout in %lu us", timeout);
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu us", timeout);
// start reception
uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625);

Wyświetl plik

@ -9,7 +9,7 @@ int16_t Si4430::begin(float freq, float br, float freqDev, float rxBw, int8_t po
// execute common part
int16_t state = Si443x::begin(br, freqDev, rxBw, preambleLen);
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PRINTLN("M\tSi4430");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSi4430");
// configure publicly accessible settings
state = setFrequency(freq);

Wyświetl plik

@ -9,7 +9,7 @@ int16_t Si4431::begin(float freq, float br, float freqDev, float rxBw, int8_t po
// execute common part
int16_t state = Si443x::begin(br, freqDev, rxBw, preambleLen);
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PRINTLN("M\tSi4431");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSi4431");
// configure publicly accessible settings
state = setFrequency(freq);

Wyświetl plik

@ -9,7 +9,7 @@ int16_t Si4432::begin(float freq, float br, float freqDev, float rxBw, int8_t po
// execute common part
int16_t state = Si443x::begin(br, freqDev, rxBw, preambleLen);
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PRINTLN("M\tSi4432");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSi4432");
// configure publicly accessible settings
state = setFrequency(freq);

Wyświetl plik

@ -15,11 +15,11 @@ int16_t Si443x::begin(float br, float freqDev, float rxBw, uint8_t preambleLen)
// try to find the Si443x chip
if(!Si443x::findChip()) {
RADIOLIB_DEBUG_PRINTLN("No Si443x found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No Si443x found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
} else {
RADIOLIB_DEBUG_PRINTLN("M\tSi443x");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tSi443x");
}
// reset the device
@ -700,7 +700,7 @@ bool Si443x::findChip() {
if(version == RADIOLIB_SI443X_DEVICE_VERSION) {
flagFound = true;
} else {
RADIOLIB_DEBUG_PRINTLN("Si443x not found! (%d of 10 tries) RADIOLIB_SI443X_REG_DEVICE_VERSION == 0x%02X, expected 0x0%X", i + 1, version, RADIOLIB_SI443X_DEVICE_VERSION);
RADIOLIB_DEBUG_BASIC_PRINTLN("Si443x not found! (%d of 10 tries) RADIOLIB_SI443X_REG_DEVICE_VERSION == 0x%02X, expected 0x0%X", i + 1, version, RADIOLIB_SI443X_DEVICE_VERSION);
this->mod->hal->delay(10);
i++;
}
@ -769,9 +769,9 @@ int16_t Si443x::updateClockRecovery() {
uint16_t rxOsr_fixed = (uint16_t)rxOsr;
// print that whole mess
RADIOLIB_DEBUG_PRINTLN("%X\n%X\n%X", bypass, decRate, manch);
RADIOLIB_DEBUG_PRINT_FLOAT(rxOsr, 2);
RADIOLIB_DEBUG_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("%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);
// update oversampling ratio
int16_t state = this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_CLOCK_REC_OFFSET_2, (uint8_t)((rxOsr_fixed & 0x0700) >> 3), 7, 5);

Wyświetl plik

@ -23,11 +23,11 @@ int16_t nRF24::begin(int16_t freq, int16_t dr, int8_t pwr, uint8_t addrWidth) {
// check SPI connection
int16_t val = this->mod->SPIgetRegValue(RADIOLIB_NRF24_REG_SETUP_AW);
if(!((val >= 0) && (val <= 3))) {
RADIOLIB_DEBUG_PRINTLN("No nRF24 found!");
RADIOLIB_DEBUG_BASIC_PRINTLN("No nRF24 found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_PRINTLN("M\tnRF24");
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tnRF24");
// configure settings inaccessible by public API
int16_t state = config();

Wyświetl plik

@ -6,14 +6,14 @@
#include "../../utils/Cryptography.h"
// activation mode
#define RADIOLIB_LORAWAN_MODE_OTAA (0x01AA)
#define RADIOLIB_LORAWAN_MODE_OTAA (0x07AA)
#define RADIOLIB_LORAWAN_MODE_ABP (0x0AB9)
#define RADIOLIB_LORAWAN_MODE_NONE (0x0000)
// operation mode
#define RADIOLIB_LORAWAN_CLASS_A (0x00)
#define RADIOLIB_LORAWAN_CLASS_B (0x01)
#define RADIOLIB_LORAWAN_CLASS_C (0x02)
#define RADIOLIB_LORAWAN_CLASS_A (0x0A)
#define RADIOLIB_LORAWAN_CLASS_B (0x0B)
#define RADIOLIB_LORAWAN_CLASS_C (0x0C)
// preamble format
#define RADIOLIB_LORAWAN_LORA_SYNC_WORD (0x34)
@ -226,6 +226,56 @@ const LoRaWANMacSpec_t MacTable[RADIOLIB_LORAWAN_NUM_MAC_COMMANDS + 1] = {
{ RADIOLIB_LORAWAN_MAC_PROPRIETARY, 5, 0, true }
};
#define RADIOLIB_LORAWAN_NONCES_VERSION_VAL (0x0001)
enum LoRaWANSchemeBase_t {
RADIOLIB_LORAWAN_NONCES_VERSION = 0x00, // 2 bytes
RADIOLIB_LORAWAN_NONCES_MODE = 0x02, // 2 bytes
RADIOLIB_LORAWAN_NONCES_CLASS = 0x04, // 1 byte
RADIOLIB_LORAWAN_NONCES_PLAN = 0x05, // 1 byte
RADIOLIB_LORAWAN_NONCES_CHECKSUM = 0x06, // 2 bytes
RADIOLIB_LORAWAN_NONCES_DEV_NONCE = 0x08, // 2 bytes
RADIOLIB_LORAWAN_NONCES_JOIN_NONCE = 0x0A, // 3 bytes
RADIOLIB_LORAWAN_NONCES_ACTIVE = 0x0D, // 1 byte
RADIOLIB_LORAWAN_NONCES_SIGNATURE = 0x0E, // 2 bytes
RADIOLIB_LORAWAN_NONCES_BUF_SIZE = 0x10 // = 16 bytes
};
enum LoRaWANSchemeSession_t {
RADIOLIB_LORAWAN_SESSION_NWK_SENC_KEY = 0x00, // 16 bytes
RADIOLIB_LORAWAN_SESSION_APP_SKEY = 0x10, // 16 bytes
RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY = 0x20, // 16 bytes
RADIOLIB_LORAWAN_SESSION_SNWK_SINT_KEY = 0x30, // 16 bytes
RADIOLIB_LORAWAN_SESSION_DEV_ADDR = 0x40, // 4 bytes
RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE = 0x44, // 2 bytes
RADIOLIB_LORAWAN_SESSION_A_FCNT_DOWN = 0x46, // 4 bytes
RADIOLIB_LORAWAN_SESSION_CONF_FCNT_UP = 0x4A, // 4 bytes
RADIOLIB_LORAWAN_SESSION_CONF_FCNT_DOWN = 0x4E, // 4 bytes
RADIOLIB_LORAWAN_SESSION_RJ_COUNT0 = 0x52, // 2 bytes
RADIOLIB_LORAWAN_SESSION_RJ_COUNT1 = 0x54, // 2 bytes
RADIOLIB_LORAWAN_SESSION_HOMENET_ID = 0x56, // 4 bytes
RADIOLIB_LORAWAN_SESSION_VERSION = 0x5A, // 1 byte
RADIOLIB_LORAWAN_SESSION_DUTY_CYCLE = 0x5B, // 1 byte
RADIOLIB_LORAWAN_SESSION_RX_PARAM_SETUP = 0x5C, // 4 bytes
RADIOLIB_LORAWAN_SESSION_RX_TIMING_SETUP = 0x60, // 1 byte
RADIOLIB_LORAWAN_SESSION_TX_PARAM_SETUP = 0x61, // 1 byte
RADIOLIB_LORAWAN_SESSION_ADR_PARAM_SETUP = 0x62, // 1 byte
RADIOLIB_LORAWAN_SESSION_REJOIN_PARAM_SETUP = 0x63, // 1 byte
RADIOLIB_LORAWAN_SESSION_BEACON_FREQ = 0x64, // 3 bytes
RADIOLIB_LORAWAN_SESSION_PING_SLOT_CHANNEL = 0x67, // 4 bytes
RADIOLIB_LORAWAN_SESSION_PERIODICITY = 0x6B, // 1 byte
RADIOLIB_LORAWAN_SESSION_LAST_TIME = 0x6C, // 4 bytes
RADIOLIB_LORAWAN_SESSION_UL_CHANNELS = 0x70, // 16*8 bytes
RADIOLIB_LORAWAN_SESSION_DL_CHANNELS = 0xF0, // 16*4 bytes
RADIOLIB_LORAWAN_SESSION_MAC_QUEUE_UL = 0x0130, // 9*8+2 bytes
RADIOLIB_LORAWAN_SESSION_N_FCNT_DOWN = 0x017A, // 4 bytes
RADIOLIB_LORAWAN_SESSION_ADR_FCNT = 0x017E, // 4 bytes
RADIOLIB_LORAWAN_SESSION_LINK_ADR = 0x0182, // 4 bytes
RADIOLIB_LORAWAN_SESSION_FCNT_UP = 0x0186, // 4 bytes
RADIOLIB_LORAWAN_SESSION_SIGNATURE = 0x018A, // 2 bytes
RADIOLIB_LORAWAN_SESSION_BUF_SIZE = 0x018C // 396 bytes
};
/*!
\struct LoRaWANChannelSpan_t
\brief Structure to save information about LoRaWAN channels.
@ -284,6 +334,9 @@ struct LoRaWANChannelSpan_t {
\brief Structure to save information about LoRaWAN band
*/
struct LoRaWANBand_t {
/*! \brief Identier for this band */
uint8_t bandNum;
/*! \brief Whether the channels are fixed per specification, or dynamically allocated through the network (plus defaults) */
uint8_t bandType;
@ -415,7 +468,6 @@ class LoRaWANNode {
*/
LoRaWANNode(PhysicalLayer* phy, const LoRaWANBand_t* band, uint8_t subBand = 0);
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
/*!
\brief Wipe internal persistent parameters.
This will reset all counters and saved variables, so the device will have to rejoin the network.
@ -423,12 +475,36 @@ class LoRaWANNode {
void wipe();
/*!
\brief Restore session by loading information from persistent storage.
\returns \ref status_codes in case of error,
else LoRaWAN session mode (0 = no active session, 0xAA / 170 = OTAA, 0xAB / 171 = ABP)
\brief Returns the pointer to the internal buffer that holds the LW base parameters
\returns Pointer to uint8_t array of size RADIOLIB_LORAWAN_NONCES_BUF_SIZE
*/
int16_t restore();
#endif
uint8_t* getBufferNonces();
/*!
\brief Fill the internal buffer that holds the LW base parameters with a supplied buffer
\param persistentBuffer Buffer that should match the internal format (previously extracted using getBufferNonces)
\returns \ref status_codes
*/
int16_t setBufferNonces(uint8_t* persistentBuffer);
/*!
\brief Returns the pointer to the internal buffer that holds the LW session parameters
\returns Pointer to uint8_t array of size RADIOLIB_LORAWAN_SESSION_BUF_SIZE
*/
uint8_t* getBufferSession();
/*!
\brief Fill the internal buffer that holds the LW session parameters with a supplied buffer
\param persistentBuffer Buffer that should match the internal format (previously extracted using getBufferSession)
\returns \ref status_codes
*/
int16_t setBufferSession(uint8_t* persistentBuffer);
/*!
\brief Restore session by loading information from persistent storage.
\returns \ref status_codes
*/
int16_t restore(uint16_t checkSum, uint16_t lwMode, uint8_t lwClass, uint8_t freqPlan);
/*!
\brief Join network by performing over-the-air activation. By this procedure,
@ -437,12 +513,11 @@ class LoRaWANNode {
\param devEUI 8-byte device identifier.
\param nwkKey Pointer to the network AES-128 key.
\param appKey Pointer to the application AES-128 key.
\param joinDr (OTAA:) The datarate at which to send the join-request; (ABP:) ignored
\param force Set to true to force joining even if previously joined.
\param joinDr The datarate at which to send the join-request and any subsequent uplinks (unless ADR is enabled)
\returns \ref status_codes
*/
int16_t beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey, uint8_t joinDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED, bool force = false);
int16_t beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey, bool force = false, uint8_t joinDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED);
/*!
\brief Join network by performing activation by personalization.
@ -450,19 +525,19 @@ class LoRaWANNode {
\param addr Device address.
\param nwkSKey Pointer to the network session AES-128 key (LoRaWAN 1.0) or MAC command network session key (LoRaWAN 1.1).
\param appSKey Pointer to the application session AES-128 key.
\param fNwkSIntKey Pointer to the network session F key (LoRaWAN 1.1), unused for LoRaWAN 1.0.
\param sNwkSIntKey Pointer to the network session S key (LoRaWAN 1.1), unused for LoRaWAN 1.0.
\param fNwkSIntKey Pointer to the Forwarding network session (LoRaWAN 1.1), unused for LoRaWAN 1.0.
\param sNwkSIntKey Pointer to the Serving network session (LoRaWAN 1.1), unused for LoRaWAN 1.0.
\param force Set to true to force a new session, even if one exists.
\param initialDr The datarate at which to send the first uplink and any subsequent uplinks (unless ADR is enabled)
\returns \ref status_codes
*/
int16_t beginABP(uint32_t addr, uint8_t* nwkSKey, uint8_t* appSKey, uint8_t* fNwkSIntKey = NULL, uint8_t* sNwkSIntKey = NULL, bool force = false);
int16_t beginABP(uint32_t addr, uint8_t* nwkSKey, uint8_t* appSKey, uint8_t* fNwkSIntKey = NULL, uint8_t* sNwkSIntKey = NULL, bool force = false, uint8_t initialDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED);
/*! \brief Whether there is an ongoing session active */
bool isJoined();
/*!
\brief Save the current state of the session.
All variables are compared to what is saved and only the differences are rewritten.
\brief Save the current state of the session to the session buffer.
\returns \ref status_codes
*/
int16_t saveSession();
@ -637,10 +712,9 @@ class LoRaWANNode {
/*!
\brief Set uplink datarate. This should not be used when ADR is enabled.
\param dr Datarate to use for uplinks.
\param saveToEeprom Whether to save this setting to EEPROM or not (default false).
\returns \ref status_codes
*/
int16_t setDatarate(uint8_t drUp, bool saveToEeprom = false);
int16_t setDatarate(uint8_t drUp);
/*!
\brief Toggle ADR to on or off.
@ -686,10 +760,9 @@ class LoRaWANNode {
/*!
\brief Configure TX power of the radio module.
\param txPower Output power during TX mode to be set in dBm.
\param saveToEeprom Whether to save this setting to EEPROM or not (default false).
\returns \ref status_codes
*/
int16_t setTxPower(int8_t txPower, bool saveToEeprom = false);
int16_t setTxPower(int8_t txPower);
/*!
\brief Configures CSMA for LoRaWAN as per TR-13, LoRa Alliance.
@ -732,7 +805,15 @@ class LoRaWANNode {
PhysicalLayer* phyLayer = NULL;
const LoRaWANBand_t* band = NULL;
void beginCommon(uint8_t joinDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED);
static int16_t checkBufferCommon(uint8_t *buffer, uint16_t size);
void beginCommon(uint8_t initialDr);
// a buffer that holds all LW base parameters that should persist at all times!
uint8_t bufferNonces[RADIOLIB_LORAWAN_NONCES_BUF_SIZE] = { 0 };
// a buffer that holds all LW session parameters that preferably persist, but can be afforded to get lost
uint8_t bufferSession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE] = { 0 };
LoRaWANMacCommandQueue_t commandsUp = {
.numCommands = 0,
@ -776,7 +857,7 @@ class LoRaWANNode {
bool FSK = false;
// flag that shows whether the device is joined and there is an ongoing session (none, ABP or OTAA)
uint16_t activeMode = 0;
uint16_t activeMode = RADIOLIB_LORAWAN_MODE_NONE;
// ADR is enabled by default
bool adrEnabled = true;
@ -835,26 +916,6 @@ class LoRaWANNode {
// save the selected sub-band in case this must be restored in ADR control
uint8_t subBand = 0;
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
/*!
\brief Save the current uplink frame counter.
Note that the usable frame counter width is 'only' 30 bits for highly efficient wear-levelling.
*/
void saveFcntUp();
/*!
\brief Restore frame counter for uplinks from persistent storage.
Note that the usable frame counter width is 'only' 30 bits for highly efficient wear-levelling.
*/
void restoreFcntUp();
// set all keys to zero
void clearSession();
// test if saved keys are non-zero
bool isValidSession();
#endif
// wait for, open and listen during Rx1 and Rx2 windows; only performs listening
int16_t downlinkCommon();
@ -901,13 +962,13 @@ class LoRaWANNode {
int16_t deleteMacCommand(uint8_t cid, LoRaWANMacCommandQueue_t* queue, uint8_t* payload = NULL);
// execute mac command, return the number of processed bytes for sequential processing
bool execMacCommand(LoRaWANMacCommand_t* cmd, bool saveToEeprom = true);
bool execMacCommand(LoRaWANMacCommand_t* cmd);
// apply a channel mask to a set of readily defined channels (dynamic bands only)
bool applyChannelMaskDyn(uint8_t chMaskCntl, uint16_t chMask);
// define or delete channels from a fixed set of channels (fixed bands only)
bool applyChannelMaskFix(uint8_t chMaskCntl, uint16_t chMask, bool clear);
bool applyChannelMaskFix(uint8_t chMaskCntl, uint16_t chMask);
// get the payload length for a specific MAC command
uint8_t getMacPayloadLength(uint8_t cid);
@ -922,7 +983,7 @@ class LoRaWANNode {
void processAES(uint8_t* in, size_t len, uint8_t* key, uint8_t* out, uint32_t fcnt, uint8_t dir, uint8_t ctrId, bool counter);
// 16-bit checksum method that takes a uint8_t array of even length and calculates the checksum
static uint16_t checkSum16(uint8_t *key, uint8_t keyLen);
static uint16_t checkSum16(uint8_t *key, uint16_t keyLen);
// network-to-host conversion method - takes data from network packet and converts it to the host endians
template<typename T>

Wyświetl plik

@ -2,7 +2,21 @@
#if !RADIOLIB_EXCLUDE_LORAWAN
enum LoRaWANBandNum_t {
BandNone,
BandEU868,
BandUS915,
BandCN780,
BandEU433,
BandAU915,
BandCN500,
BandAS923,
BandKR920,
BandIN865
};
const LoRaWANBand_t EU868 = {
.bandNum = BandEU868,
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
.powerMax = 16,
@ -48,6 +62,7 @@ const LoRaWANBand_t EU868 = {
};
const LoRaWANBand_t US915 = {
.bandNum = BandUS915,
.bandType = RADIOLIB_LORAWAN_BAND_FIXED,
.payloadLenMax = { 19, 61, 133, 250, 250, 0, 0, 0, 41, 117, 230, 230, 230, 230, 0 },
.powerMax = 30,
@ -114,6 +129,7 @@ const LoRaWANBand_t US915 = {
};
const LoRaWANBand_t CN780 = {
.bandNum = BandCN780,
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 250, 230, 0, 0, 0, 0, 0, 0, 0 },
.powerMax = 12,
@ -159,6 +175,7 @@ const LoRaWANBand_t CN780 = {
};
const LoRaWANBand_t EU433 = {
.bandNum = BandEU433,
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
.powerMax = 12,
@ -204,6 +221,7 @@ const LoRaWANBand_t EU433 = {
};
const LoRaWANBand_t AU915 = {
.bandNum = BandAU915,
.bandType = RADIOLIB_LORAWAN_BAND_FIXED,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 0, 41, 117, 230, 230, 230, 230, 0 },
.powerMax = 30,
@ -270,6 +288,7 @@ const LoRaWANBand_t AU915 = {
};
const LoRaWANBand_t CN500 = {
.bandNum = BandCN500,
.bandType = RADIOLIB_LORAWAN_BAND_FIXED,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
.powerMax = 19,
@ -329,6 +348,7 @@ const LoRaWANBand_t CN500 = {
};
const LoRaWANBand_t AS923 = {
.bandNum = BandAS923,
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
.powerMax = 16,
@ -374,6 +394,7 @@ const LoRaWANBand_t AS923 = {
};
const LoRaWANBand_t KR920 = {
.bandNum = BandKR920,
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
.powerMax = 14,
@ -419,6 +440,7 @@ const LoRaWANBand_t KR920 = {
};
const LoRaWANBand_t IN865 = {
.bandNum = BandIN865,
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
.powerMax = 30,

Wyświetl plik

@ -85,7 +85,7 @@ int MorseClient::read(uint8_t* symbol, uint8_t* len, float low, float high) {
if((pauseLen >= low*(float)letterSpace) && (pauseLen <= high*(float)letterSpace)) {
return(RADIOLIB_MORSE_CHAR_COMPLETE);
} else if(pauseLen > wordSpace) {
RADIOLIB_DEBUG_PRINTLN("\n<space>");
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("\n<space>");
return(RADIOLIB_MORSE_WORD_COMPLETE);
}
@ -96,15 +96,15 @@ int MorseClient::read(uint8_t* symbol, uint8_t* len, float low, float high) {
uint32_t signalLen = mod->hal->millis() - signalStart;
if((signalLen >= low*(float)dotLength) && (signalLen <= high*(float)dotLength)) {
RADIOLIB_DEBUG_PRINT(".");
RADIOLIB_DEBUG_PROTOCOL_PRINT(".");
(*symbol) |= (RADIOLIB_MORSE_DOT << (*len));
(*len)++;
} else if((signalLen >= low*(float)dashLength) && (signalLen <= high*(float)dashLength)) {
RADIOLIB_DEBUG_PRINT("-");
RADIOLIB_DEBUG_PROTOCOL_PRINT("-");
(*symbol) |= (RADIOLIB_MORSE_DASH << (*len));
(*len)++;
} else {
RADIOLIB_DEBUG_PRINTLN("<len=%lums>", signalLen);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("<len=%lums>", signalLen);
}
}
@ -122,7 +122,7 @@ size_t MorseClient::write(uint8_t b) {
// inter-word pause (space)
if(b == ' ') {
RADIOLIB_DEBUG_PRINTLN("space");
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("space");
standby();
mod->waitForMicroseconds(mod->hal->micros(), wordSpace*1000);
return(1);
@ -141,11 +141,11 @@ size_t MorseClient::write(uint8_t b) {
// send dot or dash
if (code & RADIOLIB_MORSE_DASH) {
RADIOLIB_DEBUG_PRINT("-");
RADIOLIB_DEBUG_PROTOCOL_PRINT("-");
transmitDirect(baseFreq, baseFreqHz);
mod->waitForMicroseconds(mod->hal->micros(), dashLength*1000);
} else {
RADIOLIB_DEBUG_PRINT(".");
RADIOLIB_DEBUG_PROTOCOL_PRINT(".");
transmitDirect(baseFreq, baseFreqHz);
mod->waitForMicroseconds(mod->hal->micros(), dotLength*1000);
}
@ -161,7 +161,7 @@ size_t MorseClient::write(uint8_t b) {
// letter space
standby();
mod->waitForMicroseconds(mod->hal->micros(), letterSpace*1000 - dotLength*1000);
RADIOLIB_DEBUG_PRINTLN();
RADIOLIB_DEBUG_PROTOCOL_PRINTLN();
return(1);
}

Wyświetl plik

@ -28,6 +28,9 @@ PagerClient::PagerClient(PhysicalLayer* phy) {
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
readBitInstance = phyLayer;
#endif
filterNumAddresses = 0;
filterAddresses = NULL;
filterMasks = NULL;
}
int16_t PagerClient::begin(float base, uint16_t speed, bool invert, uint16_t shift) {
@ -245,7 +248,24 @@ int16_t PagerClient::startReceive(uint32_t pin, uint32_t addr, uint32_t mask) {
readBitPin = pin;
filterAddr = addr;
filterMask = mask;
filterAddresses = NULL;
filterMasks = NULL;
filterNumAddresses = 0;
return(startReceiveCommon());
}
int16_t PagerClient::startReceive(uint32_t pin, uint32_t *addrs, uint32_t *masks, size_t numAddresses) {
// save the variables
readBitPin = pin;
filterAddr = 0;
filterMask = 0;
filterAddresses = addrs;
filterMasks = masks;
filterNumAddresses = numAddresses;
return(startReceiveCommon());
}
int16_t PagerClient::startReceiveCommon() {
// set the carrier frequency
int16_t state = phyLayer->setFrequency(baseFreq);
RADIOLIB_ASSERT(state);
@ -260,7 +280,7 @@ int16_t PagerClient::startReceive(uint32_t pin, uint32_t addr, uint32_t mask) {
// now set up the direct mode reception
Module* mod = phyLayer->getMod();
mod->hal->pinMode(pin, mod->hal->GpioModeInput);
mod->hal->pinMode(readBitPin, mod->hal->GpioModeInput);
// set direct sync word to the frame sync word
// the logic here is inverted, because modules like SX1278
@ -356,8 +376,7 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) {
// should be an address code word, extract the address
uint32_t addr_found = ((cw & RADIOLIB_PAGER_ADDRESS_BITS_MASK) >> (RADIOLIB_PAGER_ADDRESS_POS - 3)) | (framePos/2);
if((addr_found & filterMask) == (filterAddr & filterMask)) {
// we have a match!
if (addressMatched(addr_found)) {
match = true;
if(addr) {
*addr = addr_found;
@ -460,6 +479,26 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) {
}
#endif
bool PagerClient::addressMatched(uint32_t addr) {
// check whether to match single or multiple addresses/masks
if(filterNumAddresses == 0) {
return((addr & filterMask) == (filterAddr & filterMask));
}
// multiple addresses, check there are some to match
if((filterAddresses == NULL) || (filterMasks == NULL)) {
return(false);
}
for(size_t i = 0; i < filterNumAddresses; i++) {
if((filterAddresses[i] & filterMasks[i]) == (addr & filterMasks[i])) {
return(true);
}
}
return(false);
}
void PagerClient::write(uint32_t* data, size_t len) {
// write code words from buffer
for(size_t i = 0; i < len; i++) {
@ -515,7 +554,7 @@ uint32_t PagerClient::read() {
codeWord = ~codeWord;
}
RADIOLIB_VERBOSE_PRINTLN("R\t%lX", codeWord);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("R\t%lX", codeWord);
// TODO BCH error correction here
return(codeWord);
}

Wyświetl plik

@ -130,6 +130,16 @@ class PagerClient {
*/
int16_t startReceive(uint32_t pin, uint32_t addr, uint32_t mask = 0xFFFFF);
/*!
\brief Start reception of POCSAG packets for multiple addresses and masks.
\param pin Pin to receive digital data on (e.g., DIO2 for SX127x).
\param addrs Array of addresses to receive.
\param masks Array of address masks to use for filtering. Masks will be applied to corresponding addresses in addr array.
\param numAddress Number of addresses/masks to match.
\returns \ref status_codes
*/
int16_t startReceive(uint32_t pin, uint32_t *addrs, uint32_t *masks, size_t numAddress);
/*!
\brief Get the number of POCSAG batches available in buffer. Limited by the size of direct mode buffer!
\returns Number of available batches.
@ -175,10 +185,15 @@ class PagerClient {
uint16_t bitDuration;
uint32_t filterAddr;
uint32_t filterMask;
uint32_t *filterAddresses;
uint32_t *filterMasks;
size_t filterNumAddresses;
bool inv = false;
void write(uint32_t* data, size_t len);
void write(uint32_t codeWord);
int16_t startReceiveCommon();
bool addressMatched(uint32_t addr);
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
uint32_t read();

Wyświetl plik

@ -413,7 +413,7 @@ void PhysicalLayer::updateDirectBuffer(uint8_t bit) {
this->syncBuffer <<= 1;
this->syncBuffer |= bit;
RADIOLIB_VERBOSE_PRINTLN("S\t%lu", this->syncBuffer);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("S\t%lu", this->syncBuffer);
if((this->syncBuffer & this->directSyncWordMask) == this->directSyncWord) {
this->gotSync = true;
@ -434,7 +434,7 @@ void PhysicalLayer::updateDirectBuffer(uint8_t bit) {
// check complete byte
if(this->bufferBitPos == 8) {
this->buffer[this->bufferWritePos] = Module::reflect(this->buffer[this->bufferWritePos], 8);
RADIOLIB_VERBOSE_PRINTLN("R\t%X", this->buffer[this->bufferWritePos]);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("R\t%X", this->buffer[this->bufferWritePos]);
this->bufferWritePos++;
this->bufferBitPos = 0;