Skip to content

Commit c904b43

Browse files
committed
Improve low power ticker test coverage
Update the low power ticker test to verify that the low power ticker does not fire too early. Also add a test to verify that the low power ticker can be safely rescheduled right before or after a match occurs.
1 parent 920db63 commit c904b43

File tree

3 files changed

+96
-10
lines changed

3 files changed

+96
-10
lines changed

TESTS/mbed_hal/lp_ticker/lp_ticker_api_tests.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,23 @@ void lp_ticker_deepsleep_test(void);
5151
* Then ticker does not glitch backwards due to an incorrectly implemented ripple counter driver.
5252
*/
5353
void lp_ticker_glitch_test(void);
54+
55+
/** Test that the ticker does not fire early.
56+
*
57+
* Given ticker is available.
58+
* When ticker has interrupt set.
59+
* Then ticker does not fire before the time specified.
60+
*/
61+
void lp_ticker_early_match_test(void);
62+
63+
/** Test that the ticker does not fire early.
64+
*
65+
* Given ticker is available.
66+
* When ticker is about to have a match and a second call to lp_ticker_set_interrupt is ticker is made.
67+
* Then ticker does not fire before the new time specified.
68+
*/
69+
void lp_ticker_early_match_race_test(void);
70+
5471
/**@}*/
5572

5673
#ifdef __cplusplus

TESTS/mbed_hal/lp_ticker/main.cpp

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ ticker_irq_handler_type prev_handler;
3737
#define TICKER_GLITCH_TEST_TICKS 1000
3838

3939
#define TICKER_INT_VAL 500
40+
#define TICKER_MIN_DELAY 20
4041
#define TICKER_DELTA 10
42+
#define TICKS_TO_SWEEP 8
4143

4244
#define LP_TICKER_OV_LIMIT 4000
4345

@@ -55,13 +57,24 @@ ticker_irq_handler_type prev_handler;
5557
* hardware buffers are empty. However, such an API does not exist now,
5658
* so we'll use the busy_wait_ms() function for now.
5759
*/
58-
#define SERIAL_FLUSH_TIME_MS 20
60+
#define SERIAL_FLUSH_TIME_US 20000
5961

60-
void busy_wait_ms(int ms)
62+
void busy_wait_us(uint32_t us)
6163
{
6264
const ticker_data_t *const ticker = get_us_ticker_data();
6365
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);
6578
}
6679

6780
/* Since according to the ticker requirements min acceptable counter size is
@@ -121,7 +134,7 @@ void lp_ticker_deepsleep_test()
121134
/* Give some time Green Tea to finish UART transmission before entering
122135
* deep-sleep mode.
123136
*/
124-
busy_wait_ms(SERIAL_FLUSH_TIME_MS);
137+
busy_wait_us(SERIAL_FLUSH_TIME_US);
125138

126139
overflow_protect();
127140

@@ -158,8 +171,62 @@ void lp_ticker_glitch_test()
158171
}
159172
}
160173

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)
163230
{
164231
/* disable everything using the lp ticker for this test */
165232
osKernelSuspend();
@@ -171,7 +238,7 @@ utest::v1::status_t lp_ticker_deepsleep_test_setup_handler(const Case *const sou
171238
return greentea_case_setup_handler(source, index_of_case);
172239
}
173240

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,
175242
const failure_t reason)
176243
{
177244
set_lp_ticker_irq_handler(prev_handler);
@@ -182,7 +249,6 @@ utest::v1::status_t lp_ticker_deepsleep_test_teardown_handler(const Case *const
182249
osKernelResume(0);
183250
return greentea_case_teardown_handler(source, passed, failed, reason);
184251
}
185-
#endif
186252

187253
utest::v1::status_t test_setup(const size_t number_of_cases)
188254
{
@@ -193,9 +259,11 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
193259
Case cases[] = {
194260
Case("lp ticker info test", lp_ticker_info_test),
195261
#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),
197263
#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)
199267
};
200268

201269
Specification specification(test_setup, cases);

hal/lp_ticker_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ extern "C" {
4545
*
4646
* # Potential bugs
4747
* * Glitches due to ripple counter - Verified by ::lp_ticker_glitch_test
48+
* * Firing early - Verified by - Verified by ::lp_ticker_early_match_test and ::lp_ticker_early_match_race_test
4849
*
4950
* @see hal_lp_ticker_tests
5051
*

0 commit comments

Comments
 (0)