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:

trunk/code/lib/include/libwireless/sensor_matrix.h
56 56
	/**
57 57
	 * The size of the sensor matrix.
58 58
	**/
59
	unsigned int size;
59
	int size;
60 60
	/**
61 61
	 * The matrix. Each row represents the readings of one
62 62
	 * robot.
......
78 78
/**@brief Destroy a sensor matrix **/
79 79
void sensor_matrix_destroy(SensorMatrix* m);
80 80
/**@brief Add a robot to a sensor matrix **/
81
void sensor_matrix_add_robot(SensorMatrix* m, unsigned int id);
81
void sensor_matrix_add_robot(SensorMatrix* m, int id);
82 82
/**@brief Remove a robot from a sensor matrix **/
83
void sensor_matrix_remove_robot(SensorMatrix* m, unsigned int id);
83
void sensor_matrix_remove_robot(SensorMatrix* m, int id);
84 84
/**@brief Set a reading in a sensor matrix **/
85 85
void sensor_matrix_set_reading(SensorMatrix* m, int observer, int robot, int reading);
86 86
/**@brief Get a reading in a sensor matrix **/
trunk/code/lib/include/libwireless/wireless.h
118 118
} PacketGroupHandler;
119 119

  
120 120
/**@brief Initialize the wireless library **/
121
void wl_init(void);
121
int wl_init(void);
122 122
/**@brief Uninitialize the wireless library **/
123 123
void wl_terminate(void);
124 124
/**@brief Perform wireless library functionality **/
......
150 150
/**@brief Get the channel we are using **/
151 151
int wl_get_channel(void);
152 152
/**@brief Get the 16-bit address of the XBee module **/
153
unsigned int wl_get_xbee_id(void);
153
int wl_get_xbee_id(void);
154 154
/**@brief Set the com port on a computer, undefined on the robot.**/
155 155
void wl_set_com_port(char* port);
156 156

  
trunk/code/lib/include/libwireless/wl_defs.h
59 59

  
60 60
// timing constants
61 61
#ifndef FIREFLY
62
#define BOM_DELAY 50
62
#define BOM_DELAY 100
63 63
#else
64
#define BOM_DELAY 100
64
#define BOM_DELAY 200
65 65
#endif
66 66

  
67 67
#define DEATH_DELAY 4
trunk/code/lib/include/libwireless/xbee.h
43 43
 * Also, a backup port if the other is used.
44 44
 **/
45 45
#ifndef ROBOT
46
#ifndef XBEE_PORT
47
#define XBEE_PORT "/dev/ttyUSB0"
46
#define XBEE_PORT_DEFAULT "/dev/ttyUSB1"
48 47
#endif
49
#define XBEE_PORT2 "/dev/ttyUSB0"
50
#endif
51 48

  
52 49
/**
53 50
 * @defgroup xbee XBee
......
77 74
#define XBEE_RX 0x81
78 75

  
79 76
/**@brief Initialize the XBee library **/
80
void xbee_lib_init(void);
77
int xbee_lib_init(void);
81 78
/**@brief Uninitialize the XBee library **/
82 79
void xbee_terminate(void);
83 80
/**@brief Get a packet from the XBee **/
trunk/code/lib/include/libwireless/queue.h
35 35
#ifndef WIRELESS_QUEUE_H
36 36
#define WIRELESS_QUEUE_H
37 37

  
38
#ifndef ROBOT
39
#include <pthread.h>
40
#endif
41

  
38 42
struct node_def;
39 43

  
40 44
/**
......
64 68
	 * The number of elements in the queue.
65 69
	 **/
66 70
	int size;
71
	
72
#ifndef ROBOT
73
	pthread_mutex_t lock;
74
#endif
67 75
} Queue;
68 76

  
69 77
/** @brief Create a new queue **/
......
71 79
/** @brief Destroy a queue **/
72 80
void queue_destroy(Queue* q);
73 81
/** @brief Add an element to a queue **/
74
void queue_add(Queue* q, void* item);
82
int queue_add(Queue* q, void* item);
75 83
/** @brief Remove an element from a queue **/
76 84
void* queue_remove(Queue* q);
77 85
/** @brief Remove all instances of a given element from a queue **/
......
85 93

  
86 94

  
87 95
#endif
88

  
trunk/code/lib/include/libdragonfly/move.h
72 72
/** @} **/
73 73

  
74 74
#endif
75

  
trunk/code/lib/src/libwireless/xbee.c
41 41
#include <unistd.h>
42 42
#include <pthread.h>
43 43
#include <errno.h>
44
#include <termios.h>
44 45

  
45 46
#else
46 47

  
......
53 54
#include <stdlib.h>
54 55
#include <string.h>
55 56

  
56
#include <queue.h>
57

  
58 57
#define XBEE_FRAME_START 0x7E
59 58

  
60 59
/*Frame Types*/
......
83 82
void xbee_enter_command_mode(void);
84 83
void xbee_exit_command_mode(void);
85 84
void xbee_enter_api_mode(void);
85
void xbee_exit_api_mode(void);
86 86
void xbee_wait_for_string(char* s, int len);
87 87
void xbee_wait_for_ok(void);
88 88

  
......
101 101
/*Global Variables*/
102 102

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

  
109
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;
110 117

  
118

  
111 119
//used to store packets as they are read
112 120
char xbee_buf[128];
113 121
int currentBufPos = 0;
......
125 133

  
126 134
/**
127 135
 * Interrupt for the robot. Adds bytes received from the xbee
128
 * to the queue.
136
 * to the buffer.
129 137
 **/
130 138
#ifndef FIREFLY
131 139
ISR(USART1_RX_vect)
132 140
{
133 141
	char c = UDR1;
134
	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;
135 151
}
136 152
#else
137 153
SIGNAL(SIG_USART0_RECV)
138 154
{
139 155
	char c = UDR0;
140
	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;
141 165
}
142 166
#endif
143 167

  
......
152 176
	while (1)
153 177
	{
154 178
		xbee_read(&c, 1);
155
		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;
156 188
	}
157 189
	return 0;
158 190
}
......
162 194
/**
163 195
 * Initializes the XBee library so that other functions may be used.
164 196
 **/
165
void xbee_lib_init(void)
197
int xbee_lib_init(void)
166 198
{
167
	xbee_queue = queue_create();
168
	
199
	arrival_buf[0] = 'A';
200
	arrival_buf[1] = 'A';
201
	arrival_buf[2] = 'A';
169 202
	#ifdef ROBOT
170 203

  
171 204
	//enable the receiving interrupt
......
176 209
	#endif
177 210
	sei();
178 211
	#else
212
	printf("Connecting to port %s.\n", xbee_com_port);
179 213
	xbee_stream = open(xbee_com_port, O_RDWR);
180
	if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
181
		xbee_stream = open(XBEE_PORT2, O_RDWR);
182
	if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
214
	if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/)
183 215
	{
184
		printf("Failed to open connection to XBee on port %s\r\n",xbee_com_port);
185
		exit(0);
216
		printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port);
217
		return -1;
186 218
	}
187
	lockf(xbee_stream, F_LOCK, 0);
188 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
	
189 245
	xbee_listen_thread =
190 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
	}
191 252
	
192
	int ret = pthread_create(xbee_listen_thread, NULL, 
253
	int ret = pthread_create(xbee_listen_thread, NULL,
193 254
		listen_to_xbee, NULL);
194 255
	if (ret)
195 256
	{
196
		printf("Failed to create listener thread.\r\n");
197
		exit(0);
257
		fprintf(stderr, "Failed to create listener thread.\r\n");
258
		return -1;
198 259
	}
260
	
199 261
	#endif
200 262
	xbee_enter_command_mode();
201 263
	xbee_enter_api_mode();
......
204 266
	
205 267
	//wait to return until the address is set
206 268
	while (xbee_address == 0) xbee_get_packet(NULL);
269

  
270

  
271
	return 0;
207 272
}
208 273

  
209 274
/**
......
218 283
	lockf(xbee_stream, F_ULOCK, 0);
219 284
	close(xbee_stream);
220 285
	#endif
221
	queue_destroy(xbee_queue);
222 286
}
223 287

  
224 288
/**
......
302 366
}
303 367

  
304 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
/**
305 377
 * Wait until the string "OK\r" is received from the XBee.
306 378
 **/
307 379
void xbee_wait_for_ok()
......
321 393
	char* curr = s;
322 394
	while (curr - s < len)
323 395
	{
324
		if (queue_is_empty(xbee_queue))
396
		// check if buffer is empty
397
		if (buffer_last == buffer_first)
325 398
			continue;
326
		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;
327 402
		if (c == *curr)
328 403
			curr++;
329 404
		else
......
531 606
	if (currentBufPos == 0)
532 607
	{
533 608
		do
534
			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)
535 614
				return -1;
536
		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;
537 619
		xbee_buf[0] = XBEE_FRAME_START;
538 620
		currentBufPos++;
539 621
	}
......
555 637
				return -1;
556 638
			}
557 639
		}
558
		if (queue_is_empty(xbee_queue))
640
		// check if buffer is empty
641
		if (buffer_first == buffer_last)
559 642
			return -1;
560
		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;
561 646
	}
562 647
	
563 648
	currentBufPos = 0;
......
781 866
}
782 867

  
783 868
#ifndef ROBOT
784
void xbee_set_com_port(char* port){
785
  //printf("Port being passed is %s\n",port);
786
  xbee_com_port = (char *) malloc(strlen(port));
787
  strcpy(xbee_com_port,port); 
869
void xbee_set_com_port(char* port)
870
{
871
	xbee_com_port = port;
788 872
}
789 873
#endif
790 874

  
trunk/code/lib/src/libwireless/queue.c
37 37

  
38 38
#include <stdlib.h>
39 39
#include <stdio.h>
40
#ifndef ROBOT
41
#include <pthread.h>
42
#endif
40 43

  
41 44
/**
42 45
 * @struct node_def
......
67 70
	
68 71
	q->head = NULL;
69 72
	q->size = 0;
73

  
74
	#ifndef ROBOT
75
	pthread_mutex_init(&(q->lock), NULL);
76
	#endif
77

  
70 78
	return q;
71 79
}
72 80

  
......
84 92
		free(t);
85 93
		t = t2;
86 94
	}
95

  
96
	#ifndef ROBOT
97
	pthread_mutex_destroy(&(q->lock));
98
	#endif
99

  
87 100
	free(q);
88 101
}
89 102

  
......
93 106
 * @param q the queue to add an element to
94 107
 * @param item the item to add to the queue
95 108
 **/
96
void queue_add(Queue* q, void* item)
109
int queue_add(Queue* q, void* item)
97 110
{
111
	#ifndef ROBOT
112
	pthread_mutex_lock(&(q->lock));
113
	#endif
114

  
98 115
	Node* n = (Node*)malloc(sizeof(Node));
116
	if (n == NULL)
117
	{
118
		#ifndef ROBOT
119
		pthread_mutex_unlock(&(q->lock));
120
		#endif
121
		return -1;
122
	}
123

  
99 124
	n->val = item;
100 125
	n->next = NULL;
101 126
	
......
106 131
	}
107 132
	else
108 133
	{
134

  
109 135
		q->tail->next = n;
110 136
		q->tail = n;
111 137
	}
112 138
	
113 139
	q->size++;
140

  
141
	#ifndef ROBOT
142
	pthread_mutex_unlock(&(q->lock));
143
	#endif
144

  
145
	return 0;
114 146
}
115 147

  
116 148
/**
......
122 154
 **/
123 155
void* queue_remove(Queue* q)
124 156
{
157
	#ifndef ROBOT
158
	pthread_mutex_lock(&(q->lock));
159
	#endif
160
	
125 161
	Node* first = q->head;
126 162
	if (first == NULL)
127 163
	{
128 164
		WL_DEBUG_PRINT("Attempting to remove item \
129 165
			from empty queue.\r\n");
130 166
		WL_DEBUG_PRINT_INT(queue_size(q));
167
		#ifndef ROBOT
168
		pthread_mutex_unlock(&(q->lock));
169
		#endif
170
		return NULL;
131 171
	}
132 172
	void* ret = first->val;
133 173
	q->head = first->next;
......
135 175
		q->tail = NULL;
136 176
	free(first);
137 177
	q->size--;
178

  
179
	#ifndef ROBOT
180
	pthread_mutex_unlock(&(q->lock));
181
	#endif
182

  
138 183
	return ret;
139 184
}
140 185

  
......
146 191
 **/
147 192
void queue_remove_all(Queue* q, void* item)
148 193
{
194
	#ifndef ROBOT
195
	pthread_mutex_lock(&(q->lock));
196
	#endif
197

  
149 198
	Node* curr = q->head;
150 199
	Node* prev = NULL;
151 200
	
......
167 216
			prev = curr;
168 217
		curr = next;
169 218
	}
219
	
220
	#ifndef ROBOT
221
	pthread_mutex_unlock(&(q->lock));
222
	#endif
170 223
}
171 224

  
172 225
/**
......
177 230
 **/
178 231
int queue_size(Queue* q)
179 232
{
180
	return q->size;
233
	int size;
234

  
235
	#ifndef ROBOT
236
	pthread_mutex_lock(&(q->lock));
237
	#endif
238

  
239
	size = q->size;
240
 
241
	#ifndef ROBOT
242
	pthread_mutex_unlock(&(q->lock));
243
	#endif
244

  
245
	return size;
181 246
}
182 247

  
183 248
/**
......
188 253
 **/
189 254
int queue_is_empty(Queue* q)
190 255
{
191
	return q->size == 0;
256
	int result;
257

  
258
	#ifndef ROBOT
259
	pthread_mutex_lock(&(q->lock));
260
	#endif
261

  
262
	result = q->size == 0;
263

  
264
	#ifndef ROBOT
265
	pthread_mutex_unlock(&(q->lock));
266
	#endif
267

  
268
	return result;
192 269
}
193 270

  
trunk/code/lib/src/libwireless/sensor_matrix.c
99 99
 * @param m the sensor matrix
100 100
 * @param id the XBee ID of the robot to add
101 101
 **/
102
void sensor_matrix_add_robot(SensorMatrix* m, unsigned int id)
102
void sensor_matrix_add_robot(SensorMatrix* m, int id)
103 103
{
104 104
	int i;
105 105
	if (id >= m->size)
......
126 126
 * @param m the sensor matrix
127 127
 * @param id the XBee ID of the robot to remove
128 128
 **/
129
void sensor_matrix_remove_robot(SensorMatrix* m, unsigned int id)
129
void sensor_matrix_remove_robot(SensorMatrix* m, int id)
130 130
{
131 131
	int i;
132 132

  
trunk/code/lib/src/libwireless/wireless.c
1 1
/**
2 2
 * Copyright (c) 2007 Colony Project
3
 * 
3
 *
4 4
 * Permission is hereby granted, free of charge, to any person
5 5
 * obtaining a copy of this software and associated documentation
6 6
 * files (the "Software"), to deal in the Software without
......
9 9
 * copies of the Software, and to permit persons to whom the
10 10
 * Software is furnished to do so, subject to the following
11 11
 * conditions:
12
 * 
12
 *
13 13
 * The above copyright notice and this permission notice shall be
14 14
 * included in all copies or substantial portions of the Software.
15
 * 
15
 *
16 16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
......
98 98
 * Initializes the wireless library. Must be called before any
99 99
 * other function.
100 100
 **/
101
void wl_init()
101
int wl_init()
102 102
{
103 103
	int i;
104 104
	for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
105 105
		wl_packet_groups[i] = NULL;
106 106

  
107
	xbee_lib_init();
108
	
107
	if (xbee_lib_init() == -1) {
108
	  return -1;
109
	}
110

  
109 111
	//begin timeout timer
110 112
	#ifdef ROBOT
111 113
	#ifdef FIREFLY
112 114
	rtc_init(PRESCALE_DIV_256, 32, &timer_handler);
113 115
	#else
114
	rtc_init(HALF_SECOND, &timer_handler); 
116
	rtc_init(HALF_SECOND, &timer_handler);
115 117
	#endif
116 118
	#else
117
  
119

  
118 120
	//create our timer
119 121
	struct itimerval timer_val;
120 122
	struct timeval interval;
......
127 129
	timer_val.it_value = first_time;
128 130
	if(setitimer(ITIMER_REAL,&timer_val,NULL)==-1)
129 131
	{
130
		WL_DEBUG_PRINT("Error creating a timer.\r\n"); 
132
		WL_DEBUG_PRINT("Error creating a timer.\r\n");
131 133
		perror("Failure's cause");
132
		exit(1); 
134
		exit(1);
133 135
	}
134 136

  
135 137
	//create signal handler
......
140 142
	sigaction(SIGALRM, &wl_sig_act, 0);
141 143
	sigaction(SIGINT, &wl_sig_act, 0);
142 144
	#endif
145

  
146
	return 0;
143 147
}
144 148

  
145 149
/**
......
152 156
		if (wl_packet_groups[i] != NULL &&
153 157
			wl_packet_groups[i]->unregister != NULL)
154 158
			wl_packet_groups[i]->unregister();
155
	
159

  
156 160
	xbee_terminate();
157 161
}
158 162

  
......
209 213
 *
210 214
 * @return the 16-bit address of the XBee module.
211 215
 **/
212
unsigned int wl_get_xbee_id()
216
int wl_get_xbee_id()
213 217
{
214 218
	return xbee_get_address();
215 219
}
......
276 280
void wl_send_pan_packet(char group, char type,
277 281
		char* data, int len, char frame)
278 282
{
279
	wl_send_packet(group, type, data, len, XBEE_BROADCAST, 
283
	wl_send_packet(group, type, data, len, XBEE_BROADCAST,
280 284
			XBEE_OPTIONS_NONE, frame);
281 285
}
282 286

  
......
329 333

  
330 334
/**
331 335
 * Unregister a packet group from the wireless library.
332
 * 
336
 *
333 337
 * @param h the packet group to remove
334 338
 **/
335 339
void wl_unregister_packet_group(PacketGroupHandler* h)
......
367 371
		wl_do_timeout();
368 372
		wl_timeout = 0;
369 373
	}
370
	
374

  
371 375
	int len = xbee_get_packet(wl_buf);
372 376
	if (len < 0)//no packet received
373 377
		return;
374
	
378

  
375 379
	if (wl_buf[0] == XBEE_TX_STATUS)
376 380
	{
377 381
		if (len != 3)
......
379 383
			WL_DEBUG_PRINT("Transmit Status packet should be of length 3.\r\n");
380 384
			return;
381 385
		}
382
		
386

  
383 387
		//the first four bits are the packet group
384 388
		//this only works with under 16 groups
385 389
		int group = (int)(wl_buf[1] >> 4);
......
398 402
				WL_DEBUG_PRINT("Purged\r\n");
399 403
			}
400 404
		}
401
		
405

  
402 406
		if (wl_packet_groups[group] != NULL &&
403 407
					wl_packet_groups[group]->handle_response != NULL)
404 408
			wl_packet_groups[group]->handle_response(
405 409
					(int)wl_buf[1] & 0x0F, success);
406 410
		return;
407 411
	}
408
	
412

  
409 413
	if (wl_buf[0] == XBEE_RX)
410 414
	{
411 415
		if (len < 7)
......
413 417
			WL_DEBUG_PRINT("Packet is too small.\r\n");
414 418
			return;
415 419
		}
416
		
420

  
417 421
		int source = ((int)wl_buf[1] << 8) + ((int)wl_buf[2]);
418
		
422

  
419 423
		/*
420 424
		//unused for now
421 425
		int signalStrength = wl_buf[3];
422 426
		//1 for Address broadcast, 2 for PAN broadcast
423 427
		int options = wl_buf[4];
424 428
		*/
425
		
429

  
426 430
		int group = wl_buf[5];
427 431
		int type = wl_buf[6];
428 432
		int packetLen = len - 7;
429
		
433

  
430 434
		if (wl_packet_groups[group] != NULL
431 435
				&& wl_packet_groups[group]->handle_receive != NULL)
432
			wl_packet_groups[group]->handle_receive(type, source, 
436
			wl_packet_groups[group]->handle_receive(type, source,
433 437
				wl_buf + 7, packetLen);
434 438
		return;
435 439
	}
436
	
440

  
437 441
	WL_DEBUG_PRINT("Unexpected packet received from XBee.\r\n");
438 442
	return;
439 443
}
440 444

  
441 445

  
442 446
#ifndef ROBOT
443
void wl_set_com_port(char* port){
444
  xbee_set_com_port(port);
447
void wl_set_com_port(char* port)
448
{
449
	xbee_set_com_port(port);
445 450
}
446 451
#endif
447 452

  
448

  
trunk/code/lib/src/libdragonfly/time.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 time.c
29
 * @brief Timer code
30
 *
31
 * Implementation of functions for timers.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
/*
37
time.c
38
anything that requires a delay
39
mostly delay_ms
40

  
41
author: Robotics Club, Colony Project
42

  
43
Change Log:
44
	2.5.07 - Kevin
45
		Aaron fixed the orb/servo code and made them use timer3 but compare registers B and C. He hard set the prescaler
46
		to 8 so the RTC broke. Changed it so that we use a 8 prescaler which sets the compare match at 1/16th of a second.
47
		You now count how many 16ths of a second you want until you trigger your actual interrupt. Works. Changed defines
48
		for time so you can still call rtc_init with a scale but now it is defined in terms of actual time like second, quarter_second
49
		etc. Read that section in the time.h file for more information. Tested and works, though the clock drifts more than
50
		it used to
51
	1.30.07 - Kevin
52
		Modified the clock to run on timer3 on the Dragonfly. Works with decent accuracy. Using a prescaler of 256
53
	the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of
54
	256 change it by that multiple. Refer to the time.h file for all possible prescalers.
55
		The interrupt will call a specified function _rtc_func every pulse.
56
		All of it has been tested and it works.
57

  
58
*/
59
#include <avr/interrupt.h>
60
#include <util/delay.h>
61
#include <time.h>
62
#include <serial.h>
63

  
64
static volatile int _rtc_val = 0;
65
static volatile int _rtc_pulse = 0;
66
static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
67
static void (*_rtc_f)(void) = 0;
68

  
69
/**
70
 * @defgroup time Time
71
 * @brief Time functions
72
 *
73
 * Functions dealing with time.
74
 *
75
 * @{
76
 **/
77

  
78
/**
79
 * Delays for the specified number of milliseconds.
80
 * The accuracy of this function is unknown.
81
 *
82
 * @param ms the number of milliseconds to delay for
83
 **/
84
void delay_ms(int ms)
85
{
86
	for(; ms > 15; ms-=15)
87
		_delay_ms(15);
88
	_delay_ms(ms);
89
}
90

  
91

  
92
/* 	Prescales defined in time.h. SECOND will give you 1 second.
93
	More scales are defined in the time.h file.
94
	rtc_func is the address to a function that you want called every clock tick. */
95
/**
96
 * Initializes the real time clock. Prescales are defined in time.h.
97
 * For example, SECOND will give 1 second. The specified function is
98
 * called every clock tick. For the real time clock to activate,
99
 * interrupts must be enabled. (through sei() )
100
 *
101
 * @param prescale_opt the period with which the timer is triggered
102
 * @param rtc_func the function called when the timer is triggered
103
 *
104
 * @see rtc_get, rtc_reset
105
 *
106
 **/
107
void rtc_init(int prescale_opt, void (*rtc_func)(void)) {
108

  
109
	//Clear timer register for Timer 3
110
	TCNT3 = 0;
111

  
112
	/* 	This sets the Waveform Generation Module to CTC (Clear Timer on Compare) Mode (100)
113
		See page135 in Atmega128 Docs for more modes and explanations */
114
	TCCR3B |= _BV(WGM32);
115

  
116
	/* 	This sets the prescaler for the system clock (8MHz) ie: divides the clock by some number.
117
		Currently set to a prescaler of 8 because that is what the orb and servos use (they are on this timer as well)
118
		See page137 in Atemga128 Docs for all the available prescalers */
119
	TCCR3B |= _BV(CS31);
120

  
121
	/* 	Sets the two regsiters that we compare against. So the timer counts up to this number and
122
		then resets back to 0 and calls the compare match interrupt.
123
		8x10^6 / 8 = 1/16 Second. All values are based off of this number. Do not change it unless you
124
		are l337*/
125

  
126
	OCR3A = 0xF424;
127

  
128
	/* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
129
		triggerd. (See page140 in Atmega128 Docs for more information */
130
	ETIMSK |= _BV(OCIE3A);
131

  
132
	/*	Store the pointer to the function to be used in the interrupt */
133
	_rtc_f = rtc_func;
134

  
135
	/*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
136
	_rtc_scale = prescale_opt;
137
}
138

  
139
/**
140
 * Returns the time elapsed in seconds since the last call to
141
 * rtc_init or rtc_reset.
142
 *
143
 * @return the number of seconds since the last call to rtc_init or rtc_reset
144
 *
145
 * @see rtc_init, rtc_reset
146
 **/
147
int rtc_get(void){
148
	return _rtc_val;
149
}
150

  
151
/**
152
 * Resets the real time clock counter to 0.
153
 *
154
 * @see rtc_init, rtc_get
155
 **/
156
void rtc_reset(void){
157
	_rtc_val = 0;
158
}
159

  
160
/** @} **/ //end defgroup
161

  
162
/*	Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated.
163
	Bascially, since the pulse is hard set at 1/16s  you want to count how many 16ths of a second have passed
164
	and when it reaches the amount of time you want, execute the code. */
165
SIGNAL(TIMER3_COMPA_vect) {
166

  
167
	if (_rtc_pulse ==  _rtc_scale) {
168
		//Increment the real time clock counter
169
		_rtc_val++;
170

  
171
		//Calls the function tied to the real time clock if defined
172
		if(_rtc_f != 0)
173
			_rtc_f();
174

  
175
		//Resets the pulse until the next scale is matched
176
		_rtc_pulse = 0;
177
	}
178

  
179
	//Updates the amount of pulses seen since the last scale match
180
	_rtc_pulse++;
181

  
182
}
183

  
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 time.c
29
 * @brief Timer code
30
 *
31
 * Implementation of functions for timers.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

  
36
/*
37
time.c
38
anything that requires a delay
39
mostly delay_ms
40

  
41
author: Robotics Club, Colony Project
42

  
43
Change Log:
44
	2.5.07 - Kevin
45
		Aaron fixed the orb/servo code and made them use timer3 but compare registers B and C. He hard set the prescaler
46
		to 8 so the RTC broke. Changed it so that we use a 8 prescaler which sets the compare match at 1/16th of a second.
47
		You now count how many 16ths of a second you want until you trigger your actual interrupt. Works. Changed defines
48
		for time so you can still call rtc_init with a scale but now it is defined in terms of actual time like second, quarter_second
49
		etc. Read that section in the time.h file for more information. Tested and works, though the clock drifts more than
50
		it used to
51
	1.30.07 - Kevin
52
		Modified the clock to run on timer3 on the Dragonfly. Works with decent accuracy. Using a prescaler of 256
53
	the timer counts up to a precomputer value which will trigger an interrupt and reset the timer. Multiples of
54
	256 change it by that multiple. Refer to the time.h file for all possible prescalers.
55
		The interrupt will call a specified function _rtc_func every pulse.
56
		All of it has been tested and it works.
57

  
58
*/
59
#include <avr/interrupt.h>
60
#include <util/delay.h>
61
#include <time.h>
62
#include <serial.h>
63

  
64
static volatile int _rtc_val = 0;
65
static volatile int _rtc_pulse = 0;
66
static volatile int _rtc_scale = 32;	//Defaults to 1 Second per pulse
67
static void (*_rtc_f)(void) = 0;
68

  
69
/**
70
 * @defgroup time Time
71
 * @brief Time functions
72
 * 
73
 * Functions dealing with time.
74
 * 
75
 * @{
76
 **/
77

  
78
/**
79
 * Delays for the specified number of milliseconds.
80
 * The accuracy of this function is unknown.
81
 *
82
 * @param ms the number of milliseconds to delay for
83
 **/
84
void delay_ms(int ms) 
85
{
86
	for(; ms > 15; ms-=15)
87
		_delay_ms(15);
88
	_delay_ms(ms);
89
}
90

  
91

  
92
/* 	Prescales defined in time.h. SECOND will give you 1 second.
93
	More scales are defined in the time.h file.
94
	rtc_func is the address to a function that you want called every clock tick. */
95
/**
96
 * Initializes the real time clock. Prescales are defined in time.h.
97
 * For example, SECOND will give 1 second. The specified function is
98
 * called every clock tick. For the real time clock to activate,
99
 * interrupts must be enabled. (through sei() )
100
 *
101
 * @param prescale_opt the period with which the timer is triggered
102
 * @param rtc_func the function called when the timer is triggered
103
 *
104
 * @see rtc_get, rtc_reset
105
 *
106
 **/
107
void rtc_init(int prescale_opt, void (*rtc_func)(void)) {
108
	
109
	//Clear timer register for Timer 3
110
	TCNT3 = 0;
111
	
112
	/* 	This sets the Waveform Generation Module to CTC (Clear Timer on Compare) Mode (100)
113
		See page135 in Atmega128 Docs for more modes and explanations */
114
	TCCR3B |= _BV(WGM32);
115
	
116
	/* 	This sets the prescaler for the system clock (8MHz) ie: divides the clock by some number.
117
		Currently set to a prescaler of 8 because that is what the orb and servos use (they are on this timer as well)
118
		See page137 in Atemga128 Docs for all the available prescalers */
119
	TCCR3B |= _BV(CS31);
120
	
121
	/* 	Sets the two regsiters that we compare against. So the timer counts up to this number and
122
		then resets back to 0 and calls the compare match interrupt.
123
		8x10^6 / 8 = 1/16 Second. All values are based off of this number. Do not change it unless you
124
		are l337*/
125
		
126
	OCR3A = 0xF424;	
127

  
128
	/* 	Enable Output Compare A Interrupt. When OCR3A is met by the timer TCNT3 this interrupt will be
129
		triggerd. (See page140 in Atmega128 Docs for more information */
130
	ETIMSK |= _BV(OCIE3A);
131
	
132
	/*	Store the pointer to the function to be used in the interrupt */
133
	_rtc_f = rtc_func;
134
	
135
	/*	Store how many 1/16ths of a second you want to let by before triggering an interrupt */
136
	_rtc_scale = prescale_opt;
137
}
138

  
139
/**
140
 * Returns the time elapsed in seconds since the last call to
141
 * rtc_init or rtc_reset.
142
 *
143
 * @return the number of seconds since the last call to rtc_init or rtc_reset
144
 *
145
 * @see rtc_init, rtc_reset
146
 **/
147
int rtc_get(void){
148
	return _rtc_val;
149
}
150

  
151
/**
152
 * Resets the real time clock counter to 0.
153
 *
154
 * @see rtc_init, rtc_get
155
 **/
156
void rtc_reset(void){
157
	_rtc_val = 0;
158
}
159

  
160
/** @} **/ //end defgroup
161

  
162
/*	Called every pulse. Function in _rtc_f is called every _rtc_scale and also the counter is updated.
163
	Bascially, since the pulse is hard set at 1/16s  you want to count how many 16ths of a second have passed
164
	and when it reaches the amount of time you want, execute the code. */
165
SIGNAL(TIMER3_COMPA_vect) {
166

  
167
	if (_rtc_pulse ==  _rtc_scale) {
168
		//Increment the real time clock counter
169
		_rtc_val++;
170
		
171
		//Calls the function tied to the real time clock if defined
172
		if(_rtc_f != 0)
173
			_rtc_f();
174
		
175
		//Resets the pulse until the next scale is matched
176
		_rtc_pulse = 0;
177
	}	
178
	
179
	//Updates the amount of pulses seen since the last scale match
180
	_rtc_pulse++;
181
	
182
}
183

  
trunk/code/lib/src/libdragonfly/motor.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 motor.c
29
 * @brief Motors
30
 *
31
 * Implementation of functions for controlling the motors.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 * Much of this is taken from FWR's library, author: Tom Lauwers
35
 **/
36

  
37
#include "motor.h"
38

  
39
/**
40
 * @defgroup motors Motors
41
 * @brief Functions for controlling the motors.
42
 * Functions for controlling the motors. Found in motor.h.
43
 * @{
44
 **/
45

  
46
/**
47
 * Initializes both motors so that they can be used with future
48
 * calls to motor1_set and motor2_set.
49
 *
50
 * @see motors_off, motor1_set, motor2_set
51
 **/
52
void motors_init( void ) {
53
	// Configure counter such that we use phase correct
54
	// PWM with 8-bit resolution
55
	PORTA &= 0x0F;
56
	DDRA |= 0xF0;
57
	DDRB |= 0x60;
58

  
59
	//timer 1A and 1B
60
	TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
61
	TCCR1B = _BV(WGM12) | _BV(CS10);
62
//	TCCR1A = 0xA1;
63
//	TCCR1B = 0x04;
64
	OCR1AH=0;
65
	OCR1AL=0;
66
	OCR1BH=0;
67
	OCR1BL=0;
68
}
69

  
70
/**
71
 * Sets the speed and direction of motor1.
72
 * motors_init must be called before this function can be used.
73
 *
74
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
75
 * @param speed The speed the motor will run at, in the range 0-255.
76
 *
77
 * @see motor2_set, motors_init
78
 **/
79
void motor1_set(int direction, int speed) {
80

  
81
	if(direction == 0) {
82
	    // turn off PWM first if switching directions
83
		if((PORTA & 0x30) != 0x10)
84
		{
85
		  OCR1A = 0;
86
		}
87
		PORTA = (PORTA & 0xCF) | 0x10;
88
//		PORTD |= 0x10;
89
//		PORTD &= 0xBF;
90
	}
91
	else {
92
	    // turn off PWM first if switching directions
93
		if((PORTA & 0x30) != 0x20)
94
		{
95
		  OCR1A = 0;
96
		}
97
		PORTA = (PORTA & 0xCF) | 0x20;
98
//		PORTD |= 0x40;
99
//		PORTD &= 0xEF;
100
	}
101

  
102
	// Set the timer to count up to speed, an 8-bit value
103
	OCR1AL = speed;
104
}
105

  
106
/**
107
 * Sets the speed and direction of motor2.
108
 * motors_init must be called before this function can be used.
109
 *
110
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
111
 * @param speed The speed the motor will run at, in the range 0-255.
112
 *
113
 * @see motor1_set, motors_init
114
 **/
115
void motor2_set(int direction, int speed) {
116
	if(direction == 0) {
117
//		PORTD |= 0x20;
118
//		PORTD &= 0x7F;
119
	    // turn off PWM first if switching directions
120
		if((PORTA & 0xC0) != 0x80)
121
		{
122
		  OCR1B = 0;
123
		}
124

  
125
		PORTA = (PORTA & 0x3F) | 0x80;
126
	}
127
	else {
128
//		PORTD |= 0x80;
129
//		PORTD &= 0xDF;
130

  
131
	    // turn off PWM first if switching directions
132
		if((PORTA & 0xC0) != 0x40)
133
		{
134
		  OCR1B = 0;
135
		}
136

  
137
		PORTA = (PORTA & 0x3F) | 0x40;
138
	}
139
	OCR1BL = speed;
140
}
141

  
142
/**
143
 * Turns off both motors.
144
 *
145
 * @see motors_init
146
 **/
147
void motors_off( void ) {
148
	OCR1AL = 0x0;
149
	OCR1BL = 0x0;
150
}
151

  
152
/**@}**///end defgroup
153

  
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 motor.c
29
 * @brief Motors
30
 *
31
 * Implementation of functions for controlling the motors.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 * Much of this is taken from FWR's library, author: Tom Lauwers
35
 **/
36

  
37
#include "motor.h"
38

  
39
/**
40
 * @defgroup motors Motors
41
 * @brief Functions for controlling the motors.
42
 * Functions for controlling the motors. Found in motor.h.
43
 * @{
44
 **/
45

  
46
/**
47
 * Initializes both motors so that they can be used with future
48
 * calls to motor1_set and motor2_set.
49
 *
50
 * @see motors_off, motor1_set, motor2_set
51
 **/
52
void motors_init( void ) {
53
	// Configure counter such that we use phase correct
54
	// PWM with 8-bit resolution
55
	PORTA &= 0x0F;
56
	DDRA |= 0xF0;
57
	DDRB |= 0x60;
58

  
59
	//timer 1A and 1B
60
	TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
61
	TCCR1B = _BV(WGM12) | _BV(CS10);
62
//	TCCR1A = 0xA1;
63
//	TCCR1B = 0x04;
64
	OCR1AH=0;
65
	OCR1AL=0;
66
	OCR1BH=0;
67
	OCR1BL=0;
68
}
69

  
70
/**
71
 * Sets the speed and direction of motor1.
72
 * motors_init must be called before this function can be used.
73
 *
74
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
75
 * @param speed The speed the motor will run at, in the range 0-255.
76
 * 
77
 * @see motor2_set, motors_init
78
 **/
79
void motor1_set(int direction, int speed) {
80

  
81
	if(direction == 0) {
82
	    // turn off PWM first if switching directions
83
		if((PORTA & 0x30) != 0x10)
84
		{
85
		  OCR1A = 0;
86
		}	
87
		PORTA = (PORTA & 0xCF) | 0x10;
88
//		PORTD |= 0x10;
89
//		PORTD &= 0xBF;
90
	}
91
	else {
92
	    // turn off PWM first if switching directions
93
		if((PORTA & 0x30) != 0x20)
94
		{
95
		  OCR1A = 0;
96
		}
97
		PORTA = (PORTA & 0xCF) | 0x20;
98
//		PORTD |= 0x40;
99
//		PORTD &= 0xEF;
100
	}
101
	
102
	// Set the timer to count up to speed, an 8-bit value
103
	OCR1AL = speed;
104
}
105

  
106
/**
107
 * Sets the speed and direction of motor2.
108
 * motors_init must be called before this function can be used.
109
 *
110
 * @param direction Either FORWARD or BACKWARD to set the direction of rotation.
111
 * @param speed The speed the motor will run at, in the range 0-255.
112
 *
113
 * @see motor1_set, motors_init
114
 **/
115
void motor2_set(int direction, int speed) {
116
	if(direction == 0) {
117
//		PORTD |= 0x20;
118
//		PORTD &= 0x7F;
119
	    // turn off PWM first if switching directions
120
		if((PORTA & 0xC0) != 0x80)
121
		{
122
		  OCR1B = 0;
123
		}		
124
		
125
		PORTA = (PORTA & 0x3F) | 0x80;
126
	}
127
	else {
128
//		PORTD |= 0x80;
129
//		PORTD &= 0xDF;
130

  
131
	    // turn off PWM first if switching directions
132
		if((PORTA & 0xC0) != 0x40)
133
		{
134
		  OCR1B = 0;
135
		}		
136
		
137
		PORTA = (PORTA & 0x3F) | 0x40;
138
	}
139
	OCR1BL = speed;
140
}
141

  
142
/**
143
 * Turns off both motors.
144
 *
145
 * @see motors_init
146
 **/
147
void motors_off( void ) {
148
	OCR1AL = 0x0;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff