From 85915dfa16407eb4e32940c88dbc2798ffa362de Mon Sep 17 00:00:00 2001 From: bsekisser Date: Mon, 3 Mar 2014 17:14:36 -0500 Subject: [PATCH] avr_timer: changed avr_timer_write_ocr as part of larger avr_timer refactor. - 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 --- simavr/sim/avr_timer.c | 50 ++++++++++++++++++++++-------------------- simavr/sim/avr_timer.h | 18 ++++++++------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/simavr/sim/avr_timer.c b/simavr/sim/avr_timer.c index 9518e2f..81fafd9 100644 --- a/simavr/sim/avr_timer.c +++ b/simavr/sim/avr_timer.c @@ -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); diff --git a/simavr/sim/avr_timer.h b/simavr/sim/avr_timer.h index 7cb236f..87ec0b4 100644 --- a/simavr/sim/avr_timer.h +++ b/simavr/sim/avr_timer.h @@ -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 -- 2.39.5