Project

General

Profile

Statistics
| Revision:

root / branches / ir_branch / code / projects / libdragonfly / serial.c @ 1572

History | View | Annotate | Download (8.73 KB)

1 241 bcoltin
/**
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 8 bcoltin
26 241 bcoltin
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 8 bcoltin
#include <avr/io.h>
37
#include "serial.h"
38
39 1452 dsschult
#ifdef USE_STDIO
40
41
#include <stdio.h>
42
43 1370 dsschult
/**
44
 * For use with fprintf() and related stdio functions
45
 **/
46
FILE *usb_fd;
47 8 bcoltin
48
/**
49 1370 dsschult
 * For use with fprintf() and related stdio functions
50
 **/
51
FILE *xbee_fd;
52
53 1452 dsschult
#endif
54
55 1370 dsschult
/**
56 8 bcoltin
 * Initializes communication over the USB serial port.
57
 * This must be called before any other usb function
58
 * may be used.
59
 **/
60 1496 jsexton
void usb_init() {
61 8 bcoltin
  //Set baud rate
62
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
63
  // - 9600 is U2X =1, UBRR = 107.
64 380 jknichel
#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 1496 jsexton
  return;
74 380 jknichel
#endif
75 8 bcoltin
76
  /*Enable receiver and transmitter */
77 380 jknichel
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
78 8 bcoltin
79 380 jknichel
  /* Set frame format: 8data, 1stop bit, asynchronous normal mode */
80
  UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
81 8 bcoltin
82
  // if we have enabled the stdio stuff, then we init it here
83 380 jknichel
#ifdef USE_STDIO
84
  /* Open the stdio stream corresponding to this port */
85
  usb_fd = fdevopen(usb_putc, usb_getc);
86
#endif
87 8 bcoltin
}
88
89
/**
90
 * Initializes communication over the XBee.
91
 * This must be called before any other xbee function
92
 * may be used.
93
 **/
94 1496 jsexton
void xbee_init() {
95 8 bcoltin
  //Set baud rate
96
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
97
  // - 9600 is U2X =1, UBRR = 107.
98 380 jknichel
#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 1496 jsexton
  return;
108 380 jknichel
#endif
109 8 bcoltin
110 380 jknichel
  //Enable receiver and transmitter
111
  UCSR1B |= (1<<RXEN1)|(1<<TXEN1);
112 8 bcoltin
113 380 jknichel
  // Set frame format: 8data, 1stop bit, asynchronous normal mode
114
  UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11);
115 8 bcoltin
116
  // if we have enabled the stdio stuff, then we init it here
117 380 jknichel
#ifdef USE_STDIO
118
  /* Open the stdio stream corresponding to this port */
119
  xbee_fd = fdevopen(xbee_putc, xbee_getc);
120
#endif
121 8 bcoltin
}
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 380 jknichel
int usb_putc(char c) {
130 8 bcoltin
  // 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 380 jknichel
int xbee_putc(char c) {
145 8 bcoltin
  // 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 380 jknichel
int usb_puts(char *s) {
160
  char *t = s;
161
  while (*t != 0) {
162
    usb_putc(*t);
163
    t++;
164
  }
165 8 bcoltin
  return 0;
166
}
167
168
/**
169 1207 deffi
 * Sends a sequence of characters from program space over USB.
170
 *
171
 * @param s the string to send
172
 **/
173 1496 jsexton
void usb_puts_P (PGM_P s) {
174 1207 deffi
    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 8 bcoltin
 * 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 1496 jsexton
 * @return the first character in the usb buffer
190 8 bcoltin
 *
191
 * @see usb_init, usb_getc_nb
192
 **/
193 380 jknichel
int usb_getc(void) {
194
  // Wait for the receive buffer to be filled
195
  loop_until_bit_is_set(UCSR0A, RXC0);
196 8 bcoltin
197 380 jknichel
  // Read the receive buffer
198
  return UDR0;
199 8 bcoltin
}
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 1496 jsexton
 * @return the first character in the xbee buffer
208 8 bcoltin
 *
209
 * @see xbee_init, xbee_getc_nb
210
 **/
211 380 jknichel
int xbee_getc(void) {
212
  // Wait for the receive buffer to be filled
213
  loop_until_bit_is_set(UCSR1A, RXC1);
214 8 bcoltin
215 380 jknichel
  // Read the receive buffer
216
  return UDR1;
217 8 bcoltin
}
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 1496 jsexton
 * @return -1 if no character is available, 0 otherwise
228 8 bcoltin
 *
229
 * @see usb_init, usb_getc
230
 **/
231 380 jknichel
int usb_getc_nb(char *c) {
232
  // check if the receive buffer is filled
233 8 bcoltin
  if (UCSR0A & _BV(RXC0)) {
234
    // Read the receive buffer
235
    (*c) = UDR0;
236
    return 0;
237 380 jknichel
  } else {
238 8 bcoltin
    // Return empty
239
    return -1;
240 380 jknichel
  }
241 8 bcoltin
}
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 1496 jsexton
 * @return -1 if no character is available, 0 otherwise
252 8 bcoltin
 *
253
 * @see xbee_init, xbee_getc
254
 **/
255 380 jknichel
int xbee_getc_nb(char *c) {
256
  // check if the receive buffer is filled
257 8 bcoltin
  if (UCSR1A & _BV(RXC1)) {
258
    // Read the receive buffer
259
    (*c) = UDR1;
260
    return 0;
261 380 jknichel
  } else {
262 8 bcoltin
    // Return empty
263
    return -1;
264 380 jknichel
  }
265 8 bcoltin
}
266
267
268
/*
269 380 jknichel
  prints an int to serial
270 8 bcoltin

271 380 jknichel
  code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
272
  uses usb_putc
273 8 bcoltin
*/
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 380 jknichel
  unsigned char usb_data[6]={'0','0','0','0','0','0' }, position=sizeof(usb_data), radix=10;
286 8 bcoltin
287 380 jknichel
  /* 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;
296
  } while(value);
297 8 bcoltin
298
299 380 jknichel
  /* start displaying the number */
300
  for(;position<=(sizeof(usb_data)-1);position++) {
301 8 bcoltin
302 380 jknichel
    usb_putc(usb_data[position]);
303
  }
304 8 bcoltin
305 380 jknichel
  return 0;
306 8 bcoltin
}
307 1143 deffi
308
/**
309
 * Determines a hexadecimal digit in ASCII code.
310
 *
311
 * @param value the value of the digit (0<=value<=15)
312
 *
313
 * @return the hexadecimal digit in ASCII code, or '?'
314
 * if the input is invalid.
315
 **/
316
uint8_t hex_digit (uint8_t value)
317
{
318
    if (value>15) return '?';
319
    // Postcondition: 0<=x<=15
320
321
    return "0123456789ABCDEF"[value];
322
}
323
324
/**
325
 * Prints a fixed width hexadecimal representation of an unsigned
326
 * 16 bit integer in ASCII code to USB.
327
 * usb_init must be called before this function can be used.
328
 *
329
 * @param value the value to print
330
 *
331
 * @see usb_init, usb_puti, usb_puts, usb_puth8, hex_digit
332
 **/
333 1496 jsexton
void usb_puth16 (uint16_t value)
334 1143 deffi
{
335
    usb_putc (hex_digit((value >>12)&0xF));
336
    usb_putc (hex_digit((value >>8 )&0xF));
337
    usb_putc (hex_digit((value >>4 )&0xF));
338
    usb_putc (hex_digit( value      &0xF));
339
}
340
341
/**
342
 * Prints a fixed width hexadecimal representation of an unsigned
343
 * 8 bit integer in ASCII code to USB.
344
 * usb_init must be called before this function can be used.
345
 *
346
 * @param value the value to print
347
 *
348
 * @see usb_init, usb_puti, usb_puts, usb_puth16, hex_digit
349
 **/
350 1496 jsexton
void usb_puth8(uint8_t value)
351 1143 deffi
{
352
    usb_putc (hex_digit ((value)>>4 &0xF));
353
    usb_putc (hex_digit ( value     &0xF));
354
}