#include <avr/io.h>
#include <avr/interrupt.h>
+#include <avr/sleep.h>
#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)
+#define BATTERY_ADC (N_PWMLEDS + 0)
+#define BUTTON_ADC (N_PWMLEDS + 1)
+#define ZERO_ADC (N_PWMLEDS + 2)
-#define NUM_ADCS ZERO_ADC
+//#define NUM_ADCS ZERO_ADC
+#define NUM_ADCS 1
struct {
unsigned char read_zero_log : 2;
unsigned char read_keep_log : 4;
} adc_params[NUM_ADCS] = {
{ 0, 1, PWMLED_ADC_SHIFT }, // pwmled 1
+#if 0
{ 0, 1, PWMLED_ADC_SHIFT }, // pwmled 2
{ 0, 1, PWMLED_ADC_SHIFT }, // pwmled 3
{ 0, 1, AMBIENT_ADC_SHIFT }, // ambient
{ 0, 1, 0 }, // battery
{ 0, 1, 0 }, // gain20
{ 0, 1, 0 }, // buttons
+#endif
};
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;
static void setup_mux(unsigned char n)
{
/* ADC numbering: PWM LEDs first, then others, zero at the end */
switch (n) {
- case 0: // pwmled 1: 1.1V, ADC0,1 (PA0,1), gain 20
- ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX1) | _BV(MUX0);
- break;
- case 1: // pwmled 2: 1.1V, ADC2,1 (PA2,1), gain 20
- ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
- break;
- case 2: // pwmled 3: 1.1V, ADC4 (PA5), single-ended
- ADMUX = _BV(REFS1) | _BV(MUX2);
- break;
- case AMBIENT_ADC: // ambient light: 1.1V, ADC5 (PA6), single-ended
- ADMUX = _BV(REFS1) | _BV(MUX2) | _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
+ case 0: // pwmled 1: 1.1V, ADC3 (PB3), single-ended
ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0);
break;
- case ZERO_ADC: // zero: 1.1V, ADC1 (PA1), single-ended
- ADMUX = _BV(REFS1) | _BV(MUX0);
+ case ZERO_ADC: // zero: 1.1V, GND, single-ended
+ ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
break;
}
}
-static void start_next_adc()
+void start_next_adc()
{
+#if 0
if (current_adc == 0) {
if (current_slow_adc > N_PWMLEDS) {
// read one of the non-PWMLED ADCs
// next PWMLED
current_adc--;
}
+#else
+ // single ADC for testing only
+ current_adc = 0;
+#endif
#if 0
log_byte(0x90 + current_adc); // debug ADC switching
// ADCSRB |= _BV(GSEL); // gain 8 or 32
// Disable digital input on all bits used by ADC
- DIDR0 = _BV(ADC0D) | _BV(ADC1D) | _BV(ADC2D) | _BV(ADC3D)
- | _BV(ADC4D) | _BV(ADC5D) | _BV(ADC6D);
-
- // 1.1V, ADC1,1, gain 20
+ DIDR0 = _BV(ADC3D) | _BV(ADC2D);
+
+ // 1.1V, GND
ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
/* Do first conversion and drop the result */
read_adc_sync();
- adc1_gain20_offset = 0;
-
- for (i = 0; i < (1 << ADC1_GAIN20_OFFSET_SHIFT); i++) {
- adc1_gain20_offset += read_adc_sync()
- - (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
- }
-
ADCSRA |= _BV(ADIE); // enable IRQ
start_next_adc();
}
+#if 0
void susp_adc()
{
ADCSRA = 0;
adc1_gain20_offset += adcsum
- (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
}
+#endif
ISR(ADC_vect) { // IRQ handler
uint16_t adcval = ADCW;
* Now we have performed read_count measurements and have them
* in adc_sum.
*/
-
- // For inputs with gain, subtract the measured gain stage offset
- if (current_adc < 2) {
- uint16_t offset = adc1_gain20_offset
- >> (ADC1_GAIN20_OFFSET_SHIFT - n_reads_log);
-
- if (adc_sum > offset)
- adc_sum -= offset;
- else
- adc_sum = 0;
- }
-
switch (current_adc) {
case 0:
- case 1:
- case 2:
- pwmled_adc(current_adc, adc_sum);
- break;
- 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 ADC1_GAIN20:
- adc1_gain20_adc(adcval);
+ // pwmled_adc(current_adc, adc_sum);
+ log_word(0x9000+adc_sum);
+ return;
break;
}
start_next_adc();
}
-