Revision 312
analog works on updating. Need to do code cleanup. Tested everything except analog8 and analog10.
analog.c | ||
---|---|---|
48 | 48 |
* @{ |
49 | 49 |
**/ |
50 | 50 |
|
51 |
int adc_loop_running; |
|
52 |
int adc_current_port; |
|
53 |
adc_t an_val[9];
|
|
51 |
int adc_loop_running = 0;
|
|
52 |
int adc_current_port = 0;
|
|
53 |
adc_t an_val[10];
|
|
54 | 54 |
|
55 | 55 |
/** |
56 | 56 |
* Initializes the ADC. |
... | ... | |
60 | 60 |
**/ |
61 | 61 |
void analog_init(int start_conversion) |
62 | 62 |
{ |
63 |
for (int i = 0; i < 10; i++) { |
|
64 |
an_val[i].adc10 = 0; |
|
65 |
an_val[i].adc8 = 0; |
|
66 |
} |
|
67 |
|
|
63 | 68 |
//cli(); |
64 | 69 |
// ADMUX register |
65 | 70 |
// Bit 7,6 - Set voltage reference to AVcc (0b01) |
66 |
// Bit 5 - ADLAR not set to simplify moving from register
|
|
71 |
// Bit 5 - ADLAR set to simplify moving from register |
|
67 | 72 |
// Bit 4 - X |
68 | 73 |
// Bit 3:0 - Sets the current channel |
69 | 74 |
// Initializes to read from AN1 first (AN0 is reservered for the BOM) |
70 | 75 |
ADMUX = 0; |
71 |
ADMUX |= _BV(REFS0) | _BV(MUX0); |
|
76 |
ADMUX |= ADMUX_OPT | _BV(MUX0); |
|
77 |
|
|
72 | 78 |
|
73 | 79 |
// ADC Status Register A |
74 | 80 |
// Bit 7 - ADEN is set (enables analog) |
... | ... | |
78 | 84 |
// Bit 3 - Enable ADC Interrupt (required to run free-running mode) |
79 | 85 |
// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz |
80 | 86 |
ADCSRA = 0; |
81 |
ADCSRA |= _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1); - |
|
87 |
ADCSRA |= _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); |
|
88 |
|
|
82 | 89 |
// Set external mux lines to outputs |
83 | 90 |
DDRG |= 0x1C; |
84 | 91 |
|
85 | 92 |
// Set up first port for conversions |
86 |
set_adc_mux(0x07);
|
|
93 |
set_adc_mux(0x00);
|
|
87 | 94 |
adc_current_port = AN1; |
88 | 95 |
|
89 |
//Start the conversion |
|
90 |
if (start_conversion == ADC_START) {
|
|
91 |
ADCSRA |= _BV(ADSC);
|
|
92 |
adc_loop_running = 1;
|
|
93 |
}
|
|
96 |
//Start the conversion if requested
|
|
97 |
if (start_conversion)
|
|
98 |
analog_start_loop();
|
|
99 |
else
|
|
100 |
analog_stop_loop();
|
|
94 | 101 |
//sei(); |
95 | 102 |
|
96 | 103 |
} |
... | ... | |
115 | 121 |
void analog_start_loop(void) { |
116 | 122 |
//Start the conversion |
117 | 123 |
ADCSRA |= _BV(ADSC); |
118 |
adc_loop_running = 1; |
|
124 |
adc_loop_running = 0x1;
|
|
119 | 125 |
} |
120 | 126 |
|
127 |
//will stop after current conversion finishes |
|
121 | 128 |
void analog_stop_loop(void) { |
122 | 129 |
//Stop the conversion |
123 |
//ADCSRA &= ~_BV(ADSC); |
|
124 |
adc_loop_running = 0; |
|
130 |
adc_loop_running = 0x0; |
|
125 | 131 |
} |
126 | 132 |
/** |
127 | 133 |
* Reads an eight bit number from an analog port. |
... | ... | |
139 | 145 |
// Let any previous conversion finish |
140 | 146 |
while (ADCSRA & _BV(ADSC)); |
141 | 147 |
|
142 |
if(which < EXT_MUX) |
|
143 |
ADMUX = 0x40 + which; |
|
144 |
else if(which == EXT_MUX) |
|
145 |
return 0; |
|
146 |
else |
|
147 |
{ |
|
148 |
ADMUX = 0x40 + EXT_MUX; |
|
148 |
if(which < EXT_MUX) { |
|
149 |
ADMUX = ADMUX_OPT + which; |
|
150 |
} else { |
|
151 |
ADMUX = ADMUX_OPT + EXT_MUX; |
|
149 | 152 |
set_adc_mux(which - 8); |
150 | 153 |
} |
151 | 154 |
|
... | ... | |
153 | 156 |
ADCSRA |= _BV(ADSC); |
154 | 157 |
|
155 | 158 |
// Wait for the conversion to finish |
156 |
while (ADCSRA & _BV(ADSC)) ;
|
|
159 |
while (ADCSRA & _BV(ADSC)); |
|
157 | 160 |
|
158 |
return ADCL; //since we left aligned the data, ADCH is the 8 MSB.
|
|
161 |
return ADCH; //since we left aligned the data, ADCH is the 8 MSB.
|
|
159 | 162 |
} |
160 | 163 |
|
161 | 164 |
/** |
... | ... | |
174 | 177 |
// Let any previous conversion finish |
175 | 178 |
while (ADCSRA & _BV(ADSC)); |
176 | 179 |
|
177 |
if(which < EXT_MUX) |
|
178 |
ADMUX = 0x40 + which; |
|
179 |
else if(which == EXT_MUX) |
|
180 |
return 0; |
|
181 |
else |
|
182 |
{ |
|
183 |
ADMUX = 0x40 + EXT_MUX; |
|
180 |
if(which < EXT_MUX) { |
|
181 |
ADMUX = ADMUX_OPT + which; |
|
182 |
} else { |
|
183 |
ADMUX = ADMUX_OPT + EXT_MUX; |
|
184 | 184 |
set_adc_mux(which - 8); |
185 | 185 |
} |
186 | 186 |
|
... | ... | |
188 | 188 |
ADCSRA |= _BV(ADSC); |
189 | 189 |
|
190 | 190 |
// Wait for the conversion to finish |
191 |
while (ADCSRA & _BV(ADSC)) ;
|
|
191 |
while (ADCSRA & _BV(ADSC)); |
|
192 | 192 |
|
193 |
return ((ADCH << 8) | ADCL);
|
|
193 |
return ((ADCH << 2) | (ADCL >> 6));
|
|
194 | 194 |
} |
195 | 195 |
|
196 | 196 |
/** |
... | ... | |
222 | 222 |
} |
223 | 223 |
|
224 | 224 |
ISR(ADC_vect) { |
225 |
usb_puts("Interrupt!\n\r"); |
|
225 |
static volatile int adc_prev_loop_running = 0; |
|
226 |
|
|
227 |
int adc_h = 0; |
|
228 |
int adc_l = 0; |
|
229 |
|
|
230 |
//usb_putc('p'); |
|
231 |
//usb_puti(adc_current_port); |
|
232 |
//usb_putc('r'); |
|
233 |
//usb_puti(adc_loop_running); |
|
234 |
//usb_puts("\n\r"); |
|
235 |
|
|
226 | 236 |
//Store the value only if this read isn't for the BOM |
227 |
if (ADMUX != BOM_PORT) { |
|
228 |
an_val[adc_current_port - 1].adc10 = (ADCH << 8) | ADCL; |
|
237 |
if (ADMUX != BOM_PORT) { |
|
238 |
adc_l = ADCL; |
|
239 |
adc_h = ADCH; |
|
240 |
|
|
241 |
an_val[adc_current_port - 1].adc10 = (adc_h << 2) | (adc_l >> 6); |
|
242 |
an_val[adc_current_port - 1].adc8 = adc_h; |
|
243 |
//usb_puti(an_val[adc_current_port - 1].adc10); |
|
244 |
//usb_puts("\n\r"); |
|
245 |
//usb_puti(an_val[adc_current_port - 1].adc8); |
|
246 |
//usb_puti(ADCH); |
|
247 |
//usb_puts("\n\r"); |
|
229 | 248 |
} |
230 |
usb_puts("Value written!\n\r"); |
|
231 |
//Only perform this if we are running the loop
|
|
232 |
if (!adc_loop_running) |
|
249 |
|
|
250 |
//Save the result only if we just turned off the loop
|
|
251 |
if (!adc_loop_running && !adc_prev_loop_running)
|
|
233 | 252 |
return; |
253 |
|
|
254 |
adc_prev_loop_running = adc_loop_running; |
|
234 | 255 |
|
235 |
//Increment current sensor, wrap around if needed |
|
236 |
if (adc_current_port == AN10) { |
|
256 |
//Skip AN7 because it is not a real port |
|
257 |
if (adc_current_port == AN6) { |
|
258 |
ADMUX = ADMUX_OPT | EXT_MUX; |
|
259 |
set_adc_mux(AN8 - 8); |
|
260 |
adc_current_port = AN8; |
|
261 |
//Wrap around |
|
262 |
} else if (adc_current_port == AN11) { |
|
237 | 263 |
adc_current_port = AN1; |
238 |
ADMUX = 0x40 + adc_current_port; |
|
264 |
ADMUX = ADMUX_OPT | adc_current_port; |
|
265 |
//Normal increment |
|
239 | 266 |
} else { |
240 | 267 |
adc_current_port++; |
241 |
|
|
268 |
|
|
242 | 269 |
if(adc_current_port < EXT_MUX) { |
243 |
ADMUX = 0x40 + adc_current_port;
|
|
270 |
ADMUX = ADMUX_OPT | adc_current_port;
|
|
244 | 271 |
} else { |
245 |
ADMUX = 0x40 + EXT_MUX;
|
|
272 |
ADMUX = ADMUX_OPT | EXT_MUX;
|
|
246 | 273 |
set_adc_mux(adc_current_port - 8); |
247 | 274 |
} |
248 | 275 |
} |
249 |
usb_puts("Next value put in!\n\r"); |
|
276 |
|
|
277 |
//Initiate next conversion only if we are running a loop |
|
278 |
if (!adc_loop_running) |
|
279 |
return; |
|
280 |
|
|
250 | 281 |
ADCSRA |= _BV(ADSC); |
251 |
|
|
282 |
|
|
283 |
//if (ADCSRA & _BV(ADSC)) |
|
284 |
// usb_putc('s'); |
|
285 |
|
|
286 |
return; |
|
252 | 287 |
} |
253 | 288 |
|
Also available in: Unified diff