Project

General

Profile

Revision 336

Updated wireless to use a circular buffer instead of a queue using malloc. Tested on both the computer and robots with a token ring, and was successful.

View differences:

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 <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
#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

  
64
  /*Enable receiver and transmitter */
65
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
66

  
67
  /* Set frame format: 8data, 1stop bit, asynchronous normal mode */
68
  UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
69

  
70
  // if we have enabled the stdio stuff, then we init it here
71
#ifdef USE_STDIO
72
  /* Open the stdio stream corresponding to this port */
73
  usb_fd = fdevopen(usb_putc, usb_getc);
74
#endif
75
}
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
#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

  
98
  //Enable receiver and transmitter
99
  UCSR1B |= (1<<RXEN1)|(1<<TXEN1);
100

  
101
  // Set frame format: 8data, 1stop bit, asynchronous normal mode
102
  UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11);
103

  
104
  // if we have enabled the stdio stuff, then we init it here
105
#ifdef USE_STDIO
106
  /* Open the stdio stream corresponding to this port */
107
  xbee_fd = fdevopen(xbee_putc, xbee_getc);
108
#endif
109
}
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
int usb_putc(char c)
118
{
119
  // Wait until buffer is clear for sending
120
  loop_until_bit_is_set(UCSR0A, UDRE0);
121

  
122
  // Load buffer with your character
123
  UDR0 = c;
124
  return 0;
125
}
126

  
127
/**
128
 * Sends a character to the XBee.
129
 *
130
 * @param c the character to send
131
 * @return 0 for success, nonzero for failure
132
 **/
133
int xbee_putc(char c)
134
{
135
  // Wait until buffer is clear for sending
136
  loop_until_bit_is_set(UCSR1A, UDRE1);
137

  
138
  // Load buffer with your character
139
  UDR1 = c;
140
  return 0;
141
}
142

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

  
159
/**
160
 * Returns the first character in the buffer received from USB.
161
 * This function blocks execution until a character has been received.
162
 * xbee_init must be called before this function may be used.
163
 *
164
 * @return the first character in the usb buffer
165
 *
166
 * @see usb_init, usb_getc_nb
167
 **/
168
int usb_getc(void)
169
{
170
  // Wait for the receive buffer to be filled
171
  loop_until_bit_is_set(UCSR0A, RXC0);
172

  
173
  // Read the receive buffer
174
  return UDR0;
175
}
176

  
177
/**
178
 * Returns the first character in the buffer received from USB.
179
 * This function blocks execution until a character has been
180
 * received. xbee_init must be called before this function
181
 * may be used.
182
 *
183
 * @return the first character in the xbee buffer
184
 *
185
 * @see xbee_init, xbee_getc_nb
186
 **/
187
int xbee_getc(void)
188
{
189
  // Wait for the receive buffer to be filled
190
  loop_until_bit_is_set(UCSR1A, RXC1);
191

  
192
  // Read the receive buffer
193
  return UDR1;
194
}
195

  
196
/**
197
 * Non blocking version of usb_getc. If a character is present in the buffer,
198
 * it is returned, otherwise -1 is returned immediately. usb_init must be
199
 * called before this function can be used.
200
 *
201
 * @param c the received character. This will be set if a character has
202
 * been received.
203
 *
204
 * @return -1 if no character is available, 0 otherwise
205
 *
206
 * @see usb_init, usb_getc
207
 **/
208
int usb_getc_nb(char *c)
209
{
210
  // check if the receive buffer is filled
211
  if (UCSR0A & _BV(RXC0)) {
212
    // Read the receive buffer
213
    (*c) = UDR0;
214
    return 0;
215
  } else {
216
    // Return empty
217
    return -1;
218
  }
219
}
220

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

  
246

  
247
/*
248
prints an int to serial
249

  
250
code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
251
uses usb_putc
252
*/
253
/**
254
 * Prints an integer, converted to ASCII, to usb. usb_init must be called
255
 * before this function can be used.
256
 *
257
 * @param value the integer to print
258
 *
259
 * @return 0 if successful, nonzero otherwise
260
 *
261
 * @see usb_init, usb_putc
262
 **/
263
int usb_puti(int value) {
264
  unsigned char usb_data[6]={'0','0','0','0','0','0' }, position=sizeof(usb_data), radix=10;
265

  
266
  /* convert int to ascii  */
267
  if(value<0) { usb_putc('-'); value=-value; }
268
  do { position--; *(usb_data+position)=(value%radix)+'0'; value/=radix; } while(value);
269

  
270
  /* start displaying the number */
271
  for(; position <= (sizeof(usb_data)-1); position++) {
272
    usb_putc(usb_data[position]);
273
  }
274

  
275
  return 0;
276
}
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
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
	#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

  
64
  /*Enable receiver and transmitter */
65
	UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
66
	
67
	/* Set frame format: 8data, 1stop bit, asynchronous normal mode */
68
	UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
69
  
70
  // if we have enabled the stdio stuff, then we init it here
71
  #ifdef USE_STDIO
72
    /* Open the stdio stream corresponding to this port */
73
    usb_fd = fdevopen(usb_putc, usb_getc);
74
  #endif
75
}
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
	#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

  
98
	//Enable receiver and transmitter
99
	UCSR1B |= (1<<RXEN1)|(1<<TXEN1);
100
	
101
	// Set frame format: 8data, 1stop bit, asynchronous normal mode
102
	UCSR1C |= (1<<UCSZ10) | (1<<UCSZ11);
103
  
104
  // if we have enabled the stdio stuff, then we init it here
105
  #ifdef USE_STDIO
106
    /* Open the stdio stream corresponding to this port */
107
    xbee_fd = fdevopen(xbee_putc, xbee_getc);
108
  #endif
109
}
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
int usb_putc(char c) 
118
{
119
  // Wait until buffer is clear for sending
120
  loop_until_bit_is_set(UCSR0A, UDRE0);
121
	
122
  // Load buffer with your character
123
  UDR0 = c;
124
  return 0;
125
}
126

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

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

  
160
/**
161
 * Returns the first character in the buffer received from USB.
162
 * This function blocks execution until a character has been received.
163
 * xbee_init must be called before this function may be used.
164
 * 
165
 * @return the first character in the usb buffer
166
 *
167
 * @see usb_init, usb_getc_nb
168
 **/
169
int usb_getc(void)
170
{
171
	// Wait for the receive buffer to be filled
172
	loop_until_bit_is_set(UCSR0A, RXC0);
173
	
174
	// Read the receive buffer
175
	return UDR0;
176
}
177

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

  
197
/**
198
 * Non blocking version of usb_getc. If a character is present in the buffer,
199
 * it is returned, otherwise -1 is returned immediately. usb_init must be
200
 * called before this function can be used.
201
 *
202
 * @param c the received character. This will be set if a character has
203
 * been received.
204
 * 
205
 * @return -1 if no character is available, 0 otherwise
206
 * 
207
 * @see usb_init, usb_getc
208
 **/
209
int usb_getc_nb(char *c)
210
{
211
	// check if the receive buffer is filled
212
  if (UCSR0A & _BV(RXC0)) {
213
    // Read the receive buffer
214
    (*c) = UDR0;
215
    return 0;
216
  }
217
  else {
218
    // Return empty
219
    return -1;
220
	}
221
}
222

  
223
/**
224
 * Non blocking version of xbee_getc. If a character is present in the buffer,
225
 * it is returned, otherwise -1 is returned immediately. xbee_init
226
 * must be called before this function can be used.
227
 *
228
 * @param c the received character. This will be set if a character has
229
 * been received.
230
 * 
231
 * @return -1 if no character is available, 0 otherwise
232
 *
233
 * @see xbee_init, xbee_getc
234
 **/
235
int xbee_getc_nb(char *c)
236
{
237
	// check if the receive buffer is filled
238
  if (UCSR1A & _BV(RXC1)) {
239
    // Read the receive buffer
240
    (*c) = UDR1;
241
    return 0;
242
  }
243
  else {
244
    // Return empty
245
    return -1;
246
	}
247
}
248

  
249

  
250
/*
251
prints an int to serial
252

  
253
code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
254
uses usb_putc
255
*/
256
/**
257
 * Prints an integer, converted to ASCII, to usb. usb_init must be called
258
 * before this function can be used.
259
 *
260
 * @param value the integer to print
261
 * 
262
 * @return 0 if successful, nonzero otherwise
263
 *
264
 * @see usb_init, usb_putc
265
 **/
266
int usb_puti(int value ) {
267
	unsigned char usb_data[6]={'0','0','0','0','0','0' }, position=sizeof(usb_data), radix=10; 
268

  
269
        /* convert int to ascii  */ 
270
        if(value<0) { usb_putc('-'); value=-value; }    
271
        do { position--; *(usb_data+position)=(value%radix)+'0'; value/=radix;  } while(value); 
272

  
273
    
274
        /* start displaying the number */
275
        for(;position<=(sizeof(usb_data)-1);position++)
276
          {
277
            
278
            usb_putc(usb_data[position]);
279
          }
280

  
281
	return 0;
282
}
283

  
284

  

Also available in: Unified diff