Project

General

Profile

Revision 275

Added by Kevin Woo over 16 years ago

Converted analog function to use interrupts and continuously poll. Need to test it.

Functions in the library that depend on analog will need to be updated to take
advantage of this when it works.

View differences:

branches/analog/trunk/code/projects/libdragonfly/analog.c
48 48
 * @{
49 49
 **/
50 50

  
51
int adc_loop_running;
52
int adc_current_port;
51 53

  
52 54
/**
53 55
 * Initializes the ADC.
......
57 59
 **/
58 60
void analog_init(void)
59 61
{
62
	// ADMUX register
63
	// Bit 7,6 - Set voltage reference to AVcc (0b01)
64
	// Bit 5 - ADLAR not set to simplify moving from register
65
	// Bit 4 - X
66
	// Bit 3:0 - Sets the current channel
67
	// Initializes to read from AN1 first (AN0 is reservered for the BOM)
68
	ADMUX = ~_BV(REFS1) | _BV(REFS0) | ~_BV(ADLAR) | _BV(MUX0);
69

  
60 70
	// ADC Status Register A
61 71
	// Bit 7 - ADEN is set (enables analog)
62 72
	// Bit 6 - Start conversion bit is set (must be done once for free-running mode)
63
	// Bit 5 - Enable Auto Trigger (for free running mode)
73
	// Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW
64 74
	// Bit 4 - ADC interrupt flag, 0
65 75
	// Bit 3 - Enable ADC Interrupt (required to run free-running mode)
66
	// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/128
67
	ADCSRA |= 0xEF;
76
	// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz
77
	ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | ~_BV(ADPS0);
 
68
	// ADC Status Register B
69
	// Bit 7, 5-3 - Must be cleared
70
	// Bit 2:0 - Set mode, currently cleared for free running operation
71
	// Bit 6 - Analog comparator mode - cleared
72
//	ADCSRB = 0x00;
73
	
74
	// ADMUX register
75
	// Bit 7,6 - Set voltage reference to AVcc (0b01)
76
	// Bit 5 - Set ADLAR bit for left adjust to do simple 8-bit reads
77
	// Bit 4 - X
78
	// Bit 3:0 - Sets the current channel, set to ADC7 (the external mux)
79
	ADMUX = 0x67;
80 78

  
81 79
	// Set external mux lines to outputs
82 80
	DDRG |= 0x1C;
83
	set_adc_mux(0x07);
81
	set_adc_mux(0x07);
82

  
83
	adc_loop_running = 1;
84
	adc_current_port = AN1;
84 85
}	
86

  
87
unsigned int analog_get8(int which) {
88
	return an_val[which - 1].adc8;
89
}
90

  
91
unsigned int analog_get10(int which) {
92
	return an_val[which - 1].adc10;
93
}
85 94

  
86 95

  
87 96
/**
......
97 106
 * @see analog_init, analog10
98 107
 **/
99 108
unsigned int analog8(int which)
100
{
109
{
110
	// Let any previous conversion finish
111
	while (ADCSRA & _BV(ADSC));
112

  
101 113
	if(which < EXT_MUX)
102
		ADMUX = 0x60 + which;
114
		ADMUX = 0x40 + which;
103 115
	else if(which == EXT_MUX)
104 116
		return 0;
105 117
	else
106 118
	{
107
		ADMUX = 0x60 + EXT_MUX;
119
		ADMUX = 0x40 + EXT_MUX;
108 120
		set_adc_mux(which - 8);
109
		_delay_ms(1);
110 121
	}
111 122
	
112
	_delay_ms(1); // need at least 130 us between conversions
113
	return ADCH;
123
	// Start the conversion
124
	ADCSRA |= _BV(ADSC);
125

  
126
	// Wait for the conversion to finish
127
	while (ADCSRA & _BV(ADSC)) ;
128

  
129
	return ADCL; //since we left aligned the data, ADCH is the 8 MSB.
114 130
}
115 131

  
116 132
/**
......
126 142
 **/
127 143
unsigned int analog10(int which)
128 144
{
129
	unsigned int adc_h = 0;
130
	unsigned int adc_l = 0;

145
	// Let any previous conversion finish
146
	while (ADCSRA & _BV(ADSC));
131 147

  
132 148
	if(which < EXT_MUX)
133
		ADMUX = 0x60 + which;
149
		ADMUX = 0x40 + which;
134 150
	else if(which == EXT_MUX)
135 151
		return 0;
136 152
	else
137 153
	{
138
		ADMUX = 0x60 + EXT_MUX;
154
		ADMUX = 0x40 + EXT_MUX;
139 155
		set_adc_mux(which - 8);
140
		_delay_ms(1);
141 156
	}
157
	
158
	// Start the conversion
159
	ADCSRA |= _BV(ADSC);
142 160

  
143
	_delay_ms(1);
144
	adc_l = ADCL; /* highest 2 bits of ADCL -> least 2 bits of analog val */
145
	adc_h = ADCH; /* ADCH -> 8 highest bits of analog val */
146
	
147
	return (adc_h << 2) | (adc_l >> 6);
161
	// Wait for the conversion to finish
162
	while (ADCSRA & _BV(ADSC)) ;
163

  
164
	return ((ADCH << 8) | ADCL);
148 165
}
149 166

  
150 167
/**
......
159 176
 **/
160 177
int wheel(void)
161 178
{
162
	return analog8(WHEEL_PORT);
179
	return analog_get8(WHEEL_PORT);
163 180
}
164 181

  
165 182
/**@}**/ //end defgroup
166 183

  
167
SIGNAL (SIG_ADC)
168
{
169
	// This is just here to catch ADC interrupts because ADC is free running.  
170
	// No code needs to be in here.
171
}
172

  
173 184
void set_adc_mux(int which)
174 185
{
175 186
  // FIX THIS IN NEXT REVISION
......
180 191
  // mask so only proper bits are possible.  
181 192
  PORTG = (PORTG & 0xE3) | ((which & 0x03) << 3) | (which & 0x04);
182 193
}
194

  
195
ISR(ANALOG_COMP_vect) {
196
	//Only perform this if we are running the loop
197
	if (!adc_loop_running)
198
		return;
199

  
200
	an_val[adc_current_port - 1].adc10 = (ADCH << 8) | ADCL;
201
	
202
	//Increment current sensor, wrap around if needed
203
	if (adc_current_port == AN10) {
204
		adc_current_port = AN1;
205
		ADMUX = 0x40 + adc_current_port;
206
	} else {
207
		adc_current_port++;
208
		
209
		if(adc_current_port < EXT_MUX) {
210
			ADMUX = 0x40 + adc_current_port;
211
		} else {
212
			ADMUX = 0x40 + EXT_MUX;
213
			set_adc_mux(adc_current_port - 8);
214
		}
215
	}
216
	
217
	ADCSRA |= _BV(ADSC);
218

  
219
}
183 220

  
branches/analog/trunk/code/projects/libdragonfly/analog.h
42 42
#ifndef _ANALOG_H
43 43
#define _ANALOG_H
44 44

  
45
#include <inttypes.h>
46

  
45 47
/**
46 48
 * @addtogroup analog
47 49
 * @{
......
87 89
/** @brief Analog port for the battery voltage detector **/
88 90
#define BATT_PORT  AN11
89 91

  
92
typedef union adc_t{
93
	uint8_t adc8;
94
	uint16_t adc10;
95
} adc_t;
96

  
97
extern adc_t an_val[9];
98

  
90 99
/** @brief Initialize analog ports. **/
91 100
void analog_init(void);
92 101
/** @brief Read an 8-bit number from an analog port. **/
......
95 104
unsigned int analog10(int which);
96 105
/** @brief Read the position of the wheel. **/
97 106
int wheel(void);
107
unsigned int analog_get8(int which);
108
unsigned int analog_get10(int which);
98 109

  
110

  
99 111
/**@}**/ //end group
100 112

  
101 113
#endif

Also available in: Unified diff