X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=simavr%2Fsim%2Favr_adc.c;h=a88f335679697ae2c67468bb2c0633038b77d230;hb=2cfe735034b602ecfd9188b2970389719edfb804;hp=781bba373bd48c5dcfcb35e108cea42314e4fff6;hpb=bc864086a6b92f7409c72561bce2e604f6e324ba;p=simavr diff --git a/simavr/sim/avr_adc.c b/simavr/sim/avr_adc.c index 781bba3..a88f335 100644 --- a/simavr/sim/avr_adc.c +++ b/simavr/sim/avr_adc.c @@ -1,7 +1,7 @@ /* avr_adc.c - Copyright 2008, 2009 Michel Pollet + Copyright 2008, 2010 Michel Pollet This file is part of simavr. @@ -22,6 +22,7 @@ #include #include #include +#include "sim_time.h" #include "avr_adc.h" static avr_cycle_count_t avr_adc_int_raise(struct avr_t * avr, avr_cycle_count_t when, void * param) @@ -49,7 +50,7 @@ static uint8_t avr_adc_read_l(struct avr_t * avr, avr_io_addr_t addr, void * par uint8_t muxi = avr_regbit_get_array(avr, p->mux, ARRAY_SIZE(p->mux)); avr_adc_mux_t mux = p->muxmode[muxi]; // optional shift left/right - uint8_t shift = avr_regbit_get(avr, p->adlar) ? 0 : 6; + uint8_t shift = avr_regbit_get(avr, p->adlar) ? 6 : 0; // shift LEFT uint32_t reg = 0; switch (mux.kind) { @@ -68,18 +69,30 @@ static uint8_t avr_adc_read_l(struct avr_t * avr, avr_io_addr_t addr, void * par case ADC_MUX_REF: reg = mux.src; // reference voltage break; + case ADC_MUX_VCC4: + if ( !avr->vcc) { + AVR_LOG(avr, LOG_WARNING, "ADC: missing VCC analog voltage\n"); + } else + reg = avr->vcc / 4; + break; } uint32_t vref = 3300; switch (ref) { + case ADC_VREF_VCC: + if (!avr->vcc) + AVR_LOG(avr, LOG_WARNING, "ADC: missing VCC analog voltage\n"); + else + vref = avr->vcc; + break; case ADC_VREF_AREF: if (!avr->aref) - printf("ADC Warning : missing AREF analog voltage\n"); + AVR_LOG(avr, LOG_WARNING, "ADC: missing AREF analog voltage\n"); else vref = avr->aref; break; case ADC_VREF_AVCC: if (!avr->avcc) - printf("ADC Warning : missing AVCC analog voltage\n"); + AVR_LOG(avr, LOG_WARNING, "ADC: missing AVCC analog voltage\n"); else vref = avr->avcc; break; @@ -92,7 +105,7 @@ static uint8_t avr_adc_read_l(struct avr_t * avr, avr_io_addr_t addr, void * par reg = (reg * 0x3ff) / vref; // scale to 10 bits ADC // printf("ADC to 10 bits 0x%x %d\n", reg, reg); if (reg > 0x3ff) { - printf("ADC Warning channel %d clipped %u/%u VREF %d\n", mux.kind, reg, 0x3ff, vref); + AVR_LOG(avr, LOG_WARNING, "ADC: channel %d clipped %u/%u VREF %d\n", mux.kind, reg, 0x3ff, vref); reg = 0x3ff; } reg <<= shift; @@ -142,12 +155,13 @@ static void avr_adc_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, voi if (!aden && avr_regbit_get(avr, p->aden)) { // first conversion p->first = 1; - printf("ADC Start AREF %d AVCC %d\n", avr->aref, avr->avcc); + AVR_LOG(avr, LOG_TRACE, "ADC: Start AREF %d AVCC %d\n", avr->aref, avr->avcc); } if (aden && !avr_regbit_get(avr, p->aden)) { // stop ADC avr_cycle_timer_cancel(avr, avr_adc_int_raise, p); avr_regbit_clear(avr, p->adsc); + v = avr->data[p->adsc.reg]; // Peter Ross pross@xvid.org } if (!adsc && avr_regbit_get(avr, p->adsc)) { // start one! @@ -164,7 +178,7 @@ static void avr_adc_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, voi div = avr->frequency >> div; if (p->first) - printf("ADC starting at %uKHz\n", div / 13 / 100); + AVR_LOG(avr, LOG_TRACE, "ADC: starting at %uKHz\n", div / 13 / 100); div /= p->first ? 25 : 13; // first cycle is longer avr_cycle_timer_register(avr, @@ -206,22 +220,42 @@ static void avr_adc_reset(avr_io_t * port) avr_irq_register_notify(p->io.irq + i, avr_adc_irq_notify, p); } +static const char * irq_names[ADC_IRQ_COUNT] = { + [ADC_IRQ_ADC0] = "16io = _io; - // allocate this module's IRQ - p->io.irq_count = ADC_IRQ_COUNT; - p->io.irq = avr_alloc_irq(0, p->io.irq_count); - p->io.irq_ioctl_get = AVR_IOCTL_ADC_GETIRQ; - avr_register_io(avr, &p->io); avr_register_vector(avr, &p->adc); + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_ADC_GETIRQ, ADC_IRQ_COUNT, NULL); avr_register_io_write(avr, p->r_adcsra, avr_adc_write, p); avr_register_io_read(avr, p->r_adcl, avr_adc_read_l, p);