From 295d6d70b233e295c5080c998b9f54306c1170cf Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Fri, 30 Nov 2012 02:12:05 +0100 Subject: [PATCH] adc: measure gain stage offset _slowly_ use running sum of 1<<6 measurements, and do only one measurement per loop in order to not disturb other measurements. Also, do not log timer overruns for ADC, as we do most of the processing in ADC IRQs now. --- firmware/adc.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/firmware/adc.c b/firmware/adc.c index ba30e5c..fa0782c 100644 --- a/firmware/adc.c +++ b/firmware/adc.c @@ -12,7 +12,8 @@ volatile static unsigned char current_adc; static uint16_t adc_sum; static unsigned char sum_shift; static unsigned char adc_vals; -static uint16_t adc1_gain20_offset_x16; +#define ADC1_GAIN20_OFFSET_SHIFT 6 +static uint16_t adc1_gain20_offset; static void inline setup_mux(unsigned char n) { @@ -28,7 +29,7 @@ static void inline setup_mux(unsigned char n) break; case 2: // pwmled 3: 1.1V, ADC4 (PA5), single-ended ADMUX = _BV(REFS1) | _BV(MUX2); - sum_shift = 2; // 4 measurements + sum_shift = 3; // 8 measurements break; case 3: // ambient light: 1.1V, ADC5 (PA6), single-ended ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX0); @@ -40,7 +41,7 @@ static void inline setup_mux(unsigned char n) break; case 5: // gain stage offset: 1.1V, ADC1,1, gain 20 ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0); - sum_shift = 3; // 8 measurements + sum_shift = 0; // 1 measurement break; } @@ -85,14 +86,15 @@ void init_adc() ; ADCSRA |= _BV(ADIF); // clear the IRQ flag - adc1_gain20_offset_x16 = 0; + adc1_gain20_offset = 0; - for (i = 0; i < 16; i++) { + for (i = 0; i < (1 << ADC1_GAIN20_OFFSET_SHIFT); i++) { ADCSRA |= _BV(ADSC); while ((ADCSRA & _BV(ADIF)) == 0) ; - adc1_gain20_offset_x16 += ADCW; + adc1_gain20_offset += ADCW + - (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT); ADCSRA |= _BV(ADIF); // clear the IRQ flag } @@ -128,18 +130,19 @@ ISR(ADC_vect) { // IRQ handler if (current_adc == ADC1_GAIN20) { // running average - adc1_gain20_offset_x16 += adcval - - (adc1_gain20_offset_x16 >> 4); + adc1_gain20_offset += adcval + - (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT); } else if (current_adc == 0 || current_adc == 1) { - uint16_t offset = adc1_gain20_offset_x16 >> 4; - if (adcval >= offset) - adcval -= offset; + uint16_t offset = adc1_gain20_offset + >> (ADC1_GAIN20_OFFSET_SHIFT - sum_shift); + if (adc_sum > offset) + adc_sum -= offset; else - adcval = 0; + adc_sum = 0; } if (current_adc < N_PWMLEDS) - pwmled_adc(current_adc, adcval); + pwmled_adc(current_adc, adc_sum); if (current_adc == AMBIENT_ADC) ambient_adc(adcval); if (current_adc == BATTERY_ADC) @@ -152,7 +155,9 @@ void timer_start_adcs() { if (current_adc == NUM_ADCS) // Don't start if in progress start_next_adc(); +#if 0 else log_byte(0x99); +#endif } -- 2.39.3