@@ -196,7 +196,7 @@ void lp_ticker_init(void)
196
196
__HAL_LPTIM_CLEAR_FLAG (& LptimHandle , LPTIM_FLAG_CMPOK );
197
197
198
198
/* Init is called with Interrupts disabled, so the CMPOK interrupt
199
- * will not be handler . Let's mark it is now safe to write to LP counter */
199
+ * will not be handled . Let's mark it is now safe to write to LP counter */
200
200
lp_cmpok = true;
201
201
}
202
202
@@ -292,8 +292,18 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
292
292
timestamp = LP_TIMER_WRAP (timestamp + LP_TIMER_SAFE_GUARD );
293
293
}
294
294
}
295
- /* Then check if this target timestamp is not in the past, or close to wrap-around */
296
- if ((timestamp < last_read_counter ) && (last_read_counter <= (0xFFFF - LP_TIMER_SAFE_GUARD ))) {
295
+ /* Then check if this target timestamp is not in the past, or close to wrap-around
296
+ * Let's assume last_read_counter = 0xFFFC, and we want to program timestamp = 0x100
297
+ * The interrupt will not fire before the CMPOK flag is OK, so there are 2 cases:
298
+ * in case CMPOK flag is set by HW after or at wrap-around, then this will fire only @0x100
299
+ * in case CMPOK flag is set before, it will indeed fire early, as for the wrap-around case.
300
+ * But that will take at least 3 cycles and the interrupt fires at the end of a cycle.
301
+ * In our case 0xFFFC + 3 => at the transition between 0xFFFF and 0.
302
+ * If last_read_counter was 0xFFFB, it should be at the transition between 0xFFFE and 0xFFFF.
303
+ * There might be crossing cases where it would also fire @ 0xFFFE, but by the time we read the counter,
304
+ * it may already have moved to the next one, so for now we've taken this as margin of error.
305
+ */
306
+ if ((timestamp < last_read_counter ) && (last_read_counter <= (0xFFFF - LP_TIMER_SAFE_GUARD ))) {
297
307
/* Workaround, because limitation */
298
308
__HAL_LPTIM_COMPARE_SET (& LptimHandle , ~0 );
299
309
} else {
0 commit comments