Go Down

Topic: realtime clock, microseconds, etc. (Read 10 times) previous topic - next topic

dcb

updated micros, passes all test thus far:

Code: [Select]

unsigned long micros()
{
 unsigned long m, t;
 uint8_t oldSREG = SREG;
 cli();
 t = TCNT0;
 if ((TIFR0 & _BV(TOV0)) && (t == 0))
   t = 256;
 m = timer0_tics;
 SREG = oldSREG;
#if F_CPU >= 16000000L
 return ((m << 8) + t) <<2;
#else
 return ((m << 8) + t) <<3;
#endif  
 
}

mikalhart

#31
Nov 11, 2008, 03:25 pm Last Edit: Nov 11, 2008, 03:31 pm by mikalhart Reason: 1
@dcb--

If you just change your hpticks derivative in reply 24 from

Code: [Select]
 unsigned long t0_ticks = (clock_cycles / 64) + (millis * (1000L * clockCyclesPerMicrosecond() / 64)) + t0;
 return ((t0_ticks) * 64L / (F_CPU / 1000000L));


to

Code: [Select]
 unsigned long t0_ticks = (clock_cycles / 64UL) + t0;
 return 1000 * millis + t0_ticks * 64UL / clockCyclesPerMicrosecond();


the 268-second micros() overflow problem goes away (overflows at the 32-bit boundary).  (This change avoids the unnecessary translation of millis into the "tick" domain and then back into the "micro" domain.)

This seems ideal to me.  No changing wiring.c and all the benefits of Don's and dcb's work.  It also has the added benefit of working with the 20MHz clock (I think).  Do you agree?

Mikal

dcb

Mikal, I do appreciate the investigation, but let me get a read from you on the function in reply 30 first.

Having seen this approach work 5 times faster than the no-change to wiring version, you can imagine I want the fast one :)

mikalhart

On the surface it looks good!  I'll study it enthusiastically later on.  (At some point I need to pretend to be doing "real" work today. :))  

Nice work!  This is fun.

Mikal

dcb

fyi, timer0_tics appears to be identical to the former timer0_overflow_count  ::)

Go Up