It appears to me that the original code should work with any clock frequency in a reasonable range
The reasonable range is 1, 2, 4, 8, and 16 MHz. The code produces an inaccurate millis
) at all other clock frequencies.
whereas your code only works at 8, 16 and 20MHz
By design. It's meant solely as a test case for someone with a 20 MHz board.
As a minimum, I would add "#else <newline> #error This code only works with F_CPU = 8000000, 16000000 or 20000000" before the first #endif in your code.
As folks test it and provide feedback, I will fill it out (e.g. try to fix micros
) and add support for more clock frequencies (and a trap for unsupported frequencies as you suggested).
Thank you for the feedback!
What is the reason that the original code isn't accurate enough?
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
The assumption is that FRACT_INC is a whole number. At 16 MHz, the actual value is exactly 3. At 20 MHz, the actual value is 102.4. The 0.4 is truncated away leaving a 0.39% error.
Could it be improved so that it is more accurate, while still retaining the ability to work with any reasonable F_CPU?
I believe making the fraction variables 16 bit would eliminate the error for 20 MHz but there is not a general purpose solution that addresses all clock frequencies.