Project

General

Profile

Revision 206

I really hate myself...

View differences:

branches/slam/code/projects/libwireless/robotTest/Makefile
1
# Hey Emacs, this is a -*- makefile -*-
2
#----------------------------------------------------------------------------
3
# WinAVR Makefile Template written by Eric B. Weddington, J?rg Wunsch, et al.
4
#
5
# Released to the Public Domain
6
#
7
# Additional material for this makefile was written by:
8
# Peter Fleury
9
# Tim Henigan
10
# Colin O'Flynn
11
# Reiner Patommel
12
# Markus Pfaff
13
# Sander Pool
14
# Frederik Rouleau
15
#
16
#----------------------------------------------------------------------------
17
# On command line:
18
#
19
# make all = Make software.
20
#
21
# make clean = Clean out built project files.
22
#
23
# make coff = Convert ELF to AVR COFF.
24
#
25
# make extcoff = Convert ELF to AVR Extended COFF.
26
#
27
# make program = Download the hex file to the device, using avrdude.
28
#                Please customize the avrdude settings below first!
29
#
30
# make debug = Start either simulavr or avarice as specified for debugging, 
31
#              with avr-gdb or avr-insight as the front end for debugging.
32
#
33
# make filename.s = Just compile filename.c into the assembler code only.
34
#
35
# make filename.i = Create a preprocessed source file for use in submitting
36
#                   bug reports to the GCC project.
37
#
38
# To rebuild project do "make clean" then "make all".
39
#----------------------------------------------------------------------------
40

  
41
#if you want your code to work on the Firefly++ and not Firefly+
42
#then add the -DFFPP line to CDEFS
43
COLONYROOT = y:
44
CDEFS = 
45
#-DFFPP
46

  
47
# MCU name
48
MCU = atmega128
49

  
50

  
51
# Processor frequency.
52
#     This will define a symbol, F_CPU, in all source code files equal to the 
53
#     processor frequency. You can then use this symbol in your source code to 
54
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
55
#     automatically to create a 32-bit value in your source code.
56
F_CPU = 8000000
57

  
58

  
59
# Output format. (can be srec, ihex, binary)
60
FORMAT = ihex
61

  
62

  
63
# Target file name (without extension).
64
TARGET = main
65

  
66

  
67
# List C source files here. (C dependencies are automatically generated.)
68
SRC = $(wildcard *.c)
69
#$(TARGET).c 
70

  
71

  
72
# List Assembler source files here.
73
#     Make them always end in a capital .S.  Files ending in a lowercase .s
74
#     will not be considered source files but generated files (assembler
75
#     output from the compiler), and will be deleted upon "make clean"!
76
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
77
#     it will preserve the spelling of the filenames, and gcc itself does
78
#     care about how the name is spelled on its command-line.
79
ASRC = 
80

  
81

  
82
# Optimization level, can be [0, 1, 2, 3, s]. 
83
#     0 = turn off optimization. s = optimize for size.
84
#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
85
OPT = s
86

  
87

  
88
# Debugging format.
89
#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
90
#     AVR Studio 4.10 requires dwarf-2.
91
#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
92
DEBUG =
93

  
94

  
95
# List any extra directories to look for include files here.
96
#     Each directory must be seperated by a space.
97
#     Use forward slashes for directory separators.
98
#     For a directory that has spaces, enclose it in quotes.
99
EXTRAINCDIRS = $(COLONYROOT)/code/firefly_plus_lib
100
#C:\WinAVR\include\fwr
101

  
102

  
103
# Compiler flag to set the C Standard level.
104
#     c89   = "ANSI" C
105
#     gnu89 = c89 plus GCC extensions
106
#     c99   = ISO C99 standard (not yet fully implemented)
107
#     gnu99 = c99 plus GCC extensions
108
CSTANDARD = -std=gnu99
109

  
110

  
111
# Place -D or -U options here
112
CDEFS += -DF_CPU=$(F_CPU)UL 
113
CDEFS += -DFFP
114

  
115

  
116
# Place -I options here
117
CINCS = -I../lib -I../../../lib/include/libdragonfly -L../lib -L../../../lib/bin
118

  
119

  
120

  
121
#---------------- Compiler Options ----------------
122
#  -g*:          generate debugging information
123
#  -O*:          optimization level
124
#  -f...:        tuning, see GCC manual and avr-libc documentation
125
#  -Wall...:     warning level
126
#  -Wa,...:      tell GCC to pass this to the assembler.
127
#    -adhlns...: create assembler listing
128
CFLAGS = -g$(DEBUG)
129
CFLAGS += $(CDEFS) $(CINCS)
130
CFLAGS += -O$(OPT)
131
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
132
CFLAGS += -Wall -Wstrict-prototypes
133
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
134
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
135
CFLAGS += $(CSTANDARD)
136
CFLAGS += -DROBOT
137

  
138

  
139
#---------------- Assembler Options ----------------
140
#  -Wa,...:   tell GCC to pass this to the assembler.
141
#  -ahlms:    create listing
142
#  -gstabs:   have the assembler create line number information; note that
143
#             for use in COFF files, additional information about filenames
144
#             and function names needs to be present in the assembler source
145
#             files -- see avr-libc docs [FIXME: not yet described there]
146
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
147

  
148

  
149
#---------------- Library Options ----------------
150
# Minimalistic printf version
151
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
152

  
153
# Floating point printf version (requires MATH_LIB = -lm below)
154
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
155

  
156
# If this is left blank, then it will use the Standard printf version.
157
PRINTF_LIB = 
158
#PRINTF_LIB = $(PRINTF_LIB_MIN)
159
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
160

  
161

  
162
# Minimalistic scanf version
163
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
164

  
165
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
166
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
167

  
168
# If this is left blank, then it will use the Standard scanf version.
169
SCANF_LIB = 
170
#SCANF_LIB = $(SCANF_LIB_MIN)
171
#SCANF_LIB = $(SCANF_LIB_FLOAT)
172

  
173

  
174
MATH_LIB = -lm
175

  
176

  
177

  
178
#---------------- External Memory Options ----------------
179

  
180
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
181
# used for variables (.data/.bss) and heap (malloc()).
182
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
183

  
184
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
185
# only used for heap (malloc()).
186
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
187

  
188
EXTMEMOPTS =
189

  
190

  
191

  
192
#---------------- Linker Options ----------------
193
#  -Wl,...:     tell GCC to pass this to linker.
194
#    -Map:      create map file
195
#    --cref:    add cross reference to  map file
196
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
197
LDFLAGS += $(EXTMEMOPTS)
198
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
199
LDFLAGS += -lwireless -ldragonfly
200

  
201

  
202

  
203
#---------------- Programming Options (avrdude) ----------------
204

  
205
# Programming hardware: alf avr910 avrisp bascom bsd 
206
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
207
#
208
# Type: avrdude -c ?
209
# to get a full listing.
210
#
211
AVRDUDE_PROGRAMMER = avrisp
212

  
213
# com1 = serial port. Use lpt1 to connect to parallel port.
214
AVRDUDE_PORT = /dev/ttyUSB1
215
# programmer connected to serial device
216

  
217
AVRDUDE_WRITE_FLASH = -b 57600 -U flash:w:$(TARGET).hex
218
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
219

  
220

  
221
# Uncomment the following if you want avrdude's erase cycle counter.
222
# Note that this counter needs to be initialized first using -Yn,
223
# see avrdude manual.
224
#AVRDUDE_ERASE_COUNTER = -y
225

  
226
# Uncomment the following if you do /not/ wish a verification to be
227
# performed after programming the device.
228
#AVRDUDE_NO_VERIFY = -V
229

  
230
# Increase verbosity level.  Please use this when submitting bug
231
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
232
# to submit bug reports.
233
#AVRDUDE_VERBOSE = -v -v
234

  
235
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
236
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
237
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
238
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
239

  
240
#don't check for device signature
241
AVRDUDE_FLAGS += -F
242
AVRDUDE_FLAGS += -D
243

  
244

  
245

  
246
#---------------- Debugging Options ----------------
247

  
248
# For simulavr only - target MCU frequency.
249
DEBUG_MFREQ = $(F_CPU)
250

  
251
# Set the DEBUG_UI to either gdb or insight.
252
# DEBUG_UI = gdb
253
DEBUG_UI = insight
254

  
255
# Set the debugging back-end to either avarice, simulavr.
256
DEBUG_BACKEND = avarice
257
#DEBUG_BACKEND = simulavr
258

  
259
# GDB Init Filename.
260
GDBINIT_FILE = __avr_gdbinit
261

  
262
# When using avarice settings for the JTAG
263
JTAG_DEV = /dev/com1
264

  
265
# Debugging port used to communicate between GDB / avarice / simulavr.
266
DEBUG_PORT = 4242
267

  
268
# Debugging host used to communicate between GDB / avarice / simulavr, normally
269
#     just set to localhost unless doing some sort of crazy debugging when 
270
#     avarice is running on a different computer.
271
DEBUG_HOST = localhost
272

  
273

  
274

  
275
#============================================================================
276

  
277

  
278
# Define programs and commands.
279
SHELL = sh
280
CC = avr-gcc
281
OBJCOPY = avr-objcopy
282
OBJDUMP = avr-objdump
283
SIZE = avr-size
284
NM = avr-nm
285
AVRDUDE = avrdude
286
REMOVE = rm -f
287
REMOVEDIR = rm -rf
288
COPY = cp
289
WINSHELL = cmd
290

  
291

  
292
# Define Messages
293
# English
294
MSG_ERRORS_NONE = Errors: none
295
MSG_BEGIN = -------- begin --------
296
MSG_END = --------  end  --------
297
MSG_SIZE_BEFORE = Size before: 
298
MSG_SIZE_AFTER = Size after:
299
MSG_COFF = Converting to AVR COFF:
300
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
301
MSG_FLASH = Creating load file for Flash:
302
MSG_EEPROM = Creating load file for EEPROM:
303
MSG_EXTENDED_LISTING = Creating Extended Listing:
304
MSG_SYMBOL_TABLE = Creating Symbol Table:
305
MSG_LINKING = Linking:
306
MSG_COMPILING = Compiling:
307
MSG_ASSEMBLING = Assembling:
308
MSG_CLEANING = Cleaning project:
309

  
310

  
311

  
312

  
313
# Define all object files.
314
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) 
315

  
316
# Define all listing files.
317
LST = $(SRC:.c=.lst) $(ASRC:.S=.lst) 
318

  
319

  
320
# Compiler flags to generate dependency files.
321
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
322

  
323

  
324
# Combine all necessary flags and optional flags.
325
# Add target processor to flags.
326
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
327
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
328

  
329

  
330

  
331

  
332

  
333
# Default target.
334
all: begin gccversion sizebefore build sizeafter end
335

  
336
build: elf hex eep lss sym
337

  
338
elf: $(TARGET).elf
339
hex: $(TARGET).hex
340
eep: $(TARGET).eep
341
lss: $(TARGET).lss 
342
sym: $(TARGET).sym
343

  
344

  
345

  
346
# Eye candy.
347
# AVR Studio 3.x does not check make's exit code but relies on
348
# the following magic strings to be generated by the compile job.
349
begin:
350
	@echo
351
	@echo $(MSG_BEGIN)
352

  
353
end:
354
	@echo $(MSG_END)
355
	@echo
356

  
357

  
358
# Display size of file.
359
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
360
ELFSIZE = $(SIZE) -A $(TARGET).elf
361
AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
362

  
363
sizebefore:
364
	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
365
	$(AVRMEM) 2>/dev/null; echo; fi
366

  
367
sizeafter:
368
	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
369
	$(AVRMEM) 2>/dev/null; echo; fi
370

  
371

  
372

  
373
# Display compiler version information.
374
gccversion : 
375
	@$(CC) --version
376

  
377

  
378

  
379
# Program the device.  
380
program: $(TARGET).hex $(TARGET).eep
381
	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
382

  
383

  
384
# Generate avr-gdb config/init file which does the following:
385
#     define the reset signal, load the target file, connect to target, and set 
386
#     a breakpoint at main().
387
gdb-config: 
388
	@$(REMOVE) $(GDBINIT_FILE)
389
	@echo define reset >> $(GDBINIT_FILE)
390
	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
391
	@echo end >> $(GDBINIT_FILE)
392
	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
393
	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
394
ifeq ($(DEBUG_BACKEND),simulavr)
395
	@echo load  >> $(GDBINIT_FILE)
396
endif	
397
	@echo break main >> $(GDBINIT_FILE)
398
	
399
debug: gdb-config $(TARGET).elf
400
ifeq ($(DEBUG_BACKEND), avarice)
401
	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
402
	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
403
	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
404
	@$(WINSHELL) /c pause
405
	
406
else
407
	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
408
	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
409
endif
410
	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
411
	
412

  
413

  
414

  
415
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
416
COFFCONVERT=$(OBJCOPY) --debugging \
417
--change-section-address .data-0x800000 \
418
--change-section-address .bss-0x800000 \
419
--change-section-address .noinit-0x800000 \
420
--change-section-address .eeprom-0x810000 
421

  
422

  
423
coff: $(TARGET).elf
424
	@echo
425
	@echo $(MSG_COFF) $(TARGET).cof
426
	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
427

  
428

  
429
extcoff: $(TARGET).elf
430
	@echo
431
	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
432
	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
433

  
434

  
435

  
436
# Create final output files (.hex, .eep) from ELF output file.
437
%.hex: %.elf
438
	@echo
439
	@echo $(MSG_FLASH) $@
440
	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
441

  
442
%.eep: %.elf
443
	@echo
444
	@echo $(MSG_EEPROM) $@
445
	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
446
	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
447

  
448
# Create extended listing file from ELF output file.
449
%.lss: %.elf
450
	@echo
451
	@echo $(MSG_EXTENDED_LISTING) $@
452
	$(OBJDUMP) -h -S $< > $@
453

  
454
# Create a symbol table from ELF output file.
455
%.sym: %.elf
456
	@echo
457
	@echo $(MSG_SYMBOL_TABLE) $@
458
	$(NM) -n $< > $@
459

  
460

  
461

  
462
# Link: create ELF output file from object files.
463
.SECONDARY : $(TARGET).elf
464
.PRECIOUS : $(OBJ)
465
%.elf: $(OBJ)
466
	@echo
467
	@echo $(MSG_LINKING) $@
468
	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
469

  
470

  
471
# Compile: create object files from C source files.
472
%.o : %.c
473
	@echo
474
	@echo $(MSG_COMPILING) $<
475
	$(CC) -c $(ALL_CFLAGS) $< -o $@ 
476

  
477

  
478
# Compile: create assembler files from C source files.
479
%.s : %.c
480
	$(CC) -S $(ALL_CFLAGS) $< -o $@
481

  
482

  
483
# Assemble: create object files from assembler source files.
484
%.o : %.S
485
	@echo
486
	@echo $(MSG_ASSEMBLING) $<
487
	$(CC) -c $(ALL_ASFLAGS) $< -o $@
488

  
489
# Create preprocessed source for use in sending a bug report.
490
%.i : %.c
491
	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ 
492

  
493

  
494
# Target: clean project.
495
clean: begin clean_list end
496

  
497
clean_list :
498
	@echo
499
	@echo $(MSG_CLEANING)
500
	$(REMOVE) $(TARGET).hex
501
	$(REMOVE) $(TARGET).eep
502
	$(REMOVE) $(TARGET).cof
503
	$(REMOVE) $(TARGET).elf
504
	$(REMOVE) $(TARGET).map
505
	$(REMOVE) $(TARGET).sym
506
	$(REMOVE) $(TARGET).lss
507
	$(REMOVE) $(OBJ)
508
	$(REMOVE) $(LST)
509
	$(REMOVE) $(SRC:.c=.s)
510
	$(REMOVE) $(SRC:.c=.d)
511
	$(REMOVEDIR) .dep
512

  
513

  
514

  
515
# Include the dependency files.
516
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
517

  
518

  
519
# Listing of phony targets.
520
.PHONY : all begin finish end sizebefore sizeafter gccversion \
521
build elf hex eep lss sym coff extcoff \
522
clean clean_list program debug gdb-config
523

  
branches/slam/code/projects/libwireless/robotTest/main.c
1
#include <dragonfly_lib.h>
2
#include <wireless.h>
3
#include <wl_token_ring.h>
4

  
5
int main(void)
6
{
7
	dragonfly_init(ALL_ON);
8
	usb_puts("Start.\r\n");
9
	wl_init();
10
	usb_puts("Wireless initialized.\n");
11
	wl_token_ring_register();
12
	wl_token_ring_join();
13
	while (1)
14
		wl_do();
15
}
branches/slam/code/projects/libwireless/lib/wireless.c
1
#include "wireless.h"
2
#include "xbee.h"
3
#include <stdlib.h>
4
#include <stdio.h>
5

  
6
#include "wl_defs.h"
7

  
8
#ifndef ROBOT
9
#include <sys/time.h>
10
#include <signal.h>
11
#else
12
#include <time.h>
13
#ifndef FIREFLY
14
#include <bom.h>
15
#endif
16
#endif
17

  
18
/*Function Prototypes*/
19

  
20
void wl_do_timeout(void);
21

  
22
//Note: the actual frame sent has group as the first four bits and
23
//frame as the last four.
24
void wl_send_packet(char group, char type, char* data, int len,
25
					int dest, char options, char frame);
26

  
27
/*Data Members*/
28

  
29
//used to store incoming and outgoing packets
30
unsigned char wl_buf[128];
31
//1 if we have timed out since we last checked, 0 otherwise.
32
int wl_timeout = 0;
33

  
34
PacketGroupHandler* wl_packet_groups[WL_MAX_PACKET_GROUPS];
35

  
36
#ifndef ROBOT
37
#ifdef _POSIX_TIMERS
38
timer_t wl_timeout_timer;
39
#endif
40
//called when we time out, or receive interrupt
41
void sig_handler(int signo)
42
{
43
	switch (signo)
44
	{
45
		case SIGALRM:
46
			wl_timeout = 1;
47
			break;
48
		case SIGINT:
49
			wl_terminate();
50
			exit(1);
51
			break;
52
	}
53
	return;
54
}
55
#else 
56
//Alternate non posix code here.
57

  
58
#endif
59

  
60
/**
61
 * Initializes the wireless library. Must be called before any
62
 * other function.
63
 **/
64
void wl_init()
65
{
66
	int i;
67
	for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
68
		wl_packet_groups[i] = NULL;
69

  
70
	xbee_lib_init();
71
	
72
	//begin timeout timer
73
	#ifdef ROBOT
74
	#ifdef FIREFLY
75
	rtc_init(PRESCALE_DIV_128, 32, &wl_do_timeout);
76
	#else
77
	rtc_init(HALF_SECOND, &wl_do_timeout); 
78
	#endif
79
	#else
80
	
81
  #ifdef _POSIX_TIMERS 
82
  
83
  //create a timer to trigger every half second
84
	struct sigevent evp;
85
	evp.sigev_signo = SIGALRM;
86
	evp.sigev_notify = SIGEV_SIGNAL;
87
	if (timer_create(CLOCK_REALTIME, &evp, &wl_timeout_timer) == -1)
88
	{ 
89
		WL_DEBUG_PRINT("Error creating a timer.\r\n"); 
90
		exit(1); 
91
	}
92
	
93
  struct itimerspec wl_timeout_time;
94
	wl_timeout_time.it_interval.tv_sec = 0;
95
	wl_timeout_time.it_interval.tv_nsec = 500000000;
96
	wl_timeout_time.it_value.tv_sec = 0;
97
	wl_timeout_time.it_value.tv_nsec = 500000000;
98
	timer_settime(wl_timeout_timer, 0,
99
                        &wl_timeout_time, NULL);
100
  #else
101
  
102
  printf("Creating a non posix timer.\n"); 
103
  struct itimerval timer_val;
104
  struct timeval interval;
105
  interval.tv_sec = 0;
106
  interval.tv_usec = 500000;
107
  struct timeval first_time;
108
  first_time.tv_sec = 0;
109
  first_time.tv_usec = 500000;
110
  timer_val.it_interval = interval;
111
  timer_val.it_value = first_time;
112
  if(setitimer(ITIMER_REAL,&timer_val,NULL)==-1)
113
  {
114
		WL_DEBUG_PRINT("Error creating a timer.\r\n"); 
115
    perror("Failure's cause");
116
		exit(1); 
117
  }
118
  
119
  #endif
120

  
121
	struct sigaction wl_sig_act;
122
	wl_sig_act.sa_handler = (void *)sig_handler;
123
	wl_sig_act.sa_flags = 0;
124
	sigemptyset(&wl_sig_act.sa_mask);
125
	sigaction(SIGALRM, &wl_sig_act, 0);
126
	sigaction(SIGINT, &wl_sig_act, 0);
127
	#endif
128
}
129

  
130
/**
131
 * Uninitializes the wireless library.
132
 **/
133
void wl_terminate()
134
{
135
	#ifndef ROBOT
136
  #ifdef _POSIX_TIMERS	
137
  timer_delete(wl_timeout_timer);
138
  #endif
139
	#endif
140
	
141
	int i;
142
	for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
143
		if (wl_packet_groups[i] != NULL &&
144
			wl_packet_groups[i]->unregister != NULL)
145
			wl_packet_groups[i]->unregister();
146
	
147
	xbee_terminate();
148
}
149

  
150
/**
151
 * Set the PAN for the XBee to join.
152
 *
153
 * @param pan the new PAN
154
 *
155
 * @see wl_get_pan
156
 **/
157
void wl_set_pan(int pan)
158
{
159
	xbee_set_pan_id(pan);
160
}
161

  
162
/**
163
 * Get the PAN the XBee is currently part of.
164
 *
165
 * @return the PAN of the XBee
166
 *
167
 * @see wl_set_pan
168
 **/
169
int wl_get_pan(void)
170
{
171
	return xbee_get_pan_id();
172
}
173

  
174
/**
175
 * Set the channel the XBee is listening to.
176
 *
177
 * @param channel the new channel to join
178
 *
179
 * @see wl_get_channel
180
 **/
181
void wl_set_channel(int channel)
182
{
183
	xbee_set_channel(channel);
184
}
185

  
186
/**
187
 * Get the channel the XBee is part of.
188
 *
189
 * @return the channel the XBee is part of
190
 *
191
 * @see wl_set_channel
192
 **/
193
int wl_get_channel(void)
194
{
195
	return xbee_get_channel();
196
}
197

  
198
/**
199
 * Returns the 16-bit address of the XBee module.
200
 *
201
 * @return the 16-bit address of the XBee module.
202
 **/
203
unsigned int wl_get_xbee_id()
204
{
205
	return xbee_get_address();
206
}
207

  
208
/**
209
 * Send a packet to a specific XBee without specifying a PAN.
210
 *
211
 * @param group the packet group
212
 * @param type the packet type
213
 * @param data the packet data
214
 * @param len the packet length in bytes
215
 * @param dest the 16-bit address of the XBee to send the packet to
216
 * @param frame the frame number to see with a TX_STATUS response
217
 **/
218
void wl_send_robot_to_robot_global_packet(char group, char type,
219
		char* data, int len, int dest, char frame)
220
{
221
	wl_send_packet(group, type, data, len, dest,
222
			XBEE_OPTIONS_BROADCAST_ALL_PANS, frame);
223
}
224

  
225
/**
226
 * Send a packet to a specific XBee in the same PAN.
227
 *
228
 * @param group the packet group
229
 * @param type the packet type
230
 * @param data the packet data
231
 * @param len the packet length in bytes
232
 * @param dest the 16-bit address of the XBee to send the packet to
233
 * @param frame the frame number to see with a TX_STATUS response
234
 **/
235
void wl_send_robot_to_robot_packet(char group, char type,
236
		char* data, int len, int dest, char frame)
237
{
238
	wl_send_packet(group, type, data, len, dest, XBEE_OPTIONS_NONE,
239
			frame);
240
}
241

  
242
/**
243
 * Send a packet to all XBees in all PANs.
244
 *
245
 * @param group the packet group
246
 * @param type the packet type
247
 * @param data the packet data
248
 * @param len the packet length in bytes
249
 * @param frame the frame number to see with a TX_STATUS response
250
 **/
251
void wl_send_global_packet(char group, char type,
252
		char* data, int len, char frame)
253
{
254
	wl_send_packet(group, type, data, len, XBEE_BROADCAST,
255
			XBEE_OPTIONS_BROADCAST_ALL_PANS, frame);
256
}
257

  
258
/**
259
 * Send a packet to all XBee's in the same PAN.
260
 *
261
 * @param group the packet group
262
 * @param type the packet type
263
 * @param data the packet data
264
 * @param len the packet length in bytes
265
 * @param frame the frame number to see with a TX_STATUS response
266
 **/
267
void wl_send_pan_packet(char group, char type,
268
		char* data, int len, char frame)
269
{
270
	wl_send_packet(group, type, data, len, XBEE_BROADCAST, 
271
			XBEE_OPTIONS_NONE, frame);
272
}
273

  
274
/**
275
 * Send a packet.
276
 *
277
 * @param group the packet group
278
 * @param type the packet type
279
 * @param data the packet data
280
 * @param len the packet length in bytes
281
 * @param dest the destination of the packet
282
 * @param options the options for sending the packet
283
 * @param frame the frame number to see with a TX_STATUS response
284
 **/
285
void wl_send_packet(char group, char type, char* data, int len,
286
					int dest, char options, char frame)
287
{
288
	char buf[128];
289
	int i;
290
	if (frame != 0)
291
		frame = (frame & 0x0F) | ((group & 0x0F) << 4);
292
	buf[0] = group;
293
	buf[1] = type;
294
	for (i = 0; i < len; i++)
295
		buf[2 + i] = data[i];
296
	xbee_send_packet(buf, len + 2, dest, options, frame);
297
}
298

  
299
/**
300
 * Register a packet group with the wireless library. The event
301
 * handlers in the packet group will be called whenever an
302
 * event dealing with the packet group's group code occurs.
303
 *
304
 * @param h the PacketGroupHandler to register
305
 **/
306
void wl_register_packet_group(PacketGroupHandler* h)
307
{
308
	if (h->groupCode >= WL_MAX_PACKET_GROUPS)
309
	{
310
		WL_DEBUG_PRINT("Packet group code too large.\r\n");
311
		return;
312
	}
313
	if (wl_packet_groups[h->groupCode] != NULL)
314
	{
315
		WL_DEBUG_PRINT("Packet group code already registered.\r\n");
316
		return;
317
	}
318
	wl_packet_groups[h->groupCode] = h;
319
}
320

  
321
/**
322
 * Unregister a packet group from the wireless library.
323
 * 
324
 * @param h the packet group to remove
325
 **/
326
void wl_unregister_packet_group(PacketGroupHandler* h)
327
{
328
	unsigned int groupCode = h->groupCode;
329
	PacketGroupHandler* p = wl_packet_groups[groupCode];
330
	if (p != NULL && p->unregister != NULL)
331
		p->unregister();
332
	wl_packet_groups[groupCode] = NULL;
333
}
334

  
335
/**
336
 * Called when the timer is triggered. This calls the timeout
337
 * handlers of all the registered packet groups.
338
 **/
339
void wl_do_timeout()
340
{
341
	int i;
342
	for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
343
		if (wl_packet_groups[i] != NULL &&
344
			wl_packet_groups[i]->timeout_handler != NULL)
345
			wl_packet_groups[i]->timeout_handler();
346
}
347

  
348
/**
349
 * Performs wireless library functionality. This function must
350
 * be called frequently for wireless to perform effectively.
351
 * This function will call timeout handlers, as well as
352
 * received packet and transmit status handlers.
353
 **/
354
void wl_do()
355
{
356
	if (wl_timeout)
357
	{
358
		wl_do_timeout();
359
		wl_timeout = 0;
360
	}
361
	
362
	int len = xbee_get_packet(wl_buf);
363
	if (len < 0)//no packet received
364
		return;
365
	
366
	if (wl_buf[0] == XBEE_TX_STATUS)
367
	{
368
		if (len != 3)
369
		{
370
			WL_DEBUG_PRINT("Transmit Status packet should be of length 3.\r\n");
371
			return;
372
		}
373
		
374
		//the first four bits are the packet group
375
		//this only works with under 16 groups
376
		int group = (int)(wl_buf[1] >> 4);
377
		int success = 0;
378
		if (wl_buf[2] == 0)
379
			success = 1;
380
		else
381
		{
382
			WL_DEBUG_PRINT("No response received.\r\n");
383
			if (wl_buf[2] == 2)
384
				WL_DEBUG_PRINT("CCA Failure\r\n");
385
			if (wl_buf[2] == 3)
386
				WL_DEBUG_PRINT("Purged\r\n");
387
		}
388
		
389
		if (wl_packet_groups[group] != NULL &&
390
					wl_packet_groups[group]->handle_response != NULL)
391
			wl_packet_groups[group]->handle_response(
392
					(int)wl_buf[1] & 0x0F, success);
393
		return;
394
	}
395
	
396
	if (wl_buf[0] == XBEE_RX)
397
	{
398
		if (len < 7)
399
		{
400
			WL_DEBUG_PRINT("Packet is too small.\r\n");
401
			return;
402
		}
403
		
404
		int source = ((int)wl_buf[1] << 8) + ((int)wl_buf[2]);
405
		
406
		/*
407
		//unused for now
408
		int signalStrength = wl_buf[3];
409
		//1 for Address broadcast, 2 for PAN broadcast
410
		int options = wl_buf[4];
411
		*/
412
		
413
		int group = wl_buf[5];
414
		int type = wl_buf[6];
415
		int packetLen = len - 7;
416
		
417
		if (wl_packet_groups[group] != NULL
418
				&& wl_packet_groups[group]->handle_receive != NULL)
419
			wl_packet_groups[group]->handle_receive(type, source, 
420
				wl_buf + 7, packetLen);
421
		return;
422
	}
423
	
424
	WL_DEBUG_PRINT("Unexpected packet received from XBee.\r\n");
425
	return;
426
}
427

  
branches/slam/code/projects/libwireless/lib/sensor_matrix.c
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <wl_defs.h>
4

  
5
#include "sensor_matrix.h"
6

  
7
#define DEFAULT_SENSOR_MATRIX_SIZE 20
8

  
9
/*Sensor Matrix Functions*/
10
void sensor_matrix_expand(SensorMatrix* m, int nextSize);
11

  
12
/**
13
 * Initializes the sensor matrix.
14
 *
15
 * @return the newly created sensor matrix
16
 **/
17
SensorMatrix* sensor_matrix_create()
18
{
19
	SensorMatrix* m;
20
	int i;
21
	
22
	m = malloc(sizeof(SensorMatrix));
23
	if (!m)
24
	{
25
		WL_DEBUG_PRINT("Out of memory - create sensor matrix.\r\n");
26
		return NULL;
27
	}
28
	m->size = DEFAULT_SENSOR_MATRIX_SIZE;
29
	m->matrix = malloc(m->size * sizeof(int*));
30
	m->joined = malloc(m->size * sizeof(int));
31
	m->numJoined = 0;
32
	if (!(m->matrix) || !(m->joined))
33
	{
34
		WL_DEBUG_PRINT("Out of memory - create sensor matrix 2.\r\n");
35
		return NULL;
36
	}
37
	
38
	for (i = 0; i < m->size; i++)
39
	{
40
		m->matrix[i] = NULL;
41
		m->joined[i] = 0;
42
	}
43
	return m;
44
}
45

  
46
/**
47
 * Deletes and frees memory from the sensor matrix.
48
 *
49
 * @param m the sensor matrix to delete
50
 **/
51
void sensor_matrix_destroy(SensorMatrix* m)
52
{
53
	int i;
54
	for (i = 0; i < m->size; i++)
55
		if (m->matrix[i] != NULL)
56
			free(m->matrix[i]);
57
	free(m->matrix);
58
	free(m->joined);
59
	free(m);
60
}
61

  
62
/**
63
 * Adds robot with XBee id id to the sensor matrix.
64
 * 
65
 * @param m the sensor matrix
66
 * @param id the XBee ID of the robot to add
67
 **/
68
void sensor_matrix_add_robot(SensorMatrix* m, unsigned int id)
69
{
70
	int i;
71
	if (id >= m->size)
72
		sensor_matrix_expand(m, id + 1);
73
	if (m->matrix[id] != NULL)
74
		return;
75
	
76
	m->matrix[id] = malloc(m->size * sizeof(int));
77
	if (!(m->matrix[id]))
78
	{
79
		WL_DEBUG_PRINT("Out of memory - add robot.\r\n");
80
		return;
81
	}
82

  
83
	for (i = 0; i < m->size; i++)
84
		if (m->matrix[i] != NULL)
85
			m->matrix[i][id] = -1;
86
}
87

  
88
/**
89
 * Removes robot with id from the sensor matrix, and removes
90
 * all sensor information regarding the robot.
91
 *
92
 * @param m the sensor matrix
93
 * @param id the XBee ID of the robot to remove
94
 **/
95
void sensor_matrix_remove_robot(SensorMatrix* m, unsigned int id)
96
{
97
	int i;
98

  
99
	if (id >= m->size || m->matrix[id] == NULL)
100
	{
101
		WL_DEBUG_PRINT("Removing robot not added to matrix.\r\n");
102
		return;
103
	}
104
	
105
	free(m->matrix[id]);
106
	m->matrix[id] = NULL;
107
	
108
	for (i = 0 ; i < m->size; i++)
109
		if (m->matrix[i] != NULL)
110
			m->matrix[i][id] = -1;
111
	
112
	m->joined[id] = 0;
113
}
114

  
115
/**
116
 * Expands the size of the sensor matrix if an id number we attempt
117
 * to add is too large.
118
 *
119
 * @param m the sensor matrix to expand
120
 * @param size the new size of the sensor matrix
121
 **/
122
//Note: this has probably not been tested, hopefully it works
123
void sensor_matrix_expand(SensorMatrix* m, int nextSize)
124
{
125
	int i, j;
126
	WL_DEBUG_PRINT("Expanding sensor matrix.\r\n");
127
	
128
	int** tempMatrix = malloc(nextSize * sizeof(int*));
129
	if (!tempMatrix)
130
	{
131
		WL_DEBUG_PRINT("Out of memory - expand matrix.\r\n");
132
		return;
133
	}
134
	
135
	for (i = 0; i < nextSize; i++)
136
		tempMatrix[i] = NULL;
137
	
138
	//copy over old sensor data
139
	for (i = 0; i < m->size; i++)
140
		if (m->matrix[i] != NULL)
141
		{
142
			tempMatrix[i] = malloc(nextSize * sizeof(int));
143
			if (!tempMatrix[i])
144
			{
145
				WL_DEBUG_PRINT("Out of memory - expand matrix 2.\r\n");
146
				return;
147
			}
148
			for (j = 0; j < m->size; j++)
149
				tempMatrix[i][j] = m->matrix[i][j];
150
			for (j = m->size; j < nextSize; j++)
151
				tempMatrix[i][j] = -1;
152
			
153
			free(m->matrix[i]);
154
		}
155
	
156
	free(m->matrix);
157
	m->matrix = tempMatrix;
158
	m->size = nextSize;
159

  
160
	//expand the size of joined
161
	int* tempJoined = malloc(nextSize * sizeof(int));
162
	if (!tempJoined)
163
	{
164
		WL_DEBUG_PRINT("Out of memory - expand matrix 3.\r\n");
165
		return;
166
	}
167
	
168
	for (i = 0; i < m->size; i++)
169
		tempJoined[i] = m->joined[i];
170
	for (i = m->size; i < nextSize; i++)
171
		tempJoined[i] = 0;
172
	
173
	free(m->joined);
174
	m->joined = tempJoined;
175
}
176

  
177
/**
178
 * Sets the sensor reading for robot robot to reading.
179
 * 
180
 * @param m the sensor matrix to set the reading for
181
 * @param observer the id of the robot who made the reading
182
 * @param robot the id of the robot who the reading is for
183
 * @param reading the BOM reading from observer to robot
184
 */
185
void sensor_matrix_set_reading(SensorMatrix* m, int observer, int robot, int reading)
186
{
187
	if (robot >= m->size || observer >= m->size || m->matrix[observer] == NULL)
188
		sensor_matrix_add_robot(m, observer);
189
	m->matrix[observer][robot] = reading;
190
}
191

  
192
/**
193
 * Gets the sensor reading for a robot to another robot.
194
 *
195
 * @param m the sensor matrix
196
 * @param observer the robot whose reading we check
197
 * @param robot the robot who we are checking the reading to
198
 *
199
 * @return the observer's BOM reading for robot
200
 **/
201
int sensor_matrix_get_reading(SensorMatrix* m, int observer, int robot)
202
{
203
	if (observer >= m->size || robot >= m->size)
204
		return -1;
205
	return m->matrix[observer][robot];
206
}
207

  
208
/**
209
 * Sets whether or not the given robot is part of the token ring.
210
 *
211
 * @param m the sensor matrix
212
 * @param robot the robot to set as a member / nonmember of the token ring
213
 * @param in 1 if the robot is in the token ring, 0 otherwise
214
 **/
215
void sensor_matrix_set_in_ring(SensorMatrix* m, int robot, int in)
216
{
217
	if (robot >= m->size)
218
		sensor_matrix_expand(m, robot + 1);
219
	if (in == 1)
220
		sensor_matrix_add_robot(m, robot);
221
	if (in == 1 && m->joined[robot] == 0)
222
		m->numJoined++;
223
	if (in == 0 && m->joined[robot] == 1)
224
		m->numJoined--;
225
	m->joined[robot] = in;
226
}
227

  
228
/**
229
 * Checks if the given robot is in the token ring.
230
 * 
231
 * @param m the sensor matrix
232
 * @param robot the ID of the robot to check
233
 *
234
 * @return 1 if the robot is in the token ring, 0 otherwise
235
 **/
236
int sensor_matrix_get_in_ring(SensorMatrix* m, int robot)
237
{
238
	if (robot >= m->size)
239
		return -1;
240
	return m->joined[robot];
241
}
242

  
243
/**
244
 * Returns the size of the sensor matrix.
245
 *
246
 * @param m the sensor matrix
247
 * 
248
 * @return the size of the sensor matrix
249
 **/
250
int sensor_matrix_get_size(SensorMatrix* m)
251
{
252
	return m->size;
253
}
254

  
255
/**
256
 * Returns the number of robots which have joined the
257
 * token ring.
258
 *
259
 * @param m the sensor matrix
260
 *
261
 * @return the number of robots in the token ring
262
 **/
263
int sensor_matrix_get_joined(SensorMatrix* m)
264
{
265
	return m->numJoined;
266
}
267

  
branches/slam/code/projects/libwireless/lib/wl_token_ring.c
1
#include <wl_token_ring.h>
2

  
3
#include <stdlib.h>
4
#include <stdio.h>
5

  
6
#include <wl_defs.h>
7
#include <wireless.h>
8
#include <sensor_matrix.h>
9
#include <queue.h>
10

  
11
#ifdef ROBOT
12
#ifndef FIREFLY
13
#include <bom.h>
14
#endif
15
#include <time.h>
16
#endif
17

  
18
#define DEFAULT_SENSOR_MATRIX_SIZE 20
19

  
20
/*Ring States*/
21

  
22
#define NONMEMBER 0
23
#define MEMBER 1
24
#define JOINING 2
25
#define ACCEPTED 3
26
#define LEAVING 4
27

  
28
/*Frame Types*/
29
#define TOKEN_JOIN_ACCEPT_FRAME 1
30

  
31
/*Function Prototypes*/
32

  
33
/*Wireless Library Prototypes*/
34
void wl_token_ring_timeout_handler(void);
35
void wl_token_ring_response_handler(int frame, int received);
36
void wl_token_ring_receive_handler(char type, int source, unsigned char* packet,
37
							int length);
38
void wl_token_ring_cleanup(void);
39

  
40
/*Helper Functions*/
41
void wl_token_pass_token(void);
42
int get_token_distance(int robot1, int robot2);
43
void wl_token_get_token(void);
44

  
45
/*Packet Handling Routines*/
46
void wl_token_pass_receive(int source, char nextRobot, unsigned char* sensorData, int sensorDataLength);
47
void wl_token_interrupt_request_receive(int source, int robot);
48
void wl_token_interrupt_pass_receive(int source, int robot);
49
void wl_token_bom_on_receive(int source);
50
void wl_token_join_receive(int source);
51
void wl_token_join_accept_receive(int source);
52

  
53
/*Global Variables*/
54

  
55
//the sensor matrix
56
SensorMatrix* sensorMatrix;
57

  
58
//the robot we are waiting to say it has received the token. -1 if unspecified
59
int wl_token_next_robot = -1;
60

  
61
//true if the robot should be in the token ring, 0 otherwise
62
int ringState = NONMEMBER;
63
//the id of the robot who accepted us into the token ring, only used in ACCEPTED state
64
int acceptor = -1;
65
//id of the robot we are accepting
66
int accepted = -1;
67

  
68
//the counter for when we assume a robot is dead
69
int deathDelay = -1;
70
//the counter for joining, before we form our own token ring
71
int joinDelay = -1;
72
//queue containing ids of interruption requests
73
Queue* interrupting = NULL;
74

  
75
//current robot to check in the iterator
76
int iteratorCount = 0;
77

  
78
void do_nothing(void) {}
79
int get_nothing(void) {return -1;}
80

  
81
#ifdef ROBOT
82
#ifndef FIREFLY
83
void (*bom_on_function) (void) = bom_on;
84
void (*bom_off_function) (void) = bom_off;
85
int (*get_max_bom_function) (void) = get_max_bom;
86
#else
87
void (*bom_on_function) (void) = do_nothing;
88
void (*bom_off_function) (void) = do_nothing;
89
int (*get_max_bom_function) (void) = get_nothing;
90
#endif
91
#else
92
void (*bom_on_function) (void) = do_nothing;
93
void (*bom_off_function) (void) = do_nothing;
94
int (*get_max_bom_function) (void) = get_nothing;
95
#endif
96

  
97
PacketGroupHandler wl_token_ring_handler =
98
		{WL_TOKEN_RING_GROUP, wl_token_ring_timeout_handler,
99
		wl_token_ring_response_handler, wl_token_ring_receive_handler,
100
		wl_token_ring_cleanup};
101

  
102
/**
103
 * Initialize the token ring packet group and register it with the
104
 * wireless library. The robot will not join a token ring.
105
 **/
106
void wl_token_ring_register()
107
{
108
	if (wl_get_xbee_id() > 0xFF)
109
	{
110
		//Note: if this becomes an issue (unlikely), we could limit sensor information
111
		//to half a byte and use 12 bits for the id
112
		WL_DEBUG_PRINT("XBee ID must be single byte for token ring, is ");
113
		WL_DEBUG_PRINT_INT(wl_get_xbee_id());
114
		WL_DEBUG_PRINT(".\r\n");
115
		return;
116
	}
117
	
118
	sensorMatrix = sensor_matrix_create();
119
	interrupting = queue_create();
120
	//add ourselves to the sensor matrix
121
	sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 0);
122

  
123
	wl_register_packet_group(&wl_token_ring_handler);
124
}
125

  
126
/**
127
 * Removes the packet group from the wireless library.
128
 **/
129
void wl_token_ring_unregister()
130
{
131
	wl_unregister_packet_group(&wl_token_ring_handler);
132
}
133

  
134
/**
135
 * Sets the functions that are called when the BOM ought to be
136
 * turned on or off. This could be used for things such as 
137
 * charging stations, which have multiple BOMs.
138
 *
139
 * @param on_function the function to be called when the BOM
140
 * should be turned on
141
 * @param off_function the function to be called when the BOM
142
 * should be turned off
143
 * @param max_bom_function the function to be called when a
144
 * measurement of the maximum BOM reading is needed.
145
 **/
146
void wl_token_ring_set_bom_functions(void (*on_function) (void),
147
	void (*off_function) (void), int (*max_bom_function) (void))
148
{
149
	bom_on_function = on_function;
150
	bom_off_function = off_function;
151
	get_max_bom_function = max_bom_function;
152
}
153

  
154
/**
155
 * Called to cleanup the token ring packet group.
156
 **/
157
void wl_token_ring_cleanup()
158
{
159
	sensor_matrix_destroy(sensorMatrix);
160
	queue_destroy(interrupting);
161
}
162

  
163
/**
164
 * Called approximately every quarter second by the wireless library.
165
 **/
166
void wl_token_ring_timeout_handler()
167
{
168
	//someone is not responding, assume they are dead
169
	if (deathDelay == 0)
170
	{
171
		//pass the token to the next robot if we think someone has died
172
		//also, declare that person dead, as long as it isn't us
173
		if (wl_token_next_robot != wl_get_xbee_id())
174
		{
175
			sensor_matrix_set_in_ring(sensorMatrix, wl_token_next_robot, 0);
176
			WL_DEBUG_PRINT("Robot ");
177
			WL_DEBUG_PRINT_INT(wl_token_next_robot);
178
			WL_DEBUG_PRINT(" has died.\r\n");
179
		}
180
		
181
		// we may have been dropped from the ring when this is received
182
		if (ringState == MEMBER)
183
			wl_token_pass_token();
184
	}
185

  
186
	//we must start our own token ring, no one is responding to us
187
	if (joinDelay == 0)
188
	{
189
		if (sensor_matrix_get_joined(sensorMatrix) == 0)
190
		{
191
			WL_DEBUG_PRINT("Creating our own token ring, no robots seem to exist.\r\n");
192
			sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
193
			ringState = MEMBER;
194
			//this will make us pass the token to ourself
195
			//repeatedly, and other robots when they join
196
			deathDelay = DEATH_DELAY;
197
			wl_token_next_robot = wl_get_xbee_id();
198
		}
199
		else
200
		{
201
			WL_DEBUG_PRINT("Attempting to join the token ring again.\r\n");
202
			//attempt to rejoin with a random delay
203
			wl_token_ring_join();
204
			joinDelay = rand() / (RAND_MAX / JOIN_DELAY) + 1;
205
		}
206
	}
207

  
208
	if (deathDelay >= 0)
209
		deathDelay--;
210
	if (joinDelay >= 0)
211
		joinDelay--;
212
}
213

  
214
/**
215
 * Called when the XBee tells us if a packet we sent has been received.
216
 * 
217
 * @param frame the frame number assigned when the packet was sent
218
 * @param received 1 if the packet was received, 0 otherwise
219
 **/
220
void wl_token_ring_response_handler(int frame, int received)
221
{
222
	if (!received)
223
	{
224
		WL_DEBUG_PRINT("FAILED.\r\n");
225
	}
226
}
227

  
228
/**
229
 * Called when we recieve a token ring packet.
230
 * @param type the type of the packet
231
 * @param source the id of the robot who sent the packet
232
 * @param packet the data in the packet
233
 * @param length the length of the packet in bytes
234
 **/
235
void wl_token_ring_receive_handler(char type, int source, unsigned char* packet,
236
							int length)
237
{
238
	switch (type)
239
	{
240
		case WL_TOKEN_PASS:
241
			if (length < 1)
242
			{
243
				WL_DEBUG_PRINT("Malformed Token Pass packet received.\r\n");
244
				return;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff