]> www.fi.muni.cz Git - bike-lights.git/commitdiff
slow ADC inputs
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 28 Mar 2013 22:33:25 +0000 (23:33 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 28 Mar 2013 22:33:25 +0000 (23:33 +0100)
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
firmware/lights.h
firmware/tmr.c

index 70c2aa1adca1a95958fc02e992354b2345aeaaff..ef714777011f1af24d171bb44cdd0d6461ac6b0e 100644 (file)
@@ -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
index e9d48aadaddd3494c0a4365d5d7c06d8e99830ee..af5eab6756ca96554d5e7c45fe8c81390a89822d 100644 (file)
@@ -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 */
 /*
index 37b240b5d65245898722036d00f740ad322b1350..23b70b68e316e372782a0d74be4883002fd564ea 100644 (file)
@@ -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();
 }