From d4db0f30c78d9c0fb4d08e3caf90ee7fff3b4900 Mon Sep 17 00:00:00 2001 From: Laurent Meunier Date: Thu, 23 May 2019 17:29:45 +0200 Subject: [PATCH 1/8] Update HAL Sleep manager test to cope with STM32 LPTIM HW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In particular and as kindly suggested by Przemec S. : 1. Add setup/teardown handler’s for all cases. This disables sys-tick, so there should be no unexpected lp ticker interrupt scheduling. 2. Modify setup/teardown handler’s: remove suspension of lp/us tickers, so they can count as this is required by test_lock_unlock_test_check test case. 3. Use TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()) after setting interrupt to cope with STM specific handling (CMPOK interrupt with deep-sleep locked). This performs wait only if needed and will not affect other targets which do not need extra wait. 4. Move sleep_manager_lock_deep_sleep() after TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()) 5. Use TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()) in test_lock_unlock_test_check to let lower layers manage deep sleep. --- TESTS/mbed_hal/sleep_manager/main.cpp | 62 +++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index 324139b4fda..9e47f91a4c5 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -34,6 +34,26 @@ using utest::v1::Case; using utest::v1::Specification; using utest::v1::Harness; +/* Make sure there are enough ticks to cope with more than SLEEP_DURATION_US sleep + * without hitting the wrap-around. + */ +void wraparound_lp_protect(void) +{ + uint32_t time_window; + + const uint32_t ticks_now = get_lp_ticker_data()->interface->read(); + const ticker_info_t *p_ticker_info = get_lp_ticker_data()->interface->get_info(); + + const uint32_t max_count = ((1 << p_ticker_info->bits) - 1); + const uint32_t delta_ticks = us_to_ticks(SLEEP_DURATION_US * 1.5, p_ticker_info->frequency); + + if (ticks_now < (max_count - delta_ticks)) { + return; + } + + while (get_lp_ticker_data()->interface->read() > (max_count - delta_ticks)); +} + void test_lock_unlock() { TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); @@ -68,31 +88,30 @@ utest::v1::status_t testcase_setup(const Case *const source, const size_t index_ { // Suspend the RTOS kernel scheduler to prevent interference with duration of sleep. osKernelSuspend(); + #if DEVICE_LPTICKER - ticker_suspend(get_lp_ticker_data()); #if (LPTICKER_DELAY_TICKS > 0) // Suspend the low power ticker wrapper to prevent interference with deep sleep lock. lp_ticker_wrapper_suspend(); #endif #endif - ticker_suspend(get_us_ticker_data()); + // Make sure HAL tickers are initialized. us_ticker_init(); #if DEVICE_LPTICKER lp_ticker_init(); #endif + return utest::v1::greentea_case_setup_handler(source, index_of_case); } utest::v1::status_t testcase_teardown(const Case *const source, const size_t passed, const size_t failed, const utest::v1::failure_t failure) { - ticker_resume(get_us_ticker_data()); #if DEVICE_LPTICKER #if (LPTICKER_DELAY_TICKS > 0) lp_ticker_wrapper_resume(); #endif - ticker_resume(get_lp_ticker_data()); #endif osKernelResume(0); return utest::v1::greentea_case_teardown_handler(source, passed, failed, failure); @@ -115,10 +134,18 @@ void test_sleep_auto() const ticker_irq_handler_type lp_ticker_irq_handler_org = set_lp_ticker_irq_handler(lp_ticker_isr); us_timestamp_t us_ts1, us_ts2, lp_ts1, lp_ts2, us_diff1, us_diff2, lp_diff1, lp_diff2; - sleep_manager_lock_deep_sleep(); + /* Let's avoid the Lp ticker wrap-around case */ + wraparound_lp_protect(); uint32_t lp_wakeup_ts_raw = lp_ticker_read() + us_to_ticks(SLEEP_DURATION_US, lp_ticker_info->frequency); timestamp_t lp_wakeup_ts = overflow_protect(lp_wakeup_ts_raw, lp_ticker_info->bits); lp_ticker_set_interrupt(lp_wakeup_ts); + + /* Some targets may need an interrupt short time after LPTIM interrupt is + * set and forbid deep_sleep during that period. Let this period pass */ + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); + + sleep_manager_lock_deep_sleep(); + us_ts1 = ticks_to_us(us_ticker_read(), us_ticker_info->frequency); lp_ts1 = ticks_to_us(lp_ticker_read(), lp_ticker_info->frequency); @@ -144,13 +171,21 @@ void test_sleep_auto() // Wait for hardware serial buffers to flush. busy_wait_ms(SERIAL_FLUSH_TIME_MS); + /* Let's avoid the Lp ticker wrap-around case */ + wraparound_lp_protect(); lp_wakeup_ts_raw = lp_ticker_read() + us_to_ticks(SLEEP_DURATION_US, lp_ticker_info->frequency); lp_wakeup_ts = overflow_protect(lp_wakeup_ts_raw, lp_ticker_info->bits); lp_ticker_set_interrupt(lp_wakeup_ts); + + /* Some targets may need an interrupt short time after LPTIM interrupt is + * set and forbid deep_sleep during that period. Let this period pass */ + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); + us_ts1 = ticks_to_us(us_ticker_read(), us_ticker_info->frequency); lp_ts1 = ticks_to_us(lp_ticker_read(), lp_ticker_info->frequency); sleep_manager_sleep_auto(); + us_ts2 = ticks_to_us(us_ticker_read(), us_ticker_info->frequency); us_diff2 = (us_ts1 <= us_ts2) ? (us_ts2 - us_ts1) : (us_ticker_mask - us_ts1 + us_ts2 + 1); lp_ts2 = ticks_to_us(lp_ticker_read(), lp_ticker_info->frequency); @@ -189,7 +224,7 @@ void test_lock_unlock_test_check() // Deep sleep unlocked: // * sleep_manager_can_deep_sleep() returns true, // * sleep_manager_can_deep_sleep_test_check() returns true instantly. - TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); lp_timer.start(); TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); lp_timer.stop(); @@ -232,8 +267,14 @@ utest::v1::status_t testsuite_setup(const size_t number_of_cases) } Case cases[] = { - Case("deep sleep lock/unlock", test_lock_unlock), - Case("deep sleep locked USHRT_MAX times", test_lock_eq_ushrt_max), + Case("deep sleep lock/unlock", + (utest::v1::case_setup_handler_t) testcase_setup, + test_lock_unlock, + (utest::v1::case_teardown_handler_t) testcase_teardown), + Case("deep sleep locked USHRT_MAX times", + (utest::v1::case_setup_handler_t) testcase_setup, + test_lock_eq_ushrt_max, + (utest::v1::case_teardown_handler_t) testcase_teardown), #if DEVICE_LPTICKER #if DEVICE_USTICKER Case("sleep_auto calls sleep/deep sleep based on lock", @@ -241,7 +282,10 @@ Case cases[] = { test_sleep_auto, (utest::v1::case_teardown_handler_t) testcase_teardown), #endif - Case("deep sleep lock/unlock test_check", test_lock_unlock_test_check), + Case("deep sleep lock/unlock test_check", + (utest::v1::case_setup_handler_t) testcase_setup, + test_lock_unlock_test_check, + (utest::v1::case_teardown_handler_t) testcase_teardown), #endif }; From 24203fc42bd79cbcfe3b29776c1ef546795adb6c Mon Sep 17 00:00:00 2001 From: Laurent Meunier Date: Mon, 10 Jun 2019 11:33:16 +0200 Subject: [PATCH 2/8] Fix compilation issue for targets without LPTICKER or USTICKER --- TESTS/mbed_hal/sleep_manager/main.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index 9e47f91a4c5..88496023564 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -34,6 +34,7 @@ using utest::v1::Case; using utest::v1::Specification; using utest::v1::Harness; +#if DEVICE_LPTICKER /* Make sure there are enough ticks to cope with more than SLEEP_DURATION_US sleep * without hitting the wrap-around. */ @@ -53,6 +54,7 @@ void wraparound_lp_protect(void) while (get_lp_ticker_data()->interface->read() > (max_count - delta_ticks)); } +#endif void test_lock_unlock() { @@ -82,8 +84,6 @@ void test_lock_eq_ushrt_max() TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); } -#if DEVICE_LPTICKER -#if DEVICE_USTICKER utest::v1::status_t testcase_setup(const Case *const source, const size_t index_of_case) { // Suspend the RTOS kernel scheduler to prevent interference with duration of sleep. @@ -94,12 +94,11 @@ utest::v1::status_t testcase_setup(const Case *const source, const size_t index_ // Suspend the low power ticker wrapper to prevent interference with deep sleep lock. lp_ticker_wrapper_suspend(); #endif + lp_ticker_init(); #endif - +#if DEVICE_USTICKER // Make sure HAL tickers are initialized. us_ticker_init(); -#if DEVICE_LPTICKER - lp_ticker_init(); #endif return utest::v1::greentea_case_setup_handler(source, index_of_case); @@ -117,6 +116,8 @@ utest::v1::status_t testcase_teardown(const Case *const source, const size_t pas return utest::v1::greentea_case_teardown_handler(source, passed, failed, failure); } +#if DEVICE_LPTICKER +#if DEVICE_USTICKER /* This test is based on the fact that the high-speed clocks are turned off * in deep sleep mode but remain on in the ordinary sleep mode. Low-speed * clocks stay on for both sleep and deep sleep modes. From 83e274a82ce48f2df9e31f38f9f43537d693a3ab Mon Sep 17 00:00:00 2001 From: Laurent Meunier Date: Thu, 13 Jun 2019 13:56:01 +0200 Subject: [PATCH 3/8] Remove unused variable and avoid associated warning ... --- TESTS/mbed_hal/sleep_manager/main.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index 88496023564..8f9654b399c 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -40,8 +40,6 @@ using utest::v1::Harness; */ void wraparound_lp_protect(void) { - uint32_t time_window; - const uint32_t ticks_now = get_lp_ticker_data()->interface->read(); const ticker_info_t *p_ticker_info = get_lp_ticker_data()->interface->get_info(); From d577e7f1860e049fc3d19240fcbdbf49c9b77766 Mon Sep 17 00:00:00 2001 From: Przemyslaw Stekiel Date: Tue, 18 Jun 2019 12:31:14 +0200 Subject: [PATCH 4/8] Further modifications in Sleep Manager test. Changes: - restore the original form of setup/teardown handlers, - test_lock_unlock_test_check(): do not use common ticker layer (Timer, Timeout). Use only ticker HAL layer. - Increase DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US delta. --- TESTS/mbed_hal/sleep_manager/main.cpp | 133 ++++++++++++++++---------- 1 file changed, 85 insertions(+), 48 deletions(-) diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index 8f9654b399c..3e9f9c8c512 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -28,7 +28,7 @@ #define SLEEP_DURATION_US 20000ULL #define DEEP_SLEEP_TEST_CHECK_WAIT_US 2000 -#define DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US 500 +#define DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US 600 using utest::v1::Case; using utest::v1::Specification; @@ -86,29 +86,31 @@ utest::v1::status_t testcase_setup(const Case *const source, const size_t index_ { // Suspend the RTOS kernel scheduler to prevent interference with duration of sleep. osKernelSuspend(); - #if DEVICE_LPTICKER + ticker_suspend(get_lp_ticker_data()); #if (LPTICKER_DELAY_TICKS > 0) // Suspend the low power ticker wrapper to prevent interference with deep sleep lock. lp_ticker_wrapper_suspend(); #endif - lp_ticker_init(); #endif -#if DEVICE_USTICKER + ticker_suspend(get_us_ticker_data()); // Make sure HAL tickers are initialized. us_ticker_init(); +#if DEVICE_LPTICKER + lp_ticker_init(); #endif - return utest::v1::greentea_case_setup_handler(source, index_of_case); } utest::v1::status_t testcase_teardown(const Case *const source, const size_t passed, const size_t failed, const utest::v1::failure_t failure) { + ticker_resume(get_us_ticker_data()); #if DEVICE_LPTICKER #if (LPTICKER_DELAY_TICKS > 0) lp_ticker_wrapper_resume(); #endif + ticker_resume(get_lp_ticker_data()); #endif osKernelResume(0); return utest::v1::greentea_case_teardown_handler(source, passed, failed, failure); @@ -209,53 +211,88 @@ void test_sleep_auto() } #endif +#define US_PER_S 1000000 + +uint32_t diff_us(uint32_t start_ticks, uint32_t stop_ticks, const ticker_info_t *info) +{ + uint32_t counter_mask = ((1 << info->bits) - 1); + + uint32_t diff_ticks = ((stop_ticks - start_ticks) & counter_mask); + + return (uint32_t)((uint64_t) diff_ticks * US_PER_S / info->frequency); +} + +uint32_t us_to_ticks(uint32_t us, const ticker_info_t *info) +{ + return (uint32_t)((uint32_t) us * info->frequency / US_PER_S); +} + +volatile bool unlock_deep_sleep = false; + +void ticker_event_handler_stub(const ticker_data_t *const ticker) +{ + if (unlock_deep_sleep) { + sleep_manager_unlock_deep_sleep_internal(); + unlock_deep_sleep = false; + } +} + +ticker_irq_handler_type prev_irq_handler; + void test_lock_unlock_test_check() { - // Make sure HAL tickers are initialized. - ticker_read(get_us_ticker_data()); - ticker_read(get_lp_ticker_data()); + prev_irq_handler = set_lp_ticker_irq_handler(ticker_event_handler_stub); - // Use LowPowerTimer instead of Timer to prevent deep sleep lock. - LowPowerTimer lp_timer; - us_timestamp_t exec_time_unlocked, exec_time_locked; - LowPowerTimeout lp_timeout; + for (int i = 0; i < 1000; i++) { - // Deep sleep unlocked: - // * sleep_manager_can_deep_sleep() returns true, - // * sleep_manager_can_deep_sleep_test_check() returns true instantly. - TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); - lp_timer.start(); - TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); - lp_timer.stop(); - exec_time_unlocked = lp_timer.read_high_resolution_us(); + wraparound_lp_protect(); - // Deep sleep locked: - // * sleep_manager_can_deep_sleep() returns false, - // * sleep_manager_can_deep_sleep_test_check() returns false with 2 ms delay. - sleep_manager_lock_deep_sleep(); - TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep()); - lp_timer.reset(); - lp_timer.start(); - TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep_test_check()); - lp_timer.stop(); - exec_time_locked = lp_timer.read_high_resolution_us(); - TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US, DEEP_SLEEP_TEST_CHECK_WAIT_US, - exec_time_locked - exec_time_unlocked); - - // Deep sleep unlocked with a 1 ms delay: - // * sleep_manager_can_deep_sleep() returns false, - // * sleep_manager_can_deep_sleep_test_check() returns true with a 1 ms delay, - // * sleep_manager_can_deep_sleep() returns true when checked again. - lp_timer.reset(); - lp_timeout.attach_us(mbed::callback(sleep_manager_unlock_deep_sleep_internal), - DEEP_SLEEP_TEST_CHECK_WAIT_US / 2); - lp_timer.start(); - TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep()); - TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); - lp_timer.stop(); - TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US, DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, - lp_timer.read_high_resolution_us()); - TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); + const ticker_info_t *p_ticker_info = get_lp_ticker_data()->interface->get_info(); + + // Use LowPowerTimer instead of Timer to prevent deep sleep lock. + us_timestamp_t exec_time_unlocked, exec_time_locked; + uint32_t start, stop; + + // Deep sleep unlocked: + // * sleep_manager_can_deep_sleep() returns true, + // * sleep_manager_can_deep_sleep_test_check() returns true instantly. + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); + start = lp_ticker_read(); + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); + stop = lp_ticker_read(); + exec_time_unlocked = diff_us(start, stop, p_ticker_info); + + // Deep sleep locked: + // * sleep_manager_can_deep_sleep() returns false, + // * sleep_manager_can_deep_sleep_test_check() returns false with 2 ms delay. + sleep_manager_lock_deep_sleep(); + TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep()); + start = lp_ticker_read(); + TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep_test_check()); + stop = lp_ticker_read(); + exec_time_locked = diff_us(start, stop, p_ticker_info); + TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US, DEEP_SLEEP_TEST_CHECK_WAIT_US, + exec_time_locked - exec_time_unlocked); + + // Deep sleep unlocked with a 1 ms delay: + // * sleep_manager_can_deep_sleep() returns false, + // * sleep_manager_can_deep_sleep_test_check() returns true with a 1 ms delay, + // * sleep_manager_can_deep_sleep() returns true when checked again. + unlock_deep_sleep = true; + lp_ticker_set_interrupt(lp_ticker_read() + us_to_ticks(DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, p_ticker_info)); + + start = lp_ticker_read(); + // Extra wait after setting interrupt to handle CMPOK + wait_ns(100000); + TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep()); + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); + stop = lp_ticker_read(); + TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US, DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, + diff_us(start, stop, p_ticker_info)); + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); + } + + set_lp_ticker_irq_handler(prev_irq_handler); } #endif @@ -284,7 +321,7 @@ Case cases[] = { Case("deep sleep lock/unlock test_check", (utest::v1::case_setup_handler_t) testcase_setup, test_lock_unlock_test_check, - (utest::v1::case_teardown_handler_t) testcase_teardown), + (utest::v1::case_teardown_handler_t) testcase_teardown) #endif }; From c4cb3de0a94653cade4826b612fe824a4728e308 Mon Sep 17 00:00:00 2001 From: Przemyslaw Stekiel Date: Tue, 18 Jun 2019 12:36:38 +0200 Subject: [PATCH 5/8] sleep_manager_can_deep_sleep_test_check(): do not use ticker common layer to count elapsed time. --- platform/mbed_sleep_manager.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/mbed_sleep_manager.c b/platform/mbed_sleep_manager.c index a0a5c3d527a..66260392373 100644 --- a/platform/mbed_sleep_manager.c +++ b/platform/mbed_sleep_manager.c @@ -192,13 +192,15 @@ bool sleep_manager_can_deep_sleep(void) bool sleep_manager_can_deep_sleep_test_check() { - const uint32_t check_time_us = 2000; - const ticker_data_t *const ticker = get_us_ticker_data(); - uint32_t start = ticker_read(ticker); - while ((ticker_read(ticker) - start) < check_time_us) { + uint32_t check_time_ns = 2000000; + + while (check_time_ns) { if (sleep_manager_can_deep_sleep()) { return true; } + + wait_ns(100000); // 100 us + check_time_ns -= 100000; } return false; } From d6c3d79a9d04099a17a3c189c6acc63bedf9503e Mon Sep 17 00:00:00 2001 From: Laurent Meunier Date: Wed, 19 Jun 2019 11:00:33 +0200 Subject: [PATCH 6/8] Increase DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US now that sleep_manager_can_deep_sleep_test_check() is based on wait_ns --- TESTS/mbed_hal/sleep_manager/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index 3e9f9c8c512..c3f120bd65d 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -28,7 +28,9 @@ #define SLEEP_DURATION_US 20000ULL #define DEEP_SLEEP_TEST_CHECK_WAIT_US 2000 -#define DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US 600 +// As sleep_manager_can_deep_sleep_test_check() is based on wait_ns +// and wait_ns can be up to 40% slower, use a 50% delta here. +#define DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US 1000 using utest::v1::Case; using utest::v1::Specification; From 8476be628579e2dde89f6955065d4be23197b450 Mon Sep 17 00:00:00 2001 From: Laurent Meunier Date: Wed, 19 Jun 2019 14:53:07 +0200 Subject: [PATCH 7/8] Update test_lock_unlock_test_check() assertion to cope with new timings With the DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US increased, we now have TEST_ASSERT_UINT64_WITHIN(delta=1000, expected=1000, actual=1000) so this assertion needed to be updated. What we need is the deep sleep to be enabled after the programed interrupt has fired and before a 2ms timeout expiration, which means >= 1000 and < 2000. --- TESTS/mbed_hal/sleep_manager/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index c3f120bd65d..4e8547089d3 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -281,16 +281,16 @@ void test_lock_unlock_test_check() // * sleep_manager_can_deep_sleep_test_check() returns true with a 1 ms delay, // * sleep_manager_can_deep_sleep() returns true when checked again. unlock_deep_sleep = true; - lp_ticker_set_interrupt(lp_ticker_read() + us_to_ticks(DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, p_ticker_info)); start = lp_ticker_read(); + lp_ticker_set_interrupt(lp_ticker_read() + us_to_ticks(DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, p_ticker_info)); // Extra wait after setting interrupt to handle CMPOK wait_ns(100000); TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep()); TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); stop = lp_ticker_read(); - TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US, DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, - diff_us(start, stop, p_ticker_info)); + TEST_ASSERT(diff_us(start, stop, p_ticker_info) >= DEEP_SLEEP_TEST_CHECK_WAIT_US / 2); + TEST_ASSERT(diff_us(start, stop, p_ticker_info) < DEEP_SLEEP_TEST_CHECK_WAIT_US); TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); } From 8d8383b23ce77abbc4c1ede279dd863d700f83ce Mon Sep 17 00:00:00 2001 From: Filip Jagodzinski Date: Mon, 24 Jun 2019 17:43:19 +0200 Subject: [PATCH 8/8] Tests: SleepManager: Fix test_check for NRF5X Add missing `lp_ticker_clear_interrupt()` in the interrput handler used in `test_lock_unlock_test_check()` test. Remove redefined `us_to_ticks()`. --- TESTS/mbed_hal/sleep_manager/main.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index 4e8547089d3..7e7cca03d0e 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -224,15 +224,11 @@ uint32_t diff_us(uint32_t start_ticks, uint32_t stop_ticks, const ticker_info_t return (uint32_t)((uint64_t) diff_ticks * US_PER_S / info->frequency); } -uint32_t us_to_ticks(uint32_t us, const ticker_info_t *info) -{ - return (uint32_t)((uint32_t) us * info->frequency / US_PER_S); -} - volatile bool unlock_deep_sleep = false; void ticker_event_handler_stub(const ticker_data_t *const ticker) { + lp_ticker_clear_interrupt(); if (unlock_deep_sleep) { sleep_manager_unlock_deep_sleep_internal(); unlock_deep_sleep = false; @@ -281,15 +277,19 @@ void test_lock_unlock_test_check() // * sleep_manager_can_deep_sleep_test_check() returns true with a 1 ms delay, // * sleep_manager_can_deep_sleep() returns true when checked again. unlock_deep_sleep = true; - + /* Let's avoid the Lp ticker wrap-around case */ + wraparound_lp_protect(); start = lp_ticker_read(); - lp_ticker_set_interrupt(lp_ticker_read() + us_to_ticks(DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, p_ticker_info)); + uint32_t lp_wakeup_ts_raw = start + us_to_ticks(DEEP_SLEEP_TEST_CHECK_WAIT_US / 2, p_ticker_info->frequency); + timestamp_t lp_wakeup_ts = overflow_protect(lp_wakeup_ts_raw, p_ticker_info->bits); + lp_ticker_set_interrupt(lp_wakeup_ts); + // Extra wait after setting interrupt to handle CMPOK wait_ns(100000); TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep()); TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); stop = lp_ticker_read(); - TEST_ASSERT(diff_us(start, stop, p_ticker_info) >= DEEP_SLEEP_TEST_CHECK_WAIT_US / 2); + TEST_ASSERT(diff_us(start, stop, p_ticker_info) > 0UL); TEST_ASSERT(diff_us(start, stop, p_ticker_info) < DEEP_SLEEP_TEST_CHECK_WAIT_US); TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); } @@ -300,7 +300,7 @@ void test_lock_unlock_test_check() utest::v1::status_t testsuite_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10, "default_auto"); + GREENTEA_SETUP(15, "default_auto"); return utest::v1::greentea_test_setup_handler(number_of_cases); }