Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (8.7 KB)

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 <stdio.h>
38
#include "serial.h"
39

    
40
/**
41
 * For use with fprintf() and related stdio functions
42
 **/
43
FILE *usb_fd;
44

    
45
/**
46
 * For use with fprintf() and related stdio functions
47
 **/
48
FILE *xbee_fd;
49

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

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

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

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

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

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

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

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

    
177

    
178

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

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

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

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

    
262

    
263
/*
264
  prints an int to serial
265

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

    
282
  /* convert int to ascii  */ 
283
  if(value<0) { 
284
    usb_putc('-'); 
285
    value=-value; 
286
  }    
287
  do { 
288
    position--; 
289
    *(usb_data+position)=(value%radix)+'0'; 
290
    value/=radix;  
291
  } while(value); 
292

    
293
    
294
  /* start displaying the number */
295
  for(;position<=(sizeof(usb_data)-1);position++) {
296
            
297
    usb_putc(usb_data[position]);
298
  }
299

    
300
  return 0;
301
}
302

    
303
/**
304
 * Determines a hexadecimal digit in ASCII code.
305
 *
306
 * @param value the value of the digit (0<=value<=15)
307
 * 
308
 * @return the hexadecimal digit in ASCII code, or '?'
309
 * if the input is invalid.
310
 **/
311
uint8_t hex_digit (uint8_t value)
312
{
313
    if (value>15) return '?';
314
    // Postcondition: 0<=x<=15
315

    
316
    return "0123456789ABCDEF"[value];
317
}
318

    
319
/**
320
 * Prints a fixed width hexadecimal representation of an unsigned
321
 * 16 bit integer in ASCII code to USB.
322
 * usb_init must be called before this function can be used.
323
 *
324
 * @param value the value to print
325
 * 
326
 * @see usb_init, usb_puti, usb_puts, usb_puth8, hex_digit
327
 **/
328
void usb_puth16 (uint16_t value)
329
{
330
    usb_putc (hex_digit((value >>12)&0xF));
331
    usb_putc (hex_digit((value >>8 )&0xF));
332
    usb_putc (hex_digit((value >>4 )&0xF));
333
    usb_putc (hex_digit( value      &0xF));
334
}
335

    
336
/**
337
 * Prints a fixed width hexadecimal representation of an unsigned
338
 * 8 bit integer in ASCII code to USB.
339
 * usb_init must be called before this function can be used.
340
 *
341
 * @param value the value to print
342
 * 
343
 * @see usb_init, usb_puti, usb_puts, usb_puth16, hex_digit
344
 **/
345
void usb_puth8(uint8_t value)
346
{
347
    usb_putc (hex_digit ((value)>>4 &0xF));
348
    usb_putc (hex_digit ( value     &0xF));
349
}
350