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

adc.c: freewheeling measurements of ADC3 only

parent 899ce952
Loading
Loading
Loading
Loading
+25 −70
Original line number Original line Diff line number Diff line
#include <avr/io.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>


#include "lights.h"
#include "lights.h"


#define AMBIENT_ADC N_PWMLEDS
#define BATTERY_ADC (N_PWMLEDS + 0)
#define BATTERY_ADC (N_PWMLEDS + 1)
#define BUTTON_ADC  (N_PWMLEDS + 1)
#define ADC1_GAIN20 (N_PWMLEDS + 2)
#define ZERO_ADC    (N_PWMLEDS + 2)
#define BUTTON_ADC  (N_PWMLEDS + 3)
#define ZERO_ADC    (N_PWMLEDS + 4)


#define NUM_ADCS	ZERO_ADC
//#define NUM_ADCS	ZERO_ADC
#define NUM_ADCS	1


struct {
struct {
	unsigned char read_zero_log : 2;
	unsigned char read_zero_log : 2;
@@ -17,54 +17,36 @@ struct {
	unsigned char read_keep_log : 4;
	unsigned char read_keep_log : 4;
} adc_params[NUM_ADCS] = {
} adc_params[NUM_ADCS] = {
	{ 0, 1, PWMLED_ADC_SHIFT },	// pwmled 1
	{ 0, 1, PWMLED_ADC_SHIFT },	// pwmled 1
#if 0
	{ 0, 1, PWMLED_ADC_SHIFT },	// pwmled 2
	{ 0, 1, PWMLED_ADC_SHIFT },	// pwmled 2
	{ 0, 1, PWMLED_ADC_SHIFT },	// pwmled 3
	{ 0, 1, PWMLED_ADC_SHIFT },	// pwmled 3
	{ 0, 1, AMBIENT_ADC_SHIFT },	// ambient
	{ 0, 1, AMBIENT_ADC_SHIFT },	// ambient
	{ 0, 1, 0 },			// battery
	{ 0, 1, 0 },			// battery
	{ 0, 1, 0 },			// gain20
	{ 0, 1, 0 },			// gain20
	{ 0, 1, 0 },			// buttons
	{ 0, 1, 0 },			// buttons
#endif
};
};


volatile static unsigned char current_adc, current_slow_adc;
volatile static unsigned char current_adc, current_slow_adc;
static uint16_t adc_sum, zero_count, drop_count, read_count, n_reads_log;
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)
static void setup_mux(unsigned char n)
{
{
	/* ADC numbering: PWM LEDs first, then others, zero at the end */
	/* ADC numbering: PWM LEDs first, then others, zero at the end */
	switch (n) {
	switch (n) {
	case 0: // pwmled 1: 1.1V, ADC0,1 (PA0,1), gain 20
	case 0: // pwmled 1: 1.1V, ADC3 (PB3), single-ended
		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
		ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0);
		ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0);
		break;
		break;
	case ZERO_ADC: // zero: 1.1V, ADC1 (PA1), single-ended
	case ZERO_ADC: // zero: 1.1V, GND, single-ended
		ADMUX = _BV(REFS1) | _BV(MUX0);
		ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
		break;
		break;
	}
	}
}
}


static void start_next_adc()
void start_next_adc()
{
{
#if 0
	if (current_adc == 0) {
	if (current_adc == 0) {
		if (current_slow_adc > N_PWMLEDS) {
		if (current_slow_adc > N_PWMLEDS) {
			// read one of the non-PWMLED ADCs
			// read one of the non-PWMLED ADCs
@@ -80,6 +62,10 @@ static void start_next_adc()
		// next PWMLED
		// next PWMLED
		current_adc--;
		current_adc--;
	}
	}
#else
	// single ADC for testing only
	current_adc = 0;
#endif


#if 0
#if 0
	log_byte(0x90 + current_adc); // debug ADC switching
	log_byte(0x90 + current_adc); // debug ADC switching
@@ -153,27 +139,20 @@ void init_adc()
	// ADCSRB |= _BV(GSEL); // gain 8 or 32
	// ADCSRB |= _BV(GSEL); // gain 8 or 32


	// Disable digital input on all bits used by ADC
	// Disable digital input on all bits used by ADC
	DIDR0 = _BV(ADC0D) | _BV(ADC1D) | _BV(ADC2D) | _BV(ADC3D)
	DIDR0 = _BV(ADC3D) | _BV(ADC2D);
		| _BV(ADC4D) | _BV(ADC5D) | _BV(ADC6D);
	
	
	// 1.1V, ADC1,1, gain 20
	// 1.1V, GND
	ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
	ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);


	/* Do first conversion and drop the result */
	/* Do first conversion and drop the result */
	read_adc_sync();
	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
	ADCSRA |= _BV(ADIE); // enable IRQ


	start_next_adc();
	start_next_adc();
}
}


#if 0
void susp_adc()
void susp_adc()
{
{
	ADCSRA = 0;
	ADCSRA = 0;
@@ -186,6 +165,7 @@ static void adc1_gain20_adc(uint16_t adcsum)
	adc1_gain20_offset += adcsum
	adc1_gain20_offset += adcsum
			- (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
			- (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
}
}
#endif


ISR(ADC_vect) { // IRQ handler
ISR(ADC_vect) { // IRQ handler
	uint16_t adcval = ADCW;
	uint16_t adcval = ADCW;
@@ -219,38 +199,13 @@ ISR(ADC_vect) { // IRQ handler
	 * Now we have performed read_count measurements and have them
	 * Now we have performed read_count measurements and have them
	 * in adc_sum.
	 * 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) {
	switch (current_adc) {
	case 0:
	case 0:
	case 1:
		// pwmled_adc(current_adc, adc_sum);
	case 2:
		log_word(0x9000+adc_sum);
		pwmled_adc(current_adc, adc_sum);
		return;
		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);
		break;
		break;
	}
	}


	start_next_adc();
	start_next_adc();
}
}