30
30
/* nb of LPTIM counter unit per kernel tick */
31
31
#define COUNT_PER_TICK (LPTIM_CLOCK / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
32
32
33
+ /* minimum nb of clock cycles to have to set autoreload register correctly */
34
+ #define LPTIM_GUARD_VALUE 2
35
+
33
36
/* A 32bit value cannot exceed 0xFFFFFFFF/LPTIM_TIMEBASE counting cycles.
34
37
* This is for example about of 65000 x 2000ms when clocked by LSI
35
38
*/
36
39
static u32_t accumulated_lptim_cnt ;
37
40
38
41
static struct k_spinlock lock ;
39
- volatile u8_t lptim_fired ;
40
42
41
43
static void lptim_irq_handler (struct device * unused )
42
44
{
@@ -51,13 +53,6 @@ static void lptim_irq_handler(struct device *unused)
51
53
/* do not change ARR yet, z_clock_announce will do */
52
54
LL_LPTIM_ClearFLAG_ARRM (LPTIM1 );
53
55
54
- if (lptim_fired ) {
55
- lptim_fired = 0 ;
56
- #if defined(LPTIM_CR_COUNTRST )
57
- LL_LPTIM_ResetCounter (LPTIM1 );
58
- #endif
59
- }
60
-
61
56
/* increase the total nb of autoreload count
62
57
* used in the z_timer_cycle_get_32() function.
63
58
* Reading the CNT register gives a reliable value
@@ -147,7 +142,6 @@ int z_clock_driver_init(struct device *device)
147
142
LL_LPTIM_ClearFlag_ARROK (LPTIM1 );
148
143
149
144
accumulated_lptim_cnt = 0 ;
150
- lptim_fired = 0 ;
151
145
152
146
/* Enable the LPTIM1 counter */
153
147
LL_LPTIM_Enable (LPTIM1 );
@@ -212,6 +206,17 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
212
206
lp_time = LL_LPTIM_GetCounter (LPTIM1 );
213
207
}
214
208
209
+ u32_t autoreload = LL_LPTIM_GetAutoReload (LPTIM1 );
210
+
211
+ if (LL_LPTIM_IsActiveFlag_ARRM (LPTIM1 )
212
+ || ((autoreload - lp_time ) < LPTIM_GUARD_VALUE )) {
213
+ /* interrupt happens or happens soon.
214
+ * It's impossible to set autoreload value.
215
+ */
216
+ k_spin_unlock (& lock , key );
217
+ return ;
218
+ }
219
+
215
220
/* calculate the next arr value (cannot exceed 16bit)
216
221
* adjust the next ARR match value to align on Ticks
217
222
* from the current counter value to first next Tick
@@ -227,15 +232,12 @@ void z_clock_set_timeout(s32_t ticks, bool idle)
227
232
if (next_arr > LPTIM_TIMEBASE ) {
228
233
next_arr = LPTIM_TIMEBASE ;
229
234
}
230
-
231
- /* If we are close to the roll over of the ticker counter
232
- * change current tick so it can be compared with buffer.
233
- * If this event got outdated fire interrupt right now,
234
- * else schedule it normally.
235
+ /* The new autoreload value must be LPTIM_GUARD_VALUE clock cycles
236
+ * after current lptim to make sure we don't miss
237
+ * an autoreload interrupt
235
238
*/
236
- if (next_arr <= ((lp_time + 1 ) & LPTIM_TIMEBASE )) {
237
- NVIC_SetPendingIRQ (LPTIM1_IRQn );
238
- lptim_fired = 1 ;
239
+ else if (next_arr < (lp_time + LPTIM_GUARD_VALUE )) {
240
+ next_arr = lp_time + LPTIM_GUARD_VALUE ;
239
241
}
240
242
241
243
/* ARROK bit validates previous write operation to ARR register */
0 commit comments