Project

General

Profile

Revision 743

Fixed compilation errors.

View differences:

xbee.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
 * @file xbee.c
28
 * @brief XBee Interface
29
 *
30
 * Implementation of low level communication with the XBee in API mode.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

  
1 35
#include "xbee.h"
2 36
#include "wl_defs.h"
3 37

  
......
7 41
#include <unistd.h>
8 42
#include <pthread.h>
9 43
#include <errno.h>
44
#include <termios.h>
10 45

  
11 46
#else
12 47

  
......
19 54
#include <stdlib.h>
20 55
#include <string.h>
21 56

  
22
#include <queue.h>
23

  
24 57
#define XBEE_FRAME_START 0x7E
25 58

  
26 59
/*Frame Types*/
......
49 82
void xbee_enter_command_mode(void);
50 83
void xbee_exit_command_mode(void);
51 84
void xbee_enter_api_mode(void);
85
void xbee_exit_api_mode(void);
52 86
void xbee_wait_for_string(char* s, int len);
53 87
void xbee_wait_for_ok(void);
54 88

  
......
67 101
/*Global Variables*/
68 102

  
69 103
#ifndef ROBOT
104
char* xbee_com_port = XBEE_PORT_DEFAULT;
70 105
int xbee_stream;
71 106
pthread_t* xbee_listen_thread;
72 107
#endif
73 108

  
74
Queue* xbee_queue;
109
// TODO: is this a good size?
110
#define XBEE_BUFFER_SIZE	256
111
// a buffer for data received from the XBee
112
char arrival_buf[XBEE_BUFFER_SIZE];
113
// location of last unread byte in buffer
114
volatile int buffer_last = 0;
115
// first unread byte in buffer
116
volatile int buffer_first = 0;
75 117

  
118

  
76 119
//used to store packets as they are read
77 120
char xbee_buf[128];
78 121
int currentBufPos = 0;
......
90 133

  
91 134
/**
92 135
 * Interrupt for the robot. Adds bytes received from the xbee
93
 * to the queue.
136
 * to the buffer.
94 137
 **/
95 138
#ifndef FIREFLY
96 139
ISR(USART1_RX_vect)
97 140
{
98 141
	char c = UDR1;
99
	queue_add(xbee_queue, (void*)(int)c);
142
	arrival_buf[buffer_last] = c;
143
	int t = buffer_last + 1;
144
	if (t == XBEE_BUFFER_SIZE)
145
		t = 0;
146
	if (t == buffer_first)
147
	{
148
		WL_DEBUG_PRINT("Out of space in buffer.\n");
149
	}
150
	buffer_last = t;
100 151
}
101 152
#else
102 153
SIGNAL(SIG_USART0_RECV)
103 154
{
104 155
	char c = UDR0;
105
	queue_add(xbee_queue, (void*)(int)c);
156
	arrival_buf[buffer_last] = c;
157
	int t = buffer_last + 1;
158
	if (t == XBEE_BUFFER_SIZE)
159
		t = 0;
160
	if (t == buffer_first)
161
	{
162
		WL_DEBUG_PRINT("Out of space in buffer.\n");
163
	}
164
	buffer_last = t;
106 165
}
107 166
#endif
108 167

  
......
117 176
	while (1)
118 177
	{
119 178
		xbee_read(&c, 1);
120
		queue_add(xbee_queue, (void*)(int)c);
179
		arrival_buf[buffer_last] = c;
180
		int t = buffer_last + 1;
181
		if (t == XBEE_BUFFER_SIZE)
182
			t = 0;
183
		if (t == buffer_first)
184
		{
185
			WL_DEBUG_PRINT("Out of space in buffer.\n");
186
		}
187
		buffer_last = t;
121 188
	}
122 189
	return 0;
123 190
}
......
126 193

  
127 194
/**
128 195
 * Initializes the XBee library so that other functions may be used.
129
 *
130
 * @param pan_id the PAN to join initially. Use XBEE_PAN_DEFAULT
131
 * to leave the PAN as it is initially.
132 196
 **/
133
void xbee_lib_init(void)
197
int xbee_lib_init(void)
134 198
{
135
	xbee_queue = queue_create();
136
	
199
	arrival_buf[0] = 'A';
200
	arrival_buf[1] = 'A';
201
	arrival_buf[2] = 'A';
137 202
	#ifdef ROBOT
138 203

  
139 204
	//enable the receiving interrupt
......
144 209
	#endif
145 210
	sei();
146 211
	#else
147
	xbee_stream = open(XBEE_PORT, O_RDWR);
148
	if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
149
		xbee_stream = open(XBEE_PORT2, O_RDWR);
150
	if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
212
	printf("Connecting to port %s.\n", xbee_com_port);
213
	xbee_stream = open(xbee_com_port, O_RDWR);
214
	if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/)
151 215
	{
152
		printf("Failed to open connection to XBee.\r\n");
153
		exit(0);
216
		printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port);
217
		return -1;
154 218
	}
155
	lockf(xbee_stream, F_LOCK, 0);
156 219
	
220
	// set baud rate, etc. correctly
221
	struct termios options;
222

  
223
	tcgetattr(xbee_stream, &options);
224
	cfsetispeed(&options, B9600);
225
	cfsetospeed(&options, B9600);
226
	options.c_iflag &= ~ICRNL;
227
	options.c_oflag &= ~OCRNL;
228
	options.c_cflag |= (CLOCAL | CREAD);
229
	options.c_cflag &= ~PARENB;
230
	options.c_cflag &= ~CSTOPB;
231
	options.c_cflag &= ~CSIZE;
232
	options.c_cflag |= CS8;
233
	options.c_lflag &= ~ICANON;
234
	options.c_cc[VMIN] = 1;
235
	options.c_cc[VTIME] = 50;
236

  
237
	if (tcsetattr(xbee_stream, TCSANOW, &options))
238
	{
239
		fprintf(stderr, "Error setting attributes.\n");
240
		return -1;
241
	}
242

  
243
	//lockf(xbee_stream, F_LOCK, 0);
244
	
157 245
	xbee_listen_thread =
158 246
		(pthread_t*)malloc(sizeof(pthread_t));
247
	if (xbee_listen_thread == NULL)
248
	{
249
		fprintf(stderr, "%s: Malloc failed.\n", __FUNCTION__);
250
		return -1;
251
	}
159 252
	
160
	int ret = pthread_create(xbee_listen_thread, NULL, 
253
	int ret = pthread_create(xbee_listen_thread, NULL,
161 254
		listen_to_xbee, NULL);
162 255
	if (ret)
163 256
	{
164
		printf("Failed to create listener thread.\r\n");
165
		exit(0);
257
		fprintf(stderr, "Failed to create listener thread.\r\n");
258
		return -1;
166 259
	}
260
	
167 261
	#endif
168 262
	xbee_enter_command_mode();
169 263
	xbee_enter_api_mode();
......
172 266
	
173 267
	//wait to return until the address is set
174 268
	while (xbee_address == 0) xbee_get_packet(NULL);
269

  
270

  
271
	return 0;
175 272
}
176 273

  
177 274
/**
......
186 283
	lockf(xbee_stream, F_ULOCK, 0);
187 284
	close(xbee_stream);
188 285
	#endif
189
	queue_destroy(xbee_queue);
190 286
}
191 287

  
192 288
/**
......
270 366
}
271 367

  
272 368
/**
369
 * Exit API mode. (warning - does not check for response)
370
 **/
371
void xbee_exit_api_mode()
372
{
373
	xbee_send_string("ATAP 0\r");
374
}
375

  
376
/**
273 377
 * Wait until the string "OK\r" is received from the XBee.
274 378
 **/
275 379
void xbee_wait_for_ok()
......
289 393
	char* curr = s;
290 394
	while (curr - s < len)
291 395
	{
292
		if (queue_is_empty(xbee_queue))
396
		// check if buffer is empty
397
		if (buffer_last == buffer_first)
293 398
			continue;
294
		char c = (char)(int)queue_remove(xbee_queue);
399
		char c = arrival_buf[buffer_first++];
400
		if (buffer_first == XBEE_BUFFER_SIZE)
401
			buffer_first = 0;
295 402
		if (c == *curr)
296 403
			curr++;
297 404
		else
......
499 606
	if (currentBufPos == 0)
500 607
	{
501 608
		do
502
			if (queue_is_empty(xbee_queue))
609
		{
610
			if (buffer_first == XBEE_BUFFER_SIZE)
611
				buffer_first = 0;
612
			// check if buffer is empty
613
			if (buffer_first == buffer_last)
503 614
				return -1;
504
		while ((char)(int)queue_remove(xbee_queue) != XBEE_FRAME_START);
615
		}
616
		while (arrival_buf[buffer_first++] != XBEE_FRAME_START);
617
		if (buffer_first == XBEE_BUFFER_SIZE)
618
			buffer_first = 0;
505 619
		xbee_buf[0] = XBEE_FRAME_START;
506 620
		currentBufPos++;
507 621
	}
......
514 628
			|| currentBufPos < len + 4)
515 629
	{
516 630
		if (currentBufPos == 3)
631
		{
517 632
			len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8);
518
		if (queue_is_empty(xbee_queue))
633
			if (len > 120)
634
			{
635
				WL_DEBUG_PRINT("Packet too large. Probably error in XBee transmission.\n");
636
				currentBufPos = 0;
637
				return -1;
638
			}
639
		}
640
		// check if buffer is empty
641
		if (buffer_first == buffer_last)
519 642
			return -1;
520
		xbee_buf[currentBufPos++] = (char)(int)queue_remove(xbee_queue);
643
		xbee_buf[currentBufPos++] = arrival_buf[buffer_first++];
644
		if (buffer_first == XBEE_BUFFER_SIZE)
645
			buffer_first = 0;
521 646
	}
522 647
	
523 648
	currentBufPos = 0;
524 649
	
525 650
	if (!xbee_verify_checksum(xbee_buf, len + 4))
526 651
	{
527
		usb_puts("XBee checksum failed.\r\n");
652
		WL_DEBUG_PRINT("XBee checksum failed.\r\n");
528 653
		return -1;
529 654
	}
530 655

  
......
740 865
	return xbee_address;
741 866
}
742 867

  
868
#ifndef ROBOT
869
void xbee_set_com_port(char* port)
870
{
871
	xbee_com_port = port;
872
}
873
#endif
874

  

Also available in: Unified diff