|
@@ -43,17 +43,28 @@ uint32_t millis() {
|
43
|
43
|
return _millis;
|
44
|
44
|
}
|
45
|
45
|
|
46
|
|
-//todo: recheck all of this
|
47
|
46
|
void delayMicroseconds(uint32_t us) {
|
48
|
|
- if (us < 2) return; // function jump, compare, return about 1us
|
49
|
|
- us--;
|
50
|
|
- static const int nop_factor = (SystemCoreClock / 10000000); // measured accurate at 10us
|
|
47
|
+ static const int nop_factor = (SystemCoreClock / 11000000);
|
51
|
48
|
static volatile int loops = 0;
|
52
|
|
- if (us < 20) { // burn cycles
|
|
49
|
+
|
|
50
|
+ //previous ops already burned most of 1us, burn the rest
|
|
51
|
+ loops = nop_factor / 4; //measured at 1us
|
|
52
|
+ while (loops > 0) --loops;
|
|
53
|
+
|
|
54
|
+ if (us < 2) return;
|
|
55
|
+ us--;
|
|
56
|
+
|
|
57
|
+ //redirect to delay for large values, then set new delay to remainder
|
|
58
|
+ if (us > 1000) {
|
|
59
|
+ delay(us / 1000);
|
|
60
|
+ us = us % 1000;
|
|
61
|
+ }
|
|
62
|
+
|
|
63
|
+ if (us < 5) { // burn cycles, time in interrupts will not be taken into account
|
53
|
64
|
loops = us * nop_factor;
|
54
|
65
|
while (loops > 0) --loops;
|
55
|
66
|
}
|
56
|
|
- else { // poll systick
|
|
67
|
+ else { // poll systick, more accurate through interrupts
|
57
|
68
|
int32_t start = SysTick->VAL;
|
58
|
69
|
int32_t load = SysTick->LOAD;
|
59
|
70
|
int32_t end = start - (load / 1000) * us;
|
|
@@ -67,6 +78,8 @@ void delayMicroseconds(uint32_t us) {
|
67
|
78
|
|
68
|
79
|
extern "C" void delay(int msec) {
|
69
|
80
|
volatile int32_t end = _millis + msec;
|
|
81
|
+ SysTick->VAL = SysTick->LOAD; // reset systick counter so next systick is in exactly 1ms
|
|
82
|
+ // this could extend the time between systicks by upto 1ms
|
70
|
83
|
while (_millis < end) __WFE();
|
71
|
84
|
}
|
72
|
85
|
|