@@ -12,6 +12,7 @@ struct timer_data {
1212 int expire_cnt ;
1313 int stop_cnt ;
1414 int64_t timestamp ;
15+ int slew_ppm ;
1516};
1617
1718#define DURATION 100
@@ -28,15 +29,6 @@ struct timer_data {
2829 */
2930#define INEXACT_MS_CONVERT ((CONFIG_SYS_CLOCK_TICKS_PER_SEC % MSEC_PER_SEC) != 0)
3031
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
4032#define PPM_DIVISOR 1000000U
4133
4234/* If the tick clock is faster or slower than the busywait clock the
@@ -45,8 +37,8 @@ struct timer_data {
4537 * between the two clocks. Produce a maximum error for a given
4638 * duration in microseconds.
4739 */
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 \
5042 / PPM_DIVISOR)
5143
5244static void duration_expire (struct k_timer * timer );
@@ -253,8 +245,8 @@ ZTEST_USER(timer_api, test_timer_period_0)
253245 /** TESTPOINT: set period 0 */
254246 k_timer_start (& period0_timer ,
255247 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 )),
258250 K_NO_WAIT );
259251 /* Need to wait at least 2 durations to ensure one-shot behavior. */
260252 busy_wait_ms (2 * DURATION + 1 );
@@ -291,7 +283,7 @@ ZTEST_USER(timer_api, test_timer_period_k_forever)
291283 k_timer_start (
292284 & period0_timer ,
293285 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 )),
295287 K_FOREVER );
296288 tdata .timestamp = k_uptime_get ();
297289
@@ -648,7 +640,7 @@ ZTEST_USER(timer_api, test_timer_user_data)
648640 } else {
649641 uint32_t wait_us = 1000 * wait_ms ;
650642
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 );
652644 }
653645
654646 for (ii = 0 ; ii < 5 ; ii ++ ) {
@@ -722,7 +714,9 @@ ZTEST_USER(timer_api, test_timer_remaining)
722714 * skew.
723715 */
724716 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 );
726720 zassert_true (abs (delta_ticks ) <= MAX (slew_ticks , latency_ticks ),
727721 "tick/busy slew %d larger than test threshold %u" ,
728722 delta_ticks , slew_ticks );
@@ -857,8 +851,29 @@ static void timer_init(struct k_timer *timer, k_timer_expiry_t expiry_fn,
857851 k_timer_init (timer , expiry_fn , stop_fn );
858852}
859853
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+
860873void * setup_timer_api (void )
861874{
875+ tdata .slew_ppm = slew_estimate ();
876+
862877 timer_init (& duration_timer , duration_expire , duration_stop );
863878 timer_init (& period0_timer , period0_expire , NULL );
864879 timer_init (& expire_timer , NULL , duration_stop );
0 commit comments