I have had to use Timer0 with phase correct PWM and a prescaler of 1. This results in a 32khz PWM frequency and obviously impacts millis, delay and micros. (Timer1 and Timer 2 are also in use so changing to those is not an option)
millis() is trivial to work around - multiply by 32 as the TOV0 interrupt handler is called 32 times more frequently (subject to overflow of course)
micros() is somewhat trickier - as normally it is the Timer0 overflow count (as used in millis() though shifted in this case) plus the current value of TCNT0. That works great when TCNT0 is increasing only and resetting to 0 after MAX - but in phase correct PWM it could be going upwards or downwards.
I think what I need to do is find the direction the Timer is currently using - but pouring over the datasheet for the ATmega328P I can't seem to find a way to do so...
Is there a way of reading this, eg from a register I can interrogate for it?
Alternatively can anyone else think of a way to get microsecond (or close - 10 microsecond would be good enough) resolution when all timers are in phase correct mode?
I'm considering a fall-back of reading TCNT0 twice and deriving it from that - with a prescaler of 1I am assuming it is not possible to read it twice faster than it could change - however I'd prefer a neater solution if there is one.
micros()
?OC0x
register. I don't have an atmega328p at hand now, but you can test it out. The relevant part in the datasheet:In non-inverting compare output mode, the output compare (OC0x) is cleared on the compare match between TCNT0 and OCR0x while upcounting, and set on the compare match while downcounting. In inverting output compare mode, the operation is inverted.
(header14.7.4 Phase Correct PWM Mode
)