|
|
@ -43,17 +43,28 @@ uint32_t millis() { |
|
|
|
return _millis; |
|
|
|
} |
|
|
|
|
|
|
|
//todo: recheck all of this
|
|
|
|
void delayMicroseconds(uint32_t us) { |
|
|
|
if (us < 2) return; // function jump, compare, return about 1us
|
|
|
|
us--; |
|
|
|
static const int nop_factor = (SystemCoreClock / 10000000); // measured accurate at 10us
|
|
|
|
static const int nop_factor = (SystemCoreClock / 11000000); |
|
|
|
static volatile int loops = 0; |
|
|
|
if (us < 20) { // burn cycles
|
|
|
|
|
|
|
|
//previous ops already burned most of 1us, burn the rest
|
|
|
|
loops = nop_factor / 4; //measured at 1us
|
|
|
|
while (loops > 0) --loops; |
|
|
|
|
|
|
|
if (us < 2) return; |
|
|
|
us--; |
|
|
|
|
|
|
|
//redirect to delay for large values, then set new delay to remainder
|
|
|
|
if (us > 1000) { |
|
|
|
delay(us / 1000); |
|
|
|
us = us % 1000; |
|
|
|
} |
|
|
|
|
|
|
|
if (us < 5) { // burn cycles, time in interrupts will not be taken into account
|
|
|
|
loops = us * nop_factor; |
|
|
|
while (loops > 0) --loops; |
|
|
|
} |
|
|
|
else { // poll systick
|
|
|
|
else { // poll systick, more accurate through interrupts
|
|
|
|
int32_t start = SysTick->VAL; |
|
|
|
int32_t load = SysTick->LOAD; |
|
|
|
int32_t end = start - (load / 1000) * us; |
|
|
@ -67,6 +78,8 @@ void delayMicroseconds(uint32_t us) { |
|
|
|
|
|
|
|
extern "C" void delay(int msec) { |
|
|
|
volatile int32_t end = _millis + msec; |
|
|
|
SysTick->VAL = SysTick->LOAD; // reset systick counter so next systick is in exactly 1ms
|
|
|
|
// this could extend the time between systicks by upto 1ms
|
|
|
|
while (_millis < end) __WFE(); |
|
|
|
} |
|
|
|
|
|
|
|