Skip to content

Commit 128afbd

Browse files
committed
MP: Add clock sync support for 150 BPS
Rework the clock sync math to determine the number of hops that occurred during the transmitted frame. The resulting math seems to gets the clock sync within 2 mSec.
1 parent 63fedee commit 128afbd

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

Firmware/LoRaSerial/Radio.ino

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3250,7 +3250,7 @@ void stopChannelTimer()
32503250

32513251
//Given the remote unit's number of ms before its next hop,
32523252
//adjust our own channelTimer interrupt to be synchronized with the remote unit
3253-
void syncChannelTimer(uint32_t frameAirTimeUsec)
3253+
void syncChannelTimer(uint32_t frameAirTimeUsec, bool clockStarting)
32543254
{
32553255
int16_t adjustment;
32563256
uint8_t caseNumber;
@@ -3318,6 +3318,48 @@ void syncChannelTimer(uint32_t frameAirTimeUsec)
33183318
//timer update will add only microseconds to when the hop is done.
33193319
delayedHopCount = timeToHop ? 1 : 0;
33203320

3321+
// 4800 BPS operation
3322+
//
3323+
// |<---------------- Millis to HOP ---------------->|
3324+
// _____ | |_____________
3325+
// |_|_________________________________________________|
3326+
// | | |
3327+
// TX Start ^ TX Complete ^ |<-- rmtHopTimeMsec -->|
3328+
// RX Complete ^
3329+
//
3330+
//
3331+
// 150 BPS operation
3332+
//
3333+
// |<--- Millis to HOP --->|
3334+
// _____ | |_________________________
3335+
// |_|_______________________| | |_____________
3336+
// | | |
3337+
// TX Start ^ TX Complete ^ | |
3338+
// RX Complete ^ |
3339+
// |<- ->|
3340+
// rmtHopTimeMsec
3341+
//
3342+
// Millis to HOP
3343+
// |<- ->|
3344+
// | |_________________________ __
3345+
// ___________|_____| |_________________________|
3346+
// | | |
3347+
// TX Start ^ TX Complete ^ | |
3348+
// RX Complete ^ |
3349+
// |<---- ---->|
3350+
// rmtHopTimeMsec
3351+
//
3352+
//For low speed operation move the TX start into the current dwell time period
3353+
//to make the rest of the math look like the 4800 BPS operation.
3354+
frameAirTimeMsec = settings.maxDwellTime - msToNextHopRemote
3355+
+ (frameAirTimeUsec + settings.txToRxUsec + micros() - transactionCompleteMicros) / 1000;
3356+
while (frameAirTimeMsec >= (settings.maxDwellTime + (settings.maxDwellTime >> 6)))
3357+
{
3358+
frameAirTimeMsec -= settings.maxDwellTime;
3359+
if (clockStarting)
3360+
delayedHopCount += 1; //Account for the missing hop when the timer is stopped
3361+
}
3362+
33213363
//The radios are using the same frequencies since the frame was successfully
33223364
//received. The goal is to adjust the channel timer to fire in close proximity
33233365
//to the firing of the remote sysstem's channel timer. The following cases
@@ -3338,8 +3380,7 @@ void syncChannelTimer(uint32_t frameAirTimeUsec)
33383380
//Compute the remote system's channel timer firing time offset in milliseconds
33393381
//using the channel timer value and the adjustments for transmit and receive
33403382
//time (time of flight)
3341-
frameAirTimeMsec = (frameAirTimeUsec + settings.txToRxUsec + micros() - transactionCompleteMicros) / 1000;
3342-
rmtHopTimeMsec = msToNextHopRemote - frameAirTimeMsec;
3383+
rmtHopTimeMsec = settings.maxDwellTime - frameAirTimeMsec;
33433384

33443385
//Compute when the local system last hopped
33453386
lclHopTimeMsec = currentMillis - channelTimerStart;

Firmware/LoRaSerial/States.ino

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ void updateRadioState()
750750
COMPUTE_TIMESTAMP_OFFSET(rxData, 1, txDataAckUsec);
751751

752752
//The datagram we are expecting
753-
syncChannelTimer(txDataAckUsec); //Adjust freq hop ISR based on remote's remaining clock
753+
syncChannelTimer(txDataAckUsec, 0); //Adjust freq hop ISR based on remote's remaining clock
754754

755755
triggerEvent(TRIGGER_RX_ACK);
756756

@@ -1067,9 +1067,9 @@ void updateRadioState()
10671067
//then skip active discovery and go to standby
10681068
if (((frameAirTimeUsec + txDataAckUsec + settings.txToRxUsec) / 1000) > (settings.maxDwellTime / 2))
10691069
{
1070-
stopChannelTimer();
10711070
channelNumber = 0;
10721071
setRadioFrequency(false);
1072+
stopChannelTimer();
10731073
changeState(RADIO_DISCOVER_STANDBY);
10741074
}
10751075
else
@@ -1160,7 +1160,7 @@ void updateRadioState()
11601160
//Start and adjust freq hop ISR based on remote's remaining clock
11611161
startChannelTimer();
11621162
channelTimerStart -= settings.maxDwellTime;
1163-
syncChannelTimer(txSyncClocksUsec);
1163+
syncChannelTimer(txSyncClocksUsec, 1);
11641164
triggerEvent(TRIGGER_RX_SYNC_CLOCKS);
11651165

11661166
if (settings.debugSync)
@@ -1304,7 +1304,7 @@ void updateRadioState()
13041304
//Start and adjust freq hop ISR based on remote's remaining clock
13051305
startChannelTimer();
13061306
channelTimerStart -= settings.maxDwellTime;
1307-
syncChannelTimer(txSyncClocksUsec);
1307+
syncChannelTimer(txSyncClocksUsec, 1);
13081308

13091309
if (settings.debugSync)
13101310
{
@@ -1422,7 +1422,7 @@ void updateRadioState()
14221422
if (settings.server == false)
14231423
{
14241424
//Adjust freq hop ISR based on server's remaining clock
1425-
syncChannelTimer(txHeartbeatUsec);
1425+
syncChannelTimer(txHeartbeatUsec, 0);
14261426

14271427
//Received heartbeat - do not ack.
14281428
triggerEvent(TRIGGER_RX_HEARTBEAT);
@@ -3224,7 +3224,7 @@ void vcReceiveHeartbeat(uint32_t rxMillis)
32243224

32253225
//Adjust freq hop ISR based on server's remaining clock
32263226
if ((rxSrcVc == VC_SERVER) || (memcmp(rxVcData, myUniqueId, sizeof(myUniqueId)) == 0))
3227-
syncChannelTimer(txHeartbeatUsec);
3227+
syncChannelTimer(txHeartbeatUsec, 0);
32283228

32293229
//Update the timestamp offset
32303230
if (rxSrcVc == VC_SERVER)

0 commit comments

Comments
 (0)