X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=bike-lights.git;a=blobdiff_plain;f=adc.c;h=bef7375e8b54f40167e4c591a10021a0b653360e;hp=a37e95886f237828537666d5bb209048a521eaeb;hb=911d9d5f5a6c106faafa17e8b7e21ac3e61b4d2a;hpb=4b93ea55987c25fcce022403a505ca1749dc329c diff --git a/adc.c b/adc.c index a37e958..bef7375 100644 --- a/adc.c +++ b/adc.c @@ -3,6 +3,7 @@ #include "lights.h" +/* ADC numbering: PWM LEDs first, then ambient light sensor, battery sensor */ static unsigned char adc_mux[] = { // pwmleds should be first // 0: pwmled 0: 1.1V, ADC3 (PA4), single-ended _BV(REFS1) | _BV(MUX1) | _BV(MUX0), @@ -16,8 +17,12 @@ static unsigned char adc_mux[] = { // pwmleds should be first _BV(REFS1) | _BV(MUX2) | _BV(MUX0), }; -#define LAST_ADC (sizeof(adc_mux)/sizeof(char)) -volatile static unsigned char current_adc = LAST_ADC; +#define AMBIENT_ADC N_PWMLEDS +#define BATTERY_ADC (N_PWMLEDS + 1) + +#define LAST_ADC (sizeof(adc_mux)/sizeof(adc_mux[0])) +volatile static unsigned char current_adc; +static unsigned char adc_ignore; static void start_next_adc() { @@ -25,9 +30,11 @@ static void start_next_adc() --current_adc; // test if current_adc should be measured - if (current_adc < N_PWMLEDS && pwmled_is_on(current_adc)) + if (current_adc < N_PWMLEDS && pwmled_needs_adc(current_adc)) + goto found; + if (current_adc == AMBIENT_ADC) goto found; - // TODO ambient light, battery sense, etc. + // TODO battery sense, etc. } // all ADCs have been handled @@ -36,11 +43,15 @@ static void start_next_adc() found: // ADCSRB |= _BV(GSEL); // gain 8 or 32 ADMUX = adc_mux[current_adc]; // set up mux, start one-shot conversion + adc_ignore = 1; // ignore first reading after mux change ADCSRA |= _BV(ADSC); } void init_adc() { + current_adc = LAST_ADC; + adc_ignore = 1; + ADCSRA = _BV(ADEN) // enable | _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz // | _BV(ADPS2) // CLK/16 = 62.5 kHz @@ -64,9 +75,23 @@ void init_adc() ISR(ADC_vect) { // IRQ handler uint16_t adcval = ADCW; +#if 0 + log_byte(0xF3); + log_byte(current_adc); + log_word(adcval); +#endif + + if (adc_ignore) { + ADCSRA |= _BV(ADSC); + adc_ignore = 0; + return; + } + if (current_adc < N_PWMLEDS) pwmled_adc(current_adc, adcval); - // TODO ambient light, battery sense, etc. + if (current_adc == AMBIENT_ADC) + ambient_adc(adcval); + // TODO battery sense, etc. start_next_adc(); }