Skip to content

Commit 3c37881

Browse files
committed
tests-mbed_hal-sleep: add exception for STM LPTIM targets.
On some targets like STM family boards with LPTIM enabled an interrupt is triggered on counter rollover. We need special handling for cases when next_match_timestamp < start_timestamp (interrupt is to be fired after rollover). In such case after first wake-up we need to reset interrupt and go back to sleep waiting for the valid one. On some targets like STM family boards with LPTIM enabled there is a required delay (~100 us) before we are able to reprogram LPTIM_COMPARE register back to back. This is handled by the low level lp ticker wrapper which uses LPTIM_CMPOK interrupt. CMPOK fires when LPTIM_COMPARE register can be safely reprogrammed again. This means that on these platforms we have additional interrupt (CMPOK) fired always ~100 us after programming lp ticker. Since this interrupt wake-ups the board from the sleep we need to go to sleep after CMPOK is handled. Background: There is an errata in LPTIM specification that explains that CMP Flag condition is not an exact match (COUNTER = MATCH) but rather a comparison (COUNTER >= MATCH). As a consequence the interrupt is firing early than expected when programing a timestamp after the 0xFFFF wrap-around. In order to work-around this issue, we implement the below work-around. In case timestamp is after the work-around, let's decide to program the CMP value to 0xFFFF, which is the wrap-around value. There would anyway be a wake-up at the time of wrap-around to let the OS update the system time. When the wrap-around interrupt happen, OS will check the current time and program again the timestamp to the proper value.
1 parent b21c278 commit 3c37881

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

TESTS/mbed_hal/sleep/main.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,29 @@ void deepsleep_lpticker_test()
122122

123123
lp_ticker_set_interrupt(next_match_timestamp);
124124

125+
/* On some targets like STM family boards with LPTIM enabled there is a required delay (~100 us) before we are able to
126+
reprogram LPTIM_COMPARE register back to back. This is handled by the low level lp ticker wrapper which uses LPTIM_CMPOK interrupt.
127+
CMPOK fires when LPTIM_COMPARE register can be safely reprogrammed again. This means that on these platforms we have additional interrupt
128+
(CMPOK) fired always ~100 us after programming lp ticker. Since this interrupt wake-ups the board from the sleep we need to go to sleep
129+
after CMPOK is handled. */
130+
#if MBED_CONF_TARGET_LPTICKER_LPTIM
131+
wait_ns(200000);
132+
#endif
133+
125134
sleep();
126135

136+
/* On some targets like STM family boards with LPTIM enabled an interrupt is triggered on counter rollover.
137+
We need special handling for cases when next_match_timestamp < start_timestamp (interrupt is to be fired after rollover).
138+
In such case after first wake-up we need to reset interrupt and go back to sleep waiting for the valid one.
139+
NOTE: Above comment (CMPOK) applies also here.*/
140+
#if MBED_CONF_TARGET_LPTICKER_LPTIM
141+
if ((next_match_timestamp < start_timestamp) && lp_ticker_read() < next_match_timestamp) {
142+
lp_ticker_set_interrupt(next_match_timestamp);
143+
wait_ns(200000);
144+
sleep();
145+
}
146+
#endif
147+
127148
const timestamp_t wakeup_timestamp = lp_ticker_read();
128149

129150
sprintf(info, "Delta ticks: %u, Ticker width: %u, Expected wake up tick: %d, Actual wake up tick: %d, delay ticks: %d, wake up after ticks: %d",
@@ -154,11 +175,15 @@ void deepsleep_high_speed_clocks_turned_off_test()
154175

155176
TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should not be locked");
156177

157-
const unsigned int us_ticks_before_sleep = us_ticker_read();
158-
159178
const timestamp_t wakeup_time = lp_ticker_read() + us_to_ticks(20000, lp_ticker_freq);
160179
lp_ticker_set_interrupt(wakeup_time);
161180

181+
#if MBED_CONF_TARGET_LPTICKER_LPTIM
182+
wait_ns(200000);
183+
#endif
184+
185+
const unsigned int us_ticks_before_sleep = us_ticker_read();
186+
162187
sleep();
163188

164189
const unsigned int us_ticks_after_sleep = us_ticker_read();

0 commit comments

Comments
 (0)