[LoRaWAN] A-synchronize transmissions (#1410)
This commit is contained in:
parent
c43b89dc42
commit
d6b6a0bf51
2 changed files with 66 additions and 8 deletions
|
@ -906,14 +906,22 @@ int16_t LoRaWANNode::activateOTAA(uint8_t joinDr, LoRaWANJoinEvent_t *joinEvent)
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// calculate JoinRequest time-on-air in milliseconds
|
// calculate JoinRequest time-on-air in milliseconds
|
||||||
|
RadioLibTime_t toa = this->phyLayer->getTimeOnAir(RADIOLIB_LORAWAN_JOIN_REQUEST_LEN) / 1000;
|
||||||
|
|
||||||
if(this->dwellTimeUp) {
|
if(this->dwellTimeUp) {
|
||||||
RadioLibTime_t toa = this->phyLayer->getTimeOnAir(RADIOLIB_LORAWAN_JOIN_REQUEST_LEN) / 1000;
|
|
||||||
if(toa > this->dwellTimeUp) {
|
if(toa > this->dwellTimeUp) {
|
||||||
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Dwell time exceeded: ToA = %lu, max = %d", (unsigned long)toa, this->dwellTimeUp);
|
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Dwell time exceeded: ToA = %lu, max = %d", (unsigned long)toa, this->dwellTimeUp);
|
||||||
return(RADIOLIB_ERR_DWELL_TIME_EXCEEDED);
|
return(RADIOLIB_ERR_DWELL_TIME_EXCEEDED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RadioModeConfig_t modeCfg;
|
||||||
|
modeCfg.transmit.data = joinRequestMsg;
|
||||||
|
modeCfg.transmit.len = RADIOLIB_LORAWAN_JOIN_REQUEST_LEN;
|
||||||
|
modeCfg.transmit.addr = 0;
|
||||||
|
state = this->phyLayer->stageMode(RADIOLIB_RADIO_MODE_TX, modeCfg);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// if requested, delay until transmitting JoinRequest
|
// if requested, delay until transmitting JoinRequest
|
||||||
RadioLibTime_t tNow = mod->hal->millis();
|
RadioLibTime_t tNow = mod->hal->millis();
|
||||||
if(this->tUplink > tNow) {
|
if(this->tUplink > tNow) {
|
||||||
|
@ -923,8 +931,26 @@ int16_t LoRaWANNode::activateOTAA(uint8_t joinDr, LoRaWANJoinEvent_t *joinEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// send it
|
// start transmission
|
||||||
state = this->phyLayer->transmit(joinRequestMsg, RADIOLIB_LORAWAN_JOIN_REQUEST_LEN);
|
state = this->phyLayer->launchMode();
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// sleep for the duration of the transmission
|
||||||
|
mod->hal->delay(toa);
|
||||||
|
RadioLibTime_t txEnd = mod->hal->millis();
|
||||||
|
|
||||||
|
// wait for an additional transmission duration as Tx timeout period
|
||||||
|
while(!mod->hal->digitalRead(mod->getIrq())) {
|
||||||
|
// yield for multi-threaded platforms
|
||||||
|
mod->hal->yield();
|
||||||
|
|
||||||
|
if(mod->hal->millis() > txEnd + toa) {
|
||||||
|
return(RADIOLIB_ERR_TX_TIMEOUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = this->phyLayer->finishTransmit();
|
||||||
|
|
||||||
|
// set the timestamp so that we can measure when to start receiving
|
||||||
this->rxDelayStart = mod->hal->millis();
|
this->rxDelayStart = mod->hal->millis();
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("JoinRequest sent (DevNonce = %d) <-- Rx Delay start", this->devNonce);
|
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("JoinRequest sent (DevNonce = %d) <-- Rx Delay start", this->devNonce);
|
||||||
|
@ -935,7 +961,7 @@ int16_t LoRaWANNode::activateOTAA(uint8_t joinDr, LoRaWANJoinEvent_t *joinEvent)
|
||||||
LoRaWANNode::hton<uint16_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_DEV_NONCE], this->devNonce);
|
LoRaWANNode::hton<uint16_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_DEV_NONCE], this->devNonce);
|
||||||
|
|
||||||
// set the Time on Air of the JoinRequest
|
// set the Time on Air of the JoinRequest
|
||||||
this->lastToA = this->phyLayer->getTimeOnAir(RADIOLIB_LORAWAN_JOIN_REQUEST_LEN) / 1000;
|
this->lastToA = toa;
|
||||||
|
|
||||||
// configure Rx1 and Rx2 delay for JoinAccept message - these are re-configured once a valid JoinAccept is received
|
// configure Rx1 and Rx2 delay for JoinAccept message - these are re-configured once a valid JoinAccept is received
|
||||||
this->rxDelays[1] = RADIOLIB_LORAWAN_JOIN_ACCEPT_DELAY_1_MS;
|
this->rxDelays[1] = RADIOLIB_LORAWAN_JOIN_ACCEPT_DELAY_1_MS;
|
||||||
|
@ -1270,7 +1296,6 @@ int16_t LoRaWANNode::transmitUplink(const LoRaWANChannel_t* chnl, uint8_t* in, u
|
||||||
Module* mod = this->phyLayer->getMod();
|
Module* mod = this->phyLayer->getMod();
|
||||||
|
|
||||||
// check if the Rx windows were closed after sending the previous uplink
|
// check if the Rx windows were closed after sending the previous uplink
|
||||||
// this FORCES a user to call downlink() after an uplink()
|
|
||||||
if(this->rxDelayEnd < this->rxDelayStart) {
|
if(this->rxDelayEnd < this->rxDelayStart) {
|
||||||
// not enough time elapsed since the last uplink, we may still be in an Rx window
|
// not enough time elapsed since the last uplink, we may still be in an Rx window
|
||||||
return(RADIOLIB_ERR_UPLINK_UNAVAILABLE);
|
return(RADIOLIB_ERR_UPLINK_UNAVAILABLE);
|
||||||
|
@ -1295,6 +1320,22 @@ int16_t LoRaWANNode::transmitUplink(const LoRaWANChannel_t* chnl, uint8_t* in, u
|
||||||
RADIOLIB_LORAWAN_UPLINK,
|
RADIOLIB_LORAWAN_UPLINK,
|
||||||
this->txPowerMax - 2*this->txPowerSteps);
|
this->txPowerMax - 2*this->txPowerSteps);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// check whether dwell time limitation is exceeded
|
||||||
|
RadioLibTime_t toa = this->phyLayer->getTimeOnAir(len) / 1000;
|
||||||
|
if(this->dwellTimeUp) {
|
||||||
|
if(toa > this->dwellTimeUp) {
|
||||||
|
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Dwell time exceeded: ToA = %lu, max = %d", (unsigned long)toa, this->dwellTimeUp);
|
||||||
|
return(RADIOLIB_ERR_DWELL_TIME_EXCEEDED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioModeConfig_t modeCfg;
|
||||||
|
modeCfg.transmit.data = in;
|
||||||
|
modeCfg.transmit.len = len;
|
||||||
|
modeCfg.transmit.addr = 0;
|
||||||
|
state = this->phyLayer->stageMode(RADIOLIB_RADIO_MODE_TX, modeCfg);
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// if requested, wait until transmitting uplink
|
// if requested, wait until transmitting uplink
|
||||||
tNow = mod->hal->millis();
|
tNow = mod->hal->millis();
|
||||||
|
@ -1305,14 +1346,31 @@ int16_t LoRaWANNode::transmitUplink(const LoRaWANChannel_t* chnl, uint8_t* in, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state = this->phyLayer->transmit(in, len);
|
// start transmission
|
||||||
|
state = this->phyLayer->launchMode();
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
|
// sleep for the duration of the transmission
|
||||||
|
mod->hal->delay(toa);
|
||||||
|
RadioLibTime_t txEnd = mod->hal->millis();
|
||||||
|
|
||||||
|
// wait for an additional transmission duration as Tx timeout period
|
||||||
|
while(!mod->hal->digitalRead(mod->getIrq())) {
|
||||||
|
// yield for multi-threaded platforms
|
||||||
|
mod->hal->yield();
|
||||||
|
|
||||||
|
if(mod->hal->millis() > txEnd + toa) {
|
||||||
|
return(RADIOLIB_ERR_TX_TIMEOUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = this->phyLayer->finishTransmit();
|
||||||
|
|
||||||
// set the timestamp so that we can measure when to start receiving
|
// set the timestamp so that we can measure when to start receiving
|
||||||
this->rxDelayStart = mod->hal->millis();
|
this->rxDelayStart = mod->hal->millis();
|
||||||
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Uplink sent <-- Rx Delay start");
|
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Uplink sent <-- Rx Delay start");
|
||||||
|
|
||||||
// increase Time on Air of the uplink sequence
|
// increase Time on Air of the uplink sequence
|
||||||
this->lastToA += this->phyLayer->getTimeOnAir(len) / 1000;
|
this->lastToA += toa;
|
||||||
|
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -850,7 +850,7 @@ class LoRaWANNode {
|
||||||
500 is the **maximum** value, but it is not a good idea to go anywhere near that.
|
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.
|
If you have to go above 50 you probably have a bug somewhere. Check your device timing.
|
||||||
*/
|
*/
|
||||||
RadioLibTime_t scanGuard = 4;
|
RadioLibTime_t scanGuard = 5;
|
||||||
|
|
||||||
#if !RADIOLIB_GODMODE
|
#if !RADIOLIB_GODMODE
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Add table
Reference in a new issue