Commit 85915dfa16407eb4e32940c88dbc2798ffa362de
authorbsekisser <squirmyworms@embarqmail.com>
Mon, 3 Mar 2014 22:14:36 +0000 (17:14 -0500)
committerbsekisser <squirmyworms@embarqmail.com>
Mon, 3 Mar 2014 22:14:36 +0000 (17:14 -0500)
- changed avr_timer_write_ocr code to take pointer of relevant
   comparator structure rather than its parent timer.

- added _timer_get_comp_ocr which the modified avr_timer_write_ocr
function uses.

modified:   simavr/sim/avr_timer.c
modified:   simavr/sim/avr_timer.h

2 files changed:
simavr/sim/avr_timer.c
simavr/sim/avr_timer.h

index 9518e2fb0c3889e0d417efad0f1599e60871421f..81fafd92d2ab09c19d3f02659aa2df5760cd099b 100644 (file)
@@ -38,6 +38,12 @@ static uint16_t _timer_get_ocr(avr_timer_t * p, int compi)
        return p->io.avr->data[p->comp[compi].r_ocr] |
                      (p->comp[compi].r_ocrh ? (p->io.avr->data[p->comp[compi].r_ocrh] << 8) : 0);
 }
+static uint16_t _timer_get_comp_ocr(struct avr_t * avr, avr_timer_comp_p comp)
+{
+       int ocrh = comp->r_ocrh;
+       return avr->data[comp->r_ocr] |
+               (ocrh ? (avr->data[ocrh] << 8) : 0);
+}
 static uint16_t _timer_get_tcnt(avr_timer_t * p)
 {
        return p->io.avr->data[p->r_tcnt] |
@@ -283,45 +289,39 @@ static void avr_timer_reconfigure(avr_timer_t * p)
 
 static void avr_timer_write_ocr(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
 {
-       avr_timer_t * p = (avr_timer_t *)param;
-       uint16_t oldv[AVR_TIMER_COMP_COUNT];
-       int target = -1;
+       avr_timer_comp_p comp = (avr_timer_comp_p)param;
+       avr_timer_t *timer = comp->timer;
+       uint16_t oldv;
 
        /* check to see if the OCR values actually changed */
-       for (int oi = 0; oi < AVR_TIMER_COMP_COUNT; oi++)
-               oldv[oi] = _timer_get_ocr(p, oi);
+       oldv = _timer_get_comp_ocr(avr, comp);
        avr_core_watch_write(avr, addr, v);
-       for (int oi = 0; oi < AVR_TIMER_COMP_COUNT; oi++)
-               if (oldv[oi] != _timer_get_ocr(p, oi)) {
-                       target = oi;
-                       break;
-               }
 
-       switch (p->mode.kind) {
+       switch (timer->mode.kind) {
                case avr_timer_wgm_normal:
-                       avr_timer_reconfigure(p);
+                       avr_timer_reconfigure(timer);
                        break;
                case avr_timer_wgm_fc_pwm:      // OCR is not used here
-                       avr_timer_reconfigure(p);
+                       avr_timer_reconfigure(timer);
                        break;
                case avr_timer_wgm_ctc:
-                       avr_timer_reconfigure(p);
+                       avr_timer_reconfigure(timer);
                        break;
                case avr_timer_wgm_pwm:
-                       if (p->mode.top != avr_timer_wgm_reg_ocra) {
-                               avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocr(p, AVR_TIMER_COMPA));
-                               avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocr(p, AVR_TIMER_COMPB));
+                       if (timer->mode.top != avr_timer_wgm_reg_ocra) {
+                               avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocr(timer, AVR_TIMER_COMPA));
+                               avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocr(timer, AVR_TIMER_COMPB));
                        }
                        break;
                case avr_timer_wgm_fast_pwm:
-                       if (target != -1)
-                               avr_timer_reconfigure(p);
-                       avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocr(p, AVR_TIMER_COMPA));
-                       avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocr(p, AVR_TIMER_COMPB));
+                       if (oldv != _timer_get_comp_ocr(avr, comp))
+                               avr_timer_reconfigure(timer);
+                       avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocr(timer, AVR_TIMER_COMPA));
+                       avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocr(timer, AVR_TIMER_COMPB));
                        break;
                default:
-                       AVR_LOG(avr, LOG_WARNING, "TIMER: %s-%c mode %d UNSUPPORTED\n", __FUNCTION__, p->name, p->mode.kind);
-                       avr_timer_reconfigure(p);
+                       AVR_LOG(avr, LOG_WARNING, "TIMER: %s-%c mode %d UNSUPPORTED\n", __FUNCTION__, timer->name, timer->mode.kind);
+                       avr_timer_reconfigure(timer);
                        break;
        }
 }
@@ -478,10 +478,12 @@ void avr_timer_init(avr_t * avr, avr_timer_t * p)
         * the trigger.
         */
        for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
+               p->comp[compi].timer = p;
+               
                avr_register_vector(avr, &p->comp[compi].interrupt);
 
                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);
+                       avr_register_io_write(avr, p->comp[compi].r_ocr, avr_timer_write_ocr, &p->comp[compi]);
        }
        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 7cb236ff3f41872ca55ca8eb3dd8770ef22839b6..87ec0b4889892ae61ed87252ae7c3759985759c2 100644 (file)
@@ -88,6 +88,15 @@ typedef struct avr_timer_wgm_t {
 #define AVR_TIMER_WGM_OCPWM() { .kind = avr_timer_wgm_pwm, .top = avr_timer_wgm_reg_ocra }
 #define AVR_TIMER_WGM_ICPWM() { .kind = avr_timer_wgm_pwm, .top = avr_timer_wgm_reg_icr }
 
+typedef struct avr_timer_comp_t {
+               avr_int_vector_t        interrupt;              // interrupt vector
+               struct avr_timer_t      *timer;                 // parent timer
+               avr_io_addr_t           r_ocr;                  // comparator register low byte
+               avr_io_addr_t           r_ocrh;                 // comparator register hi byte
+               avr_regbit_t            com;                    // comparator output mode registers
+               avr_regbit_t            com_pin;                // where comparator output is connected
+               uint64_t                comp_cycles;
+} avr_timer_comp_t, *avr_timer_comp_p;
 
 typedef struct avr_timer_t {
        avr_io_t        io;
@@ -107,14 +116,7 @@ typedef struct avr_timer_t {
        avr_regbit_t    icp;            // input capture pin, to link IRQs
        avr_regbit_t    ices;           // input capture edge select
 
-       struct {
-               avr_int_vector_t        interrupt;              // interrupt vector
-               avr_io_addr_t           r_ocr;                  // comparator register low byte
-               avr_io_addr_t           r_ocrh;                 // comparator register hi byte
-               avr_regbit_t            com;                    // comparator output mode registers
-               avr_regbit_t            com_pin;                // where comparator output is connected
-               uint64_t                        comp_cycles;
-       } comp[AVR_TIMER_COMP_COUNT];
+       avr_timer_comp_t comp[AVR_TIMER_COMP_COUNT];
 
        avr_int_vector_t overflow;      // overflow
        avr_int_vector_t icr;   // input capture