Project

General

Profile

Revision 365

made a copy

View differences:

branches/rbom/code/lib/src/libdragonfly/lights.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file ligths.c
29
 * @brief Orbs
30
 *
31
 * Implemenation for the orbs (tri-colored LEDs)
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 * @bug Colors are incorrect, seems to not work with wireless library
35
 **/
36

  
37
/*
38
lights.c
39
Controls orb1 and orb2. Also contains the framework for a software PWM that may be used for servos in the future.
40

  
41
author: CMU Robotics Club, Colony Project
42

  
43
Change Log:
44
2.4.07 - Aaron
45
	Revamped orb code so it works.  Need to check interaction with rtc, and tweak some colors.
46

  
47
2.1.07 - James
48
	Modified sort_buffer() to prune for repeats.  PWM now uses orb_buf_size for the number of orb values in orb_time_arr[].
49
		Changed sorting algorithm used in sort_buffer() to selection sort (faster). And it works now.
50

  
51
1.25.07 - KWoo
52
	Deleted old FF+ code to make it cleaner. Commented code. This all works. Note however that if you ever plan to use the
53
		software PWM (which is this) you will need to change the implementation of orb_enable() and orb_disable() to not
54
		shutdown the PWM.
55

  
56
*/
57

  
58
#include "lights.h"
59
#include "dragonfly_lib.h"
60
#include <avr/interrupt.h>
61

  
62
#define ORB_RESET 1025
63
#define ORBPORT PORTC
64
#define ORBDDR DDRC
65
#define ORBMASK 0x77
66

  
67
/***** Port and Pin Definitions ****/
68

  
69
//Orb Ports and Registers
70
#define ORB_PORT        PORTC
71
#define ORB_DDR         DDRC
72

  
73
//Orb Pins
74
#define ORB1_RED        0x00
75
#define ORB1_GREEN      0x01
76
#define ORB1_BLUE       0x02
77
#define ORB2_RED        0x04
78
#define ORB2_GREEN      0x05
79
#define ORB2_BLUE       0x06
80

  
81

  
82
#define ORB_COUNT 8	//please dont change this, or bad things might happen
83

  
84
// an orb node
85
struct ORB_NODE {
86
   uint8_t num;
87
   uint16_t angle;
88
};
89

  
90
//the change in an orb
91
struct ORB_CHANGE {
92
   uint16_t port_val;
93
   uint16_t split_time_period;
94
};
95

  
96
// the status of an orb
97
struct ORB_STATUS_STRUCT {
98
   struct ORB_NODE orbs[ORB_COUNT];
99
   uint16_t orb_angles[ORB_COUNT];
100
   struct ORB_CHANGE changes[ORB_COUNT+1];
101
   uint8_t change_count;
102
   uint8_t new_angles;
103
   uint8_t current_orb;
104

  
105
} ORB_STATUS;
106

  
107
//TODO: if these are only used in this file, make them static.  If they are used
108
// by other files then put them in a header file
109
void orb_sort(void);
110
void orb_setup_pulse(void);
111

  
112
SIGNAL (SIG_OUTPUT_COMPARE3C){
113

  
114
		//pull the correct ones down
115
      ORBPORT &= (~ORBMASK)|(ORB_STATUS.changes[ORB_STATUS.current_orb].port_val);
116

  
117
      ++ORB_STATUS.current_orb; //now look at next orb transition
118

  
119
      if (ORB_STATUS.current_orb < ORB_STATUS.change_count) { //if it isnt the end...
120
	  
121
			//setup timer for next pull down
122
         OCR3C = TCNT3+ORB_STATUS.changes[ORB_STATUS.current_orb].split_time_period;
123
		 
124
     }
125
      else { //we are done with these pulses
126
		orb_setup_pulse();
127
      }
128

  
129
}
130

  
131

  
132
//sets a channel to a value
133
void orb_set_angle(int orb, int angle) {
134
	uint8_t mysreg;
135
	
136
	orb=orb&0x07; //only have 8
137
	angle=angle&0xff; //only accept 0-255
138
	angle=255-angle; //inverse intensity
139
	angle=angle<<2; //scale up so that we dont run it too often
140
	angle+=3; //0 values dont really work
141
   if (ORB_STATUS.orb_angles[orb] != angle) { //if the angle has changed
142
	  mysreg=SREG; 
143
	  cli(); //disable interrupts
144
      ORB_STATUS.orb_angles[orb] = angle; //update angle
145
      ORB_STATUS.new_angles = 1;
146
	  SREG=mysreg; //put interrupt status back
147
   }
148
}
149

  
150

  
151
void orb_sort(void) {
152
   int done = 0, i;
153
   
154
   while (! done) {
155
      done = 1;
156

  
157
      for (i = 0; i < ORB_COUNT - 1; ++i) {  //loop through all
158
	  
159
			//if they are out of order, swap them
160
         if (ORB_STATUS.orbs[i].angle > ORB_STATUS.orbs[i+1].angle) {
161
            ORB_STATUS.orbs[i].angle ^= ORB_STATUS.orbs[i+1].angle;
162
            ORB_STATUS.orbs[i+1].angle ^= ORB_STATUS.orbs[i].angle;
163
            ORB_STATUS.orbs[i].angle ^= ORB_STATUS.orbs[i+1].angle;
164

  
165
            ORB_STATUS.orbs[i].num ^= ORB_STATUS.orbs[i+1].num;
166
            ORB_STATUS.orbs[i+1].num ^= ORB_STATUS.orbs[i].num;
167
            ORB_STATUS.orbs[i].num ^= ORB_STATUS.orbs[i+1].num;
168

  
169
            done = 0;
170
         }
171
      }
172
   }
173
}
174

  
175
//calculate the split times
176
void orb_setup_pulse(void) {
177
   int i;
178
   uint16_t my_port;
179
   uint16_t sum = 0;
180
   uint16_t split_time;
181

  
182
   my_port = 0xff; //all on
183

  
184
   if (ORB_STATUS.new_angles) {
185

  
186
      ORB_STATUS.change_count = 0;
187
	  for (i = 0; i < ORB_COUNT; ++i) { //get the new values
188
         ORB_STATUS.orbs[i].angle = ORB_STATUS.orb_angles[ORB_STATUS.orbs[i].num];
189
      }
190

  
191
      orb_sort(); //sort them
192
      ORB_STATUS.new_angles = 0;
193

  
194
      for (i = 0; i < ORB_COUNT; ++i) { //calculate split times
195
         split_time = ORB_STATUS.orbs[i].angle - sum;
196
         my_port &= ~_BV(ORB_STATUS.orbs[i].num);
197
		 
198
         for (; i < ORB_COUNT - 1 && ORB_STATUS.orbs[i].angle == ORB_STATUS.orbs[i+1].angle; ++i) {
199
            my_port &= ~_BV(ORB_STATUS.orbs[i+1].num); //look for doups
200
         }
201
		 
202
         ORB_STATUS.changes[ORB_STATUS.change_count].port_val = my_port; //which pins are low
203
         ORB_STATUS.changes[ORB_STATUS.change_count].split_time_period = split_time;
204
         
205
		 ++ORB_STATUS.change_count;
206
		 
207
         sum += split_time;
208
      }
209

  
210
      ORB_STATUS.changes[ORB_STATUS.change_count].port_val = my_port;
211
      ORB_STATUS.changes[ORB_STATUS.change_count].split_time_period = ORB_RESET - sum; //get a constant period
212

  
213
      ++ORB_STATUS.change_count;
214

  
215
   }
216

  
217
   ORB_STATUS.current_orb = 0;
218

  
219
    ORBPORT |= ORBMASK; //start with all high
220
	OCR3C = TCNT3 + ORB_STATUS.changes[0].split_time_period; //wait for first split
221
}
222

  
223
/**
224
 * @defgroup orbs Orbs
225
 * @brief Functions for controlling the color of the orbs.
226
 * 
227
 * Functions for controlling the color and lighting of the orbs.
228
 *
229
 * @{
230
 **/
231

  
232
/**
233
 * Initializes the PWM for Orb control. This must be called before 
234
 * the orbs are used for them to function.
235
 **/
236
void orb_init() 
237
{	
238
   int i;
239
   uint8_t mysreg;
240
   
241
   ORBDDR |= ORBMASK;	//all outputs
242
   
243
	mysreg=SREG;
244
	cli(); //turn off interrupts for now
245

  
246
	//init everything
247

  
248
   for (i = 0; i < ORB_COUNT; ++i) {
249
      ORB_STATUS.orbs[i].num = i;
250
      ORB_STATUS.orbs[i].angle = 1023;	//127 is a pretty stupid start angle, but oh well
251
      ORB_STATUS.orb_angles[i] = 1023;
252
   }
253

  
254
   ORB_STATUS.new_angles = 1;
255
   ORB_STATUS.change_count = 0;
256

  
257
	//init timer3
258
	TCCR3A = 0; 
259
	TCCR3B = _BV(CS31); //prescale = 8
260
	TCCR3C = 0;
261
	ETIMSK |= _BV(OCIE3C); //turn on oc3c interrupt
262
	OCR3C = TCNT3+ORB_RESET;
263

  
264
	SREG=mysreg;
265
}
266

  
267
/**
268
 * Set both orbs to the color specified. orb_init must
269
 * be called before this function may be used.
270
 *
271
 * @param red_led the red component of the color
272
 * @param green_led the green component of the color
273
 * @param blue_led the blue component of the color
274
 *
275
 * @see orb_init
276
 **/
277
void orb_set(unsigned char red_led, unsigned char green_led, unsigned char blue_led) {
278
	orb1_set(red_led,green_led,blue_led);
279
	orb2_set(red_led,green_led,blue_led);
280

  
281
}
282

  
283
/**
284
 * Set orb1 to the color specified. orb_init must
285
 * be called before this function may be used.
286
 *
287
 * @param red_led the red component of the color
288
 * @param green_led the green component of the color
289
 * @param blue_led the blue component of the color
290
 *
291
 * @see orb_init
292
 **/
293
void orb1_set(unsigned char red_led, unsigned char green_led, unsigned char blue_led) {
294
	orb_set_angle(0,red_led);
295
	orb_set_angle(1,green_led);
296
	orb_set_angle(2,blue_led);
297
}
298

  
299
/**
300
 * Set orb2 to the color specified. orb_init must
301
 * be called before this function may be used.
302
 *
303
 * @param red_led the red component of the color
304
 * @param green_led the green component of the color
305
 * @param blue_led the blue component of the color
306
 *
307
 * @see orb_init
308
 **/
309
void orb2_set(unsigned char red_led, unsigned char green_led, unsigned char blue_led) {	
310
	orb_set_angle(4,red_led);
311
	orb_set_angle(5,green_led);
312
	orb_set_angle(6,blue_led);
313
}
314

  
315
/**
316
 * Set both orbs to the specified color. This function
317
 * is intended to be used with the predefined
318
 * colors. orb_init must be called before this
319
 * function may be used.
320
 *
321
 * @param col the color to set the orbs to
322
 *
323
 * @see orb_init
324
 **/
325
void orb_set_color(int col)
326
{
327
 int red, green, blue;
328

  
329
 red = ((col & 0xE0) >> 5) * 36;
330
 green = ((col & 0x1C) >> 2) * 36;
331
 blue = (col & 0x03) * 85;
332

  
333
 orb_set(red, green, blue);
334
}
335

  
336
/**
337
 * Set orb1 to the specified color. This function
338
 * is intended to be used with the predefined
339
 * colors. orb_init must be called before this
340
 * function may be used.
341
 *
342
 * @param col the color to set the orbs to
343
 *
344
 * @see orb_init
345
 **/
346
void orb1_set_color(int col)
347
{
348
 int red, green, blue;
349

  
350
 red = ((col & 0xE0) >> 5) * 36;
351
 green = ((col & 0x1C) >> 2) * 36;
352
 blue = (col & 0x03) * 85;
353

  
354
 orb1_set(red, green, blue);
355
}
356

  
357
/**
358
 * Set orb2 to the specified color. This function
359
 * is intended to be used with the predefined
360
 * colors. orb_init must be called before this
361
 * function may be used.
362
 *
363
 * @param col the color to set the orbs to
364
 *
365
 * @see orb_init
366
 **/
367
void orb2_set_color(int col)
368
{
369
 int red, green, blue;
370

  
371
 red = ((col & 0xE0) >> 5) * 36;
372
 green = ((col & 0x1C) >> 2) * 36;
373
 blue = (col & 0x03) * 85;
374

  
375
 orb2_set(red, green, blue);
376
}
377

  
378
//DOES THIS WORK?
379
// Disables the timer1 interrupt, disabling the Orb's color fading capabilities
380
// You can still turn the red, green, and blue leds on and off with set_orb_dio
381
/* If we use the PWM for anything else besides the ORB, this implementation needs to be done better */
382
/**
383
 * Disables the orb color fading capabilities
384
 * by disabling the timer1 interrupt.
385
 *
386
 * @see orb_init
387
 **/
388
void orb_disable()
389
{
390
	TCCR3B &= 0;  	//Turn off everything
391
	ORB_PORT |= _BV(ORB1_RED);
392
	ORB_PORT |= _BV(ORB1_GREEN);
393
	ORB_PORT |= _BV(ORB1_BLUE);
394
	ORB_PORT |= _BV(ORB2_RED);
395
	ORB_PORT |= _BV(ORB2_GREEN);
396
	ORB_PORT |= _BV(ORB2_BLUE);
397
}
398

  
399
//DOES THIS WORK?
400
// Enables the timer1 interrupt, enabling the Orb's color fading capabilities
401
/**
402
 * Enables the orb's color fading capabilities.
403
 *
404
 * @see orb_init
405
 **/
406
void orb_enable()
407
{
408
//	TCCR0 |= _BV(COM01) | _BV(COM00)  | _BV(WGM00) | _BV(CS01);	//Toggle OC Pin on match, FAST PWM Mode, clock/8
409
	TCCR3B =_BV(CS31);
410
}
411

  
412
/** @} **/ //end group
413

  
branches/rbom/code/lib/src/libdragonfly/lcd.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file lcd.c
29
 * @brief LCD
30
 *
31
 * Implementation of functions for using the LCD.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35
#include <avr/io.h>
36
#include <lcd.h>
37
#include <time.h>
38

  
39
//LCD defines
40
#define RST _BV(4)  // pd4 (GPIO)
41
#define SCE _BV(0)  // pb0 (~SS)
42
#define D_C _BV(5)  // pd5 (GPIO?)
43
#define SDI _BV(2)  // pb2 (MOSI)
44
#define SCK _BV(1) // pb1 (SCK)
45

  
46
#define LCDPORT PORTB
47
#define LCDDDR DDRB
48

  
49
#define LCDRESETPORT PORTD
50
#define LCDRESETDDR DDRD
51

  
52
void lcd_putbyte(unsigned char b);
53

  
54

  
55
//**************************************Old shit below!*****************
56
/*
57
FontLookup - a lookup table for all characters
58
*/
59
static const unsigned char FontLookup [][5] =
60
{
61
    { 0x00, 0x00, 0x00, 0x00, 0x00 },  // sp
62
    { 0x00, 0x00, 0x5f, 0x00, 0x00 },   // !
63
    { 0x00, 0x07, 0x00, 0x07, 0x00 },   // "
64
    { 0x14, 0x7f, 0x14, 0x7f, 0x14 },   // #
65
    { 0x24, 0x2a, 0x7f, 0x2a, 0x12 },   // $
66
    { 0x23, 0x13, 0x08, 0x64, 0x62 },   // %
67
    { 0x36, 0x49, 0x55, 0x22, 0x50 },   // &
68
    { 0x00, 0x05, 0x03, 0x00, 0x00 },   // '
69
    { 0x00, 0x1c, 0x22, 0x41, 0x00 },   // (
70
    { 0x00, 0x41, 0x22, 0x1c, 0x00 },   // )
71
    { 0x14, 0x08, 0x3E, 0x08, 0x14 },   // *
72
    { 0x08, 0x08, 0x3E, 0x08, 0x08 },   // +
73
    { 0x00, 0x00, 0x50, 0x30, 0x00 },   // ,
74
    { 0x10, 0x10, 0x10, 0x10, 0x10 },   // -
75
    { 0x00, 0x60, 0x60, 0x00, 0x00 },   // .
76
    { 0x20, 0x10, 0x08, 0x04, 0x02 },   // /
77
    { 0x3E, 0x51, 0x49, 0x45, 0x3E },   // 0
78
    { 0x00, 0x42, 0x7F, 0x40, 0x00 },   // 1
79
    { 0x42, 0x61, 0x51, 0x49, 0x46 },   // 2
80
    { 0x21, 0x41, 0x45, 0x4B, 0x31 },   // 3
81
    { 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4
82
    { 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5
83
    { 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6
84
    { 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7
85
    { 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8
86
    { 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9
87
    { 0x00, 0x36, 0x36, 0x00, 0x00 },   // :
88
    { 0x00, 0x56, 0x36, 0x00, 0x00 },   // ;
89
    { 0x08, 0x14, 0x22, 0x41, 0x00 },   // <
90
    { 0x14, 0x14, 0x14, 0x14, 0x14 },   // =
91
    { 0x00, 0x41, 0x22, 0x14, 0x08 },   // >
92
    { 0x02, 0x01, 0x51, 0x09, 0x06 },   // ?
93
    { 0x32, 0x49, 0x59, 0x51, 0x3E },   // @
94
    { 0x7E, 0x11, 0x11, 0x11, 0x7E },   // A
95
    { 0x7F, 0x49, 0x49, 0x49, 0x36 },   // B
96
    { 0x3E, 0x41, 0x41, 0x41, 0x22 },   // C
97
    { 0x7F, 0x41, 0x41, 0x22, 0x1C },   // D
98
    { 0x7F, 0x49, 0x49, 0x49, 0x41 },   // E
99
    { 0x7F, 0x09, 0x09, 0x09, 0x01 },   // F
100
    { 0x3E, 0x41, 0x49, 0x49, 0x7A },   // G
101
    { 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H
102
    { 0x00, 0x41, 0x7F, 0x41, 0x00 },   // I
103
    { 0x20, 0x40, 0x41, 0x3F, 0x01 },   // J
104
    { 0x7F, 0x08, 0x14, 0x22, 0x41 },   // K
105
    { 0x7F, 0x40, 0x40, 0x40, 0x40 },   // L
106
    { 0x7F, 0x02, 0x0C, 0x02, 0x7F },   // M
107
    { 0x7F, 0x04, 0x08, 0x10, 0x7F },   // N
108
    { 0x3E, 0x41, 0x41, 0x41, 0x3E },   // O
109
    { 0x7F, 0x09, 0x09, 0x09, 0x06 },   // P
110
    { 0x3E, 0x41, 0x51, 0x21, 0x5E },   // Q
111
    { 0x7F, 0x09, 0x19, 0x29, 0x46 },   // R
112
    { 0x46, 0x49, 0x49, 0x49, 0x31 },   // S
113
    { 0x01, 0x01, 0x7F, 0x01, 0x01 },   // T
114
    { 0x3F, 0x40, 0x40, 0x40, 0x3F },   // U
115
    { 0x1F, 0x20, 0x40, 0x20, 0x1F },   // V
116
    { 0x3F, 0x40, 0x38, 0x40, 0x3F },   // W
117
    { 0x63, 0x14, 0x08, 0x14, 0x63 },   // X
118
    { 0x07, 0x08, 0x70, 0x08, 0x07 },   // Y
119
    { 0x61, 0x51, 0x49, 0x45, 0x43 },   // Z
120
    { 0x00, 0x7F, 0x41, 0x41, 0x00 },   // [
121
    { 0x02, 0x04, 0x08, 0x10, 0x20 },   // backslash
122
    { 0x00, 0x41, 0x41, 0x7F, 0x00 },   // ]
123
    { 0x04, 0x02, 0x01, 0x02, 0x04 },   // ^
124
    { 0x40, 0x40, 0x40, 0x40, 0x40 },   // _
125
    { 0x00, 0x01, 0x02, 0x04, 0x00 },   // '
126
    { 0x20, 0x54, 0x54, 0x54, 0x78 },   // a
127
    { 0x7F, 0x48, 0x44, 0x44, 0x38 },   // b
128
    { 0x38, 0x44, 0x44, 0x44, 0x20 },   // c
129
    { 0x38, 0x44, 0x44, 0x48, 0x7F },   // d
130
    { 0x38, 0x54, 0x54, 0x54, 0x18 },   // e
131
    { 0x08, 0x7E, 0x09, 0x01, 0x02 },   // f
132
    { 0x0C, 0x52, 0x52, 0x52, 0x3E },   // g
133
    { 0x7F, 0x08, 0x04, 0x04, 0x78 },   // h
134
    { 0x00, 0x44, 0x7D, 0x40, 0x00 },   // i
135
    { 0x20, 0x40, 0x44, 0x3D, 0x00 },   // j
136
    { 0x7F, 0x10, 0x28, 0x44, 0x00 },   // k
137
    { 0x00, 0x41, 0x7F, 0x40, 0x00 },   // l
138
    { 0x7C, 0x04, 0x18, 0x04, 0x78 },   // m
139
    { 0x7C, 0x08, 0x04, 0x04, 0x78 },   // n
140
    { 0x38, 0x44, 0x44, 0x44, 0x38 },   // o
141
    { 0x7C, 0x14, 0x14, 0x14, 0x08 },   // p
142
    { 0x08, 0x14, 0x14, 0x18, 0x7C },   // q
143
    { 0x7C, 0x08, 0x04, 0x04, 0x08 },   // r
144
    { 0x48, 0x54, 0x54, 0x54, 0x20 },   // s
145
    { 0x04, 0x3F, 0x44, 0x40, 0x20 },   // t
146
    { 0x3C, 0x40, 0x40, 0x20, 0x7C },   // u
147
    { 0x1C, 0x20, 0x40, 0x20, 0x1C },   // v
148
    { 0x3C, 0x40, 0x30, 0x40, 0x3C },   // w
149
    { 0x44, 0x28, 0x10, 0x28, 0x44 },   // x
150
    { 0x0C, 0x50, 0x50, 0x50, 0x3C },   // y
151
    { 0x44, 0x64, 0x54, 0x4C, 0x44 },    // z
152
    { 0x00, 0x08, 0x36, 0x41, 0x41 },   // {
153
    { 0x00, 0x00, 0x7F, 0x00, 0x00 },   // |
154
    { 0x41, 0x41, 0x36, 0x08, 0x00 },   // }
155
    { 0x02, 0x01, 0x01, 0x02, 0x01 },   // ~
156
    { 0x55, 0x2A, 0x55, 0x2A, 0x55 },   // del
157
};
158

  
159

  
160
/**
161
 * @defgroup lcd LCD
162
 * @brief Functions for the LCD
163
 * Functions for writing to the LCD.
164
 * All functions may be found in lcd.h.
165
 *
166
 * @{
167
 **/
168

  
169
/**
170
 * Initializes the LCD. Must be called before any other
171
 * LCD functions.
172
 **/
173
void lcd_init(void)
174
{
175
	LCDDDR |= (SCE | SDI | SCK);
176
	LCDRESETDDR |= (RST|D_C);
177

  
178
	LCDPORT &= ~( SCE | SDI | SCK);
179
	LCDRESETPORT &=~(D_C);
180
  
181
	SPCR |= 0x50;//0b01010000; // no SPI int, SPI en, Master, sample on rising edge, fosc/2
182
	SPSR |= 0x01;       // a continuation of the above
183

  
184
	LCDRESETPORT |= RST;
185
	delay_ms(10);
186
	LCDRESETPORT &= (~RST);
187
	delay_ms(100);
188
	LCDRESETPORT |= RST;
189
	
190
	lcd_putbyte( 0x21 );  // LCD Extended Commands.
191
	lcd_putbyte( 0xC8 );  // Set LCD Vop (Contrast).
192
	lcd_putbyte( 0x06 );  // Set Temp coefficent.
193
	lcd_putbyte( 0x13 );  // LCD bias mode 1:48.
194
	lcd_putbyte( 0x20 );  // LCD Standard Commands, Horizontal addressing mode.
195
	lcd_putbyte( 0x0C );  // LCD in normal mode.
196
	
197
	LCDRESETPORT |= D_C;		//put it in init instead of main
198
	
199
	lcd_clear_screen();
200
}
201

  
202
/**
203
 * Clears the LCD screen. lcd_init must be called first.
204
 * 
205
 * @see lcd_init
206
 **/
207
void lcd_clear_screen( void ) {
208
	int i;
209
	for (i = 0; i < 504; i++)
210
		lcd_putbyte(0x0);
211
	
212
	lcd_gotoxy(0,0);
213
}
214

  
215
/**
216
 * Prints a character on the LCD screen. lcd_init
217
 * must be called before this function may be used.
218
 *
219
 * @param c the character to print
220
 *
221
 * @see lcd_init
222
 **/
223
void lcd_putc(char c)
224
{
225
	int i;
226
	
227
	for (i = 0; i < 5; i++)
228
		lcd_putbyte(FontLookup[c-32][i]);
229
	lcd_putbyte(0);
230
}
231

  
232
/*
233
print an entire string to the lcd
234
*/
235
void lcd_puts(char *s)
236
{
237
	char *t = s;
238
	while (*t != 0)
239
	{
240
		lcd_putc(*t);
241
		t++;
242
	}
243
}
244

  
245
/*
246
go to coordinate x, y
247
y: vertically - 1 char
248
x: horizontally - 1 pixel
249

  
250
multiply x by 6 if want to move 1 entire character
251

  
252
origin (0,0) is at top left corner of lcd screen
253
*/
254

  
255
/**
256
 * Move the current cursor position to the one specified.
257
 * lcd_init must be called before this function may be used.
258
 * 
259
 * @param x The x coordinate of the new position
260
 * @param y The y coordinate of the new position
261
 *
262
 * @see lcd_init
263
 **/
264
void lcd_gotoxy(int x, int y)
265
{
266
	LCDRESETPORT &= ~(D_C);
267
	lcd_putbyte(0x40 | (y & 0x07));
268
	lcd_putbyte(0x80 | (x & 0x7f));
269
	LCDRESETPORT |= D_C;
270
}
271

  
272
/*
273
prints an int to the lcd
274

  
275
code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
276
*/
277

  
278
/**
279
 * Print an integer to the LCD screen.
280
 * lcd_init must be called before this function may be used.
281
 * 
282
 * @param value the integer to print
283
 *
284
 * @see lcd_init
285
 **/
286
void lcd_puti(int value )
287
{
288
	unsigned char lcd_data[6]={'0','0','0','0','0','0' }, position=sizeof(lcd_data), radix=10; 
289

  
290
        /* convert int to ascii  */ 
291
        if(value<0) { 
292
	  lcd_putc('-'); 
293
	  value=-value; 
294
	}    
295
        do { 
296
	  position--; 
297
	  *(lcd_data+position)=(value%radix)+'0'; 
298
	  value/=radix;  
299
	} while(value); 
300

  
301
    
302
        /* start displaying the number */
303
        for( ; position<=(sizeof(lcd_data)-1); position++)
304
		lcd_putc(lcd_data[position]);
305

  
306
	return;
307
}
308

  
309
/** @} **/ //end defgroup
310

  
311
void lcd_putbyte(unsigned char b)
312
{
313
	SPDR = b;
314
	while (!(SPSR & 0x80)); /* Wait until SPI transaction is complete */
315
}
316

  
branches/rbom/code/lib/src/libdragonfly/bom.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file bom.c
29
 * @brief Implementation for using the BOM
30
 *
31
 * Contains functions for using the Bearing and Orientation Module (BOM)
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
#include <dragonfly_lib.h>
37
#include "bom.h"
38
#include "dio.h"
39
#include "analog.h"
40

  
41
//constants
42
//TODO: for better readability, make all of these hex or decimal
43
const int lookup[16] = {7,6,5,0xe,1,4,3,2,0xf,0,0xd,8,0xc,0xb,9,0xa};
44

  
45
// internal function prototypes
46
//TODO: if these are only used in this file, make them static
47
void output_high(int which);
48
void output_low(int which);
49

  
50
/*
51
 Bk R Y (Analog)
52
---------
53
 Green
54
 Blue
55
 White
56
---------
57
 Blue
58
 White
59
*/
60

  
61

  
62
/*
63
the analog pin definitions from dio.h DO NOT work here,
64
so we must use PF0 from avrgcc (as opposed to _PIN_F0).
65
BUT the dio pin definitions from dio.h must be used (no PE...).
66

  
67
also, _PIN_E2 is initialized to high for some reason,
68
which turns the BOM on when the robot is turned on.
69
WORK-AROUND: call digital_output(_PIN_E2,0) at some point.
70

  
71
*/
72

  
73
#define MONKI PF0         //analog (yellow)
74
//------------------------//
75
#define MONKL _PIN_E2     //green
76
#define MONK1 _PIN_E3     //blue
77
#define MONK0 _PIN_E4     //white
78
//------------------------//
79
#define MONK3 _PIN_E6     //blue
80
#define MONK2 _PIN_E7     //white
81

  
82
#define BOM_VALUE_THRESHOLD 200
83

  
84

  
85
/**
86
 * @defgroup bom BOM (Bearing and Orientation Module)
87
 * @brief Functions for dealing with the BOM.
88
 *
89
 * The Bearing and Orientation Module / Barrel of Monkeys / BOM
90
 * is a custom sensor designed and built by the Colony Project.
91
 * It consists of a ring of 16 IR emitters and 16 IR detectors.
92
 * The BOM is most often use to determine the direction of other
93
 * robots. This module contains functions for controlling the BOM.
94
 *
95
 * Include bom.h to access these functions.
96
 *
97
 * @{
98
 **/
99

  
100
/**
101
 * Returns the direction of the maximum BOM reading,
102
 * as an integer in the range 0-15. 0 indicates to the
103
 * robot's right, while the rest of the sensors are
104
 * numbered counterclockwise. This is useful for determining
105
 * the direction of a robot flashing its BOM, of only one
106
 * robot is currently doing so. analog_init must be called
107
 * before this function can be used.
108
 *
109
 * @return the direction of the maximum BOM reading
110
 *
111
 * @see analog_init
112
 **/
113
int get_max_bom(void) {
114
	int max_bom_temp = 0;
115
	//TODO: renamed a, i, and h to give them meaningful names
116
	int a, i, j, h;
117
    h = 255;
118

  
119
	//Turn off the loop so that we can actually use analog8 correctly
120
	analog_stop_loop();
121

  
122
	//Iterate through through each LED
123
    for (j = 0; j < 16; j++)
124
    {
125
      i = lookup[j];
126

  
127
      if (i&8)
128
        output_high(MONK3);
129
      else
130
        output_low(MONK3);
131

  
132
      if (i&4)
133
        output_high(MONK2);
134
      else
135
        output_low(MONK2);
136

  
137
      if (i&2)
138
        output_high(MONK1);
139
      else
140
        output_low(MONK1);
141

  
142
      if (i&1)
143
        output_high(MONK0);
144
      else
145
        output_low(MONK0);
146

  
147
      a = analog_get8(MONKI);
148
              
149
      if (a < h)
150
      {
151
        h = a;
152
        max_bom_temp = j;
153
      }
154

  
155
    }
156
	
157
	//Restart loop now that we are done using analog8
158
	analog_start_loop();
159

  
160
	//threshold on the bom analog value.
161
	//defined in bom.h
162
	// if the analog value read is above the threshold, we cannot see a robot
163
	// (remember, low means higher intensity).
164
	if(h < BOM_VALUE_THRESHOLD) {
165
		return max_bom_temp;
166
	}
167
	else
168
		return -1;
169
}
170

  
171
/**
172
 * Flashes the BOM. analog_init must be called before this
173
 * function can be used.
174
 * 
175
 * @see bom_off, analog_init
176
 **/
177
void bom_on(void)
178
{
179
  output_high(MONKL);
180
}
181

  
182
/**
183
 * Stops flashing the BOM. analog_init must be called
184
 * before this function can be used.
185
 * 
186
 * @see bom_on, analog_init
187
 **/
188
void bom_off(void)
189
{
190
  output_low(MONKL);
191
}
192

  
193
/** @} **/ //end group
194

  
195
void output_high(int which) {
196
	digital_output(which, 1);
197
}
198

  
199
void output_low(int which) {
200
	digital_output(which, 0);
201
}
branches/rbom/code/lib/src/libdragonfly/analog.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26
/**
27
 * @file analog.c
28
 * @brief Analog input and output
29
 *
30
 * Contains functions for manipulating the ADC on the Dragonfly board.
31
 * 
32
 * @author Colony Project, CMU Robotics Club
33
 * code mostly taken from fwr analog file (author: Tom Lauwers)
34
 **/
35

  
36
#include <util/delay.h>
37
#include <avr/interrupt.h>
38
#include "analog.h"
39
#include "serial.h"
40
// Internal Function Prototypes
41
//TODO: if this function is only used in this file, make it static
42
void set_adc_mux(int which);
43

  
44
/**
45
 * @defgroup analog Analog
46
 * Functions for manipulation the ADC on the dragonfly board.
47
 * All definitions may be found in analog.h.
48
 *
49
 * @{
50
 **/
51

  
52
//TODO: if these variables are only used in this file, make them static
53
int adc_loop_running = 0;
54
int adc_current_port = 0;
55
adc_t an_val[11];
56

  
57
/**
58
 * Initializes the ADC.
59
 * Call analog_init before reading from the analog ports.
60
 *
61
 * @see analog8, analog10
62
 **/
63
void analog_init(int start_conversion) {
64
	for (int i = 0; i < 11; i++) {
65
		an_val[i].adc10 = 0;
66
		an_val[i].adc8 = 0;
67
	}
68

  
69
	//cli();
70
	// ADMUX register
71
	// Bit 7,6 - Set voltage reference to AVcc (0b01)
72
	// Bit 5 - ADLAR set to simplify moving from register
73
	// Bit 4 - X
74
	// Bit 3:0 - Sets the current channel
75
	// Initializes to read from AN1 first (AN0 is reservered for the BOM)
76
	ADMUX = 0;
77
	ADMUX |= ADMUX_OPT | _BV(MUX0);
78

  
79

  
80
	// ADC Status Register A
81
	// Bit 7 - ADEN is set (enables analog)
82
	// Bit 6 - Start conversion bit is set (must be done once for free-running mode)
83
	// Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW
84
	// Bit 4 - ADC interrupt flag, 0
85
	// Bit 3 - Enable ADC Interrupt (required to run free-running mode)
86
	// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz
87
	ADCSRA = 0;
88
	ADCSRA |= _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
89
	
90
	// Set external mux lines to outputs
91
	DDRG |= 0x1C;
92
	
93
	// Set up first port for conversions
94
	set_adc_mux(0x00);
95
	adc_current_port = AN1;
96

  
97
	//Start the conversion if requested
98
	if (start_conversion)
99
		analog_start_loop();
100
	else
101
		analog_stop_loop();
102
	//sei();
103
	
104
}	
105

  
106
unsigned int analog8(int which) {
107
	if (which == BOM_PORT) {
108
		return 0;
109
	} else {
110
		return an_val[which - 1].adc8;
111
	}
112
}
113

  
114
unsigned int analog10(int which) {
115
	if (which == BOM_PORT) {
116
		return 0;
117
	} else {
118
		return an_val[which - 1].adc10;
119
	}
120
}
121

  
122
void analog_start_loop(void) {
123
	//Start the conversion
124
	ADCSRA |= _BV(ADSC);
125
	adc_loop_running = 0x1;
126
}
127

  
128
//will stop after current conversion finishes
129
void analog_stop_loop(void) {
130
	//Stop the conversion
131
	adc_loop_running = 0x0;
132
}
133
/**
134
 * Reads an eight bit number from an analog port.
135
 * analog_init must be called before using this function.
136
 * 
137
 * @param which the analog port to read from. One of
138
 * the constants AN0 - AN7.
139
 *
140
 * @return the eight bit input to the specified port
141
 *
142
 * @see analog_init, analog10
143
 **/
144
unsigned int analog_get8(int which)
145
{	
146
	// Let any previous conversion finish
147
	while (ADCSRA & _BV(ADSC));
148
	
149
	if(which < EXT_MUX) {
150
		ADMUX = ADMUX_OPT + which;
151
	} else {
152
		ADMUX = ADMUX_OPT + EXT_MUX;
153
		set_adc_mux(which - 8);
154
	}
155
	
156
	// Start the conversion
157
	ADCSRA |= _BV(ADSC);
158

  
159
	// Wait for the conversion to finish
160
	while (ADCSRA & _BV(ADSC));
161

  
162
	return ADCH; //since we left aligned the data, ADCH is the 8 MSB.
163
}
164

  
165
/**
166
 * Reads a ten bit number from the specified port.
167
 * analog_init must be called before using this function.
168
 * 
169
 *
170
 * @param which the analog port to read from. Typically
171
 * a constant, one of AN0 - AN7.
172
 *
173
 * @return the ten bit number input to the specified port
174
 * 
175
 * @see analog_init, analog8
176
 **/
177
unsigned int analog_get10(int which)
178
{
179
	int adc_h;
180
	int adc_l;
181
	
182
	// Let any previous conversion finish
183
	while (ADCSRA & _BV(ADSC));
184

  
185
	if(which < EXT_MUX) {
186
		ADMUX = ADMUX_OPT + which;
187
	} else {
188
		ADMUX = ADMUX_OPT + EXT_MUX;
189
		set_adc_mux(which - 8);
190
	}
191
	
192
	// Start the conversion
193
	ADCSRA |= _BV(ADSC);
194

  
195
	// Wait for the conversion to finish
196
	while (ADCSRA & _BV(ADSC));
197
	
198
	adc_l = ADCL;
199
	adc_h = ADCH;
200

  
201
	return ((adc_h << 2) | (adc_l >> 6));
202
}
203

  
204
/**
205
 * Returns the current position of the wheel, as an integer
206
 * in the range 0 - 255.
207
 * analog_init must be called before using this function.
208
 *
209
 * @return the orientation of the wheel, as an integer in
210
 * the range 0 - 255.
211
 *
212
 * @see analog_init
213
 **/
214
int wheel(void)
215
{
216
	return analog8(WHEEL_PORT);
217
}
218

  
219

  
220
/**
221
 * Sets the value of the external analog mux. Values are read
222
 * 	on AN7 physical port. (AN8 - AN15 are "virtual" ports).
223
 *
224
 * @param which which analog mux port (0-7) which corresponds
225
 * 		  to AN8-AN15.
226
 *
227
 * @bug FIX THIS IN THE NEXT BOARD REVISION:
228
 *		ADDR2 ADDR1 ADDR0
229
 *		G2.G4.G3 set mux to port 0-7 via vinary selection
230
 *		math would be much cleaner if it was G4.G3.G2
231
 *
232
 * @see analog_init
233
 **/
234
void set_adc_mux(int which)
235
{  
236
  // mask so only proper bits are possible.  
237
  PORTG = (PORTG & 0xE3) | ((which & 0x03) << 3) | (which & 0x04);
238
}
239

  
240
/**@}**/ //end defgroup
241

  
242

  
243
ISR(ADC_vect) {
244
	static volatile int adc_prev_loop_running = 0;
245

  
246
	int adc_h = 0;
247
	int adc_l = 0;
248

  
249
	//usb_putc('p');
250
	//usb_puti(adc_current_port);
251
	//usb_putc('r');
252
	//usb_puti(adc_loop_running);
253
	//usb_puts("\n\r");
254

  
255
	//Store the value only if this read isn't for the BOM
256
	if (ADMUX != BOM_PORT) {
257
		adc_l = ADCL;
258
		adc_h = ADCH;
259
	
260
		an_val[adc_current_port - 1].adc10 = (adc_h << 2) | (adc_l >> 6);
261
		an_val[adc_current_port - 1].adc8 = adc_h;
262
		//usb_puti(an_val[adc_current_port - 1].adc10);
263
		//usb_puts("\n\r");
264
		//usb_puti(an_val[adc_current_port - 1].adc8);
265
		//usb_puti(ADCH);
266
		//usb_puts("\n\r");
267
	}
268
	
269
	//Save the result only if we just turned off the loop
270
	if (!adc_loop_running && !adc_prev_loop_running)
271
		return;
272
	
273
	adc_prev_loop_running = adc_loop_running;
274
	
275
	//Skip AN7 because it is not a real port
276
	if (adc_current_port == AN6) {
277
		ADMUX = ADMUX_OPT | EXT_MUX;
278
		set_adc_mux(AN8 - 8);
279
		adc_current_port = AN8;
280
	//Wrap around
281
	} else if (adc_current_port == AN11) {
282
		adc_current_port = AN1;
283
		ADMUX = ADMUX_OPT | adc_current_port;
284
	//Normal increment
285
	} else {
286
		adc_current_port++;
287
	
288
		if(adc_current_port < EXT_MUX) {
289
			ADMUX = ADMUX_OPT | adc_current_port;
290
		} else {
291
			ADMUX = ADMUX_OPT | EXT_MUX;
292
			set_adc_mux(adc_current_port - 8);
293
		}
294
	}
295

  
296
	//Initiate next conversion only if we are running a loop
297
	if (!adc_loop_running)
298
		return;
299

  
300
	ADCSRA |= _BV(ADSC);
301
	
302
	//if (ADCSRA & _BV(ADSC))
303
	//	usb_putc('s');
304
		
305
	return;
306
}
307

  
branches/rbom/code/lib/src/libdragonfly/dragonfly_lib.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file dragonfly_lib.c
29
 * @brief Dragonfly initialization
30
 *
31
 * Contains implementation of dragonfly_init.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
#include <dragonfly_lib.h>
37

  
38
/* init_dragonfly - Initializes functions based on configuration parameters
39
   examples:
40

  
41
   init_dragonfly (0, 0, 0); - just initialize the digital IO (buttons, potentiometer)
42

  
43
   init_dragonfly (ANALOG | SERIAL | BUZZER, C0_C1_ANALOG, BAUD115200); 
44
   Initialize ADC and set C0 and C1 as analog inputs.  Initialize serial and set baud rate
45
   to 115200 bps.  Initialize the buzzer.
46
   
47
   init_dragonfly (MOTORS | ORB, 0, 0);
48
   Initialize motor driving and the color fading abilities of the ORB. */
49

  
50
/**
51
 * @defgroup dragonfly Dragonfly
52
 * @brief General Dragonfly Functions
53
 * General functions for the dragonfly. Include
54
 * dragonfly_lib.h to access these functions.
55
 *
56
 * @{
57
 **/
58

  
59
/**
60
 * Initializes the components specified by config.
61
 * 
62
 * @see analog_init, usb_init, xbee_init, buzzer_init,
63
 * bom_init, orb_init, motors_init, lcd_init
64
 **/
65
void dragonfly_init(int config) 
66
{
67
		sei();
68

  
69
	// Set directionality of various IO pins
70
	DDRG &= ~(_BV(PING0)|_BV(PING1));
71
	PORTG |= _BV(PING0)|_BV(PING1);
72
	
73
	if(config & ANALOG)
74
		analog_init(ADC_START);
75
	
76
	if(config & COMM)
77
	{
78
		//Defaults to 115200. Check serial.h for more information.
79
		usb_init();
80
		xbee_init();
81
	}
82
	
83
	if(config & BUZZER)
84
	{
85
		sei();
86
		buzzer_init();
87
	}
88
	
89
	if(config & ORB)
90
	{
91
		sei();
92
		orb_init();
93
	}
94
	
95
	if(config & MOTORS)
96
		motors_init();
97

  
98
	if(config & LCD)
99
		lcd_init();
100
	
101
	if(config & ORB)
102
	{
103
		sei();
104
		orb_init();
105
	}
106
	
107
	// delay a bit for stability
108
	_delay_ms(1);
109
}
110

  
111

  
112
/** @} **/ //end defgroup
113

  
branches/rbom/code/lib/src/libdragonfly/rangefinder.c
1
/**
2
 * Copyright (c) 2007 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

  
26

  
27
/**
28
 * @file rangefinder.c
29
 * @brief Rangefinders
30
 *
31
 * Implementation of functions for rangefinder use.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
/*
37
Authors: James Kong and Greg Tress
38

  
39
Last Modified: 4/30/06 by James
40
-Started log_distance conversion function !!!NOT COMPLETE!!!
41
-Cleaning up comments
42

  
43
-----------------
44
rangefinder.c
45
Using Sharp GP2D02 IR Rangefinder
46

  
47
Vin is the input to the rangefinder, designated RANGE_CTRL.
48
Vout is the output from the rangefinder, designated RANGE_IN# where # is the rangefinder you are reading from
49

  
50
Expected Initial Conditions:
51
Vin is high and Vout should read high.
52

  
53
Usage:
54
1.) Set Vin low. Vout should read low.
55
2.) Wait for high on Vout.
56
3.) Begin clocking Vin and reading 8 bits from Vout (MSB first).
57
4.) Set Vin high for 2ms or more to turn off rangefinder
58

  
59
*/
60

  
61
#include "dragonfly_lib.h"
62
#include "rangefinder.h"
63

  
64
/*
65
read_distance returns the 8-bit reading from the rangefinder
66
parameters:
67
range_id - dio pin set as the rangefinder Vout [i.e. RANGE_IN0]
68

  
69
NOTE:
70
The Sharp GD2D02 returns values on a decreasing logrithmic scale.
71
So higher values correspond to closer distances.  Use linearize_distance to convert to normal centimeter scale.  Also, when reading distances closer than 8cm, the Sharp GD2D02 will return lower values than the values at 8cm.
72
At this point, we are only reading from one rangefinder [RANGE_IN0].
73
*/
74

  
75
// constants
76
/* Nasty IR approximation table
77
  I'm using this for the heck of it.  We can do whatever.
78

  
79
  Note the minimum value is .4V (20), and the maximum is 2.6V (133).
80
  Gives distance in mm.
81

  
82
  excel formula(valid for inputs 20-133):  ROUND(2353.6*(E2^(-1.1146))*10,0)
83

  
84
  This is only valid for the GP2D12, with objects directly ahead and more than
85
  10cm from the detector.  See the datasheet for more information.
86
*/
87

  
88
#define MIN_IR_ADC8 20
89
#define MAX_IR_ADC8 133
90

  
91
static int IR_dist_conversion[114] = {
92
800,791,751,714,681,651,623,597,574,552,531,512,494,478,462,447
93
,434,421,408,397,386,375,365,356,347,338,330,322,315,307,301,294
94
,288,282,276,270,265,260,255,250,245,241,237,232,228,224,221,217
95
,213,210,207,203,200,197,194,191,189,186,183,181,178,176,173,171
96
,169,166,164,162,160,158,156,154,152,151,149,147,145,144,142,140
97
,139,137,136,134,133,131,130,129,127,126,125,124,122,121,120,119
98
,118,117,115,114,113,112,111,110,109,108,107,106,105,105,104,103
99
,102,101
100
};
101

  
102
int linearize_distance(int value);
103

  
104
/**
105
 * @defgroup rangefinder Rangefinder
106
 * @brief Functions for using the IR rangefinders
107
 * 
108
 * Functions for using the IR rangefinders.
109
 *
110
 * @{
111
 **/
112

  
113
/**
114
 * Initializes the rangefinders. This must be called before
115
 * range_read_distance.
116
 *
117
 * @see range_read_distance
118
 **/
119
void range_init(void)
120
{
121
	digital_output(_PIN_B4,0);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff