Commit 93513b8f authored by Sandeep Mistry's avatar Sandeep Mistry

Port delayMicroseconds from SAMD core

parent 888798d6
...@@ -25,6 +25,8 @@ extern "C" { ...@@ -25,6 +25,8 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include "variant.h"
/** /**
* \brief Returns the number of milliseconds since the Arduino board began running the current program. * \brief Returns the number of milliseconds since the Arduino board began running the current program.
* *
...@@ -59,7 +61,42 @@ extern void delay( uint32_t dwMs ) ; ...@@ -59,7 +61,42 @@ extern void delay( uint32_t dwMs ) ;
* *
* \param dwUs the number of microseconds to pause (uint32_t) * \param dwUs the number of microseconds to pause (uint32_t)
*/ */
extern void delayMicroseconds( uint32_t usec ) ; static __inline__ void delayMicroseconds( uint32_t ) __attribute__((always_inline, unused)) ;
static __inline__ void delayMicroseconds( uint32_t usec )
{
if ( usec == 0 )
{
return ;
}
/*
* 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 #ifdef __cplusplus
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment