Skip to content

Commit

Permalink
Merge pull request #1158 from alistair23/alistair/scan-guard
Browse files Browse the repository at this point in the history
protocol: LoRaWAN: Allow configuring scanGuard
  • Loading branch information
jgromes authored Jul 13, 2024
2 parents fb049cc + 5b9cad0 commit a93dd1a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
14 changes: 5 additions & 9 deletions src/protocols/LoRaWAN/LoRaWAN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1187,14 +1187,10 @@ int16_t LoRaWANNode::uplink(uint8_t* data, size_t len, uint8_t fPort, bool isCon
int16_t LoRaWANNode::downlinkCommon() {
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
// 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
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(now < this->rxDelayStart + this->rxDelays[1]) {
mod->hal->delay(this->rxDelays[1] + this->rxDelayStart - now);
Expand All @@ -1220,7 +1216,7 @@ int16_t LoRaWANNode::downlinkCommon() {
downlinkAction = false;

// 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);

// wait for the start of the Rx window
Expand All @@ -1230,8 +1226,8 @@ int16_t LoRaWANNode::downlinkCommon() {
waitLen = this->rxDelays[i];
}
// the waiting duration is shortened a bit to cover any possible timing errors
if(waitLen > scanGuard) {
waitLen -= scanGuard;
if(waitLen > this->scanGuard) {
waitLen -= this->scanGuard;
}
mod->hal->delay(waitLen);

Expand All @@ -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));

// 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);

// check if the IRQ bit for Rx Timeout is set
Expand Down
14 changes: 14 additions & 0 deletions src/protocols/LoRaWAN/LoRaWAN.h
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,20 @@ class LoRaWANNode {
*/
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
private:
#endif
Expand Down

0 comments on commit a93dd1a

Please sign in to comment.