Skip to content

Commit 3876108

Browse files
STM32CubeWL: Fix RX timing issue due to relative timestamps
For the RX window timing, a timer is started after TxDone. However, since this is done in the mainloop rather than the TxDone ISR, the exact timing of the RX window depends on how soon after the interrupt LoRaMacProcess() is called (but it will always be at least a little too late). The TxDone interrupt already captures a timestamp, so this commit uses that to correctly position the RX window. There is still a small race condition where interrupts could still cause a delay, but the influence of that should be small and rare enough in practice, so this is left unfixed here (a proper fix would require changes to the timer subsystem, which are a bit too invasive to make here). This fixes Lora-net/LoRaMac-node#1349
1 parent 8e43a13 commit 3876108

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

src/STM32CubeWL/LoRaWAN/Mac/LoRaMac.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -959,19 +959,30 @@ static void ProcessRadioTxDone( void )
959959
{
960960
Radio.Sleep( );
961961
}
962+
// XXX: There is a race condition here: If an interrupt (or any
963+
// other delay) happens between calculating the offset and actually
964+
// setting the timer, the timer will be set too late. In practice,
965+
// assuming that an IRQ is rare an also does not take more than
966+
// a few ms, this is probably still within the allowed margins. This
967+
// could be fixed by disabling interrupts, but that requires
968+
// disabling them for quite some time, which probably has more
969+
// impact. A proper fix would be to allow setting an absolute
970+
// timestamp into a timer instead of relative, but that is a change
971+
// best made upstream in Semtech's codebase.
972+
uint32_t offset = TimerGetCurrentTime() - TxDoneParams.CurTime;
962973
#if ( !defined(DISABLE_LORAWAN_RX_WINDOW) || (DISABLE_LORAWAN_RX_WINDOW == 0) )
963974
// Setup timers
964-
TimerSetValue( &MacCtx.RxWindowTimer1, MacCtx.RxWindow1Delay );
975+
TimerSetValue( &MacCtx.RxWindowTimer1, MacCtx.RxWindow1Delay - offset );
965976
TimerStart( &MacCtx.RxWindowTimer1 );
966-
TimerSetValue( &MacCtx.RxWindowTimer2, MacCtx.RxWindow2Delay );
977+
TimerSetValue( &MacCtx.RxWindowTimer2, MacCtx.RxWindow2Delay - offset );
967978
TimerStart( &MacCtx.RxWindowTimer2 );
968979
#else
969980
if (Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE)
970981
{
971982
// Setup timers
972-
TimerSetValue( &MacCtx.RxWindowTimer1, MacCtx.RxWindow1Delay );
983+
TimerSetValue( &MacCtx.RxWindowTimer1, MacCtx.RxWindow1Delay - offset );
973984
TimerStart( &MacCtx.RxWindowTimer1 );
974-
TimerSetValue( &MacCtx.RxWindowTimer2, MacCtx.RxWindow2Delay );
985+
TimerSetValue( &MacCtx.RxWindowTimer2, MacCtx.RxWindow2Delay - offset );
975986
TimerStart( &MacCtx.RxWindowTimer2 );
976987
}
977988
else

0 commit comments

Comments
 (0)