ADCSRA |= _BV(ADSC);
}
+/*
+ * Single synchronous ADC conversion.
+ * Has to be called with IRQs disabled (or with the ADC IRQ disabled).
+ */
+static uint16_t read_adc_sync()
+{
+ uint16_t rv;
+
+ ADCSRA |= _BV(ADSC); // start the conversion
+
+ // wait for the conversion to finish
+ while((ADCSRA & _BV(ADIF)) == 0)
+ ;
+
+ rv = ADCW;
+ ADCSRA |= _BV(ADIF); // clear the IRQ flag
+
+ return rv;
+}
+
void init_adc()
{
unsigned char i;
// 1.1V, ADC1,1, gain 20
ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
- ADCSRA |= _BV(ADSC);
/* Do first conversion and drop the result */
- while ((ADCSRA & _BV(ADIF)) == 0)
- ;
- ADCSRA |= _BV(ADIF); // clear the IRQ flag
+ read_adc_sync();
adc1_gain20_offset = 0;
for (i = 0; i < (1 << ADC1_GAIN20_OFFSET_SHIFT); i++) {
- ADCSRA |= _BV(ADSC);
-
- while ((ADCSRA & _BV(ADIF)) == 0)
- ;
- adc1_gain20_offset += ADCW
+ adc1_gain20_offset += read_adc_sync()
- (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
-
- ADCSRA |= _BV(ADIF); // clear the IRQ flag
}
ADCSRA |= _BV(ADIE); // enable IRQ