Project

General

Profile

Revision 328

Added by James Kong over 16 years ago

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.

View differences:

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