49
49
#define COUNTER_SPAN (GRTC_SYSCOUNTERL_VALUE_Msk | ((uint64_t)GRTC_SYSCOUNTERH_VALUE_Msk << 32))
50
50
#define MAX_ABS_TICKS (COUNTER_SPAN / CYC_PER_TICK)
51
51
52
- /* To allow use of CCADD we need to limit max cycles to 31 bits. */
53
- #define MAX_REL_CYCLES BIT_MASK(31)
54
- #define MAX_REL_TICKS (MAX_REL_CYCLES / CYC_PER_TICK)
52
+ #define MAX_TICKS \
53
+ (((COUNTER_SPAN / CYC_PER_TICK) > INT_MAX) ? INT_MAX : (COUNTER_SPAN / CYC_PER_TICK))
55
54
56
- #define LFCLK_FREQUENCY_HZ DT_PROP(LFCLK_NODE, clock_frequency )
55
+ #define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK )
57
56
58
- /* Threshold used to determine if there is a risk of unexpected GRTC COMPARE event coming
59
- * from previous CC value.
60
- */
61
- #define LATENCY_THR_TICKS 200
57
+ #define LFCLK_FREQUENCY_HZ DT_PROP(LFCLK_NODE, clock_frequency)
62
58
63
59
#if defined(CONFIG_TEST )
64
60
const int32_t z_sys_timer_irq_for_test = DT_IRQN (GRTC_NODE );
65
61
#endif
66
62
67
63
static void sys_clock_timeout_handler (int32_t id , uint64_t cc_val , void * p_context );
68
64
65
+ static struct k_spinlock lock ;
69
66
static uint64_t last_count ; /* Time (SYSCOUNTER value) @last sys_clock_announce() */
70
- static uint32_t last_elapsed ;
71
- static uint64_t cc_value ; /* Value that is expected to be in CC register. */
72
- static uint64_t expired_cc ; /* Value that is expected to be in CC register. */
73
67
static atomic_t int_mask ;
74
68
static uint8_t ext_channels_allocated ;
75
69
static uint64_t grtc_start_value ;
@@ -152,13 +146,17 @@ static void compare_int_unlock(int32_t chan, bool key)
152
146
static void sys_clock_timeout_handler (int32_t id , uint64_t cc_val , void * p_context )
153
147
{
154
148
ARG_UNUSED (id );
155
- ARG_UNUSED (cc_val );
156
149
ARG_UNUSED (p_context );
157
- uint32_t dticks ;
150
+ uint64_t dticks ;
151
+ uint64_t now = counter ();
152
+
153
+ if (unlikely (now < cc_val )) {
154
+ return ;
155
+ }
158
156
159
157
dticks = counter_sub (cc_val , last_count ) / CYC_PER_TICK ;
160
- last_count += ( dticks * CYC_PER_TICK );
161
- expired_cc = cc_val ;
158
+
159
+ last_count += dticks * CYC_PER_TICK ;
162
160
163
161
if (!IS_ENABLED (CONFIG_TICKLESS_KERNEL )) {
164
162
/* protection is not needed because we are in the GRTC interrupt
@@ -167,7 +165,6 @@ static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_conte
167
165
system_timeout_set_abs (last_count + CYC_PER_TICK );
168
166
}
169
167
170
- last_elapsed = 0 ;
171
168
sys_clock_announce ((int32_t )dticks );
172
169
}
173
170
@@ -371,7 +368,6 @@ uint64_t z_nrf_grtc_timer_startup_value_get(void)
371
368
int z_nrf_grtc_wakeup_prepare (uint64_t wake_time_us )
372
369
{
373
370
nrfx_err_t err_code ;
374
- static struct k_spinlock lock ;
375
371
static uint8_t systemoff_channel ;
376
372
uint64_t now = counter ();
377
373
nrfx_grtc_sleep_config_t sleep_cfg ;
@@ -434,12 +430,20 @@ int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us)
434
430
435
431
uint32_t sys_clock_cycle_get_32 (void )
436
432
{
437
- return nrf_grtc_sys_counter_low_get (NRF_GRTC );
433
+ k_spinlock_key_t key = k_spin_lock (& lock );
434
+ uint32_t ret = (uint32_t )counter ();
435
+
436
+ k_spin_unlock (& lock , key );
437
+ return ret ;
438
438
}
439
439
440
440
uint64_t sys_clock_cycle_get_64 (void )
441
441
{
442
- return counter ();
442
+ k_spinlock_key_t key = k_spin_lock (& lock );
443
+ uint64_t ret = counter ();
444
+
445
+ k_spin_unlock (& lock , key );
446
+ return ret ;
443
447
}
444
448
445
449
uint32_t sys_clock_elapsed (void )
@@ -448,9 +452,7 @@ uint32_t sys_clock_elapsed(void)
448
452
return 0 ;
449
453
}
450
454
451
- last_elapsed = (uint32_t )counter_sub (counter (), last_count );
452
-
453
- return last_elapsed / CYC_PER_TICK ;
455
+ return (uint32_t )(counter_sub (counter (), last_count ) / CYC_PER_TICK );
454
456
}
455
457
456
458
static int sys_clock_driver_init (void )
@@ -491,10 +493,6 @@ static int sys_clock_driver_init(void)
491
493
492
494
last_count = (counter () / CYC_PER_TICK ) * CYC_PER_TICK ;
493
495
grtc_start_value = last_count ;
494
- expired_cc = UINT64_MAX ;
495
- nrfx_grtc_channel_callback_set (system_clock_channel_data .channel ,
496
- sys_clock_timeout_handler , NULL );
497
-
498
496
int_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK ;
499
497
if (!IS_ENABLED (CONFIG_TICKLESS_KERNEL )) {
500
498
system_timeout_set_relative (CYC_PER_TICK );
@@ -549,47 +547,22 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
549
547
{
550
548
ARG_UNUSED (idle );
551
549
552
- if (ticks == 0 ) {
553
- return ;
554
- }
555
-
556
550
if (!IS_ENABLED (CONFIG_TICKLESS_KERNEL )) {
557
551
return ;
558
552
}
559
553
560
- uint32_t ch = system_clock_channel_data . channel ;
554
+ ticks = ( ticks == K_TICKS_FOREVER ) ? MAX_TICKS : MIN ( MAX_TICKS , MAX ( ticks , 0 )) ;
561
555
562
- if ((cc_value == expired_cc ) && (ticks < MAX_REL_TICKS )) {
563
- uint32_t cyc = ticks * CYC_PER_TICK ;
556
+ uint64_t delta_time = ticks * CYC_PER_TICK ;
564
557
565
- /* If it's the first timeout setting after previous expiration and timeout
566
- * is short so fast method can be used which utilizes relative CC configuration.
567
- */
568
- cc_value += cyc ;
569
- nrfx_grtc_syscounter_cc_rel_set (ch , cyc , NRFX_GRTC_CC_RELATIVE_COMPARE );
570
- return ;
571
- }
572
-
573
- uint64_t cyc = (uint64_t )ticks * CYC_PER_TICK ;
574
- bool safe_setting = false;
575
- int64_t prev_cc_val = cc_value ;
558
+ uint64_t target_time = counter () + delta_time ;
576
559
577
- cc_value = last_count + last_elapsed + cyc ;
578
-
579
- /* In case of timeout abort it may happen that CC is being set to a value
580
- * that later than previous CC. If previous CC value is not far in the
581
- * future, there is a risk that COMPARE event will be triggered for that
582
- * previous CC value. If there is such risk safe procedure must be applied
583
- * which is more time consuming but ensures that there will be no spurious
584
- * event.
560
+ /* Rounded down target_time to the tick boundary
561
+ * (but not less than one tick after the last)
585
562
*/
586
- if (prev_cc_val < cc_value ) {
587
- int64_t now = last_count + last_elapsed ;
588
-
589
- safe_setting = (prev_cc_val - now ) < LATENCY_THR_TICKS ;
590
- }
563
+ target_time = MAX ((target_time - last_count )/CYC_PER_TICK , 1 )* CYC_PER_TICK + last_count ;
591
564
592
- nrfx_grtc_syscounter_cc_abs_set ( ch , cc_value , safe_setting );
565
+ system_timeout_set_abs ( target_time );
593
566
}
594
567
595
568
#if defined(CONFIG_NRF_GRTC_TIMER_APP_DEFINED_INIT )
0 commit comments