Revision 1378
Modified bom_refresh() to check analog_loop_running()
branches/analog/code/projects/libdragonfly/analog.c | ||
---|---|---|
30 | 30 |
* Contains functions for manipulating the ADC on the Dragonfly board. |
31 | 31 |
* |
32 | 32 |
* @author Colony Project, CMU Robotics Club |
33 |
* code mostly taken from fwr analog file (author: Tom Lauwers) |
|
33 |
* originally taken from fwr analog file (author: Tom Lauwers) |
|
34 |
* loop code written by Kevin Woo and James Kong |
|
34 | 35 |
**/ |
35 | 36 |
|
36 | 37 |
#include <util/delay.h> |
... | ... | |
57 | 58 |
* Call analog_init before reading from the analog ports. |
58 | 59 |
* |
59 | 60 |
* @see analog8, analog10, analog_get8, analog_get10 |
61 |
* |
|
62 |
* @bug First conversion takes a performance penalty of |
|
63 |
* 25 vs. 13 ADC clock cycles of successive conversions. |
|
64 |
* Analog_init should run a dummy conversion to pre-empt |
|
65 |
* this. |
|
66 |
* |
|
67 |
* For good 10-bit precision, ACD clock must be between |
|
68 |
* 50kHz and 200kHz. Currently, ADC clock is fixed at |
|
69 |
* 125kHz using 1/64prescalar. However, most code uses |
|
70 |
* 8-bit precision which can work at ADC clock speeds |
|
71 |
* higher than 200kHz. Experimental tests needed to |
|
72 |
* determine highest clock speed for accurate 8-bit ADC. |
|
73 |
* |
|
60 | 74 |
**/ |
61 | 75 |
void analog_init(int start_conversion) { |
62 | 76 |
for (int i = 0; i < 11; i++) { |
... | ... | |
81 | 95 |
// Bit 3 - Enable ADC Interrupt (required to run free-running mode) |
82 | 96 |
// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz |
83 | 97 |
ADCSRA = 0; |
84 |
ADCSRA |= _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
|
|
98 |
ADCSRA |= _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); |
|
85 | 99 |
|
86 | 100 |
// Set external mux lines to outputs |
87 | 101 |
DDRG |= 0x1C; |
... | ... | |
155 | 169 |
* Starts the analog update loop. Will continue to run |
156 | 170 |
* until analog_stop_loop is called. |
157 | 171 |
* |
158 |
* @see analog_stop_loop |
|
172 |
* @see analog_stop_loop, analog_loop_running
|
|
159 | 173 |
**/ |
160 | 174 |
void analog_start_loop(void) { |
161 |
//Start the conversion |
|
162 |
ADCSRA |= _BV(ADSC); |
|
175 |
//Start the conversion, enable ADC interrupt
|
|
176 |
ADCSRA |= _BV(ADSC) | _BV(ADIE);
|
|
163 | 177 |
adc_loop_running = 0x1; |
164 | 178 |
} |
165 | 179 |
|
... | ... | |
169 | 183 |
* is interrupted. No further updates will be made until |
170 | 184 |
* the loop is started again. |
171 | 185 |
* |
172 |
* @see analog_start_loop |
|
186 |
* @param Whether or not to block until current conversion |
|
187 |
* to complete. Use WAIT_UNTIL_FINISHED or |
|
188 |
* SKIP_WAIT. |
|
189 |
* |
|
190 |
* @see analog_start_loop, analog_loop_running |
|
173 | 191 |
**/ |
174 |
void analog_stop_loop(void) {
|
|
192 |
void analog_stop_loop(int skip_wait) {
|
|
175 | 193 |
//Stop the conversion |
176 | 194 |
adc_loop_running = 0x0; |
195 |
|
|
196 |
if(skip_wait) { |
|
197 |
//Stop the interrupt |
|
198 |
ADCSRA &= _BV(ADIE); |
|
199 |
return; |
|
200 |
} |
|
201 |
|
|
202 |
//Wait for the ADC interrupt flag to clear / conversion to complete |
|
203 |
while(ADCSRA & _BV(ADIF)); |
|
204 |
//Stop the interrupt |
|
205 |
ADCSRA &= _BV(ADIE); |
|
177 | 206 |
} |
207 |
|
|
178 | 208 |
/** |
209 |
* Returns the status of loop. 1 for running. |
|
210 |
* 0 for not running. |
|
211 |
* |
|
212 |
* @see analog_start_loop, analog_stop_loop |
|
213 |
**/ |
|
214 |
int analog_loop_running(void) { |
|
215 |
return adc_loop_running; |
|
216 |
} |
|
217 |
|
|
218 |
/** |
|
179 | 219 |
* Reads an 8-bit number from an analog port. |
180 | 220 |
* analog_init must be called before using this function. |
181 | 221 |
* The analog loop must also be stopped before using this |
branches/analog/code/projects/libdragonfly/analog.h | ||
---|---|---|
36 | 36 |
* to analog. |
37 | 37 |
|
38 | 38 |
* @author Colony Project, CMU Robotics Club, based on firefly |
39 |
* code by Tom Lauwers |
|
39 |
* originally taken from fwr analog file (author: Tom Lauwers) |
|
40 |
* loop code written by Kevin Woo and James Kong |
|
40 | 41 |
*/ |
41 | 42 |
|
42 | 43 |
#ifndef _ANALOG_H |
... | ... | |
91 | 92 |
/** @brief Analog port for the battery voltage detector **/ |
92 | 93 |
#define BATT_PORT AN11 |
93 | 94 |
|
95 |
/** @brief Wait for current conversion to complete. Parameter for analog_stop_loop **/ |
|
96 |
#define WAIT_UNTIL_FINISHED 0 |
|
97 |
/** @brief Don't wait for current conversion to complete. Parameter for analog_stop_loop **/ |
|
98 |
#define SKIP_WAIT 1 |
|
99 |
|
|
94 | 100 |
#define ADC_START 1 |
95 | 101 |
#define ADC_STOP 0 |
96 | 102 |
|
... | ... | |
110 | 116 |
void analog_start_loop(void); |
111 | 117 |
/** @brief Stops the analog loop. Doesn't do anything if the loop is already stopped. **/ |
112 | 118 |
void analog_stop_loop(void); |
119 |
/** @brief Returns the status of the analog loop. **/ |
|
120 |
int analog_loop_running(void); |
|
113 | 121 |
/** @brief Returns an 8-bit analog value from the look up table. Use this instead of analog_get8. **/ |
114 | 122 |
unsigned int analog8(int which); |
115 | 123 |
/** @brief Returns an 10-bit analog value from the look up table. Use this instead of analog_get10. **/ |
branches/analog/code/projects/libdragonfly/bom.c | ||
---|---|---|
167 | 167 |
**/ |
168 | 168 |
void bom_refresh(int bit_field) { |
169 | 169 |
int i; |
170 |
int loop_running; |
|
170 | 171 |
|
171 |
analog_stop_loop(); |
|
172 |
//Check analog loop status |
|
173 |
loop_running = analog_loop_running(); |
|
174 |
if(loop_running) |
|
175 |
analog_stop_loop(); |
|
172 | 176 |
|
173 | 177 |
for(i = 0; i < NUM_BOM_LEDS; i++) { |
174 | 178 |
if(bit_field & 0x1) { |
... | ... | |
178 | 182 |
bit_field = bit_field >> 1; |
179 | 183 |
} |
180 | 184 |
|
181 |
analog_start_loop(); |
|
185 |
//Restore analog loop status |
|
186 |
if(loop_running) |
|
187 |
analog_start_loop(); |
|
182 | 188 |
} |
183 | 189 |
|
184 | 190 |
/** |
Also available in: Unified diff