diff --git a/cores/arduino/delay.h b/cores/arduino/delay.h index 527bf464815b5893cf5f6e4568946481f9730cb2..854617869e94b4deb1be4ae1fba15c89f11ff390 100644 --- a/cores/arduino/delay.h +++ b/cores/arduino/delay.h @@ -61,40 +61,40 @@ extern void delay( uint32_t dwMs ) ; * \param dwUs the number of microseconds to pause (uint32_t) */ static __inline__ void delayMicroseconds( uint32_t ) __attribute__((always_inline, unused)) ; -static __inline__ void delayMicroseconds( uint32_t ul_usec ) +static __inline__ void delayMicroseconds( uint32_t usec ) { - if ( ul_usec == 0 ) + if ( usec == 0 ) { return ; } - uint32_t ul = ul_usec * (VARIANT_MCK / 3000000); // = ul_usec * 16 with VARIANT_MCK @ 48MHz - -/* following 'for' loop will generate this: - * loop: - * subs r3, #1 // 1 Core cycle - * bne.n loop // 1 or 2 Core cycles, depends on pipeline break (50/50?) - - for ( ; ul != 0 ; ul-- ) - { - __asm__ volatile(""); - } -*/ - -/* - * __asm__ [__volatile__] ( AssemblerTemplate : [OutputOperands] [ : [InputOperands] [ : [Clobbers] ] ] ) - * - * __asm__ documentation for GCC: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html - * __volatile__ documentation for GCC: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile - * - */ - __asm__ __volatile__( "1: \n" - "sub %0, #1 \n" /* substract 1 from %0 (ul) */ - "bne 1b \n" - : /* no outputs */ - : "r" (ul) /* 'ul' variable is '%0', '+' means R/W constraint on this variable/register, 'r' means 'register' (versus 'm' for 'memory' */ - : /* no clobber, ie nothing should be damaged by this asm code */ - ) ; + /* + * The following loop: + * + * for (; ul; ul--) { + * __asm__ volatile(""); + * } + * + * produce the following assembly code: + * + * loop: + * subs r3, #1 // 1 Core cycle + * bne.n loop // 1 Core cycle + 1 if branch is taken + */ + + // VARIANT_MCK / 1000000 == cycles needed to delay 1uS + // 3 == cycles used in a loop + uint32_t n = usec * (VARIANT_MCK / 1000000) / 3; + __asm__ __volatile__( + "1: \n" + " sub %0, #1 \n" // substract 1 from %0 (n) + " bne 1b \n" // if result is not 0 jump to 1 + : "+r" (n) // '%0' is n variable with RW constraints + : // no input + : // no clobber + ); + // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html + // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile } #ifdef __cplusplus