analog.c: trim down analog values storage.

Saves 10 bytes RAM and 16 bytes binary size on an 1284P (8 ADC
channels) running two sensors. Should also be a bit faster, as one
loop runs fewer iterations.

Also, checking for NUM_TEMP_SENSORS was a mistake, as temp sensors
_not_ using an analog pin exist. Extreme case is, temp sensors
exist, but zero ADC channels are used.
This commit is contained in:
Markus Hitter 2012-09-01 01:09:39 +02:00
parent c75693af38
commit 97a663a00c
3 changed files with 26 additions and 32 deletions

View File

@ -12,34 +12,31 @@
/* OR-combined mask of all channels */
#undef DEFINE_TEMP_SENSOR
//! automagically generate analog_mask from DEFINE_TEMP_SENSOR entries in config.h
#define DEFINE_TEMP_SENSOR(name, type, pin, additional) | (((type == TT_THERMISTOR) || (type == TT_AD595)) ? (1 << (pin ## _ADC)) : 0)
#define DEFINE_TEMP_SENSOR(name, type, pin, additional) \
| (((type == TT_THERMISTOR) || (type == TT_AD595)) ? (1 << (pin ## _ADC)) : 0)
#ifdef AIO8_PIN
static const uint16_t analog_mask = 0
#else
static const uint8_t analog_mask = 0
#endif
#include "config.h"
;
#undef DEFINE_TEMP_SENSOR
#ifdef AIO8_PIN
#define AINDEX_MASK 0x1F
#define AINDEX_MAX 15
#define AINDEX_CURRENT ((ADMUX & 0x07) | ((ADCSRB & MASK(MUX5))?0x08:0))
#else
#define AINDEX_MASK 0x0F
#define AINDEX_MAX 7
#define AINDEX_CURRENT (ADMUX & 0x07)
#endif
static uint8_t adc_counter;
static volatile uint16_t adc_result[AINDEX_MAX + 1] __attribute__ ((__section__ (".bss")));
static volatile uint16_t adc_result[NUM_TEMP_SENSORS] __attribute__ ((__section__ (".bss")));
#define DEFINE_TEMP_SENSOR(name, type, pin, additional) \
((type == TT_THERMISTOR) || (type == TT_AD595)) ? (pin ## _ADC) : 255,
static uint8_t adc_channel[NUM_TEMP_SENSORS] =
{
#include "config.h"
};
#undef DEFINE_TEMP_SENSOR
//! Configure all registers, start interrupt loop
void analog_init() {
if (NUM_TEMP_SENSORS > 0) {
if (analog_mask > 0) {
// clear ADC bit in power reduction register because of ADC use.
#ifdef PRR
PRR &= ~MASK(PRADC);
@ -84,24 +81,21 @@ ISR(ADC_vect, ISR_NOBLOCK) {
uint8_t sreg_save = SREG;
// emulate free-running mode but be more deterministic about exactly which result we have, since this project has long-running interrupts
if (NUM_TEMP_SENSORS > 0) {
if (analog_mask > 0) { // at least one temp sensor uses an analog channel
// store next result
adc_result[AINDEX_CURRENT] = ADC;
adc_result[adc_counter] = ADC;
// find next channel
/* TODO: this is not exactly high performance. adc_result[] should be of
size NUM_TEMP_SENSORS only, along with an array of the corresponding
ADC channel(s). This also requires changes to the callers of
analog_read(). */
// next channel
do {
adc_counter++;
adc_counter &= AINDEX_MAX;
} while ((analog_mask & (1 << adc_counter)) == 0);
if (adc_counter >= sizeof(adc_channel))
adc_counter = 0;
} while (adc_channel[adc_counter] == 255);
// start next conversion
ADMUX = (adc_counter & 0x07) | REFERENCE;
ADMUX = (adc_channel[adc_counter] & 0x07) | REFERENCE;
#ifdef MUX5
if (adc_counter & 0x08)
if (adc_channel[adc_counter] & 0x08)
ADCSRB |= MASK(MUX5);
else
ADCSRB &= ~MASK(MUX5);
@ -120,8 +114,8 @@ ISR(ADC_vect, ISR_NOBLOCK) {
\param channel Channel to be read
\return analog reading, 10-bit right aligned
*/
uint16_t analog_read(uint8_t channel) {
if (NUM_TEMP_SENSORS > 0) {
uint16_t analog_read(uint8_t index) {
if (analog_mask > 0) {
uint16_t r;
uint8_t sreg;
@ -131,7 +125,7 @@ uint16_t analog_read(uint8_t channel) {
cli();
// atomic 16-bit copy
r = adc_result[channel];
r = adc_result[index];
// restore interrupt flag
SREG = sreg;

View File

@ -27,6 +27,6 @@
void analog_init(void);
uint16_t analog_read(uint8_t channel);
uint16_t analog_read(uint8_t index);
#endif /* _ANALOG_H */

4
temp.c
View File

@ -178,7 +178,7 @@ void temp_sensor_tick() {
do {
uint8_t j, table_num;
//Read current temperature
temp = analog_read(temp_sensors[i].temp_pin);
temp = analog_read(i);
// for thermistors the thermistor table number is in the additional field
table_num = temp_sensors[i].additional;
@ -237,7 +237,7 @@ void temp_sensor_tick() {
#ifdef TEMP_AD595
case TT_AD595:
temp = analog_read(temp_sensors[i].temp_pin);
temp = analog_read(i);
// convert
// >>8 instead of >>10 because internal temp is stored as 14.2 fixed point