]> www.fi.muni.cz Git - bike-lights.git/commitdiff
Merge branch 'master' of ssh://anxur.fi.muni.cz/~kas/html/git/bike-lights
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 18 Jan 2013 21:50:50 +0000 (22:50 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 18 Jan 2013 21:50:50 +0000 (22:50 +0100)
Conflicts:
firmware/adc.c

1  2 
firmware/adc.c

diff --combined firmware/adc.c
index 4213ef56bc01b5114ee2c76f6ef16dfce1e7158d,5f7849fb1128ed47414f71fd1072dddab68e3e80..9155f325ccfd2c857a93c503b2c2f6337a78ad04
@@@ -1,5 -1,6 +1,6 @@@
  #include <avr/io.h>
  #include <avr/interrupt.h>
+ #include <util/atomic.h>
  
  #include "lights.h"
  
@@@ -14,6 -15,7 +15,7 @@@ static unsigned char sum_shift
  static unsigned char adc_vals;
  #define ADC1_GAIN20_OFFSET_SHIFT      6
  static uint16_t adc1_gain20_offset;
+ static unsigned char handler_running;
  
  static void inline setup_mux(unsigned char n)
  {
@@@ -33,7 -35,7 +35,7 @@@
                break;
        case 3: // ambient light: 1.1V, ADC5 (PA6), single-ended
                ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX0);
 -              sum_shift = 0; // 1 measurement
 +              sum_shift = 3; // 3 measurements
                break;
        case 4: // batt voltage: 1.1V, ADC6 (PA7), single-ended
                ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX1);
@@@ -62,10 -64,31 +64,31 @@@ static void start_next_adc(
        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;
        current_adc = NUM_ADCS;
+       handler_running = 0;
  
        ADCSRA = _BV(ADEN)                      // enable
                | _BV(ADPS1) | _BV(ADPS0)       // CLK/8 = 125 kHz
  
        // 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
@@@ -143,13 -157,28 +157,28 @@@ ISR(ADC_vect) { // IRQ handle
                        adc_sum = 0;
        }
  
-       if (current_adc < N_PWMLEDS)
-               pwmled_adc(current_adc, adc_sum);
-       if (current_adc == AMBIENT_ADC)
-               ambient_adc(adc_sum);
-       if (current_adc == BATTERY_ADC)
-               battery_adc(adcval);
-       
-       start_next_adc();
+       if (handler_running & (1 << current_adc)) {
+               log_byte(0xB0 + current_adc);
+               // drop the result, what else to do?
+               start_next_adc();
+       } else {
+               unsigned char current_adc_copy = current_adc;
+               uint16_t adc_sum_copy = adc_sum;
+               start_next_adc();
+               handler_running |= (1 << current_adc_copy);
+               NONATOMIC_BLOCK(NONATOMIC_FORCEOFF) {
+                       if (current_adc_copy < N_PWMLEDS)
+                               pwmled_adc(current_adc_copy, adc_sum_copy);
+                       if (current_adc_copy == AMBIENT_ADC)
+                               ambient_adc(adc_sum_copy);
+                       if (current_adc_copy == BATTERY_ADC)
+                               battery_adc(adc_sum_copy);
+               }
+               handler_running &= ~(1 << current_adc_copy);
+       }
  }