Commit 4b42bb17 authored by Jan Kasprzak's avatar Jan Kasprzak
Browse files

adc.c: freewheeling measurements of ADC3 only

parent 899ce952
#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;
......@@ -17,54 +17,36 @@ struct {
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
......@@ -80,6 +62,10 @@ static void start_next_adc()
// next PWMLED
current_adc--;
}
#else
// single ADC for testing only
current_adc = 0;
#endif
#if 0
log_byte(0x90 + current_adc); // debug ADC switching
......@@ -153,27 +139,20 @@ void init_adc()
// 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;
......@@ -186,6 +165,7 @@ static void adc1_gain20_adc(uint16_t adcsum)
adc1_gain20_offset += adcsum
- (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
}
#endif
ISR(ADC_vect) { // IRQ handler
uint16_t adcval = ADCW;
......@@ -219,38 +199,13 @@ ISR(ADC_vect) { // IRQ handler
* 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();
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment