Handle writing a one bit to the interrupt flag, ADIF.
authorga <ga@oldell.fish>
Mon, 25 Jan 2021 19:20:32 +0000 (19:20 +0000)
committerga <ga@oldell.fish>
Tue, 26 Jan 2021 13:50:18 +0000 (13:50 +0000)
simavr/sim/avr_adc.c
tests/attiny85_adc_test.c

index 611cdd5..6adf1f2 100644 (file)
@@ -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;
        }
 }
 
index 044ddc4..23643bf 100644 (file)
@@ -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.