Skip to content

Commit 26c0444

Browse files
committed
[Nuvoton] Add nu_delay_cycle_x4
nu_delay_cycle_x4 is a replacement for wait_us when us ticker is not available.
1 parent 88b9f20 commit 26c0444

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

targets/TARGET_NUVOTON/nu_timer.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,65 @@ void nu_busy_wait_us(uint32_t us)
6565
prev = cur;
6666
}
6767
}
68+
69+
/* Delay 4 cycles per round by hand-counting instruction cycles
70+
*
71+
* The delay function here is implemented by just hand-counting instruction cycles rather than preferred
72+
* H/W timer since it is to use in cases where H/W timer is not available. Usually, it can delay at least
73+
* 4-cycles per round.
74+
*
75+
* In modern pipeline core, plus flash performance and other factors, we cannot rely accurately on hand-
76+
* counting instruction cycles for expected delay cycles.
77+
*/
78+
#if defined(__CC_ARM)
79+
MBED_NOINLINE
80+
__asm void nu_delay_cycle_x4(uint32_t rounds)
81+
{
82+
// AStyle should not format inline assembly
83+
// *INDENT-OFF*
84+
1
85+
#if !defined(__CORTEX_M0)
86+
NOP // 1 cycle
87+
#endif
88+
SUBS a1, a1, #1 // 1 cycle
89+
BCS %BT1 // 3 cycles(M0)/2 cycles(non-M0)
90+
BX lr
91+
// *INDENT-ON*
92+
}
93+
#elif defined (__ICCARM__)
94+
MBED_NOINLINE
95+
void nu_delay_cycle_x4(uint32_t rounds)
96+
{
97+
__asm volatile(
98+
"loop: \n"
99+
#if !defined(__CORTEX_M0)
100+
" NOP \n" // 1 cycle
101+
#endif
102+
" SUBS %0, %0, #1 \n" // 1 cycle
103+
" BCS.n loop\n" // 3 cycles(M0)/2 cycles(non-M0)
104+
: "+r"(rounds)
105+
:
106+
: "cc"
107+
);
108+
}
109+
#elif defined ( __GNUC__ ) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
110+
MBED_NOINLINE
111+
void nu_delay_cycle_x4(uint32_t rounds)
112+
{
113+
__asm__ volatile(
114+
"%=:\n\t"
115+
#if !defined(__CORTEX_M0)
116+
"NOP\n\t" // 1 cycle
117+
#endif
118+
#if defined(__thumb__) && !defined(__thumb2__) && !defined(__ARMCC_VERSION)
119+
"SUB %0, #1\n\t" // 1 cycle
120+
#else
121+
"SUBS %0, %0, #1\n\t" // 1 cycle
122+
#endif
123+
"BCS %=b\n\t" // 3 cycles(M0)/2 cycles(non-M0)
124+
: "+l"(rounds)
125+
:
126+
: "cc"
127+
);
128+
}
129+
#endif

targets/TARGET_NUVOTON/nu_timer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ void nu_countdown_free(struct nu_countdown_ctx_s *ctx);
7474
*/
7575
void nu_busy_wait_us(uint32_t us);
7676

77+
/* Delay 4 cycles per round by hand-counting instruction cycles */
78+
void nu_delay_cycle_x4(uint32_t rounds);
79+
7780
#ifdef __cplusplus
7881
}
7982
#endif

0 commit comments

Comments
 (0)