Commit 7a98dc66cb6e11f13d2b4f055dd8c97c1143678a
authorMike Playle <mike@mythik.co.uk>
Thu, 1 Feb 2018 22:24:37 +0000 (22:24 +0000)
committerMike Playle <mike@mythik.co.uk>
Thu, 1 Feb 2018 22:30:44 +0000 (22:30 +0000)
compare" bits.

ATmega32U4 only.

3 files changed:
simavr/cores/sim_mega32u4.c
simavr/sim/avr_timer.c
simavr/sim/avr_timer.h

index ea79fac1fc5a8ccb2de3da0a4d1d6d7b398127c8..357123e21bc02140d1790cb9f1ff46cc66479a75 100644 (file)
@@ -331,6 +331,7 @@ const struct mcu_t {
                                .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),
@@ -342,6 +343,7 @@ const struct mcu_t {
                                .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),
index 2eb2009ea0b8e9262fcd97edef688fb6416b1dc3..96b40e13f69133dcc7faa32d1698367fd221d673 100644 (file)
@@ -704,6 +704,23 @@ avr_timer_write(
        }
 }
 
+/*
+ * 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.
@@ -936,6 +953,8 @@ avr_timer_init(
 
                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);
index 8e998571e433336c3498d34ebf00b3dbc08edb61..ce525923f8317e467886a4ff2cfb8973384d454b 100644 (file)
@@ -114,6 +114,7 @@ typedef struct avr_timer_comp_t {
                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 {