#include "lights.h"
-#define AMBIENT_ADC N_PWMLEDS
-#define BATTERY_ADC (N_PWMLEDS + 1)
-#define ADC1_GAIN20 (N_PWMLEDS + 2)
-#define BUTTON_ADC (N_PWMLEDS + 3)
-#define ZERO_ADC (N_PWMLEDS + 4)
+// pwmleds are measured continuously (when active)
+#define AMBIENT_ADC N_PWMLEDS // measured every jiffy (16 Hz)
+#define BUTTON_ADC (N_PWMLEDS + 1) // measured every jiffy (16 Hz)
+#define BATTERY_ADC (N_PWMLEDS + 2) // once per second
+#define ADC1_GAIN20 (N_PWMLEDS + 3) // once per second
+#define ZERO_ADC (N_PWMLEDS + 4) // must be last
#define NUM_ADCS ZERO_ADC
{ 0, 1, PWMLED_ADC_SHIFT }, // pwmled 2
{ 0, 1, PWMLED_ADC_SHIFT }, // pwmled 3
{ 0, 1, AMBIENT_ADC_SHIFT }, // ambient
+ { 0, 1, 0 }, // buttons
{ 0, 1, 0 }, // battery
{ 0, 1, 0 }, // gain20
- { 0, 1, 0 }, // buttons
};
-volatile static unsigned char current_adc;
+volatile static unsigned char current_adc, current_slow_adc;
static uint16_t adc_sum, zero_count, drop_count, read_count, n_reads_log;
#define ADC1_GAIN20_OFFSET_SHIFT 6
static uint16_t adc1_gain20_offset;
case AMBIENT_ADC: // ambient light: 1.1V, ADC5 (PA6), single-ended
ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX0);
break;
+ case BUTTON_ADC: // buttons: 1.1V, ADC3, single-ended
+ PORTA |= _BV(PA3); // +5V to the voltage splitter
+ ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0);
+ break;
case BATTERY_ADC: // batt voltage: 1.1V, ADC6 (PA7), single-ended
ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX1);
break;
case ADC1_GAIN20: // gain stage offset: 1.1V, ADC1,1, gain 20
ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
break;
- case BUTTON_ADC: // buttons: 1.1V, ADC3, single-ended
- PORTA |= _BV(PA3); // +5V to the voltage splitter
- ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0);
- break;
case ZERO_ADC: // zero: 1.1V, ADC1 (PA1), single-ended
ADMUX = _BV(REFS1) | _BV(MUX0);
break;
static void start_next_adc()
{
- if (current_adc > 0) {
- current_adc--;
+ if (current_adc == 0) {
+ if (current_slow_adc > N_PWMLEDS) {
+ // read one of the non-PWMLED ADCs
+ current_adc = --current_slow_adc;
+ } else {
+ // no more non-PWMLEDs to do, start with PWMLEDs
+ current_adc = N_PWMLEDS-1;
+ }
+ } else if (current_adc >= N_PWMLEDS) {
+ // one of the non-PWMLED ADCs just finished, skip to PWMLEDs.
+ current_adc = N_PWMLEDS-1;
} else {
- // TODO: kick the watchdog here.
- current_adc = NUM_ADCS;
- return;
+ // next PWMLED
+ current_adc--;
}
+#if 0
+ log_byte(0x90 + current_adc); // debug ADC switching
+#endif
+
adc_sum = 0;
// we use the last iteration of zero_count to set up the MUX
// to its final destination, hence the "1 +" below:
ADCSRA |= _BV(ADSC);
}
-void timer_start_adcs()
+void timer_start_slow_adcs()
{
- if (current_adc == NUM_ADCS) // Don't start if in progress
- start_next_adc();
- else
- log_byte(0x99); // overrun
+ if (current_slow_adc > N_PWMLEDS) { // Don't start if in progress
+ log_byte(0x80 + current_slow_adc);
+ } else {
+ current_slow_adc = NUM_ADCS;
+ // TODO: kick the watchdog here
+ }
}
/*
void init_adc()
{
unsigned char i;
- current_adc = NUM_ADCS;
+ current_slow_adc = NUM_ADCS;
+ current_adc = 0;
ADCSRA = _BV(ADEN) // enable
| _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz
case AMBIENT_ADC:
ambient_adc(adc_sum);
break;
- case BATTERY_ADC:
- battery_adc(adc_sum);
- break;
case BUTTON_ADC:
button_adc(adc_sum);
break;
+ case BATTERY_ADC:
+ battery_adc(adc_sum);
+ break;
case ADC1_GAIN20:
adc1_gain20_adc(adcval);
break;