Revision 275
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.
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 |
|
Also available in: Unified diff