@@ -28,20 +28,50 @@ uint32_t millis( void )
28
28
return GetTickCount () ;
29
29
}
30
30
31
+ // Interrupt-compatible version of micros
32
+ // Theory: repeatedly take readings of SysTick counter, millis counter and SysTick interrupt pending flag.
33
+ // When it appears that millis counter and pending is stable and SysTick hasn't rolled over, use these
34
+ // values to calculate micros. If there is a pending SysTick, add one to the millis counter in the calculation.
31
35
uint32_t micros ( void )
32
36
{
33
- uint32_t ticks ;
34
- uint32_t count ;
37
+ uint32_t ticks , ticks2 ;
38
+ uint32_t pend , pend2 ;
39
+ uint32_t count , count2 ;
40
+
41
+ ticks2 = SysTick -> VAL ;
42
+ pend2 = !!((SCB -> ICSR & SCB_ICSR_PENDSTSET_Msk )|| ((SCB -> SHCSR & SCB_SHCSR_SYSTICKACT_Msk ))) ;
43
+ count2 = GetTickCount ();
35
44
36
- SysTick -> CTRL ;
37
45
do {
38
- ticks = SysTick -> VAL ;
39
- count = GetTickCount ();
40
- } while (SysTick -> CTRL & SysTick_CTRL_COUNTFLAG_Msk );
46
+ ticks = ticks2 ;
47
+ pend = pend2 ;
48
+ count = count2 ;
49
+ ticks2 = SysTick -> VAL ;
50
+ pend2 = !!((SCB -> ICSR & SCB_ICSR_PENDSTSET_Msk )|| ((SCB -> SHCSR & SCB_SHCSR_SYSTICKACT_Msk ))) ;
51
+ count2 = GetTickCount ();
52
+ } while ((pend != pend2 ) || (count != count2 ) || (ticks < ticks2 ));
41
53
42
- return count * 1000 + (SysTick -> LOAD + 1 - ticks ) / (SystemCoreClock /1000000 ) ;
54
+ return ((count + pend ) * 1000 ) + (((SysTick -> LOAD - ticks )* (1048576 /(F_CPU /1000000 )))>>20 ) ;
55
+ // this is an optimization to turn a runtime division into two compile-time divisions and
56
+ // a runtime multiplication and shift, saving a few cycles
43
57
}
44
58
59
+ // original function:
60
+ // uint32_t micros( void )
61
+ // {
62
+ // uint32_t ticks ;
63
+ // uint32_t count ;
64
+ //
65
+ // SysTick->CTRL;
66
+ // do {
67
+ // ticks = SysTick->VAL;
68
+ // count = GetTickCount();
69
+ // } while (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk);
70
+ //
71
+ // return count * 1000 + (SysTick->LOAD + 1 - ticks) / (SystemCoreClock/1000000) ;
72
+ // }
73
+
74
+
45
75
void delay ( uint32_t ms )
46
76
{
47
77
uint32_t end = GetTickCount () + ms ;
0 commit comments