66#include <zephyr/ztest.h>
77#include <zephyr/drivers/timer/nrf_grtc_timer.h>
88#include <hal/nrf_grtc.h>
9+ #include <zephyr/drivers/counter.h>
910#include <zephyr/devicetree/clocks.h>
1011#include <zephyr/drivers/clock_control/nrf_clock_control.h>
1112
@@ -17,7 +18,16 @@ typedef enum {
1718 CHANGE_TO_LFRC = 2
1819} lfclk_source_change_option ;
1920
20- const struct device * lfclk_dev = DEVICE_DT_GET (DT_NODELABEL (lfclk ));
21+ struct accuracy_test_limit {
22+ bool is_reference_timer_enabled ;
23+ uint32_t grtc_timer_count_time_ms ;
24+ uint32_t time_delta_abs_tolerance_us ;
25+ uint64_t final_max_ticks_count_difference ;
26+ };
27+
28+ const struct device * const tst_timer_dev = DEVICE_DT_GET (DT_ALIAS (tst_timer ));
29+ const struct device * const lfclk_dev = DEVICE_DT_GET (DT_NODELABEL (lfclk ));
30+ const struct device * const fll16m_dev = DEVICE_DT_GET (DT_NODELABEL (fll16m ));
2131static volatile uint8_t compare_isr_call_counter ;
2232static volatile uint64_t compare_count_value ;
2333
@@ -33,6 +43,12 @@ const struct nrf_clock_spec lfclk_synth_mode = {
3343 .precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT ,
3444};
3545
46+ const struct nrf_clock_spec fll16m_bypass_mode = {
47+ .frequency = MHZ (16 ),
48+ .accuracy = 30 ,
49+ .precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT ,
50+ };
51+
3652static void request_clock_spec (const struct device * clk_dev , const struct nrf_clock_spec * clk_spec )
3753{
3854 int ret = 0 ;
@@ -61,32 +77,69 @@ static void request_clock_spec(const struct device *clk_dev, const struct nrf_cl
6177
6278static void timer_compare_interrupt_handler (int32_t id , uint64_t expire_time , void * user_data )
6379{
80+ uint32_t tst_timer_value ;
81+ uint64_t reference_timer_value_us ;
82+ struct accuracy_test_limit * test_limit = (struct accuracy_test_limit * )user_data ;
83+
6484 compare_count_value = z_nrf_grtc_timer_read ();
6585 compare_isr_call_counter ++ ;
66- TC_PRINT ("Compare value reached, user data: '%s'\n" , (char * )user_data );
67- TC_PRINT ("Call counter: %d\n" , compare_isr_call_counter );
86+ if (test_limit -> is_reference_timer_enabled ) {
87+ counter_stop (tst_timer_dev );
88+ counter_get_value (tst_timer_dev , & tst_timer_value );
89+ reference_timer_value_us = counter_ticks_to_us (tst_timer_dev , tst_timer_value );
90+ TC_PRINT ("Reference timer value [us]: %llu\n" , reference_timer_value_us );
91+ TC_PRINT ("Time delta (Specified (GRTC) - referecne timer) [us]: %lld\n" ,
92+ (uint64_t )test_limit -> grtc_timer_count_time_ms * 1000 -
93+ reference_timer_value_us );
94+ zassert_true ((uint64_t )test_limit -> grtc_timer_count_time_ms * 1000 <
95+ reference_timer_value_us +
96+ test_limit -> time_delta_abs_tolerance_us ,
97+ "GRTC timer count value is over upper limit" );
98+ zassert_true ((uint64_t )test_limit -> grtc_timer_count_time_ms * 1000 >
99+ reference_timer_value_us -
100+ test_limit -> time_delta_abs_tolerance_us ,
101+ "GRTC timer count value is under lower limit" );
102+ }
103+
104+ TC_PRINT ("Compare count value [ticks]: %llu\n" , compare_count_value );
105+ }
106+
107+ static void configure_test_timer (const struct device * timer_dev , uint32_t count_time_ms )
108+ {
109+ struct counter_alarm_cfg counter_cfg ;
110+
111+ counter_cfg .flags = 0 ;
112+ counter_cfg .ticks = counter_us_to_ticks (timer_dev , (uint64_t )count_time_ms * 1000 );
113+ counter_cfg .user_data = & counter_cfg ;
68114}
69115
70- static void test_timer_compare (uint32_t timer_count_time_ms ,
116+ static void test_timer_compare (const struct accuracy_test_limit * test_limit ,
71117 lfclk_source_change_option tst_dynamic_clk_change_option )
72118{
73119 int err ;
74120 uint64_t test_ticks = 0 ;
75121 uint64_t compare_value = 0 ;
76- char user_data [] = "test_timer_count_in_compare_mode\n" ;
77122 int32_t channel = z_nrf_grtc_timer_chan_alloc ();
78123
124+ if (test_limit -> is_reference_timer_enabled ) {
125+ TC_PRINT ("Reference timer (HFCLK sourced) is enabled\n" );
126+ configure_test_timer (tst_timer_dev , test_limit -> grtc_timer_count_time_ms * 2 );
127+ }
128+
79129 TC_PRINT ("Allocated GRTC channel %d\n" , channel );
80130 if (channel < 0 ) {
81131 TC_PRINT ("Failed to allocate GRTC channel, chan=%d\n" , channel );
82132 ztest_test_fail ();
83133 }
84134
85135 compare_isr_call_counter = 0 ;
86- test_ticks = z_nrf_grtc_timer_get_ticks (K_MSEC (timer_count_time_ms ));
136+ test_ticks = z_nrf_grtc_timer_get_ticks (K_MSEC (test_limit -> grtc_timer_count_time_ms ));
87137 err = z_nrf_grtc_timer_set (channel , test_ticks , timer_compare_interrupt_handler ,
88- (void * )user_data );
138+ (void * )test_limit );
89139
140+ if (test_limit -> is_reference_timer_enabled ) {
141+ counter_start (tst_timer_dev );
142+ }
90143 zassert_equal (err , 0 , "z_nrf_grtc_timer_set raised an error: %d" , err );
91144
92145 z_nrf_grtc_timer_compare_read (channel , & compare_value );
@@ -106,45 +159,77 @@ static void test_timer_compare(uint32_t timer_count_time_ms,
106159 TC_PRINT ("Clock source change not requested\n" );
107160 }
108161
109- k_sleep (K_MSEC (2 * timer_count_time_ms ));
162+ k_sleep (K_MSEC (2 * test_limit -> grtc_timer_count_time_ms ));
110163 zassert_equal (compare_isr_call_counter , 1 , "Compare isr call counter: %d" ,
111164 compare_isr_call_counter );
112165
113166 TC_PRINT ("Compare count - initial compare value: %lld\n" ,
114167 compare_count_value - compare_value );
168+
169+ zassert_true ((compare_count_value - compare_value ) <
170+ test_limit -> final_max_ticks_count_difference ,
171+ "Maximal final ticks count difference is over the limit" );
115172 z_nrf_grtc_timer_chan_free (channel );
116173}
117174
175+ /*
176+ * This test uses HFCLK based timer130 as a reference.
177+ * The timers start is not ideally sunchronised,
178+ * this is taken into account in the limit
179+ */
118180ZTEST (grtc_timer_lfrc , test_timer_count_in_compare_mode_lfclk_source_from_lfrc )
119181{
120- uint32_t timer_count_time_ms = 50 ;
182+ const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = true,
183+ .grtc_timer_count_time_ms = 1000 ,
184+ .time_delta_abs_tolerance_us = 15 ,
185+ .final_max_ticks_count_difference = 50 };
121186
122187 request_clock_spec (lfclk_dev , & lfclk_lfrc_mode );
123- test_timer_compare (timer_count_time_ms , false );
188+ test_timer_compare (& test_limit , NO_CHANGE );
124189}
125190
126191ZTEST (grtc_timer_lfrc , test_timer_count_in_compare_mode_lfclk_source_from_synth )
127192{
128- uint32_t timer_count_time_ms = 50 ;
193+ const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = false,
194+ .grtc_timer_count_time_ms = 50 ,
195+ .time_delta_abs_tolerance_us = 0 ,
196+ .final_max_ticks_count_difference = 50 };
129197
130198 request_clock_spec (lfclk_dev , & lfclk_synth_mode );
131- test_timer_compare (timer_count_time_ms , false );
199+ test_timer_compare (& test_limit , NO_CHANGE );
132200}
133201
134202ZTEST (grtc_timer_lfrc , test_timer_count_in_compare_mode_lfclk_runtime_update_lfrc_to_synth )
135203{
136- uint32_t timer_count_time_ms = 500 ;
204+ const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = false,
205+ .grtc_timer_count_time_ms = 250 ,
206+ .time_delta_abs_tolerance_us = 0 ,
207+ .final_max_ticks_count_difference = 50 };
137208
138209 request_clock_spec (lfclk_dev , & lfclk_lfrc_mode );
139- test_timer_compare (timer_count_time_ms , CHANGE_TO_SYNTH );
210+ test_timer_compare (& test_limit , CHANGE_TO_SYNTH );
140211}
141212
142213ZTEST (grtc_timer_lfrc , test_timer_count_in_compare_mode_lfclk_runtime_update_synth_to_lfrc )
143214{
144- uint32_t timer_count_time_ms = 500 ;
215+ const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = false,
216+ .grtc_timer_count_time_ms = 250 ,
217+ .time_delta_abs_tolerance_us = 0 ,
218+ .final_max_ticks_count_difference = 50 };
145219
146220 request_clock_spec (lfclk_dev , & lfclk_synth_mode );
147- test_timer_compare (timer_count_time_ms , CHANGE_TO_LFRC );
221+ test_timer_compare (& test_limit , CHANGE_TO_LFRC );
222+ }
223+
224+ /*
225+ * FLL16M must be set in bypass mode
226+ * to achieve the HFCLK 30ppm accuracy
227+ */
228+ void * test_setup (void )
229+ {
230+ request_clock_spec (fll16m_dev , & fll16m_bypass_mode );
231+
232+ return NULL ;
148233}
149234
150- ZTEST_SUITE (grtc_timer_lfrc , NULL , NULL , NULL , NULL , NULL );
235+ ZTEST_SUITE (grtc_timer_lfrc , NULL , test_setup , NULL , NULL , NULL );
0 commit comments