Sull'Arduino, tutti i timer sono configurati in modalità Phase-PWM oppure Fast-PWM per generare un segnale di ~490 Hz oppure ~976 Hz, a seconda del timer ed avere già di default la possibilità di fare un analogWrite su tutti i pin segnali come PWM.
Quindi tutti i timer vengono preconfigurati. Se devi (non tu, dico in generale) reimpostare un timer, lo devi riconfigurare completamente perché altrimenti potresti lasciare dei flag dalla configurazione originale fatta dal core di Arduino. Inoltre quando dai un cli() tu non fai altro che disattivare gli interrupt globali, ossia dici alla MCU di ignorare tutti i segnali di interrupt generati, compresi quelli sollevati dai timer. Ma i timer continuano a girare. Per fermare materialmente un timer hai 2 modi: il primo è quello di togliergli il segnale di clock, così che il contatore non venga più incrementato, il secondo è quello di togliere materialmente l'alimentazione al timer, cioè "staccare" la spina agendo sul corrispondente pin del registro PRR.
Tornando alla delay. Questo è il suo codice:
void delay(unsigned long ms)
{
uint16_t start = (uint16_t)micros();
while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
micros() conta i microsecondi con un meccanismo un pò incasinato basato sul valore del registro del timer 0 e del numero di overflow misurati (il timer 0 va in overflow con frequenza di 976 Hz, come il segnale PWM che genera).
Piuttosto, credo che il tuo problema derivi da questo:
TIMSK1 = (1 << OCIE1A) | (1 << TOIE1);
Perché attivi 2 interrupt? Quello cioè sul raggiungimento del valore di OCIE1A e quello sull'overflow? Impostando quello sul raggiungimento di OCR1A non credo che il timer scateni quello sull'overflow in modalità CTC con top fissato su OCR1A. Vado a naso, però. Non posso fare test, sono a lavoro ora.