unsigned long micros() {
unsigned long m;
uint8_t oldSREG = SREG, t1, t2;
uint16_t t;
cli();
m = timer0_overflow_count;
#if defined(TCNT0)
t1 = TCNT0;
#elif defined(TCNT0L)
t1 = TCNT0L;
#else
#error TIMER 0 not defined
#endif
#ifdef TIFR0
if ((TIFR0 & _BV(TOV0)) && (t1 < 255)) // if overflow flag is set -> increase m
m++;
#else
if ((TIFR & _BV(TOV0)) && (t1 < 255))
m++;
#endif
#if defined(TCNT0)
t2 = TCNT0;
#elif defined(TCNT0L)
t2 = TCNT0L;
#else
#error TIMER 0 not defined
#endif
if (t1 >>= t2) {
t = 510 - t2; // counter running backwards
} else {
t = t2; // counter running upwards
}
#ifdef TIFR0
if ((TIFR0 & _BV(TOV0)) && (t2 > 1)) // if overflow flag is set -> increase m
m++;
#else
if ((TIFR & _BV(TOV0)) && (t2 > 1))
m++;
#endif
SREG = oldSREG;
return ((m * 510) + t) / clockCyclesPerMicrosecond();
}
HOWEVER - this seems to bework fine but somehow there is still a bug that I could not find out. If I leave the wiring.c delayhad issues to begin with (before editing this again) function untouched,. Due to the while loop runs into an overflow condititioncounter running much faster, because it seems thatevery 268 seconds the unsigned long datatype of micros() can also decreaseoverflows and starts from one interation to anotherzero again. This leads the second while clause while ( ms > 0 && (micros() - 1000) >= start)
to overflow. I think this is dueled to microsan unwanted lockup of delay() not steadly increasing, it might fall back below its previous value for some interationespecially if long delay times, leading to a subtractionlike in my case delays of for example 984 - 1000
leading to the overflow conditionone second per loop iterations are used.
What Therefore I did is simply change the statementalso had to while ( ms > 0 && micros() >= (1000 + start))
which essentially is the same statement but much less proneadd an overflow detection to overflows. This did the trick for me and delay was running fine, now with the right timing() function in arduino wiring.c.
Here for your referenceIf the complete delay() function that togetheroverflow occurs, timing might not be very precise. But since this is once overy 268 seconds it may be acceptable. So far with this change the revamped micors() gives more or less correct timings for phase correct PWM at 31kHzdelay function works fine again on my side.
void delay(unsigned long ms)
{
uint32_t start = micros();
uint32_t elapsed = 0;
while (ms > 0) {
yield();
while ( ms > 0 && (micros() - 1000) >= (1000start + startelapsed)) {
ms--;
startelapsed += 1000;
}
if( start > micros() ) { // overflow detected
start = micros(); // reset start
elapsed = 0; // reset elapsed
}
}
}