From 709ef4b9c1ee5b1f066561c08f728424083e084a Mon Sep 17 00:00:00 2001 From: ga Date: Mon, 25 Jan 2021 19:20:32 +0000 Subject: [PATCH] Handle writing a one bit to the interrupt flag, ADIF. --- simavr/sim/avr_adc.c | 25 ++++++++++++++++++++++++- tests/attiny85_adc_test.c | 10 +++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/simavr/sim/avr_adc.c b/simavr/sim/avr_adc.c index 611cdd5..6adf1f2 100644 --- a/simavr/sim/avr_adc.c +++ b/simavr/sim/avr_adc.c @@ -251,6 +251,20 @@ avr_adc_write_adcsra( uint8_t aden = avr_regbit_get(avr, p->aden); uint8_t new_aden; + if (p->adc.raised.reg == addr) { + uint8_t mask; + + mask = 1 << p->adc.raised.bit; + if (mask & v) { + // Clear interrupt flag on bit set. + + avr_clear_interrupt(avr, &p->adc); + v &= ~mask; + } else { + v |= (mask & avr->data[p->adsc.reg]); + } + } + avr->data[p->adsc.reg] = v; new_aden = avr_regbit_get(avr, p->aden); @@ -337,12 +351,21 @@ avr_adc_irq_notify( uint8_t addr = p->adsc.reg; if (addr) { uint8_t val = avr->data[addr] | (1 << p->adsc.bit); + if (p->adc.raised.reg == addr) { + uint8_t mask; + + mask = 1 << p->adc.raised.bit; + val &= ~mask; + } + // write ADSC to ADCSRA + avr_adc_write_adcsra(avr, addr, val, param); } } } - } break; + } + break; } } diff --git a/tests/attiny85_adc_test.c b/tests/attiny85_adc_test.c index 044ddc4..23643bf 100644 --- a/tests/attiny85_adc_test.c +++ b/tests/attiny85_adc_test.c @@ -75,12 +75,15 @@ static uint16_t int_results[NUM_SUBTESTS + 2]; ISR(ADC_vect) { - /* Write the next ADCMUX/ADSRB settings. */ - if (index_i >= NUM_SUBTESTS) { + /* Done: disable auto-trigger. */ + ADCSRA &= ~(1 << ADATE); return; } + + /* Write the next ADCMUX/ADSRB settings. */ + ADMUX = params[index_i].mux; ADCSRB = params[index_i].srb; index_i++; @@ -102,12 +105,13 @@ int main(void) for (i = 0; i < NUM_SUBTESTS; ++i) { ADMUX = params[i].mux; ADCSRB = params[i].srb; - ADCSRA = (1 << ADEN) + (1 << ADSC) + 5; + ADCSRA = (1 << ADEN) + (1 << ADSC) + (1 << ADIF) + 5; while ((ADCSRA & (1 << ADIF)) == 0) ; printf(" %d", ADC); } uart_putchar('\n', stdout); + ADCSRA = (1 << ADEN) + (1 << ADIF); // Clear interrupt flag. /* Do it again with interrupts. printf() is too slow to send the * results in real time, even with maximum pre-scaler ratio. -- 2.39.5