55#include <avr/io.h>
66#include "as_common.h"
77
8+ #define CPU_MHZ (F_CPU / 1000000)
9+
810extern uint32_t micros_raw ();
911uint32_t micros ()
1012{
1113 register uint32_t u asm("r22" );
12- // asm ("%~call %x1" : "=r" (u) : "i"(micros_raw) : "r30", "r31" );
13- //return u * 4;
14- asm (
15- "%~call %x1 \n"
16- "ldi r30, lo8(T0_SCALE + 2) \n"
17- "rcall lsl4_r22_r30 \n"
18- : "=r" ( u ) : "i" ( micros_raw ) : "r30" , "r31"
19- );
20- return u ;
14+ asm ("%~call %x1" : "=r" (u ) : "i" (micros_raw ) : "r30" , "r31" );
15+ // split into lower 8 & upper 24-bits
16+ uint8_t t0 = u & 0xFF ;
17+ __uint24 u3 = u >> 8 ;
18+
19+ //return (u3 * 1000) + (t0 * (uint8_t)(T0_PRESCALE / CPU_MHZ));
20+ // shift + add saves 24B vs * 1000, asm would be a bit smaller
21+ return ( (( u3 << 7 ) - (( u3 << 1 ) + u3 )) << 3 ) +
22+ ( t0 * ( uint8_t )( T0_PRESCALE / CPU_MHZ )) ;
2123}
2224
2325extern uint32_t millis_impl ();
2426uint32_t millis ()
2527{
28+ register uint32_t m asm("r22" );
29+ asm ("%~call %x1" : "=r" (m ) : "i" (millis_impl ) : "r30" , "r31" );
2630 return millis_impl ();
2731}
2832
29- #define CPU_MHZ (F_CPU / 1000000)
3033#define MICROS_PER_T0_OVFL ((T0_PRESCALE * 256) / CPU_MHZ)
3134#define MILLIS_INC (MICROS_PER_T0_OVFL / 1000)
3235#define FRACT_INC ((MICROS_PER_T0_OVFL % 1000) >> 2)
@@ -40,9 +43,6 @@ void init_millis()
4043 asm ( ".global FRACT_INC\n" );
4144 asm ( ".equ FRACT_INC, %0\n" :: "M" (FRACT_INC ) );
4245
43- // scaling factor for t0 vs 16Mhz
44- uint8_t t0_scale = log2 (16000000 /F_CPU );
45- asm ( ".equ T0_SCALE, %0\n" :: "M" (t0_scale ) );
4646 TIMSK0 = _BV (TOIE0 ); // enable T0 overflow interrupt
4747}
4848
0 commit comments