From d92ecc1a02b2e054debc1bb9f1732181b7756f63 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Thu, 28 Mar 2013 23:33:25 +0100 Subject: [PATCH] slow ADC inputs The fastest-repeated measurements are needed for PWM LEDs. OTOH, things like buttons, battery voltage, ambient lights, etc. can be read less frequently, and should be read in a deterministic time frame. So we will measure PWMLED current in the free-running mode (as fast as possible), and the other "slow" ADC inputs with each PATTERN_DIV-th timer tick. --- firmware/adc.c | 39 +++++++++++++++++++++++++++------------ firmware/lights.h | 2 +- firmware/tmr.c | 3 +-- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/firmware/adc.c b/firmware/adc.c index 70c2aa1..ef71477 100644 --- a/firmware/adc.c +++ b/firmware/adc.c @@ -25,7 +25,7 @@ struct { { 0, 1, 0 }, // buttons }; -volatile static unsigned char current_adc; +volatile static unsigned char current_adc, current_slow_adc; static uint16_t adc_sum, zero_count, drop_count, read_count, n_reads_log; #define ADC1_GAIN20_OFFSET_SHIFT 6 static uint16_t adc1_gain20_offset; @@ -65,14 +65,26 @@ static void setup_mux(unsigned char n) static void start_next_adc() { - if (current_adc > 0) { - current_adc--; + if (current_adc == 0) { + if (current_slow_adc > N_PWMLEDS) { + // read one of the non-PWMLED ADCs + current_adc = --current_slow_adc; + } else { + // no more non-PWMLEDs to do, start with PWMLEDs + current_adc = N_PWMLEDS-1; + } + } else if (current_adc >= N_PWMLEDS) { + // one of the non-PWMLED ADCs just finished, skip to PWMLEDs. + current_adc = N_PWMLEDS-1; } else { - // TODO: kick the watchdog here. - current_adc = NUM_ADCS; - return; + // next PWMLED + current_adc--; } +#if 0 + log_byte(0x90 + current_adc); // debug ADC switching +#endif + adc_sum = 0; // we use the last iteration of zero_count to set up the MUX // to its final destination, hence the "1 +" below: @@ -98,12 +110,14 @@ static void start_next_adc() ADCSRA |= _BV(ADSC); } -void timer_start_adcs() +void timer_start_slow_adcs() { - if (current_adc == NUM_ADCS) // Don't start if in progress - start_next_adc(); - else - log_byte(0x99); // overrun + if (current_slow_adc > N_PWMLEDS) { // Don't start if in progress + log_byte(0x80 + current_slow_adc); + } else { + current_slow_adc = NUM_ADCS; + // TODO: kick the watchdog here + } } /* @@ -129,7 +143,8 @@ static uint16_t read_adc_sync() void init_adc() { unsigned char i; - current_adc = NUM_ADCS; + current_slow_adc = NUM_ADCS; + current_adc = 0; ADCSRA = _BV(ADEN) // enable | _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz diff --git a/firmware/lights.h b/firmware/lights.h index e9d48aa..af5eab6 100644 --- a/firmware/lights.h +++ b/firmware/lights.h @@ -28,7 +28,7 @@ void inline log_word(uint16_t word) { } #define PWMLED_ADC_SHIFT 3 /* 1<<3 measurements per single callback */ void init_adc(); void susp_adc(); -void timer_start_adcs(); +void timer_start_slow_adcs(); /* pwm.c */ /* diff --git a/firmware/tmr.c b/firmware/tmr.c index 37b240b..23b70b6 100644 --- a/firmware/tmr.c +++ b/firmware/tmr.c @@ -34,9 +34,8 @@ ISR(TIMER0_COMPA_vect) if (--pattern_div == 0) { timer_check_buttons(); patterns_next_tick(); + timer_start_slow_adcs(); pattern_div = PATTERN_DIV; } - - timer_start_adcs(); } -- 2.39.3