Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / libdragonfly / serial.c @ 1306

History | View | Annotate | Download (8.67 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 <stdio.h>
38
#include "serial.h"
39
40
FILE *usb_fd;  //For use with fprintf() and related stdio functions
41
FILE *xbee_fd;  //For use with fprintf() and related stdio functions
42
43
/**
44
 * Initializes communication over the USB serial port.
45
 * This must be called before any other usb function
46
 * may be used.
47
 **/
48
void usb_init() {
49
  //Set baud rate
50
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
51
  // - 9600 is U2X =1, UBRR = 107.
52 380 jknichel
#if (USB_BAUD == 115200)
53
  UBRR0H = 0x00;
54
  UBRR0L = 8;
55
  UCSR0A |= _BV(U2X0);
56
#elif (USB_BAUD == 9600)
57
  UBRR0H = 0x00;
58
  UBRR0L = 103;
59
  UCSR0A |= _BV(U2X0);
60
#else //Baud rate is defined in the header file, we should not get here
61
  return;
62
#endif
63 8 bcoltin
64
  /*Enable receiver and transmitter */
65 380 jknichel
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
66 8 bcoltin
67 380 jknichel
  /* Set frame format: 8data, 1stop bit, asynchronous normal mode */
68
  UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
69 8 bcoltin
70
  // if we have enabled the stdio stuff, then we init it here
71 380 jknichel
#ifdef USE_STDIO
72
  /* Open the stdio stream corresponding to this port */
73
  usb_fd = fdevopen(usb_putc, usb_getc);
74
#endif
75 8 bcoltin
}
76
77
/**
78
 * Initializes communication over the XBee.
79
 * This must be called before any other xbee function
80
 * may be used.
81
 **/
82
void xbee_init() {
83
  //Set baud rate
84
  // - 115200 (both wired and wireless) is UBRR=8, U2X=1
85
  // - 9600 is U2X =1, UBRR = 107.
86 380 jknichel
#if (XBEE_BAUD == 115200)
87
  UBRR1H = 0x00;
88
  UBRR1L = 8;
89
  UCSR1A |= _BV(U2X1);
90
#elif (XBEE_BAUD == 9600)
91
  UBRR1H = 0x00;
92
  UBRR1L = 103;
93
  UCSR1A |= _BV(U2X1);
94
#else //Baud rate is defined in the header file, we should not get here
95
  return;
96
#endif
97 8 bcoltin
98 380 jknichel
  //Enable receiver and transmitter
99
  UCSR1B |= (1<<RXEN1)|(1<<TXEN1);
100 8 bcoltin
101 380 jknichel
  // Set frame format: 8data, 1stop bit, asynchronous normal mode
102
  UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11);
103 8 bcoltin
104
  // if we have enabled the stdio stuff, then we init it here
105 380 jknichel
#ifdef USE_STDIO
106
  /* Open the stdio stream corresponding to this port */
107
  xbee_fd = fdevopen(xbee_putc, xbee_getc);
108
#endif
109 8 bcoltin
}
110
111
/**
112
 * Sends a character over USB.
113
 *
114
 * @param c the character to send
115
 * @return 0 for success, nonzero for failure
116
 **/
117 380 jknichel
int usb_putc(char c) {
118 8 bcoltin
  // Wait until buffer is clear for sending
119
  loop_until_bit_is_set(UCSR0A, UDRE0);
120
121
  // Load buffer with your character
122
  UDR0 = c;
123
  return 0;
124
}
125
126
/**
127
 * Sends a character to the XBee.
128
 *
129
 * @param c the character to send
130
 * @return 0 for success, nonzero for failure
131
 **/
132 380 jknichel
int xbee_putc(char c) {
133 8 bcoltin
  // Wait until buffer is clear for sending
134
  loop_until_bit_is_set(UCSR1A, UDRE1);
135
136
  // Load buffer with your character
137
  UDR1 = c;
138
  return 0;
139
}
140
141
/**
142
 * Sends a sequence of characters over USB.
143
 *
144
 * @param s the string to send
145
 * @return 0 for success, nonzero for failure
146
 **/
147 380 jknichel
int usb_puts(char *s) {
148
  char *t = s;
149
  while (*t != 0) {
150
    usb_putc(*t);
151
    t++;
152
  }
153 8 bcoltin
  return 0;
154
}
155
156
/**
157 1207 deffi
 * Sends a sequence of characters from program space over USB.
158
 *
159
 * @param s the string to send
160
 **/
161
void usb_puts_P (PGM_P s) {
162
    char buf;
163
164
    while (memcpy_P (&buf, s, sizeof (char)), buf!=0) {
165
        usb_putc (buf);
166
        s++;
167
    }
168
}
169
170
171
172
/**
173 8 bcoltin
 * Returns the first character in the buffer received from USB.
174
 * This function blocks execution until a character has been received.
175
 * xbee_init must be called before this function may be used.
176
 *
177
 * @return the first character in the usb buffer
178
 *
179
 * @see usb_init, usb_getc_nb
180
 **/
181 380 jknichel
int usb_getc(void) {
182
  // Wait for the receive buffer to be filled
183
  loop_until_bit_is_set(UCSR0A, RXC0);
184 8 bcoltin
185 380 jknichel
  // Read the receive buffer
186
  return UDR0;
187 8 bcoltin
}
188
189
/**
190
 * Returns the first character in the buffer received from USB.
191
 * This function blocks execution until a character has been
192
 * received. xbee_init must be called before this function
193
 * may be used.
194
 *
195
 * @return the first character in the xbee buffer
196
 *
197
 * @see xbee_init, xbee_getc_nb
198
 **/
199 380 jknichel
int xbee_getc(void) {
200
  // Wait for the receive buffer to be filled
201
  loop_until_bit_is_set(UCSR1A, RXC1);
202 8 bcoltin
203 380 jknichel
  // Read the receive buffer
204
  return UDR1;
205 8 bcoltin
}
206
207
/**
208
 * Non blocking version of usb_getc. If a character is present in the buffer,
209
 * it is returned, otherwise -1 is returned immediately. usb_init must be
210
 * called before this function can be used.
211
 *
212
 * @param c the received character. This will be set if a character has
213
 * been received.
214
 *
215
 * @return -1 if no character is available, 0 otherwise
216
 *
217
 * @see usb_init, usb_getc
218
 **/
219 380 jknichel
int usb_getc_nb(char *c) {
220
  // check if the receive buffer is filled
221 8 bcoltin
  if (UCSR0A & _BV(RXC0)) {
222
    // Read the receive buffer
223
    (*c) = UDR0;
224
    return 0;
225 380 jknichel
  } else {
226 8 bcoltin
    // Return empty
227
    return -1;
228 380 jknichel
  }
229 8 bcoltin
}
230
231
/**
232
 * Non blocking version of xbee_getc. If a character is present in the buffer,
233
 * it is returned, otherwise -1 is returned immediately. xbee_init
234
 * must be called before this function can be used.
235
 *
236
 * @param c the received character. This will be set if a character has
237
 * been received.
238
 *
239
 * @return -1 if no character is available, 0 otherwise
240
 *
241
 * @see xbee_init, xbee_getc
242
 **/
243 380 jknichel
int xbee_getc_nb(char *c) {
244
  // check if the receive buffer is filled
245 8 bcoltin
  if (UCSR1A & _BV(RXC1)) {
246
    // Read the receive buffer
247
    (*c) = UDR1;
248
    return 0;
249 380 jknichel
  } else {
250 8 bcoltin
    // Return empty
251
    return -1;
252 380 jknichel
  }
253 8 bcoltin
}
254
255
256
/*
257 380 jknichel
  prints an int to serial
258 8 bcoltin

259 380 jknichel
  code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
260
  uses usb_putc
261 8 bcoltin
*/
262
/**
263
 * Prints an integer, converted to ASCII, to usb. usb_init must be called
264
 * before this function can be used.
265
 *
266
 * @param value the integer to print
267
 *
268
 * @return 0 if successful, nonzero otherwise
269
 *
270
 * @see usb_init, usb_putc
271
 **/
272
int usb_puti(int value ) {
273 380 jknichel
  unsigned char usb_data[6]={'0','0','0','0','0','0' }, position=sizeof(usb_data), radix=10;
274 8 bcoltin
275 380 jknichel
  /* convert int to ascii  */
276
  if(value<0) {
277
    usb_putc('-');
278
    value=-value;
279
  }
280
  do {
281
    position--;
282
    *(usb_data+position)=(value%radix)+'0';
283
    value/=radix;
284
  } while(value);
285 8 bcoltin
286
287 380 jknichel
  /* start displaying the number */
288
  for(;position<=(sizeof(usb_data)-1);position++) {
289 8 bcoltin
290 380 jknichel
    usb_putc(usb_data[position]);
291
  }
292 8 bcoltin
293 380 jknichel
  return 0;
294 8 bcoltin
}
295 1143 deffi
296
/**
297
 * Determines a hexadecimal digit in ASCII code.
298
 *
299
 * @param value the value of the digit (0<=value<=15)
300
 *
301
 * @return the hexadecimal digit in ASCII code, or '?'
302
 * if the input is invalid.
303
 **/
304
uint8_t hex_digit (uint8_t value)
305
{
306
    if (value>15) return '?';
307
    // Postcondition: 0<=x<=15
308
309
    return "0123456789ABCDEF"[value];
310
}
311
312
/**
313
 * Prints a fixed width hexadecimal representation of an unsigned
314
 * 16 bit integer in ASCII code to USB.
315
 * usb_init must be called before this function can be used.
316
 *
317
 * @param value the value to print
318
 *
319
 * @see usb_init, usb_puti, usb_puts, usb_puth8, hex_digit
320
 **/
321
void usb_puth16 (uint16_t value)
322
{
323
    usb_putc (hex_digit((value >>12)&0xF));
324
    usb_putc (hex_digit((value >>8 )&0xF));
325
    usb_putc (hex_digit((value >>4 )&0xF));
326
    usb_putc (hex_digit( value      &0xF));
327
}
328
329
/**
330
 * Prints a fixed width hexadecimal representation of an unsigned
331
 * 8 bit integer in ASCII code to USB.
332
 * usb_init must be called before this function can be used.
333
 *
334
 * @param value the value to print
335
 *
336
 * @see usb_init, usb_puti, usb_puts, usb_puth16, hex_digit
337
 **/
338
void usb_puth8(uint8_t value)
339
{
340
    usb_putc (hex_digit ((value)>>4 &0xF));
341
    usb_putc (hex_digit ( value     &0xF));
342
}