Skip to content

Commit d8c17b5

Browse files
authored
Merge pull request #10536 from mprse/stm_lptim_issue
Changes required by the ST low power ticker wrapper.
2 parents 2fd7f80 + 869585a commit d8c17b5

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

TESTS/mbed_drivers/timeout/timeout_tests.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,14 @@ void test_multiple(void)
196196
template<typename T>
197197
void test_no_wait(void)
198198
{
199-
Semaphore sem(0, 1);
200-
T timeout;
201-
timeout.attach_callback(mbed::callback(sem_callback, &sem), 0ULL);
202-
203-
bool acquired = sem.try_acquire();
204-
TEST_ASSERT_TRUE(acquired);
205-
timeout.detach();
199+
for (int i = 0; i < 100; i++) {
200+
Semaphore sem(0, 1);
201+
T timeout;
202+
timeout.attach_callback(mbed::callback(sem_callback, &sem), 0ULL);
203+
int32_t sem_slots = sem.wait(0);
204+
TEST_ASSERT_EQUAL(1, sem_slots);
205+
timeout.detach();
206+
}
206207
}
207208

208209
/** Template for tests: accuracy of timeout delay

TESTS/mbed_hal/sleep/main.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,27 @@ 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. During this period deep-sleep is locked.
128+
This means that on these platforms we have additional interrupt (CMPOK) fired always ~100 us after programming lp ticker.
129+
Since this interrupt wakes-up the board from the sleep we need to go to sleep after CMPOK is handled. */
130+
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check());
131+
125132
sleep();
126133

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

129148
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 +173,14 @@ void deepsleep_high_speed_clocks_turned_off_test()
154173

155174
TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should not be locked");
156175

157-
const unsigned int us_ticks_before_sleep = us_ticker_read();
158-
159176
const timestamp_t wakeup_time = lp_ticker_read() + us_to_ticks(20000, lp_ticker_freq);
160177
lp_ticker_set_interrupt(wakeup_time);
161178

179+
/* Wait for CMPOK */
180+
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check());
181+
182+
const unsigned int us_ticks_before_sleep = us_ticker_read();
183+
162184
sleep();
163185

164186
const unsigned int us_ticks_after_sleep = us_ticker_read();

hal/mbed_ticker_api.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,14 @@ void ticker_insert_event_us(const ticker_data_t *const ticker, ticker_event_t *o
377377
/* if prev is NULL we're at the head */
378378
if (prev == NULL) {
379379
ticker->queue->head = obj;
380-
schedule_interrupt(ticker);
381380
} else {
382381
prev->next = obj;
383382
}
384383

384+
if (prev == NULL || timestamp <= ticker->queue->present_time) {
385+
schedule_interrupt(ticker);
386+
}
387+
385388
core_util_critical_section_exit();
386389
}
387390

0 commit comments

Comments
 (0)