Skip to content

Fix for issue #10725 (tests-mbed_drivers-lp_timer failing nightly) #12135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions TESTS/mbed_drivers/lp_timer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,50 @@ void busy_wait_ms(int ms)
busy_wait_us(ms * US_PER_MSEC);
}

/* Frequency of low power timer may be unstable and different than the frequency provided in ticker information structure (e.g. STM targets with lp-tickers driven by RTC/LSI).
This function can be used in such cases to calibrate the lp-ticker frequency using us-ticker and update frequency in the ticker data structure. */
#if (defined(TARGET_STM) && !defined(MBED_CONF_TARGET_LPTICKER_LPTIM))
void calibrate_lp_ticker_freq()
{
Timer ref_timer;
uint32_t total = 0;

for (int i = 0; i < 5; i++) {
ref_timer.reset();

const uint32_t start_tick = lp_ticker_read();

/* Wait for the new lp-ticker tick. */
while (lp_ticker_read() == start_tick);

ref_timer.start();

/* wait 1 sec */
while (ref_timer.read_us() < 1000000);

const uint32_t stop_tick = lp_ticker_read();

ref_timer.stop();

/* Calculate number of lp-ticker ticks during 1 sec period (handle possible rollover) */
const uint32_t measured_lp_ticker_freq = ((stop_tick - start_tick) & ((1 << lp_ticker_get_info()->bits) - 1));

total += measured_lp_ticker_freq;
}

#if defined(MBED_CONF_RTOS_PRESENT)
osKernelSuspend();
#endif

ticker_update_freq(get_lp_ticker_data(), total / 5);

#if defined(MBED_CONF_RTOS_PRESENT)
osKernelResume(0);
#endif
}
#endif


/* This test verifies if low power timer is stopped after
* creation.
*
Expand Down Expand Up @@ -328,6 +372,11 @@ void test_lptimer_time_measurement()
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(15, "default_auto");

#if (defined(TARGET_STM) && !defined(MBED_CONF_TARGET_LPTICKER_LPTIM))
calibrate_lp_ticker_freq();
#endif

return verbose_test_setup_handler(number_of_cases);
}

Expand Down
26 changes: 26 additions & 0 deletions hal/mbed_ticker_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,29 @@ void ticker_resume(const ticker_data_t *const ticker)

core_util_critical_section_exit();
}

void ticker_update_freq(const ticker_data_t *const ticker, uint32_t frequency)
{
uint8_t frequency_shifts = 0;
for (uint8_t i = 31; i > 0; --i) {
if ((1U << i) == frequency) {
frequency_shifts = i;
break;
}
}

core_util_critical_section_enter();

if (!ticker->queue->initialized) {
initialize(ticker);
}

ticker->queue->frequency = frequency;
ticker->queue->frequency_shifts = frequency_shifts;
ticker->queue->tick_last_read = ticker->interface->read();

update_present_time(ticker);
schedule_interrupt(ticker);

core_util_critical_section_exit();
}
9 changes: 9 additions & 0 deletions hal/ticker_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ void ticker_suspend(const ticker_data_t *const ticker);
*/
void ticker_resume(const ticker_data_t *const ticker);

/** Update ticker frequency
*
* Update ticker frequency.
*
* @param ticker The ticker object.
* @param frequency The new frequency
*/
void ticker_update_freq(const ticker_data_t *const ticker, uint32_t frequency);

/* Private functions
*
* @cond PRIVATE
Expand Down