Merge pull request #1158 from alistair23/alistair/scan-guard

protocol: LoRaWAN: Allow configuring scanGuard
This commit is contained in:
Jan Gromeš 2024-07-13 17:10:01 +02:00 committed by GitHub
commit a93dd1af91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 9 deletions

View file

@ -1187,14 +1187,10 @@ int16_t LoRaWANNode::uplink(uint8_t* data, size_t len, uint8_t fPort, bool isCon
int16_t LoRaWANNode::downlinkCommon() { int16_t LoRaWANNode::downlinkCommon() {
Module* mod = this->phyLayer->getMod(); Module* mod = this->phyLayer->getMod();
// according to the spec, the Rx window must be at least enough time to effectively detect a preamble
// but we pad it a bit on both sides (start and end) to make sure it is wide enough
const RadioLibTime_t scanGuard = 10; // Rx window padding in milliseconds
// check if there are any upcoming Rx windows // check if there are any upcoming Rx windows
// if the Rx1 window has already started, you're too late, because most downlinks happen in Rx1 // if the Rx1 window has already started, you're too late, because most downlinks happen in Rx1
RadioLibTime_t now = mod->hal->millis(); // fix the current timestamp to prevent negative delays RadioLibTime_t now = mod->hal->millis(); // fix the current timestamp to prevent negative delays
if(now > this->rxDelayStart + this->rxDelays[0] - scanGuard) { if(now > this->rxDelayStart + this->rxDelays[0] - this->scanGuard) {
// if between start of Rx1 and end of Rx2, wait until Rx2 closes // if between start of Rx1 and end of Rx2, wait until Rx2 closes
if(now < this->rxDelayStart + this->rxDelays[1]) { if(now < this->rxDelayStart + this->rxDelays[1]) {
mod->hal->delay(this->rxDelays[1] + this->rxDelayStart - now); mod->hal->delay(this->rxDelays[1] + this->rxDelayStart - now);
@ -1220,7 +1216,7 @@ int16_t LoRaWANNode::downlinkCommon() {
downlinkAction = false; downlinkAction = false;
// calculate the Rx timeout // calculate the Rx timeout
RadioLibTime_t timeoutHost = this->phyLayer->getTimeOnAir(0) + 2*scanGuard*1000; RadioLibTime_t timeoutHost = this->phyLayer->getTimeOnAir(0) + 2*this->scanGuard*1000;
RadioLibTime_t timeoutMod = this->phyLayer->calculateRxTimeout(timeoutHost); RadioLibTime_t timeoutMod = this->phyLayer->calculateRxTimeout(timeoutHost);
// wait for the start of the Rx window // wait for the start of the Rx window
@ -1230,8 +1226,8 @@ int16_t LoRaWANNode::downlinkCommon() {
waitLen = this->rxDelays[i]; waitLen = this->rxDelays[i];
} }
// the waiting duration is shortened a bit to cover any possible timing errors // the waiting duration is shortened a bit to cover any possible timing errors
if(waitLen > scanGuard) { if(waitLen > this->scanGuard) {
waitLen -= scanGuard; waitLen -= this->scanGuard;
} }
mod->hal->delay(waitLen); mod->hal->delay(waitLen);
@ -1241,7 +1237,7 @@ int16_t LoRaWANNode::downlinkCommon() {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Opening Rx%d window (%d ms timeout)... <-- Rx Delay end ", i+1, (int)(timeoutHost / 1000 + scanGuard / 2)); RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Opening Rx%d window (%d ms timeout)... <-- Rx Delay end ", i+1, (int)(timeoutHost / 1000 + scanGuard / 2));
// wait for the timeout to complete (and a small additional delay) // wait for the timeout to complete (and a small additional delay)
mod->hal->delay(timeoutHost / 1000 + scanGuard / 2); mod->hal->delay(timeoutHost / 1000 + this->scanGuard / 2);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Closing Rx%d window", i+1); RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Closing Rx%d window", i+1);
// check if the IRQ bit for Rx Timeout is set // check if the IRQ bit for Rx Timeout is set

View file

@ -871,6 +871,20 @@ class LoRaWANNode {
*/ */
bool TS009 = false; bool TS009 = false;
/*!
\brief Rx window padding in milliseconds
according to the spec, the Rx window must be at least enough time to effectively detect a preamble
but we pad it a bit on both sides (start and end) to make sure it is wide enough
The larger this number the more power will be consumed! So be careful about changing it.
For debugging purposes 50 is a reasonable start, but for production devices it should
be as low as possible.
0 is a valid time.
500 is the **maximum** value, but it is not a good idea to go anywhere near that.
If you have to go above 50 you probably have a bug somewhere. Check your device timing.
*/
RadioLibTime_t scanGuard = 10;
#if !RADIOLIB_GODMODE #if !RADIOLIB_GODMODE
private: private:
#endif #endif