@@ -12,6 +12,7 @@ struct timer_data {
12
12
int expire_cnt ;
13
13
int stop_cnt ;
14
14
int64_t timestamp ;
15
+ int slew_ppm ;
15
16
};
16
17
17
18
#define DURATION 100
@@ -28,15 +29,6 @@ struct timer_data {
28
29
*/
29
30
#define INEXACT_MS_CONVERT ((CONFIG_SYS_CLOCK_TICKS_PER_SEC % MSEC_PER_SEC) != 0)
30
31
31
- #if CONFIG_NRF_RTC_TIMER
32
- /* On Nordic SOCs one or both of the tick and busy-wait clocks may
33
- * derive from sources that have slews that sum to +/- 13%.
34
- */
35
- #define BUSY_TICK_SLEW_PPM 130000U
36
- #else
37
- /* On other platforms assume the clocks are perfectly aligned. */
38
- #define BUSY_TICK_SLEW_PPM 0U
39
- #endif
40
32
#define PPM_DIVISOR 1000000U
41
33
42
34
/* If the tick clock is faster or slower than the busywait clock the
@@ -45,8 +37,8 @@ struct timer_data {
45
37
* between the two clocks. Produce a maximum error for a given
46
38
* duration in microseconds.
47
39
*/
48
- #define BUSY_SLEW_THRESHOLD_TICKS (_us ) \
49
- k_us_to_ticks_ceil32((_us) * (uint64_t)BUSY_TICK_SLEW_PPM \
40
+ #define BUSY_SLEW_THRESHOLD_TICKS (_us , slew_ppm ) \
41
+ k_us_to_ticks_ceil32((_us) * (uint64_t)slew_ppm \
50
42
/ PPM_DIVISOR)
51
43
52
44
static void duration_expire (struct k_timer * timer );
@@ -253,8 +245,8 @@ ZTEST_USER(timer_api, test_timer_period_0)
253
245
/** TESTPOINT: set period 0 */
254
246
k_timer_start (& period0_timer ,
255
247
K_TICKS (k_ms_to_ticks_floor32 (DURATION )
256
- - BUSY_SLEW_THRESHOLD_TICKS (DURATION
257
- * USEC_PER_MSEC )),
248
+ - BUSY_SLEW_THRESHOLD_TICKS (DURATION * USEC_PER_MSEC ,
249
+ tdata . slew_ppm )),
258
250
K_NO_WAIT );
259
251
/* Need to wait at least 2 durations to ensure one-shot behavior. */
260
252
busy_wait_ms (2 * DURATION + 1 );
@@ -291,7 +283,7 @@ ZTEST_USER(timer_api, test_timer_period_k_forever)
291
283
k_timer_start (
292
284
& period0_timer ,
293
285
K_TICKS (k_ms_to_ticks_floor32 (DURATION ) -
294
- BUSY_SLEW_THRESHOLD_TICKS (DURATION * USEC_PER_MSEC )),
286
+ BUSY_SLEW_THRESHOLD_TICKS (DURATION * USEC_PER_MSEC , tdata . slew_ppm )),
295
287
K_FOREVER );
296
288
tdata .timestamp = k_uptime_get ();
297
289
@@ -648,7 +640,7 @@ ZTEST_USER(timer_api, test_timer_user_data)
648
640
} else {
649
641
uint32_t wait_us = 1000 * wait_ms ;
650
642
651
- k_busy_wait (wait_us + (wait_us * BUSY_TICK_SLEW_PPM ) / PPM_DIVISOR );
643
+ k_busy_wait (wait_us + (wait_us * tdata . slew_ppm ) / PPM_DIVISOR );
652
644
}
653
645
654
646
for (ii = 0 ; ii < 5 ; ii ++ ) {
@@ -722,7 +714,9 @@ ZTEST_USER(timer_api, test_timer_remaining)
722
714
* skew.
723
715
*/
724
716
delta_ticks = (int32_t )(rem_ticks - target_rem_ticks );
725
- slew_ticks = BUSY_SLEW_THRESHOLD_TICKS (DURATION * USEC_PER_MSEC / 2U );
717
+ slew_ticks = BUSY_SLEW_THRESHOLD_TICKS (DURATION * USEC_PER_MSEC / 2U , tdata .slew_ppm );
718
+ printk ("slew_ticks:%d delta:%d latency:%d\n" ,
719
+ slew_ticks , delta_ticks , latency_ticks );
726
720
zassert_true (abs (delta_ticks ) <= MAX (slew_ticks , latency_ticks ),
727
721
"tick/busy slew %d larger than test threshold %u" ,
728
722
delta_ticks , slew_ticks );
@@ -857,8 +851,29 @@ static void timer_init(struct k_timer *timer, k_timer_expiry_t expiry_fn,
857
851
k_timer_init (timer , expiry_fn , stop_fn );
858
852
}
859
853
854
+ static uint32_t slew_estimate (void )
855
+ {
856
+ uint32_t now = k_cycle_get_32 ();
857
+ uint32_t t ;
858
+ int diff ;
859
+
860
+ /* Compare 10 ms measured by system clock and k_busy_wait and calculate
861
+ * the difference. It is used later on in tests.
862
+ */
863
+ k_busy_wait (10000 );
864
+ now = k_cycle_get_32 () - now ;
865
+ t = k_cyc_to_us_floor32 (now );
866
+
867
+ diff = 10000 - t ;
868
+ diff = diff < 0 ? - diff : diff ;
869
+
870
+ return diff * 100 ;
871
+ }
872
+
860
873
void * setup_timer_api (void )
861
874
{
875
+ tdata .slew_ppm = slew_estimate ();
876
+
862
877
timer_init (& duration_timer , duration_expire , duration_stop );
863
878
timer_init (& period0_timer , period0_expire , NULL );
864
879
timer_init (& expire_timer , NULL , duration_stop );
0 commit comments