allow larger chips to use analog channels 8-15
This commit is contained in:
parent
43b5c0f0b4
commit
2013effd9c
39
analog.c
39
analog.c
|
|
@ -12,13 +12,29 @@
|
|||
#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) : 0)
|
||||
static const uint8_t analog_mask = 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[8] __attribute__ ((__section__ (".bss")));
|
||||
static volatile uint16_t adc_result[AINDEX_MAX + 1] __attribute__ ((__section__ (".bss")));
|
||||
|
||||
//! Configure all registers, start interrupt loop
|
||||
void analog_init() {
|
||||
|
|
@ -33,11 +49,15 @@ void analog_init() {
|
|||
|
||||
// ADC frequency must be less than 200khz or we lose precision. At 16MHz system clock, we must use the full prescale value of 128 to get an ADC clock of 125khz.
|
||||
ADCSRA = MASK(ADEN) | MASK(ADPS2) | MASK(ADPS1) | MASK(ADPS0);
|
||||
ADCSRB = 0;
|
||||
|
||||
adc_counter = 0;
|
||||
|
||||
AIO0_DDR &= ~analog_mask;
|
||||
DIDR0 = analog_mask & 0x3F;
|
||||
DIDR0 = analog_mask & 0xFF;
|
||||
#ifdef DIDR2
|
||||
DIDR2 = (analog_mask >> 8) & 0xFF;
|
||||
#endif
|
||||
// now we start the first conversion and leave the rest to the interrupt
|
||||
ADCSRA |= MASK(ADIE) | MASK(ADSC);
|
||||
} /* analog_mask > 0 */
|
||||
|
|
@ -50,15 +70,22 @@ void analog_init() {
|
|||
ISR(ADC_vect, ISR_NOBLOCK) {
|
||||
// emulate free-running mode but be more deterministic about exactly which result we have, since this project has long-running interrupts
|
||||
if (analog_mask > 0) {
|
||||
adc_result[ADMUX & 0x0F] = ADC;
|
||||
// store next result
|
||||
adc_result[AINDEX_CURRENT] = ADC;
|
||||
|
||||
// find next channel
|
||||
do {
|
||||
adc_counter++;
|
||||
adc_counter &= 0x07;
|
||||
adc_counter &= AINDEX_MAX;
|
||||
} while ((analog_mask & (1 << adc_counter)) == 0);
|
||||
|
||||
// start next conversion
|
||||
ADMUX = (adc_counter) | REFERENCE;
|
||||
ADMUX = (adc_counter & 0x07) | REFERENCE;
|
||||
if (adc_counter & 0x08)
|
||||
ADCSRB |= MASK(MUX5);
|
||||
else
|
||||
ADCSRB &= ~MASK(MUX5);
|
||||
|
||||
ADCSRA |= MASK(ADSC);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue