Project

General

Profile

Revision 1565

deleting branch because i didn't branch the whole trunk before

View differences:

branches/ir_lookup/lcd.h
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.h
29
 * @brief Contains definitions for dealing with the LCD screen.
30
 * 
31
 * Contains definitions and functions for dealing with the 
32
 * LCD screen.
33
 *
34
 * @author Colony Project, CMU Robotics Club
35
 **/
36

  
37
#ifndef _LCD_H_
38
#define _LCD_H_
39

  
40
/**
41
 * @addtogroup lcd
42
 * @{
43
 **/
44

  
45
/** @brief Initialize the LCD screen **/
46
void lcd_init(void);
47
/** @brief Clear the LCD screen **/
48
void lcd_clear_screen( void );
49
/** @brief Print a char to the LCD screen **/
50
void lcd_putc(char c);
51
/** @brief Print a string to the LCD screen **/
52
void lcd_puts(char *s);
53
/** @brief Print an int to the LCD screen **/
54
void lcd_puti(int value);
55
/** @brief Set the current cursor position **/
56
void lcd_gotoxy(int x, int y);
57

  
58
/** @} **/
59

  
60
#endif
61

  
branches/ir_lookup/battery.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 battery.c
29
 * @brief Implementation for reading battery level
30
 *
31
 * Contains functions for reading the battery level.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
#include "battery.h"
37
#include "analog.h"
38

  
39
//Constants for Battery
40
//Constants determined experimentally 2/9/2007 - James Kong
41
//See Battery8_data.xls for experiment data
42
#define BATTERY_NEXT_READ_PRESCALAR 5
43
#define MAX_LOW_COUNT 5
44

  
45
//global variables
46
int battery_low_count;
47

  
48
/**
49
 * @defgroup battery Battery
50
 * @brief Functions for reading battery voltage.
51
 * 
52
 * Contains functions for checking the current
53
 * voltage of the battery. Include battery.h to
54
 * access these functions.
55
 *
56
 * @{
57
 **/
58

  
59
/**
60
 * Returns the voltage of the battery as an analog8
61
 * reading. 128 is approximately 5 volts. analog_init
62
 * must be called before using this function.
63
 *
64
 * @return the voltage of the battery as an analog8
65
 * reading
66
 *
67
 * @see analog_init, battery, analog8
68
 **/
69
int battery8(void)
70
{
71
  return analog8(BATT_PORT);
72
}
73

  
74
/**
75
 * Returns the voltage of the battery in deciVolts.
76
 * analog_init must be called before using this function.
77
 *
78
 * @return the voltage of the battery in deciVolts.
79
 *
80
 * @see analog_init, battery8
81
 **/
82
int battery(void)
83
{
84
  /* 5 volts is the max, 255 is the max 8bit number , *2 for the divider */
85
        return analog8(BATT_PORT) * 500 >>7;
86
}
87

  
88

  
89
/**
90
 * Checks if the battery is low. analog_init must be called before
91
 * this function can be used. This function waits for several low
92
 * battery readings in a row to avoid false positives.
93
 *
94
 * @return 1 if the battery is low, 0 otherwise
95
 *
96
 * @see analog_init
97
 **/
98
char battery_low(void)
99
{
100
  static char next_read = 0;
101
  static char ret = 0;
102
  
103
  int batt_reading = battery8();
104

  
105
  if(next_read == 0) 
106
  {
107
    if(batt_reading > BATTERY_LOWV)
108
    {
109
        ret = 0;
110
        battery_low_count = 0;
111
    }
112
    else
113
    {
114
        battery_low_count++;
115
        if( battery_low_count >= MAX_LOW_COUNT )
116
        {
117
            ret = 1;
118
            battery_low_count = 0;
119
        }
120
    }
121
    
122
    next_read = BATTERY_NEXT_READ_PRESCALAR;
123
  }
124
  else next_read--;
125
  
126
  return ret;
127
}
128

  
129
/**
130
 * Averages n_samples battery8 readings. This function may
131
 * take a while to complete, and is only made available
132
 * for convenience. analog_init must be called before this
133
 * function may be used.
134
 *
135
 * @param n_samples the number of times to sample the battery voltage
136
 *
137
 * @return the average reading for the battery voltage, where 128
138
 * is approximately 5 Volts.
139
 *
140
 * @see analog_init, battery
141
 **/
142
int battery8_avg(int n_samples)
143
{
144
  int i;
145
  long int sum = 0;
146
  
147
  for(i = 0; i < n_samples; i++) 
148
  {
149
    sum += battery8();
150
  }
151
  
152
  return (int)(sum / n_samples);
153
}
154

  
155
/** @} **/ //end defgroup
156

  
branches/ir_lookup/dio.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 dio.c
29
 * @brief Digital Input and Output
30
 *
31
 * Implementation of functions for digital input and output.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
#include <avr/interrupt.h>
37
#include "dio.h"
38
#include "time.h"
39
#include "lights.h"
40

  
41
/**
42
 * @defgroup dio Digital Input / Output
43
 * @brief Controls digital input and output
44
 * 
45
 * A general note on how port / pin numbers work:<br>
46
 * The portpin is used to select both the bank and which pin is selected.
47
 * 6 bits are used (lower 6, ex: 0b00abcdef).
48
 * The first 3 (abc in this example) are used to select the bank.<br>
49
 * A = 001<br>
50
 * B = 010<br>
51
 * C = 011<br>
52
 * D = 100<br>
53
 * E = 101<br>
54
 * F = 110<br>
55
 * G = 111<br><br>
56
 * 		
57
 * The bank can be found by doing portpin >> 3. <br>
58
 * 		
59
 * The next three (def in this example) are used to select the pin number.
60
 * These three bits are just the binary representation of the pin number.<br>
61
 * <br>
62
 * The pin number can be found by doing portpin & 0b111.<br><br>
63
 *
64
 * Include dio.h to access these functions.
65
 **/
66

  
67
/**
68
 * Reads the selected portpin.
69
 * 
70
 * @param portpin The portpin to be read. See the general description
71
 * for a description of portpins.
72
 *
73
 * @return 1 or 0, depending on the value of the portpin.
74
 **/
75
int digital_input(int portpin) {
76
  int pin = portpin & 0x7;
77
  int pin_val = 0;
78
  
79
  switch(portpin >> 3) {
80
  case _PORT_A:
81
    DDRA &= ~_BV(pin);
82
    pin_val = PINA;
83
    return (pin_val >> pin) & 1;
84
  case _PORT_B:
85
    DDRB &= ~_BV(pin);
86
    pin_val = PINB;
87
    return (pin_val >> pin) & 1;
88
  case _PORT_C:
89
    DDRC &= ~_BV(pin);
90
    pin_val = PINC;
91
    return (pin_val >> pin) & 1;
92
  case _PORT_D:
93
    DDRD &= ~_BV(pin);
94
    pin_val = PIND;
95
    return (pin_val >> pin) & 1;
96
  case _PORT_E:
97
    DDRE &= ~_BV(pin);
98
    pin_val = PINE;
99
    return (pin_val >> pin) & 1;
100
  case _PORT_F:
101
    if(pin>=4) {
102
      MCUSR|=1<<7;
103
      MCUSR|=1<<7;
104
    }
105
    DDRF &= ~_BV(pin);
106
    pin_val = PINF;
107
    return (pin_val >> pin) & 1;
108
  case _PORT_G:
109
    DDRG &= ~_BV(pin);
110
    pin_val = PING;
111
    return (pin_val >> pin) & 1;
112
  default: break;
113
  }
114
  
115
  return -1;
116
}
117

  
118
/**
119
 * Enables pullup on a pin. If it is an output pin, the pin will output
120
 * 1.
121
 *
122
 * @param portpin the pin to enable pullup on. See the general description
123
 * for a discussion of portpins.
124
 **/
125
void digital_pull_up(int portpin) {
126
  int pins = portpin & 0x07;
127

  
128
  switch(portpin >> 3) {
129
  case _PORT_A:
130
    PORTA |= _BV(pins);
131
    break;
132
  case _PORT_B:
133
    PORTB |= _BV(pins);
134
    break;    
135
  case _PORT_C:
136
    PORTC |= _BV(pins);
137
    break;    
138
  case _PORT_D:
139
    PORTD |= _BV(pins);
140
    break;    
141
  case _PORT_E:
142
    PORTE |= _BV(pins);
143
    break;    
144
  case _PORT_F:
145
    PORTF |= _BV(pins);
146
    break;    
147
  case _PORT_G:
148
    PORTG |= _BV(pins);
149
    break;
150
  }
151
}
152

  
153
/**
154
 * Sets portpin to the given value.
155
 * 
156
 * @param portpin the portpin to output to. See the general
157
 * description for a discussion of portpins.
158
 *
159
 * @param val the value to set the portpin to. 0 for off,
160
 * nonzero for on.
161
 **/
162
void digital_output(int portpin, int val) {
163
  int pins = portpin & 0x07;
164
  
165
  /* if you want to set to 0... */
166
  if(val == 0) {
167
    switch(portpin >> 3) {
168
    case _PORT_A:
169
      DDRA |= _BV(pins);
170
      PORTA &= (0XFF - _BV(pins));
171
      break;
172
    case _PORT_B:
173
      DDRB |= _BV(pins);
174
      PORTB &= (0XFF - _BV(pins));
175
      break;    
176
    case _PORT_C:
177
      DDRC |= _BV(pins);
178
      PORTC &= (0XFF - _BV(pins));
179
      break;    
180
    case _PORT_D:
181
      DDRD |= _BV(pins);
182
      PORTD &= (0XFF - _BV(pins));
183
      break;    
184
    case _PORT_E:
185
      DDRE |= _BV(pins);
186
      PORTE &= (0XFF - _BV(pins));
187
      break;    
188
    case _PORT_F:
189
      DDRF |= _BV(pins);
190
      PORTF &= (0XFF - _BV(pins));
191
      break;    
192
    case _PORT_G:
193
      DDRG |= _BV(pins);
194
      PORTG &= (0XFF - _BV(pins));
195
      break;
196
    }
197
  } else { /* ( val == 1) */ 
198
    switch(portpin >> 3) {
199
    case _PORT_A:
200
      DDRA |= _BV(pins);
201
      PORTA |= _BV(pins);
202
      break;
203
    case _PORT_B:
204
      DDRB |= _BV(pins);
205
      PORTB |= _BV(pins);
206
      break;    
207
    case _PORT_C:
208
      DDRC |= _BV(pins);
209
      PORTC |= _BV(pins);
210
      break;    
211
    case _PORT_D:
212
      DDRD |= _BV(pins);
213
      PORTD |= _BV(pins);
214
      break;    
215
    case _PORT_E:
216
      DDRE |= _BV(pins);
217
      PORTE |= _BV(pins);
218
      break;    
219
    case _PORT_F:
220
      DDRF |= _BV(pins);
221
      PORTF |= _BV(pins);
222
      break;    
223
    case _PORT_G:
224
      DDRG |= _BV(pins);
225
      PORTG |= _BV(pins);
226
      break;
227
    }
228
  }
229
}
230

  
231
/**
232
 * Checks if button1 is currently pressed.
233
 * 
234
 * @return 1 if button1 is pressed, 0 otherwise
235
 *
236
 * @see button1_wait, button1_click
237
 **/
238
int button1_read( void ) {
239
  int pin_val;
240
  DDRG &= ~_BV(PING0);
241
  PORTG|= _BV(PING0);
242
  pin_val = PING;
243
  return !((pin_val & _BV(PING0)));
244
}
245

  
246
/**
247
 * Delays execution until button1 is pressed.
248
 *
249
 * @see button1_read, button1_click
250
 **/
251
void button1_wait( void ) {
252
  while(!button1_read() ) {
253
    delay_ms(15);
254
  }
255
}
256

  
257
/**
258
 * If button1 is pressed, waits until it is released before returning.
259
 * Otherwise, the function returns immediately.
260
 *
261
 * @return 1 if button1 has been pressed, 0 otherwise
262
 *
263
 * @see button1_read, button1_wait
264
 **/
265
int button1_click() {
266
  if(button1_read()) {
267
    while(button1_read());
268
    return 1;
269
  } else {
270
    return 0;
271
  }
272
}
273

  
274
/**
275
 * Checks if button2 is currently pressed.
276
 * 
277
 * @return 1 if button2 is pressed, 0 otherwise
278
 *
279
 * @see button2_wait, button2_click
280
 **/
281
int button2_read( void ) {
282
  int pin_val;
283
  DDRG &= ~_BV(PING1);
284
  PORTG|= _BV(PING1);
285
  pin_val = PING;
286
  return !((pin_val & _BV(PING1)));
287
}
288

  
289
/**
290
 * Delays execution until button2 is pressed.
291
 *
292
 * @see button2_read, button2_click
293
 **/
294
void button2_wait( void ) {
295
  while(!button2_read()){
296
    delay_ms(15);
297
  }
298
}
299

  
300
/**
301
 * If button2 is pressed, waits until it is released before returning.
302
 * Otherwise, the function returns immediately.
303
 *
304
 * @return 1 if button2 has been pressed, 0 otherwise
305
 *
306
 * @see button2_read, button2_wait
307
 **/
308
int button2_click() {
309
  if(button2_read()) {
310
    while(button2_read());
311
    return 1;
312
  } else {
313
    return 0;
314
  }
315
}
316

  
317
/** @} **/ //end defgroup
318

  
branches/ir_lookup/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 "bom.h"
37
#include "dio.h"
38
#include "serial.h"
39
#include "analog.h"
40

  
41
//On the original BOM1.0, the emmitter angular order does not match the analog mux order
42
//so you need to iterate through the mux index in the following order if you want to get
43
//the detector readings in order:
44
static const char lookup[16] = {7,6,5,0xe,1,4,3,2,0xf,0,0xd,8,0xc,0xb,9,0xa};
45

  
46

  
47
/* *****************************
48
 * BOM Vector Component Tables *
49
 **************************** **/
50

  
51
/*
52
 * The x component of each BOM detector (indexed from 0 to 15)
53
 * was calculated using the following formula:
54
 *
55
 *		x_comp[i] = fix(25 * cos ( 2 * pi / 16 * i) )
56
 *
57
 * where "fix" rounds towards 0. If the BOM detectors were superimposed
58
 * onto a 2 dimensional Cartesian space, this effectively calculates the
59
 * x component of the emitter vector where emitter 0 corresponds to an
60
 * angle of 0 radians, 4 -> pi/2, 8 -> pi, ect.
61
 */
62
static const signed int x_comp[16] = {
63
	25,
64
	23,
65
	17,
66
	9,
67
	0,
68
	-9,
69
	-17,
70
	-23,
71
	-25,
72
	-23,
73
	-17,
74
	-9,
75
	0,
76
	9,
77
	17,
78
	23
79
};
80

  
81

  
82
/*
83
 * The y component of each BOM detector (indexed from 0 to 15)
84
 * was calculated using the following formula:
85
 *
86
 *		y_comp[i] = fix(25 * sin ( 2 * pi / 16 * i) )
87
 *
88
 * where "fix" rounds towards 0. If the BOM detectors were superimposed
89
 * onto a 2 dimensional Cartesian space, this effectively calculates the
90
 * x component of the emitter vector where emitter 0 corresponds to an
91
 * angle of 0 radians, 4 -> pi/2, 8 -> pi, ect.
92
 */
93
static signed int y_comp[16] = {
94
	0,
95
	9,
96
	17,
97
	23,
98
	25,
99
	23,
100
	17,
101
	9,
102
	0,
103
	-9,
104
	-17,
105
	-23,
106
	-25,
107
	-23,
108
	-17,
109
	-9
110
};
111

  
112
// internal function prototypes
113
static void bom_select(char which);
114

  
115
/*
116
 Bk R Y (Analog)
117
---------
118
 Green
119
 Blue
120
 White
121
---------
122
 Blue
123
 White
124
*/
125

  
126

  
127
/*
128
the analog pin definitions from dio.h DO NOT work here,
129
so we must use PF0 from avrgcc (as opposed to _PIN_F0).
130
BUT the dio pin definitions from dio.h must be used (no PE...).
131

  
132
also, _PIN_E2 is initialized to high for some reason,
133
which turns the BOM on when the robot is turned on.
134
WORK-AROUND: call digital_output(_PIN_E2,0) at some point.
135

  
136
*/
137

  
138
#define MONKI PF0         //analog (yellow)
139
//------------------------//
140
#define MONKL _PIN_E2     //green
141
#define MONK1 _PIN_E3     //blue
142
#define MONK0 _PIN_E4     //white
143
//------------------------//
144
#define MONK3 _PIN_E6     //blue
145
#define MONK2 _PIN_E7     //white
146

  
147
#define BOM_VALUE_THRESHOLD 150 //200
148
#define NUM_BOM_LEDS 16
149

  
150
/*
151
  *The following pin definitions are for the BOM v1.5
152
  */
153

  
154
#define BOM_MODE	_PIN_E2	//dio0
155
#define BOM_STROBE	_PIN_E3	//dio1
156

  
157
#define BOM_DATA	_PIN_A0 //servo0
158
#define BOM_CLOCK	_PIN_A1	//servo1
159

  
160
#define BOM_S0		_PIN_E5	//dio3
161
#define BOM_S1		_PIN_E4	//dio2
162
#define BOM_S2		_PIN_E7	//dio4
163
#define BOM_S3		_PIN_E6	//dio5
164
#define BOM_OUT		PF0		//analog(yellow)
165

  
166
/**
167
 * @defgroup bom BOM (Bearing and Orientation Module)
168
 * @brief Functions for dealing with the BOM.
169
 *
170
 * The Bearing and Orientation Module / Barrel of Monkeys / BOM
171
 * is a custom sensor designed and built by the Colony Project.
172
 * It consists of a ring of 16 IR emitters and 16 IR detectors.
173
 * The BOM is most often use to determine the direction of other
174
 * robots. This module contains functions for controlling the BOM.
175
 *
176
 * Include bom.h to access these functions.
177
 *
178
 * @{
179
 **/
180

  
181
static unsigned int bom_val[NUM_BOM_LEDS];
182
static volatile char bom_type = BOM10;
183
static int select_pins[4];
184
static int analog_pin;
185

  
186
/**
187
 * Initializes the BOM.
188
 * Call bom_init before reading bom values or turning bom leds.
189
 *
190
 * @bugs INCOMPLETE - No utilization of BOM1.5 RSSI capability. Probably leave this out
191
 * until Cornell and Pras return
192
 * 
193
 * @see bom_refresh, bom_leds_on, bom_leds_off
194
 **/
195
void bom_init(char type) {
196
    bom_type = type;
197
    
198
    switch(bom_type) {
199
    case BOM10:
200
		select_pins[0] = MONK0; 
201
		select_pins[1] = MONK1;
202
		select_pins[2] = MONK2;
203
		select_pins[3] = MONK3;
204
		analog_pin = MONKI;
205
        break;
206
    case BOM15:
207
        //Sets BOM1.5 to normal [BOM] mode
208
        digital_output(BOM_MODE, 0);
209
		select_pins[0] = BOM_S0; 
210
		select_pins[1] = BOM_S1;
211
		select_pins[2] = BOM_S2;
212
		select_pins[3] = BOM_S3;
213
		bom_set_leds(BOM_ALL);
214
		analog_pin = BOM_OUT;
215
        break;
216
    case RBOM:
217
        break;
218
    //default:
219
    }
220
}
221

  
222
/**
223
 * Iterates through each bit in the bit_field. For each set bit, sets the corresponding bom select bits
224
 *    and updates the corresponding bom value with an analog_get8 reading.  analog_init and bom_init
225
 *    must be called for this to work. Must call this before reading BOM values!
226
 *
227
 *
228
 * @param bit_field specifies which elements in bom_val[] should be updated. Use BOM_ALL to refresh all values.
229
 *    Ex. if 0x0003 is passed, bom_val[0] and bom_val[1] will be updated.
230
 *
231
 * @see bom_get
232
 **/
233
void bom_refresh(int bit_field) {
234
    int i;
235
	int loop_was_running = 0;
236
    
237
	//Check analog loop status
238
    if(analog_loop_status() == ADC_LOOP_RUNNING) {
239
		loop_was_running = 1;
240
		analog_stop_loop();
241
	}
242
    
243
	//Read BOM values
244
    for(i = 0; i < NUM_BOM_LEDS; i++) {
245
        if(bit_field & 0x1) {
246
            bom_select(i);
247
            bom_val[i] = analog_get8(analog_pin);
248
        }
249
        bit_field = bit_field >> 1;
250
    }
251
    
252
	//Restore analog loop status
253
	if(loop_was_running)
254
		analog_start_loop();
255
}
256

  
257
/**
258
 * Gets the bom reading from bom_val[which].  Call bom_refresh beforehand to read new bom values.
259
 *
260
 * @pre must call bom refresh first
261
 *
262
 * @param which which bom value to return
263
 *
264
 * @return the bom value
265
 *
266
 * see bom_refresh
267
 **/
268
int bom_get(int which) {
269
    return bom_val[which];
270
}
271

  
272
/** 
273
 * Compares all the values in bom_val[] and returns the index to the lowest (max) value element.
274
 *
275
 * @pre must call bom refresh
276
 * @return index to the lowest (max) bom value element.  -1 if no value is lower than
277
 *    BOM_VALUE_THRESHOLD
278
 **/
279
int bom_get_max(void) {
280
    int i, lowest_val, lowest_i;
281
    lowest_i = -1;
282
    lowest_val = 255;
283
    for(i = 0; i < NUM_BOM_LEDS; i++) {
284
        if(bom_val[i] < lowest_val) {
285
            lowest_val = bom_val[i];
286
            lowest_i = i;
287
        }
288
    }
289
    
290
    if(lowest_val < BOM_VALUE_THRESHOLD)
291
        return lowest_i;
292
    else
293
        return -1;
294
}
295

  
296
/** 
297
 * Compute the net resultant BOM IR vector by scaling each IR unit vector by its intensity
298
 *		and summing over all IR LEDs.
299
 *
300
 * @param v  Pointer to Vector struct to be filled by this function with an x and y net vector
301
 *		component.
302
 *
303
 * @param usrBOMvals  Pointer to array which holds 16 raw BOM readings which can be used if user
304
 *		has already collected BOM information instead of collecting a new data set from the BOM.
305
 *
306
 * @return  Exit status - Zero for success; negative on error.
307
 **/
308
int bom_get_vector(Vector* v, int* usrBOMvals) {
309

  
310
	/* Store current BOM readings and use them as a weighting factor */
311
	int intensity[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
312

  
313
	/* Arrays for storing the weighted x ("Rightness") and y ("Forwardness")
314
	 * components. Calculated by multiplying the intensity by the x and y
315
	 * component respectively (x and y components are stored in the tables
316
	 * above). */
317
	int weighted_x_comp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
318
	int weighted_y_comp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
319
	
320
	/* Accumulators to sum up the net x ("Rightness") and y ("Forwardness")
321
	 * components for the entire robot. */
322
	long net_x_comp = 0;
323
	long net_y_comp = 0;
324

  
325
	int i = 0;
326

  
327
	/* BOM intensity is actually measured as more intense = closer to 0 */
328
	if (usrBOMvals) {
329
		/* Use BOM values collected by user */
330
		for (i = 0; i < 16; i++) {
331
			intensity[i] = 255 - usrBOMvals[i];
332
		}
333
	} else {
334
		/* Collect new set of BOM data */
335
		bom_refresh(BOM_ALL);
336
		for (i = 0; i < 16; i++) {
337
			intensity[i] = 255 - bom_get(i);
338
		}
339
	}
340

  
341
	/* Calculate weighted vector components and accumulate vector sum */
342
	for (i = 0; i < 16; i++) {
343
		weighted_x_comp[i] = intensity[i] * x_comp[i];
344
		weighted_y_comp[i] = intensity[i] * y_comp[i];
345
		net_x_comp += weighted_x_comp[i];
346
		net_y_comp += weighted_y_comp[i];
347
	}
348

  
349
	/* Fill the Vector struct */
350
	v->x = net_x_comp;
351
	v->y = net_y_comp;
352

  
353
	return 0;
354

  
355
}
356

  
357
/** 
358
 * Compute the normalized net resultant BOM IR vector by scaling each IR unit vector by its
359
 *		intensity and summing over all IR LEDs.
360
 *
361
 * @param v  Pointer to Vector struct to be filled by this function with an x and y net vector
362
 *		component.
363
 *
364
 * @param usrBOMvals  Pointer to array which holds 16 raw BOM readings which can be used if user
365
 *		has already collected BOM information instead of collecting a new data set from the BOM.
366
 *
367
 * @return  Exit status - Zero for success; negative on error.
368
 **/
369
int bom_get_norm_vector(Vector* v, int* usrBOMvals) {
370

  
371
	/* Store current BOM readings and use them as a weighting factor */
372
	int intensity[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
373

  
374
	/* Arrays for storing the weighted x ("Rightness") and y ("Forwardness")
375
	 * components. Calculated by multiplying the intensity by the x and y
376
	 * component respectively (x and y components are stored in the tables
377
	 * above). */
378
	int weighted_x_comp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
379
	int weighted_y_comp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
380
	
381
	/* Accumulators to sum up the net x ("Rightness") and y ("Forwardness")
382
	 * components for the entire robot. */
383
	long net_x_comp = 0;
384
	long net_y_comp = 0;
385

  
386
	/* Variables used to normalize the net component values */
387
	int total_intensity = 0;
388
	int normalized_net_x_comp = 0;
389
	int normalized_net_y_comp = 0;
390

  
391
	int i = 0;
392

  
393
	/* BOM intensity is actually measured as more intense = closer to 0 */
394
	if (usrBOMvals) {
395
		/* Use BOM values collected by user */
396
		for (i = 0; i < 16; i++) {
397
			intensity[i] = 255 - usrBOMvals[i];
398
		}
399
	} else {
400
		/* Collect new set of BOM data */
401
		bom_refresh(BOM_ALL);
402
		for (i = 0; i < 16; i++) {
403
			intensity[i] = 255 - bom_get(i);
404
		}
405
	}
406

  
407
	/* Calculate weighted vector components and accumulate vector sum */
408
	for (i = 0; i < 16; i++) {
409
		weighted_x_comp[i] = intensity[i] * x_comp[i];
410
		weighted_y_comp[i] = intensity[i] * y_comp[i];
411
		net_x_comp += weighted_x_comp[i];
412
		net_y_comp += weighted_y_comp[i];
413
		total_intensity += intensity[i];
414
	}
415

  
416
	/* Normalize the resultant vector components by the total intensity */
417
	if (total_intensity > 0) {
418
		normalized_net_x_comp = net_x_comp / total_intensity;
419
		normalized_net_y_comp = net_y_comp / total_intensity;
420
	}
421

  
422
	/* Fill the Vector struct */
423
	v->x = normalized_net_x_comp;
424
	v->y = normalized_net_y_comp;
425

  
426
	return 0;
427

  
428
}
429

  
430
/** 
431
 * Print a histogram which shows the current BOM intensity values for each of the 16 BOM IR
432
 *		sensors. The function will attempt to send the histogram data over USB.
433
 *
434
 * @param curBOMvals  Pointer to an array of the current BOM values (the array must have
435
 *		length 16). Use this to print values you have already collected. Otherwise pass in NULL
436
 *		and bom_refresh() will be called and the current BOM intensity values will be collected.
437
 * @return  Exit status - Zero for success; negative on error.
438
 **/
439
int bom_print_usb(int* usrBOMvals) {
440

  
441
	int i, j, max = -1;
442
	int curVals[16];
443
	int* prtValPtr;
444

  
445
	if (usrBOMvals) {
446
		/* Use BOM values collected by user */
447
		prtValPtr = usrBOMvals;
448

  
449
		/* Find max BOM value from users values */
450
		for (i = 0; i < 16; i++) {
451
			if (max < prtValPtr[i])
452
				max = prtValPtr[i];
453
		}
454
	} else {
455
		/* Refresh and make sure the table is updated */
456
		bom_refresh(BOM_ALL);
457

  
458
		/* Record values into an array */
459
		for (i = 0; i < 16; i++) {
460
			curVals[i] = bom_get(i);
461
			if (max < curVals[i])
462
				max = curVals[i];
463
		}
464

  
465
		/* Use the current set of collected values */
466
		prtValPtr = curVals;
467
	}
468

  
469
	/* Display results */
470
	for (i = 0; i < 16; i++) {
471
		
472
		usb_puti(i);
473
		usb_puts(": ");
474
		usb_puti(prtValPtr[i]);
475
		usb_putc('\t');
476

  
477
		for (j = 0; j < (int)((max - prtValPtr[i]) / 5); j++) {
478
			usb_putc('#');
479
		}
480
		usb_puts("\r\n");
481
	}
482
	usb_puts("\r\n");
483

  
484
	return 0;
485

  
486
}
487

  
488
/** 
489
 * Computes the weighted average of all the bom readings to estimate the position (and distance) of another robot.
490
 *
491
 * @pre must call bom refresh
492
 * @param dist  pointer to int in which to return the estimated distance to the other robot
493
 * @return estimated position of the max bom value element as a fixed point value analogous to 10 times the
494
 *        index of the max bom value.  -1 if no value is lower than BOM_VALUE_THRESHOLD.
495
 **/
496
int bom_get_max10(int *dist) {
497
    int i, max;
498
    long long mean = 0, sum = 0;
499

  
500
    max = bom_get_max();
501
    if (max < 0)
502
    {
503
        if (dist)
504
        {
505
            *dist = -1;
506
        }
507
        return -1;
508
    }
509
    /* Record values into an array */
510
    for (i = 0; i < NUM_BOM_LEDS; i++) {
511
        int idx = ((i + (NUM_BOM_LEDS/2 - max) + NUM_BOM_LEDS) % NUM_BOM_LEDS) - (NUM_BOM_LEDS/2 - max);
512
        int val = 255 - bom_val[i];
513
        mean += idx * val;
514
        sum += val;
515
    }
516
    mean = (mean * 10) / sum;
517
    mean = (mean + NUM_BOM_LEDS*10) % (NUM_BOM_LEDS*10);
518

  
519
    if (dist)
520
    {
521
        *dist = 50 - sum/48;
522
    }
523

  
524
    return mean;
525
}
526

  
527
/**
528
 * Iterates through each bit in the bit_field. If the bit is set, the corresponding emitter will
529
 *    be enabled to turn on when bom_on() is called.
530
 *    bom_init must be called for this to work. Does nothing if a BOM1.0 is installed
531
 *
532
 * @param bit_field specifies which leds should be turned on when bom_on is called.  Use BOM_ALL to turn on all bom leds.
533
 *    Ex. if 0x0005 is passed, leds 0 and 2 will be turned on.
534
 **/
535
void bom_set_leds(int bit_field) {
536
    int i;
537
	unsigned int mask = 1<<(NUM_BOM_LEDS-1);
538
	switch(bom_type) {
539
    case BOM10:
540
        //TODO: put an assert here to alert the user that this should not be called
541
        break;
542
		
543
    case BOM15:
544
	    for(i=NUM_BOM_LEDS; i>0; i--)
545
	    {
546
		    //set the current bit, sending MSB first
547
		    digital_output(BOM_DATA, bit_field&mask);
548
		    //then pulse the clock
549
		    digital_output(BOM_CLOCK, 1);
550
		    digital_output(BOM_CLOCK, 0);
551
			mask = mask>>1;
552
	    }
553
        break;
554
		
555
    case RBOM:
556
        //add rbom code here
557
        break;
558
    }
559
}
560

  
561

  
562
/**
563
 * (DEPRECATED) Returns the direction of the maximum BOM reading,
564
 * as an integer in the range 0-15. 0 indicates to the
565
 * robot's right, while the rest of the sensors are
566
 * numbered counterclockwise. This is useful for determining
567
 * the direction of a robot flashing its BOM, of only one
568
 * robot is currently doing so. analog_init must be called
569
 * before this function can be used.
570
 *
571
 * @return the direction of the maximum BOM reading
572
 *
573
 * @see analog_init
574
 **/
575
int get_max_bom(void) {
576
    bom_refresh(BOM_ALL);
577
    return bom_get_max();
578
}
579

  
580
/**
581
 * Flashes the BOM.  If using a BOM1.5, only the emitters that have been enabled using
582
 * bom_set_leds will turn on.
583
 * 
584
 * @see bom_off, bom_set_leds
585
 **/
586
void bom_on(void)
587
{
588
  switch(bom_type) {
589
  case BOM10:
590
	digital_output(MONKL, 1);
591
	break;
592
  case BOM15:
593
	digital_output(BOM_STROBE, 1);
594
	break;
595
  case RBOM:
596
	break;
597
  }
598
}
599

  
600
/**
601
 * Turns off all bom leds.
602
 * 
603
 * @see bom_on
604
 **/
605
void bom_off(void)
606
{
607
  switch(bom_type) {
608
  case BOM10:
609
	digital_output(MONKL, 0);
610
	break;
611
  case BOM15:
612
	digital_output(BOM_STROBE, 0);
613
	break;
614
  case RBOM:
615
	break;
616
  }
617
}
618

  
619
/** @} **/ //end group
620

  
621
//select a detector to read
622
static void bom_select(char which) {
623
	if(bom_type == BOM10)
624
	  which = lookup[(int)which];
625
	
626
    if (which&8)
627
      digital_output(select_pins[3], 1);
628
    else
629
      digital_output(select_pins[3], 0);
630

  
631
    if (which&4)
632
      digital_output(select_pins[2], 1);
633
    else
634
      digital_output(select_pins[2], 0);
635

  
636
    if (which&2)
637
      digital_output(select_pins[1], 1);
638
    else
639
      digital_output(select_pins[1], 0);
640

  
641
    if (which&1)
642
      digital_output(select_pins[0], 1);
643
    else
644
      digital_output(select_pins[0], 0);
645
	
646
}
branches/ir_lookup/serial.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 serial.c
29
 * @brief Serial Input and Output
30
 *
31
 * Implementation of functions for serial input and output.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
#include <avr/io.h>
37
#include "serial.h"
38

  
39
#ifdef USE_STDIO
40

  
41
#include <stdio.h>
42

  
43
/**
44
 * For use with fprintf() and related stdio functions
45
 **/
46
FILE *usb_fd;
47

  
48
/**
49
 * For use with fprintf() and related stdio functions
50
 **/
51
FILE *xbee_fd;
52

  
53
#endif
54

  
55
/**
56
 * Initializes communication over the USB serial port.
57
 * This must be called before any other usb function
58
 * may be used.
59
 **/
60
void usb_init() {
61
  //Set baud rate
62
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
63
  // - 9600 is U2X =1, UBRR = 107.
64
#if (USB_BAUD == 115200)
65
  UBRR0H = 0x00;
66
  UBRR0L = 8;
67
  UCSR0A |= _BV(U2X0);
68
#elif (USB_BAUD == 9600)
69
  UBRR0H = 0x00;
70
  UBRR0L = 103;
71
  UCSR0A |= _BV(U2X0);
72
#else //Baud rate is defined in the header file, we should not get here
73
  return;
74
#endif
75

  
76
  /*Enable receiver and transmitter */
77
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
78
	
79
  /* Set frame format: 8data, 1stop bit, asynchronous normal mode */
80
  UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
81
  
82
  // if we have enabled the stdio stuff, then we init it here
83
#ifdef USE_STDIO
84
  /* Open the stdio stream corresponding to this port */
85
  usb_fd = fdevopen(usb_putc, usb_getc);
86
#endif
87
}
88

  
89
/**
90
 * Initializes communication over the XBee.
91
 * This must be called before any other xbee function
92
 * may be used.
93
 **/
94
void xbee_init() {
95
  //Set baud rate
96
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
97
  // - 9600 is U2X =1, UBRR = 107.
98
#if (XBEE_BAUD == 115200)
99
  UBRR1H = 0x00;
100
  UBRR1L = 8;
101
  UCSR1A |= _BV(U2X1);
102
#elif (XBEE_BAUD == 9600)
103
  UBRR1H = 0x00;
104
  UBRR1L = 103;
105
  UCSR1A |= _BV(U2X1);
106
#else //Baud rate is defined in the header file, we should not get here
107
  return;
108
#endif
109

  
110
  //Enable receiver and transmitter
111
  UCSR1B |= (1<<RXEN1)|(1<<TXEN1);
112
	
113
  // Set frame format: 8data, 1stop bit, asynchronous normal mode
114
  UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11);
115
  
116
  // if we have enabled the stdio stuff, then we init it here
117
#ifdef USE_STDIO
118
  /* Open the stdio stream corresponding to this port */
119
  xbee_fd = fdevopen(xbee_putc, xbee_getc);
120
#endif
121
}
122

  
123
/**
124
 * Sends a character over USB.
125
 *
126
 * @param c the character to send
127
 * @return 0 for success, nonzero for failure
128
 **/
129
int usb_putc(char c) {
130
  // Wait until buffer is clear for sending
131
  loop_until_bit_is_set(UCSR0A, UDRE0);
132
	
133
  // Load buffer with your character
134
  UDR0 = c;
135
  return 0;
136
}
137

  
138
/**
139
 * Sends a character to the XBee.
140
 *
141
 * @param c the character to send
142
 * @return 0 for success, nonzero for failure
143
 **/
144
int xbee_putc(char c) {
145
  // Wait until buffer is clear for sending
146
  loop_until_bit_is_set(UCSR1A, UDRE1);
147
	
148
  // Load buffer with your character
149
  UDR1 = c;
150
  return 0;
151
}
152

  
153
/**
154
 * Sends a sequence of characters over USB.
155
 *
156
 * @param s the string to send
157
 * @return 0 for success, nonzero for failure
158
 **/
159
int usb_puts(char *s) {
160
  char *t = s;
161
  while (*t != 0) {
162
    usb_putc(*t);
163
    t++;
164
  }
165
  return 0;
166
}
167

  
168
/**
169
 * Sends a sequence of characters from program space over USB.
170
 *
171
 * @param s the string to send
172
 **/
173
void usb_puts_P (PGM_P s) {
174
    char buf;
175
	
176
    while (memcpy_P (&buf, s, sizeof (char)), buf!=0) {
177
        usb_putc (buf);
178
        s++;
179
    }
180
}
181

  
182

  
183

  
184
/**
185
 * Returns the first character in the buffer received from USB.
186
 * This function blocks execution until a character has been received.
187
 * xbee_init must be called before this function may be used.
188
 * 
189
 * @return the first character in the usb buffer
190
 *
191
 * @see usb_init, usb_getc_nb
192
 **/
193
int usb_getc(void) {
194
  // Wait for the receive buffer to be filled
195
  loop_until_bit_is_set(UCSR0A, RXC0);
196
	
197
  // Read the receive buffer
198
  return UDR0;
199
}
200

  
201
/**
202
 * Returns the first character in the buffer received from USB.
203
 * This function blocks execution until a character has been
204
 * received. xbee_init must be called before this function
205
 * may be used.
206
 * 
207
 * @return the first character in the xbee buffer
208
 * 
209
 * @see xbee_init, xbee_getc_nb
210
 **/
211
int xbee_getc(void) {
212
  // Wait for the receive buffer to be filled
213
  loop_until_bit_is_set(UCSR1A, RXC1);
214
	
215
  // Read the receive buffer
216
  return UDR1;
217
}
218

  
219
/**
220
 * Non blocking version of usb_getc. If a character is present in the buffer,
221
 * it is returned, otherwise -1 is returned immediately. usb_init must be
222
 * called before this function can be used.
223
 *
224
 * @param c the received character. This will be set if a character has
225
 * been received.
226
 * 
227
 * @return -1 if no character is available, 0 otherwise
228
 * 
229
 * @see usb_init, usb_getc
230
 **/
231
int usb_getc_nb(char *c) {
232
  // check if the receive buffer is filled
233
  if (UCSR0A & _BV(RXC0)) {
234
    // Read the receive buffer
235
    (*c) = UDR0;
236
    return 0;
237
  } else {
238
    // Return empty
239
    return -1;
240
  }
241
}
242

  
243
/**
244
 * Non blocking version of xbee_getc. If a character is present in the buffer,
245
 * it is returned, otherwise -1 is returned immediately. xbee_init
246
 * must be called before this function can be used.
247
 *
248
 * @param c the received character. This will be set if a character has
249
 * been received.
250
 * 
251
 * @return -1 if no character is available, 0 otherwise
252
 *
253
 * @see xbee_init, xbee_getc
254
 **/
255
int xbee_getc_nb(char *c) {
256
  // check if the receive buffer is filled
257
  if (UCSR1A & _BV(RXC1)) {
258
    // Read the receive buffer
259
    (*c) = UDR1;
260
    return 0;
261
  } else {
262
    // Return empty
263
    return -1;
264
  }
265
}
266

  
267

  
268
/*
269
  prints an int to serial
270

  
271
  code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
272
  uses usb_putc
273
*/
274
/**
275
 * Prints an integer, converted to ASCII, to usb. usb_init must be called
276
 * before this function can be used.
277
 *
278
 * @param value the integer to print
279
 * 
280
 * @return 0 if successful, nonzero otherwise
281
 *
282
 * @see usb_init, usb_putc
283
 **/
284
int usb_puti(int value ) {
285
  unsigned char usb_data[6]={'0','0','0','0','0','0' }, position=sizeof(usb_data), radix=10; 
286

  
287
  /* convert int to ascii  */ 
288
  if(value<0) { 
289
    usb_putc('-'); 
290
    value=-value; 
291
  }    
292
  do { 
293
    position--; 
294
    *(usb_data+position)=(value%radix)+'0'; 
295
    value/=radix;  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff