kopia lustrzana https://github.com/jgromes/RadioLib
Porównaj commity
19 Commity
a926d5e13a
...
ff5ade2aa1
Autor | SHA1 | Data |
---|---|---|
HeadBoffin | ff5ade2aa1 | |
Nick McCloud | 5bc97550ec | |
Nick McCloud | 0182a123fb | |
Jan Gromeš | cfc425970c | |
jgromes | 44f6c1d432 | |
StevenCellist | ca2a3073b9 | |
Jan Gromeš | 3d5f05b963 | |
jgromes | 0b11d101aa | |
jgromes | 9fd7db4d13 | |
jgromes | b288485d6c | |
jgromes | 24ffbfc284 | |
jgromes | 4993ac7c9d | |
jgromes | 4ee17cc168 | |
jgromes | 9774a2299b | |
jgromes | cf561733d2 | |
Jan Szumiec | 268e2d704f | |
jgromes | 744834509f | |
jgromes | 10acb6d9ca | |
Nicklas Börjesson | a52920bcb2 |
|
@ -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)).
|
||||
|
|
|
@ -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 [...]
|
||||
|
|
|
@ -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.]
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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: |
|
||||
|
|
|
@ -23,3 +23,6 @@ extras/SX126x_Spectrum_Scan/out/*
|
|||
|
||||
# cmake
|
||||
build/
|
||||
|
||||
# Compote build output
|
||||
dist
|
||||
|
|
|
@ -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!_
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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() {}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>"
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
103
src/BuildOpt.h
103
src/BuildOpt.h
|
@ -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
|
|
@ -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
|
||||
|
|
47
src/Hal.cpp
47
src/Hal.cpp
|
@ -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
132
src/Hal.h
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
/*!
|
||||
\}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Ładowanie…
Reference in New Issue