Project

General

Profile

Revision 1378

Added by James Kong about 10 years ago

Modified bom_refresh() to check analog_loop_running()

View differences:

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

Also available in: Unified diff