Skip to content

Commit 88b9f20

Browse files
committed
[Nuvoton] Add nu_busy_wait_us
nu_busy_wait_us is a replacement for wait_us when intermediary us ticker layer is disabled.
1 parent 2b632b9 commit 88b9f20

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

targets/TARGET_NUVOTON/nu_timer.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "nu_timer.h"
1818
#include "mbed_power_mgmt.h"
1919
#include "mbed_critical.h"
20+
#include "us_ticker_api.h"
21+
#include "mbed_assert.h"
2022

2123
void nu_countdown_init(struct nu_countdown_ctx_s *ctx, us_timestamp_t interval_us)
2224
{
@@ -45,3 +47,21 @@ void nu_countdown_free(struct nu_countdown_ctx_s *ctx)
4547
sleep_manager_unlock_deep_sleep();
4648
core_util_critical_section_exit();
4749
}
50+
51+
52+
void nu_busy_wait_us(uint32_t us)
53+
{
54+
const uint32_t bits = us_ticker_get_info()->bits;
55+
const uint32_t mask = (1 << bits) - 1;
56+
MBED_ASSERT(us_ticker_get_info()->frequency == 1000000);
57+
uint32_t prev = us_ticker_read();
58+
while (1) {
59+
const uint32_t cur = us_ticker_read();
60+
const uint32_t elapsed = (cur - prev) & mask;
61+
if (elapsed > us) {
62+
break;
63+
}
64+
us -= elapsed;
65+
prev = cur;
66+
}
67+
}

targets/TARGET_NUVOTON/nu_timer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ void nu_countdown_init(struct nu_countdown_ctx_s *ctx, us_timestamp_t interval_u
6060
bool nu_countdown_expired(struct nu_countdown_ctx_s *ctx);
6161
void nu_countdown_free(struct nu_countdown_ctx_s *ctx);
6262

63+
64+
/* Replacement for wait_us when intermediary us ticker layer is disabled
65+
*
66+
* Use of wait_us directly from the low power ticker causes the system to deadlock during
67+
* the sleep test because the sleep test disables the intermediary us ticker layer during
68+
* the test.
69+
*
70+
* To prevent this lockup, nu_busy_wait_us is created to replace wait_us, which uses the us ticker
71+
* directly rather than go though the intermediary us ticker layer.
72+
*
73+
* During wait period through nu_busy_wait_us, CPU would be busy spinning.
74+
*/
75+
void nu_busy_wait_us(uint32_t us);
76+
6377
#ifdef __cplusplus
6478
}
6579
#endif

0 commit comments

Comments
 (0)