From b5cbba7ed8e0823719c8b8ce86b6e866ac0c3871 Mon Sep 17 00:00:00 2001 From: Robert Konklewski Date: Thu, 21 Apr 2016 19:32:23 +0200 Subject: [PATCH] Temp: read ADC on-demand, instead of constantly running. On AVRs analog conversions were running in essentially free-running mode, i.e. next conversion was being started immediately after the previous one ended. This caused many unnecessary interrupts. Now, conversions are initiated manually by start_adc(). This causes a single read on each of the registered channels. Once all channels are read, conversions stop until the next call of start_adc(). --- analog-avr.c | 17 +++++++++++++---- analog.h | 16 ++++++++++++++++ temp.c | 19 +++++++++++++------ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/analog-avr.c b/analog-avr.c index 2c34a22..bb49135 100644 --- a/analog-avr.c +++ b/analog-avr.c @@ -46,11 +46,18 @@ void analog_init() { DIDR2 = (analog_mask >> 8) & 0xFF; #endif - // now we start the first conversion and leave the rest to the interrupt - ADCSRA |= MASK(ADIE) | MASK(ADSC); + // Enable the ADC. + ADCSRA |= MASK(ADIE); } /* analog_mask */ } +/** + Start a new ADC conversion. +*/ +void start_adc() { + ADCSRA |= MASK(ADSC); +} + /*! Analog Interrupt This is where we read our analog value and store it in an array for later retrieval @@ -77,8 +84,10 @@ ISR(ADC_vect, ISR_NOBLOCK) { ADCSRB &= ~MASK(MUX5); #endif - // After the mux has been set, start a new conversion - ADCSRA |= MASK(ADSC); + // If there is another channel to read, start a new conversion. + if (adc_counter != 0) { + ADCSRA |= MASK(ADSC); + } } } diff --git a/analog.h b/analog.h index 2f72191..a2f7681 100644 --- a/analog.h +++ b/analog.h @@ -49,10 +49,26 @@ #error REFERENCE undefined. See analog.h on how to choose it. #endif +/** \def NEEDS_START_ADC + + Whether the board needs and implements start_adc(), i.e. analog reads + on-demand (as opposed to free-running ADC conversions). + + Currently only implemented on AVR. +*/ +#define NEEDS_START_ADC + #endif /* __AVR__ */ void analog_init(void); uint16_t analog_read(uint8_t index); +#ifdef NEEDS_START_ADC + #define DO_START_ADC() do { start_adc(); } while (0) + void start_adc(void); +#else + #define DO_START_ADC() +#endif + #endif /* _ANALOG_H */ diff --git a/temp.c b/temp.c index 1686a45..e06700d 100644 --- a/temp.c +++ b/temp.c @@ -110,15 +110,19 @@ void temp_init() { #endif #ifdef TEMP_THERMISTOR - // handled by analog_init() -/* case TT_THERMISTOR: - break;*/ + // Mostly handled by analog_init(). + case TT_THERMISTOR: + // Start a conversion so it's ready for the first temp_sensor_tick(). + DO_START_ADC(); + break; #endif #ifdef TEMP_AD595 - // handled by analog_init() -/* case TT_AD595: - break;*/ + // Mostly handled by analog_init(). + case TT_AD595: + // Start a conversion so it's ready for the first temp_sensor_tick(). + DO_START_ADC(); + break; #endif #ifdef TEMP_INTERCOM @@ -309,6 +313,8 @@ void temp_sensor_tick() { temp = temp_table_lookup(analog_read(i), i); temp_sensors_runtime[i].next_read_time = 0; + DO_START_ADC(); + break; #endif /* TEMP_THERMISTOR */ @@ -332,6 +338,7 @@ void temp_sensor_tick() { temp = (temp * 500L) >> 8; temp_sensors_runtime[i].next_read_time = 0; + DO_START_ADC(); break; #endif /* TEMP_AD595 */