Skip to content

Commit 56c096b

Browse files
committed
Fixed delayMicrosecond for non-constant case.
1 parent 2cba113 commit 56c096b

File tree

1 file changed

+29
-29
lines changed

1 file changed

+29
-29
lines changed

cores/arduino/delay.h

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -61,40 +61,40 @@ extern void delay( uint32_t dwMs ) ;
6161
* \param dwUs the number of microseconds to pause (uint32_t)
6262
*/
6363
static __inline__ void delayMicroseconds( uint32_t ) __attribute__((always_inline, unused)) ;
64-
static __inline__ void delayMicroseconds( uint32_t ul_usec )
64+
static __inline__ void delayMicroseconds( uint32_t usec )
6565
{
66-
if ( ul_usec == 0 )
66+
if ( usec == 0 )
6767
{
6868
return ;
6969
}
7070

71-
uint32_t ul = ul_usec * (VARIANT_MCK / 3000000); // = ul_usec * 16 with VARIANT_MCK @ 48MHz
72-
73-
/* following 'for' loop will generate this:
74-
* loop:
75-
* subs r3, #1 // 1 Core cycle
76-
* bne.n loop // 1 or 2 Core cycles, depends on pipeline break (50/50?)
77-
78-
for ( ; ul != 0 ; ul-- )
79-
{
80-
__asm__ volatile("");
81-
}
82-
*/
83-
84-
/*
85-
* __asm__ [__volatile__] ( AssemblerTemplate : [OutputOperands] [ : [InputOperands] [ : [Clobbers] ] ] )
86-
*
87-
* __asm__ documentation for GCC: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
88-
* __volatile__ documentation for GCC: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile
89-
*
90-
*/
91-
__asm__ __volatile__( "1: \n"
92-
"sub %0, #1 \n" /* substract 1 from %0 (ul) */
93-
"bne 1b \n"
94-
: /* no outputs */
95-
: "r" (ul) /* 'ul' variable is '%0', '+' means R/W constraint on this variable/register, 'r' means 'register' (versus 'm' for 'memory' */
96-
: /* no clobber, ie nothing should be damaged by this asm code */
97-
) ;
71+
/*
72+
* The following loop:
73+
*
74+
* for (; ul; ul--) {
75+
* __asm__ volatile("");
76+
* }
77+
*
78+
* produce the following assembly code:
79+
*
80+
* loop:
81+
* subs r3, #1 // 1 Core cycle
82+
* bne.n loop // 1 Core cycle + 1 if branch is taken
83+
*/
84+
85+
// VARIANT_MCK / 1000000 == cycles needed to delay 1uS
86+
// 3 == cycles used in a loop
87+
uint32_t n = usec * (VARIANT_MCK / 1000000) / 3;
88+
__asm__ __volatile__(
89+
"1: \n"
90+
" sub %0, #1 \n" // substract 1 from %0 (n)
91+
" bne 1b \n" // if result is not 0 jump to 1
92+
: "+r" (n) // '%0' is n variable with RW constraints
93+
: // no input
94+
: // no clobber
95+
);
96+
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
97+
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile
9898
}
9999

100100
#ifdef __cplusplus

0 commit comments

Comments
 (0)