void * param)
{
avr_timer_t * p = (avr_timer_t *)param;
- // save old bits values
- uint8_t ov = avr_regbit_get(avr, p->overflow.raised);
- uint8_t ic = avr_regbit_get(avr, p->icr.raised);
- uint8_t cp[AVR_TIMER_COMP_COUNT];
- for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++)
- cp[compi] = avr_regbit_get(avr, p->comp[compi].interrupt.raised);
+ // All bits in this register are assumed to be write-1-to-clear.
- // write the value
- // avr_core_watch_write(avr, addr, v); // This raises flags instead of clearing it.
-
- // clear any interrupts & flags
- avr_clear_interrupt_if(avr, &p->overflow, ov);
- avr_clear_interrupt_if(avr, &p->icr, ic);
+ if (addr == p->overflow.raised.reg &&
+ avr_regbit_from_value(avr, p->overflow.raised, v)) {
+ avr_clear_interrupt(avr, &p->overflow);
+ }
+ if (addr == p->icr.raised.reg &&
+ avr_regbit_from_value(avr, p->icr.raised, v)) {
+ avr_clear_interrupt(avr, &p->icr);
+ }
- for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++)
- avr_clear_interrupt_if(avr, &p->comp[compi].interrupt, cp[compi]);
+ for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
+ if (addr == p->comp[compi].interrupt.raised.reg &&
+ avr_regbit_from_value(avr, p->comp[compi].interrupt.raised,
+ v)) {
+ avr_clear_interrupt(avr, &p->comp[compi].interrupt);
+ }
+ }
}
static void
#include "avr_mcu_section.h"
AVR_MCU(F_CPU, "atmega48");
+volatile uint8_t count;
+
ISR(TIMER0_COMPA_vect)
{
+ ++count;
}
int main(void)
TCCR0B |= (1 << CS00) | (1 << CS01); // Start timer: clk/64
+ while ((TIFR0 & (1 << OCF0A)) == 0)
+ ;
+
+ // Now interrupt is pending. Try and clear it.
+
+ TIFR0 = 0;
+ if (TIFR0 & (1 << OCF0A))
+ ++count; // Should not clear
+ TIFR0 = (1 << OCF0A);
+ if ((TIFR0 & (1 << OCF0A)) == 0)
+ ++count; // Should clear!
+
sei(); // Enable global interrupts
- // here the interupts are enabled, but the interupt
- // vector should not be called
- sleep_mode();
+ // Let it run to next interrupt.
- // this should not be reached
- cli();
sleep_mode();
+ TIMSK0 = 0; // Disable CTC interrupt
+
+ if (count == 3) // Expected
+ cli();
+
+ // Time out if interrupting or count wrong.
+
+ for (;;)
+ sleep_mode();
}