Project

General

Profile

Revision 1378

Added by James Kong over 13 years ago

Modified bom_refresh() to check analog_loop_running()

View differences:

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