Adjust time calculation after Timer0 frequency change
Fixing the timekeeping functions with your PWM settings is not so
simple. You should at least try to rewrite ISR(TIMER0_OVF_vect),
micros(), and probably delay(). Here is why:

First, there is a rounding problem. Time is kept using two global
variables:



volatile unsigned long timer0_millis;
static unsigned char timer0_fract;


The first one is what millis() returns. The second one keeps track of
how much time has passed since the last full millisecond, and it does so
in units of 8&nbsp;µs. The two variables are incremented by
ISR(TIMER0_OVF_vect) like this:

m += MILLIS_INC;  // temporary copy of timer0_millis
f += FRACT_INC;   // temporary copy of timer0_fract


On a normal Uno configuration, the ISR is called every 1024&nbsp;µs.
Then MILLIS_INC is 1 and FRACT_INC is 3. With your timer
configuration, the ISR is called every 31.875&nbsp;µs (510 cycles), then
MILLIS_INC should be 0 and FRACT_INC should be 3.984375. But since
we are dealing with integers, it will be rounded down to 3, and your
millis() will tick about 25% too slow.

A simple fix would be to

#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(1 * 512))


in order for FRACT_INC to be 4 and millis() to be 0.4% too fast. Or
you could make timer0_fract a 16-bit variable and have it count clock
cycles, just to avoid this error. Either option should fix millis(),
but you still have a problem with micros().

micros() works by reading both timer0_overflow_count (incremented by
1 in the ISR) and the actual counter value. Since your counter is now
going alternatively up and down, it will be harder to compute a
microsecond count from these readings. Maybe you could take two
consecutive readings of the counter, just to know whether it is going up
or down...

And then there is delay(), which relies on micros(). If you fix
micros(), delay() should work fine. If not, You could rewrite
delay() to use millis() instead, which should be easy but you will
loose some accuracy.