@@ -37,7 +37,9 @@ ticker_irq_handler_type prev_handler;
37
37
#define TICKER_GLITCH_TEST_TICKS 1000
38
38
39
39
#define TICKER_INT_VAL 500
40
+ #define TICKER_MIN_DELAY 20
40
41
#define TICKER_DELTA 10
42
+ #define TICKS_TO_SWEEP 8
41
43
42
44
#define LP_TICKER_OV_LIMIT 4000
43
45
@@ -55,13 +57,24 @@ ticker_irq_handler_type prev_handler;
55
57
* hardware buffers are empty. However, such an API does not exist now,
56
58
* so we'll use the busy_wait_ms() function for now.
57
59
*/
58
- #define SERIAL_FLUSH_TIME_MS 20
60
+ #define SERIAL_FLUSH_TIME_US 20000
59
61
60
- void busy_wait_ms ( int ms )
62
+ void busy_wait_us ( uint32_t us )
61
63
{
62
64
const ticker_data_t *const ticker = get_us_ticker_data ();
63
65
uint32_t start = ticker_read (ticker);
64
- while ((ticker_read (ticker) - start) < (uint32_t )(ms * US_PER_MS));
66
+ while ((ticker_read (ticker) - start) < us);
67
+ }
68
+
69
+ void busy_wait_lp_cycles (uint32_t cycles)
70
+ {
71
+ const uint32_t mask = (1 << lp_ticker_get_info ()->bits ) - 1 ;
72
+
73
+ const uint32_t tick_count = lp_ticker_read ();
74
+ uint32_t elapsed;
75
+ do {
76
+ elapsed = (lp_ticker_read () - tick_count) & mask;
77
+ } while (elapsed < cycles);
65
78
}
66
79
67
80
/* Since according to the ticker requirements min acceptable counter size is
@@ -121,7 +134,7 @@ void lp_ticker_deepsleep_test()
121
134
/* Give some time Green Tea to finish UART transmission before entering
122
135
* deep-sleep mode.
123
136
*/
124
- busy_wait_ms (SERIAL_FLUSH_TIME_MS );
137
+ busy_wait_us (SERIAL_FLUSH_TIME_US );
125
138
126
139
overflow_protect ();
127
140
@@ -158,8 +171,62 @@ void lp_ticker_glitch_test()
158
171
}
159
172
}
160
173
161
- #if DEVICE_LPTICKER
162
- utest::v1::status_t lp_ticker_deepsleep_test_setup_handler (const Case *const source, const size_t index_of_case)
174
+ void lp_ticker_early_match_test ()
175
+ {
176
+ lp_ticker_init ();
177
+
178
+ const uint32_t mask = (1 << lp_ticker_get_info ()->bits ) - 1 ;
179
+
180
+ for (uint32_t i = 0 ; i < 100 ; i++) {
181
+ const uint32_t tick_count = lp_ticker_read ();
182
+ const uint32_t match_count = (tick_count + TICKER_MIN_DELAY + i) & mask;
183
+
184
+ intFlag = 0 ;
185
+ lp_ticker_set_interrupt (match_count);
186
+
187
+ while (!intFlag);
188
+ const uint32_t elapsed = (lp_ticker_read () - match_count) & mask;
189
+
190
+ /* Interrupt must fire between 0 and TICKER_DELTA ticks after match */
191
+ TEST_ASSERT (elapsed <= TICKER_DELTA);
192
+ }
193
+ }
194
+
195
+ void lp_ticker_early_match_race_test ()
196
+ {
197
+ lp_ticker_init ();
198
+
199
+ const uint32_t mask = (1 << lp_ticker_get_info ()->bits ) - 1 ;
200
+
201
+ /* For worst case of 4KHz (250us period) low power ticker busy wait
202
+ * in 1 microsecond increments from 0 to TICKS_TO_SWEEP ticks
203
+ */
204
+ for (uint32_t i = 0 ; i < TICKS_TO_SWEEP * 250 ; i++) {
205
+
206
+ /* Schedule an match to occur */
207
+ uint32_t match_count = (lp_ticker_read () + TICKER_MIN_DELAY) & mask;
208
+ lp_ticker_set_interrupt (match_count);
209
+
210
+ /* Wait until the match is about to or has already fired */
211
+ busy_wait_lp_cycles (TICKER_MIN_DELAY - TICKS_TO_SWEEP / 2 );
212
+ busy_wait_us (i);
213
+
214
+ /* Reset and schedule another match */
215
+ core_util_critical_section_enter ();
216
+ intFlag = 0 ;
217
+ match_count = (lp_ticker_read () + TICKER_MIN_DELAY) & mask;
218
+ lp_ticker_set_interrupt (match_count);
219
+ core_util_critical_section_exit ();
220
+
221
+ while (!intFlag);
222
+ const uint32_t elapsed = (lp_ticker_read () - match_count) & mask;
223
+
224
+ /* Interrupt must fire between 0 and TICKER_DELTA ticks after match */
225
+ TEST_ASSERT (elapsed <= TICKER_DELTA);
226
+ }
227
+ }
228
+
229
+ utest::v1::status_t lp_ticker_test_setup_handler (const Case *const source, const size_t index_of_case)
163
230
{
164
231
/* disable everything using the lp ticker for this test */
165
232
osKernelSuspend ();
@@ -171,7 +238,7 @@ utest::v1::status_t lp_ticker_deepsleep_test_setup_handler(const Case *const sou
171
238
return greentea_case_setup_handler (source, index_of_case);
172
239
}
173
240
174
- utest::v1::status_t lp_ticker_deepsleep_test_teardown_handler (const Case *const source, const size_t passed, const size_t failed,
241
+ utest::v1::status_t lp_ticker_test_teardown_handler (const Case *const source, const size_t passed, const size_t failed,
175
242
const failure_t reason)
176
243
{
177
244
set_lp_ticker_irq_handler (prev_handler);
@@ -182,7 +249,6 @@ utest::v1::status_t lp_ticker_deepsleep_test_teardown_handler(const Case *const
182
249
osKernelResume (0 );
183
250
return greentea_case_teardown_handler (source, passed, failed, reason);
184
251
}
185
- #endif
186
252
187
253
utest::v1::status_t test_setup (const size_t number_of_cases)
188
254
{
@@ -193,9 +259,11 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
193
259
Case cases[] = {
194
260
Case (" lp ticker info test" , lp_ticker_info_test),
195
261
#if DEVICE_SLEEP
196
- Case (" lp ticker sleep test" , lp_ticker_deepsleep_test_setup_handler , lp_ticker_deepsleep_test, lp_ticker_deepsleep_test_teardown_handler ),
262
+ Case (" lp ticker sleep test" , lp_ticker_test_setup_handler , lp_ticker_deepsleep_test, lp_ticker_test_teardown_handler ),
197
263
#endif
198
- Case (" lp ticker glitch test" , lp_ticker_glitch_test)
264
+ Case (" lp ticker glitch test" , lp_ticker_glitch_test),
265
+ Case (" lp ticker early match test" , lp_ticker_test_setup_handler, lp_ticker_early_match_test, lp_ticker_test_teardown_handler),
266
+ Case (" lp ticker early match race test" , lp_ticker_test_setup_handler, lp_ticker_early_match_race_test, lp_ticker_test_teardown_handler)
199
267
};
200
268
201
269
Specification specification (test_setup, cases);
0 commit comments