Revision 328
Kevin you suck. -- Chris Your code does not compile. --Brian and Chris I changed analog8 to be what you had as analog_get8, and I did change the methods used in rangefinders and BOM.
branches/analog/trunk/code/projects/libdragonfly/dragonfly_lib.c | ||
---|---|---|
64 | 64 |
**/ |
65 | 65 |
void dragonfly_init(int config) |
66 | 66 |
{ |
67 |
sei(); |
|
67 |
sei();
|
|
68 | 68 |
|
69 | 69 |
// Set directionality of various IO pins |
70 | 70 |
DDRG &= ~(_BV(PING0)|_BV(PING1)); |
... | ... | |
108 | 108 |
_delay_ms(1); |
109 | 109 |
} |
110 | 110 |
|
111 |
/** |
|
112 |
* Malloc for colony. Disables analog loop and then restarts it |
|
113 |
* to avoid problems with malloc. |
|
114 |
* |
|
115 |
* @param size the number of bytes to allocate |
|
116 |
* @return a pointer to size bytes of allocated memory |
|
117 |
**/ |
|
118 |
inline void* colony_malloc(int size) |
|
119 |
{ |
|
120 |
void* ret = NULL; |
|
121 |
analog_stop_loop(); |
|
122 |
delay_ms(1000); |
|
123 |
cli(); |
|
124 |
usb_puts("Calling malloc!\n"); |
|
125 |
ret = malloc(size); |
|
126 |
usb_puts("Malloc returned!\n"); |
|
127 |
sei(); |
|
128 |
analog_start_loop(); |
|
129 |
return ret; |
|
130 |
} |
|
131 | 111 |
|
132 |
|
|
133 | 112 |
/** @} **/ //end defgroup |
134 | 113 |
|
branches/analog/trunk/code/projects/libdragonfly/dragonfly_lib.h | ||
---|---|---|
66 | 66 |
|
67 | 67 |
/** @brief Initialize the board **/ |
68 | 68 |
void dragonfly_init(int config); |
69 |
/** @brief Special malloc to prevent errors from analog **/ |
|
70 |
void* colony_malloc(int size); |
|
71 | 69 |
|
72 | 70 |
/** @} **/ //end addtogroup |
73 | 71 |
|
branches/analog/trunk/code/projects/libdragonfly/analog.c | ||
---|---|---|
28 | 28 |
* @brief Analog input and output |
29 | 29 |
* |
30 | 30 |
* Contains functions for manipulating the ADC on the Dragonfly board. |
31 |
* It operates by running throug all available analog ports (set by AN_MAX, |
|
32 |
* see analog.h for details on that constant). It performs a conversion for |
|
33 |
* each port and stores the 8bit and 10bit value. It then increments the |
|
34 |
* port that it is looking at and then procedes to do another read. |
|
35 |
* |
|
36 |
* analog8 and analog10 are changed to use the lookup table. To use the |
|
37 |
* historic functions, use analog_get8 and analog_get10. If you do use those, |
|
38 |
* it is advised to turn off the loop by calling analog_stop_loop and restarting |
|
39 |
* the loop when done with analog_start_loop. This is especially important if you |
|
40 |
* are planning on doing a series of analog_getX reads. |
|
41 |
* |
|
42 |
* This function pretty intensive on the interrupts as it will be called quite |
|
43 |
* often. Plan ahead for this. |
|
44 | 31 |
* |
45 |
* @author Colony Project, CMU Robotics Club, Kevin Woo
|
|
46 |
* Originally based on fwr code by Tom Lauwers
|
|
32 |
* @author Colony Project, CMU Robotics Club |
|
33 |
* code mostly taken from fwr analog file (author: Tom Lauwers)
|
|
47 | 34 |
**/ |
48 | 35 |
|
49 | 36 |
#include <util/delay.h> |
... | ... | |
53 | 40 |
// Internal Function Prototypes |
54 | 41 |
void set_adc_mux(int which); |
55 | 42 |
|
56 |
/** @brief Struct to hold the value of a particular analog port */ |
|
57 |
typedef struct { |
|
58 |
uint8_t adc8; |
|
59 |
uint16_t adc10; |
|
60 |
} adc_t; |
|
61 |
|
|
62 | 43 |
/** |
63 | 44 |
* @defgroup analog Analog |
64 | 45 |
* Functions for manipulation the ADC on the dragonfly board. |
... | ... | |
69 | 50 |
|
70 | 51 |
int adc_loop_running = 0; |
71 | 52 |
int adc_current_port = 0; |
72 |
adc_t an_val[11];
|
|
53 |
adc_t an_val[10];
|
|
73 | 54 |
|
74 | 55 |
/** |
75 | 56 |
* Initializes the ADC. |
76 | 57 |
* Call analog_init before reading from the analog ports. |
77 | 58 |
* |
78 |
* @see analog8, analog10, analog_get8, analog_get10, analog_start_loop |
|
79 |
* analog_stop_loop |
|
59 |
* @see analog8, analog10 |
|
80 | 60 |
**/ |
81 | 61 |
void analog_init(int start_conversion) |
82 | 62 |
{ |
83 |
//Initialize the array to 0 |
|
84 |
for (int i = 0; i < (AN_MAX + 1); i++) { |
|
63 |
for (int i = 0; i < 10; i++) { |
|
85 | 64 |
an_val[i].adc10 = 0; |
86 | 65 |
an_val[i].adc8 = 0; |
87 | 66 |
} |
88 | 67 |
|
68 |
//cli(); |
|
89 | 69 |
// ADMUX register |
90 |
// The following bits are set |
|
91 | 70 |
// Bit 7,6 - Set voltage reference to AVcc (0b01) |
92 | 71 |
// Bit 5 - ADLAR set to simplify moving from register |
93 | 72 |
// Bit 4 - X |
... | ... | |
98 | 77 |
|
99 | 78 |
|
100 | 79 |
// ADC Status Register A |
101 |
// The following bits are set |
|
102 | 80 |
// Bit 7 - ADEN is set (enables analog) |
81 |
// Bit 6 - Start conversion bit is set (must be done once for free-running mode) |
|
82 |
// Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW |
|
83 |
// Bit 4 - ADC interrupt flag, 0 |
|
103 | 84 |
// Bit 3 - Enable ADC Interrupt (required to run free-running mode) |
104 | 85 |
// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz |
105 | 86 |
ADCSRA = 0; |
... | ... | |
112 | 93 |
set_adc_mux(0x00); |
113 | 94 |
adc_current_port = AN1; |
114 | 95 |
|
115 |
// Start the conversion if requested
|
|
96 |
//Start the conversion if requested |
|
116 | 97 |
if (start_conversion) |
117 | 98 |
analog_start_loop(); |
118 | 99 |
else |
119 | 100 |
analog_stop_loop(); |
101 |
//sei(); |
|
120 | 102 |
|
121 | 103 |
} |
122 | 104 |
|
123 |
/** |
|
124 |
* Reads an analog value from the look-up table. Values are not |
|
125 |
* good unless the analog loop is running. |
|
126 |
* |
|
127 |
* @param which is the analog port you wish to read. |
|
128 |
* |
|
129 |
* @return returns an 8 bit value which represents the analog value |
|
130 |
* |
|
131 |
* @see analog8, analog_start_loop, analog_stop_loop, analog_init |
|
132 |
**/ |
|
133 | 105 |
unsigned int analog_get8(int which) { |
134 | 106 |
if (which == BOM_PORT) { |
135 | 107 |
return 0; |
... | ... | |
138 | 110 |
} |
139 | 111 |
} |
140 | 112 |
|
141 |
/** |
|
142 |
* Reads an analog value from the look-up table. Values are not |
|
143 |
* good unless the analog loop is running. |
|
144 |
* |
|
145 |
* @param which is the analog port you wish to read. |
|
146 |
* |
|
147 |
* @return returns an 10 bit value which represents the analog value |
|
148 |
* |
|
149 |
* @see analog8, analog_start_loop, analog_stop_loop, analog_init |
|
150 |
**/ |
|
151 | 113 |
unsigned int analog_get10(int which) { |
152 | 114 |
if (which == BOM_PORT) { |
153 | 115 |
return 0; |
... | ... | |
156 | 118 |
} |
157 | 119 |
} |
158 | 120 |
|
159 |
/** |
|
160 |
* Starts the analog loop to put values into the lookup table. Need |
|
161 |
* to have the loop running before analog_get8 and analog_get10 are |
|
162 |
* valid. |
|
163 |
* |
|
164 |
* @see analog_stop_loop, analog_init, analog_get8, analog_get10 |
|
165 |
**/ |
|
166 | 121 |
void analog_start_loop(void) { |
167 | 122 |
//Start the conversion |
168 | 123 |
ADCSRA |= _BV(ADSC); |
169 | 124 |
adc_loop_running = 0x1; |
170 | 125 |
} |
171 | 126 |
|
172 |
/** |
|
173 |
* Starts the analog loop to put values into the lookup table. You |
|
174 |
* should disable to loop to use analog8 and analog10 reliably. |
|
175 |
* |
|
176 |
* @see analog_stop_loop, analog_init, analog8, analog10 |
|
177 |
**/ |
|
127 |
//will stop after current conversion finishes |
|
178 | 128 |
void analog_stop_loop(void) { |
179 | 129 |
//Stop the conversion |
180 | 130 |
adc_loop_running = 0x0; |
... | ... | |
184 | 134 |
* analog_init must be called before using this function. |
185 | 135 |
* |
186 | 136 |
* @param which the analog port to read from. One of |
187 |
* the constants AN0 - AN15.
|
|
137 |
* the constants AN0 - AN7.
|
|
188 | 138 |
* |
189 | 139 |
* @return the eight bit input to the specified port |
190 | 140 |
* |
... | ... | |
217 | 167 |
* |
218 | 168 |
* |
219 | 169 |
* @param which the analog port to read from. Typically |
220 |
* a constant, one of AN0 - AN15.
|
|
170 |
* a constant, one of AN0 - AN7.
|
|
221 | 171 |
* |
222 | 172 |
* @return the ten bit number input to the specified port |
223 | 173 |
* |
... | ... | |
262 | 212 |
**/ |
263 | 213 |
int wheel(void) |
264 | 214 |
{ |
265 |
return analog8(WHEEL_PORT); |
|
215 |
return analog_get8(WHEEL_PORT);
|
|
266 | 216 |
} |
267 | 217 |
|
268 | 218 |
|
... | ... | |
292 | 242 |
ISR(ADC_vect) { |
293 | 243 |
static volatile int adc_prev_loop_running = 0; |
294 | 244 |
|
295 |
// Need these local variables to read ADCH and ADCL in the correct order |
|
296 | 245 |
int adc_h = 0; |
297 | 246 |
int adc_l = 0; |
298 | 247 |
|
248 |
//usb_putc('p'); |
|
249 |
//usb_puti(adc_current_port); |
|
250 |
//usb_putc('r'); |
|
251 |
//usb_puti(adc_loop_running); |
|
252 |
//usb_puts("\n\r"); |
|
253 |
|
|
299 | 254 |
//Store the value only if this read isn't for the BOM |
300 | 255 |
if (ADMUX != BOM_PORT) { |
301 |
// Read ADCL before ADCH otherwise the registers change in the middle |
|
302 | 256 |
adc_l = ADCL; |
303 | 257 |
adc_h = ADCH; |
304 | 258 |
|
305 | 259 |
an_val[adc_current_port - 1].adc10 = (adc_h << 2) | (adc_l >> 6); |
306 | 260 |
an_val[adc_current_port - 1].adc8 = adc_h; |
307 |
|
|
261 |
//usb_puti(an_val[adc_current_port - 1].adc10); |
|
262 |
//usb_puts("\n\r"); |
|
263 |
//usb_puti(an_val[adc_current_port - 1].adc8); |
|
264 |
//usb_puti(ADCH); |
|
265 |
//usb_puts("\n\r"); |
|
308 | 266 |
} |
309 | 267 |
|
310 | 268 |
//Save the result only if we just turned off the loop |
... | ... | |
339 | 297 |
return; |
340 | 298 |
|
341 | 299 |
ADCSRA |= _BV(ADSC); |
300 |
|
|
301 |
//if (ADCSRA & _BV(ADSC)) |
|
302 |
// usb_putc('s'); |
|
303 |
|
|
342 | 304 |
return; |
343 | 305 |
} |
344 | 306 |
|
branches/analog/trunk/code/projects/libdragonfly/analog.h | ||
---|---|---|
29 | 29 |
* @brief Contains functions and definitions for using the ADC |
30 | 30 |
* |
31 | 31 |
* Contains definitions and function prototypes for using the |
32 |
* ADC to detect analog signals on pins AN0 - AN15. |
|
33 |
* See analog.c for implementation details. |
|
34 |
* |
|
32 |
* ADC to detect analog signals on pins AN0 - AN7. |
|
33 |
* AN6 and AN7 are used for the wheel and battery. |
|
34 |
|
|
35 |
* The pins labeled E6 and E7 are external interrupt pins and are not related |
|
36 |
* to analog. |
|
37 |
|
|
35 | 38 |
* @author Colony Project, CMU Robotics Club, based on firefly |
36 | 39 |
* code by Tom Lauwers |
37 |
**/
|
|
40 |
*/ |
|
38 | 41 |
|
39 | 42 |
#ifndef _ANALOG_H |
40 | 43 |
#define _ANALOG_H |
... | ... | |
88 | 91 |
/** @brief Analog port for the battery voltage detector **/ |
89 | 92 |
#define BATT_PORT AN11 |
90 | 93 |
|
91 |
/** @brief Used in analog_init to start the analog loop from the get-go **/ |
|
92 | 94 |
#define ADC_START 1 |
93 |
/** @brief Used in analog_init to not start the analog loop from the get-go **/ |
|
94 | 95 |
#define ADC_STOP 0 |
95 |
/** @brief Maximum number of analog ports to check. This number is equivalent to |
|
96 |
* AN1 -> AN11 as AN0 and AN7 are skipped. **/ |
|
97 |
#define ANMAX 11 |
|
98 |
/** @brief For use with ADMUX register. Means that We will use AVCC (REFS0) and |
|
99 |
* enable ADLAR. **/ |
|
96 |
|
|
100 | 97 |
#define ADMUX_OPT 0x60 |
101 | 98 |
|
99 |
/** @brief Struct to hold the value of a particular analog port */ |
|
100 |
typedef struct { |
|
101 |
uint8_t adc8; |
|
102 |
uint16_t adc10; |
|
103 |
} adc_t; |
|
102 | 104 |
|
105 |
|
|
103 | 106 |
/** @brief Initialize analog ports. Will start running a loop |
104 | 107 |
if start_conversion is ADC_START.**/ |
105 | 108 |
void analog_init(int start_conversion); |
... | ... | |
107 | 110 |
void analog_start_loop(void); |
108 | 111 |
/** @brief Stops the analog loop. Doesn't do anything if the loop is already stopped. **/ |
109 | 112 |
void analog_stop_loop(void); |
110 |
/** @brief Returns an 8-bit analog value from the look up table. Use this instead of analog8. **/
|
|
113 |
/** @brief Read an 8-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
111 | 114 |
unsigned int analog8(int which); |
112 |
/** @brief Returns an 10-bit analog value from the look up table. Use this instead of analog10. **/
|
|
115 |
/** @brief Read a 10-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
113 | 116 |
unsigned int analog10(int which); |
114 | 117 |
/** @brief Read the position of the wheel. **/ |
115 | 118 |
int wheel(void); |
116 |
/** @brief Read an 8-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
119 |
/** @brief Returns an 8-bit analog value from the look up table. Use this instead of analog8. **/
|
|
117 | 120 |
unsigned int analog_get8(int which); |
118 |
/** @brief Read a 10-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
121 |
/** @brief Returns an 10-bit analog value from the look up table. Use this instead of analog10. **/
|
|
119 | 122 |
unsigned int analog_get10(int which); |
120 | 123 |
|
121 | 124 |
|
branches/analog/trunk/code/projects/libdragonfly/bom.c | ||
---|---|---|
108 | 108 |
* |
109 | 109 |
* @see analog_init |
110 | 110 |
**/ |
111 |
int get_max_bom(void) |
|
112 |
{ |
|
111 |
int get_max_bom(void) { |
|
113 | 112 |
int max_bom_temp = 0; |
114 |
int a, i, j, h = 255; |
|
113 |
int a, i, j, h; |
|
114 |
h = 255; |
|
115 | 115 |
|
116 | 116 |
//Turn off the loop so that we can actually use analog8 correctly |
117 | 117 |
analog_stop_loop(); |
118 | 118 |
|
119 | 119 |
//Iterate through through each LED |
120 |
for (j = 0; j < 16; j++) |
|
121 |
{ |
|
122 |
i = lookup[j]; |
|
123 |
|
|
124 |
if (i&8) |
|
125 |
output_high(MONK3); |
|
126 |
else |
|
127 |
output_low(MONK3); |
|
128 |
|
|
129 |
if (i&4) |
|
130 |
output_high(MONK2); |
|
131 |
else |
|
132 |
output_low(MONK2); |
|
133 |
|
|
134 |
if (i&2) |
|
135 |
output_high(MONK1); |
|
136 |
else |
|
137 |
output_low(MONK1); |
|
138 |
|
|
139 |
if (i&1) |
|
140 |
output_high(MONK0); |
|
141 |
else |
|
142 |
output_low(MONK0); |
|
143 |
|
|
144 |
a = analog_get8(MONKI); |
|
145 |
|
|
146 |
if (a < h) |
|
147 |
{ |
|
148 |
h = a; |
|
149 |
max_bom_temp = j; |
|
150 |
} |
|
120 |
for (j = 0; j < 16; j++) |
|
121 |
{ |
|
122 |
i = lookup[j]; |
|
151 | 123 |
|
152 |
} |
|
124 |
if (i&8) |
|
125 |
output_high(MONK3); |
|
126 |
else |
|
127 |
output_low(MONK3); |
|
128 |
|
|
129 |
if (i&4) |
|
130 |
output_high(MONK2); |
|
131 |
else |
|
132 |
output_low(MONK2); |
|
133 |
|
|
134 |
if (i&2) |
|
135 |
output_high(MONK1); |
|
136 |
else |
|
137 |
output_low(MONK1); |
|
138 |
|
|
139 |
if (i&1) |
|
140 |
output_high(MONK0); |
|
141 |
else |
|
142 |
output_low(MONK0); |
|
143 |
|
|
144 |
a = analog8(MONKI); |
|
145 |
|
|
146 |
if (a < h) |
|
147 |
{ |
|
148 |
h = a; |
|
149 |
max_bom_temp = j; |
|
150 |
} |
|
151 |
|
|
152 |
} |
|
153 | 153 |
|
154 | 154 |
//Restart loop now that we are done using analog8 |
155 | 155 |
analog_start_loop(); |
branches/analog/trunk/code/projects/libdragonfly/rangefinder.c | ||
---|---|---|
134 | 134 |
**/ |
135 | 135 |
int range_read_distance (int range_id) |
136 | 136 |
{ |
137 |
return linearize_distance(analog8(range_id)); |
|
137 |
return linearize_distance(analog_get8(range_id));
|
|
138 | 138 |
} |
139 | 139 |
|
140 | 140 |
/** @} **/ //end defgroup |
Also available in: Unified diff