.r_ocrh = OCR1AH, // 16 bits timers have two bytes of it
.com = AVR_IO_REGBITS(TCCR1A, COM1A0, 0x3),
.com_pin = AVR_IO_REGBIT(PORTB, 5),
+ .foc = AVR_IO_REGBIT(TCCR1C, FOC1A),
.interrupt = {
.enable = AVR_IO_REGBIT(TIMSK1, OCIE1A),
.raised = AVR_IO_REGBIT(TIFR1, OCF1A),
.r_ocrh = OCR1BH,
.com = AVR_IO_REGBITS(TCCR1A, COM1B0, 0x3),
.com_pin = AVR_IO_REGBIT(PORTB, 6),
+ .foc = AVR_IO_REGBIT(TCCR1C, FOC1B),
.interrupt = {
.enable = AVR_IO_REGBIT(TIMSK1, OCIE1B),
.raised = AVR_IO_REGBIT(TIFR1, OCF1B),
}
}
+/*
+ * write to the "force output compare" bits
+ */
+static void avr_timer_write_foc(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
+{
+ avr_timer_t * p = (avr_timer_t *)param;
+
+ /* These are strobe writes, so just decode them, don't store them */
+
+ for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
+ if ((addr == p->comp[compi].foc.reg) &&
+ (v & (1 << p->comp[compi].foc.bit))) {
+ avr_timer_comp(p, avr->cycle, compi);
+ }
+ }
+}
+
/*
* write to the TIFR register. Watch for code that writes "1" to clear
* pending interrupts.
if (p->comp[compi].r_ocr) // not all timers have all comparators
avr_register_io_write(avr, p->comp[compi].r_ocr, avr_timer_write_ocr, &p->comp[compi]);
+ if (p->comp[compi].foc.reg)
+ avr_register_io_write(avr, p->comp[compi].foc.reg, avr_timer_write_foc, p);
}
avr_register_io_write(avr, p->r_tcnt, avr_timer_tcnt_write, p);
avr_register_io_read(avr, p->r_tcnt, avr_timer_tcnt_read, p);
avr_regbit_t com; // comparator output mode registers
avr_regbit_t com_pin; // where comparator output is connected
uint64_t comp_cycles;
+ avr_regbit_t foc; // "force compare match" strobe
} avr_timer_comp_t, *avr_timer_comp_p;
enum {