Project

General

Profile

Revision 1142

Merged new orbs code
Added atomic.h
Fixed whitespace in eeprom.h

View differences:

trunk/code/behaviors/library_test/main.c
1
#include <dragonfly_lib.h>
2
//#include "smart_run_around_fsm.h"
3

  
4
// Martin "deffi" Herrmann Test
5

  
6
static void oset(uint8_t r,uint8_t g,uint8_t b)
7
{
8
	orbs_set(r,g,b,255-r,255-g,255-b);
9
}
10

  
11
static void color_circle (void)
12
{
13
   while(1)
14
   {
15
		for (uint8_t part=0; part<6; ++part)
16
		{
17
			for (uint8_t up=0; up<255; ++up)
18
			{
19
				uint8_t dn=255-up;
20
				uint8_t on=255;
21
				uint8_t of=0;
22
				
23
				if (1)
24
				{
25
					// Maximum brightness mode
26
					switch (part)
27
					{
28
						case 0: oset (on, up, of); break;
29
						case 1: oset (dn, on, of); break;
30
						case 2: oset (of, on, up); break;
31
						case 3: oset (of, dn, on); break;
32
						case 4: oset (up, of, on); break;
33
						case 5: oset (on, of, dn); break;
34
					}
35
				}
36
				else
37
				{
38
					// Constant brightness mode (not very constant though)
39
					switch (part%3)
40
					{
41
						case 0: oset (dn, up, of); break;
42
						case 1: oset (of, dn, up); break;
43
						case 2: oset (up, of, dn); break;
44
					}
45
				}
46
				
47
				delay_ms (2);
48
			}
49
		}
50
	}
51
}
52

  
53
static void acl(void)
54
{
55
	#define redval 255
56
	#define greenval 150
57
	#define interval 1300
58
	#define flash 20
59
	#define pause 200
60

  
61
	#define def do { orb1_set(redval,0,0); orb2_set(0,greenval,0); } while (0)
62
	#define wht do { orb_set(255,255,255); } while (0)
63

  
64
	while (1)
65
	{
66
		wht; delay_ms (flash);
67
		def; delay_ms (pause-flash);
68
		wht; delay_ms (flash);
69
		def; delay_ms (pause-flash);
70
		def; delay_ms (interval-2*pause-2*flash);
71
	}
72
}
73

  
74
int main(void) {
75
//	dragonfly_init(ALL_ON);
76
	dragonfly_init(0);
77

  
78
	usb_init ();
79
	usb_puts ("Startup\r\n");
80

  
81

  
82
	//encoders_init ();
83

  
84
    //analog_init(ADC_START);
85
	//analog_init(0);
86

  
87
    //range_init();
88

  
89
	//DDRF=2;
90

  
91
	//motors_init ();
92
	//motor2_set (FORWARD, 64);
93

  
94
	//orb_init_binary ();
95
	orb_init_pwm ();
96

  
97
	if (false)
98
	{
99
		orbs_set (255, 0, 0, 0, 0, 0); delay_ms (500);
100
		orbs_set (0, 255, 0, 0, 0, 0); delay_ms (500);
101
		orbs_set (0, 0, 255, 0, 0, 0); delay_ms (500);
102
		orbs_set (0, 0, 0, 255, 0, 0); delay_ms (500);
103
		orbs_set (0, 0, 0, 0, 255, 0); delay_ms (500);
104
		orbs_set (0, 0, 0, 0, 0, 255); delay_ms (500);
105
	}
106

  
107
	if (false)
108
	{
109
		orb_set (1,1,1);
110
		while (1)
111
		{
112
			SYNC
113
			{
114
				for (uint8_t m=0; m<100; ++m)
115
				{
116
					_delay_us(10);
117
				}
118
			}
119
		}
120
	}
121
	
122
	if (false)
123
	{
124
		while (1)
125
		{
126
			for (uint8_t x=0; x<255; ++x)
127
			{
128
				orbs_set (x, 1, 2, 3, 4, 5);
129
				
130
				for (uint8_t n=0; n<80; ++n)
131
				{
132
					SYNC
133
					{ for (uint8_t m=0; m<1; ++m) _delay_us(50); }
134
				}
135
			}
136

  
137
			for (uint8_t x=255; x>0; --x)
138
			{
139
				orbs_set (x, 1, 1, 1, 1, 1);
140
				delay_ms (4);
141
			}
142
		}
143
	}
144

  
145
	if (false)
146
	{
147
		//orbs_set (2,4,6,8,10,12);
148
		//orbs_set (32, 64, 96, 128, 160, 192);
149
		orbs_set (128,128,128,128,128,128);
150
		while (1);
151
	}
152

  
153
	if (false)
154
	{
155
		if (!button2_read ())
156
		{
157
			orb_set_mode (orb_mode_pwm);
158
			orb_disable_timer ();
159
			
160
			while (1)
161
			{
162
				// Continuously call the sorting routine for timing test
163
				for (uint8_t i=0; i<200; ++i)
164
				{
165
					orbs_set (10,20,30,40,50,60);
166
					delay_ms (10);
167
				}
168
					
169
				for (uint8_t i=0; i<200; ++i)
170
				{
171
					orbs_set (60,50,40,30,20,10);
172
					delay_ms (10);
173
				}
174
			}
175
		}
176
		else
177
		{
178
			while (button2_read ());
179
			if (button1_read ())
180
			{
181
				color_circle ();
182
			}
183
			else
184
			{
185
				acl ();
186
			}
187
		}
188
	}
189
	
190
	
191

  
192
	// Do some lighting
193
	if (!button2_read ())
194
		color_circle ();
195
	else
196
		acl ();
197

  
198
}
trunk/code/behaviors/library_test/Makefile
1
########Update This Section########
2
#
3
#
4

  
5
# Relative path to the root directory (containing lib directory)
6
ifndef COLONYROOT
7
COLONYROOT = ../..
8
endif
9

  
10
# Target file name (without extension).
11
TARGET = template
12

  
13
# Uncomment this to use the wireless library
14
# USE_WIRELESS = 1
15

  
16
# com1 = serial port. Use lpt1 to connect to parallel port.
17
#AVRDUDE_PORT = com4
18
AVRDUDE_PORT = $(shell if [ -e /dev/ttyUSB0 ]; then echo /dev/ttyUSB0; else echo 'COM4:'; fi)
19
#
20
#
21
###################################
22

  
23
# Hey Emacs, this is a -*- makefile -*-
24
#----------------------------------------------------------------------------
25
# WinAVR Makefile Template written by Eric B. Weddington, J?rg Wunsch, et al.
26
#
27
# Released to the Public Domain
28
#
29
# Additional material for this makefile was written by:
30
# Peter Fleury
31
# Tim Henigan
32
# Colin O'Flynn
33
# Reiner Patommel
34
# Markus Pfaff
35
# Sander Pool
36
# Frederik Rouleau
37
#
38
#----------------------------------------------------------------------------
39
# On command line:
40
#
41
# make all = Make software.
42
#
43
# make clean = Clean out built project files.
44
#
45
# make coff = Convert ELF to AVR COFF.
46
#
47
# make extcoff = Convert ELF to AVR Extended COFF.
48
#
49
# make program = Download the hex file to the device, using avrdude.
50
#                Please customize the avrdude settings below first!
51
#
52
# make debug = Start either simulavr or avarice as specified for debugging,
53
#              with avr-gdb or avr-insight as the front end for debugging.
54
#
55
# make filename.s = Just compile filename.c into the assembler code only.
56
#
57
# make filename.i = Create a preprocessed source file for use in submitting
58
#                   bug reports to the GCC project.
59
#
60
# To rebuild project do "make clean" then "make all".
61
#----------------------------------------------------------------------------
62

  
63
#if you want your code to work on the Firefly++ and not Firefly+
64
#then add the -DFFPP line to CDEFS
65
CDEFS =
66
#-DFFPP
67

  
68
# MCU name
69
MCU = atmega128
70

  
71
# Processor frequency.
72
#     This will define a symbol, F_CPU, in all source code files equal to the
73
#     processor frequency. You can then use this symbol in your source code to
74
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
75
#     automatically to create a 32-bit value in your source code.
76
F_CPU = 8000000
77

  
78
# Output format. (can be srec, ihex, binary)
79
FORMAT = ihex
80

  
81
# List C source files here. (C dependencies are automatically generated.)
82
SRC = $(wildcard *.c)
83

  
84
# List Assembler source files here.
85
#     Make them always end in a capital .S.  Files ending in a lowercase .s
86
#     will not be considered source files but generated files (assembler
87
#     output from the compiler), and will be deleted upon "make clean"!
88
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
89
#     it will preserve the spelling of the filenames, and gcc itself does
90
#     care about how the name is spelled on its command-line.
91
ASRC =
92

  
93
# Optimization level, can be [0, 1, 2, 3, s].
94
#     0 = turn off optimization. s = optimize for size.
95
#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
96
OPT = s
97

  
98
# Debugging format.
99
#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
100
#     AVR Studio 4.10 requires dwarf-2.
101
#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
102
DEBUG =
103

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

  
111
# Place -D or -U options here
112
CDEFS += -DF_CPU=$(F_CPU)UL
113
CDEFS += -DFFP
114
# for wireless library
115
ifdef USE_WIRELESS
116
	CDEFS += -DROBOT
117
endif
118

  
119
# Place -I, -L options here
120
CINCS = -I$(COLONYROOT)/lib/include/libdragonfly
121
CINCS += -L$(COLONYROOT)/lib/bin
122
ifdef USE_WIRELESS
123
	CINCS += -I$(COLONYROOT)/lib/include/libwireless
124
endif
125

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

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

  
151

  
152
#---------------- Library Options ----------------
153
# Minimalistic printf version
154
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
155

  
156
# Floating point printf version (requires MATH_LIB = -lm below)
157
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
158

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

  
164

  
165
# Minimalistic scanf version
166
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
167

  
168
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
169
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
170

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

  
176
MATH_LIB = -lm
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
#---------------- Linker Options ----------------
191
#  -Wl,...:     tell GCC to pass this to linker.
192
#    -Map:      create map file
193
#    --cref:    add cross reference to  map file
194
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
195
LDFLAGS += $(EXTMEMOPTS)
196
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
197
ifdef USE_WIRELESS
198
	LDFLAGS += -lwireless
199
endif
200
LDFLAGS += -ldragonfly
201

  
202

  
203

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

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

  
214
# programmer connected to serial device
215

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

  
219

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

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

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

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

  
239
#don't check for device signature
240
AVRDUDE_FLAGS += -F
241

  
242

  
243

  
244
#---------------- Debugging Options ----------------
245

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

  
249
# Set the DEBUG_UI to either gdb or insight.
250
# DEBUG_UI = gdb
251
DEBUG_UI = insight
252

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

  
257
# GDB Init Filename.
258
GDBINIT_FILE = __avr_gdbinit
259

  
260
# When using avarice settings for the JTAG
261
JTAG_DEV = /dev/com1
262

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

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

  
271

  
272

  
273
#============================================================================
274

  
275

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

  
289

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

  
308

  
309

  
310

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

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

  
317

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

  
321

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

  
327

  
328

  
329

  
330

  
331
# Default target.
332
all: begin gccversion sizebefore build sizeafter end
333

  
334
build: elf hex eep lss sym
335

  
336
elf: $(TARGET).elf
337
hex: $(TARGET).hex
338
eep: $(TARGET).eep
339
lss: $(TARGET).lss
340
sym: $(TARGET).sym
341

  
342

  
343

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

  
351
end:
352
	@echo $(MSG_END)
353
	@echo
354

  
355

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

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

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

  
369

  
370

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

  
375

  
376

  
377
# Program the device.
378
program: $(TARGET).hex $(TARGET).eep
379
	-taskkill /IM ttermpro.exe
380
	sleep 1
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

  
trunk/code/lib/include/libdragonfly/lights.h
1
// FIXME remove
2
typedef unsigned char uint8_t;
3

  
4

  
1 5
/**
2 6
 * Copyright (c) 2007 Colony Project
3 7
 * 
......
37 41
#ifndef _LIGHTS_H_
38 42
#define _LIGHTS_H_
39 43

  
40

  
41 44
/**
42 45
 * @addtogroup orbs
43 46
 * @{
44 47
 **/
45 48

  
46
//ORB Colors
49
// ***** Predefined colors *****
47 50
/** @brief Red **/
48 51
#define RED       0xE0
49 52
/** @brief Orange **/
......
66 69
#define MAGENTA   0xE3
67 70
/** @brief White **/
68 71
#define WHITE     0xFE
69
/** @brief Turn the orb off (White) **/
70
#define ORB_OFF   0xFE      //ORB_OFF->WHITE
72
/** @brief Turn the orb off **/
73
#define ORB_OFF   0x00
71 74

  
72
/** @brief Enables the orbs **/
75

  
76

  
77
// ***** Initialization *****
78

  
79
/** @brief Enables the orbs in default mode **/
73 80
void orb_init(void);
81

  
82
/** @brief Enables the orbs in binary mode **/
83
void orb_init_binary (void);
84

  
85
/** @brief Enables the orbs in PWM mode **/
86
void orb_init_pwm (void);
87

  
88

  
89

  
90
// ***** Mode setting *****
91

  
92
/** Specification of the orb mode **/
93
typedef uint8_t orb_mode_t;
94

  
95
/** @brief PWM mode **/
96
#define orb_mode_pwm 0
97

  
98
/** @brief Binary mode **/
99
#define orb_mode_binary 1
100

  
101

  
102
/** @brief Switches the orbs to the specified mode **/
103
void orb_set_mode (orb_mode_t mode);
104

  
105
/** @brief Disables the orb timer, but does not change the mode **/
106
void orb_disable_timer (void);
107

  
108
/** @brief Enables the orb timer, but does not change the mode **/
109
void orb_enable_timer (void);
110

  
111

  
112

  
113
// ***** Setting RGB colors *****
114

  
115
/** @brief set the specified orb to a specified color **/
116
void orb_n_set (uint8_t num, uint8_t red, uint8_t green, uint8_t blue);
117

  
74 118
/** @brief Set both orbs to a specified color **/
75
void orb_set(unsigned char red_led, unsigned char green_led,
76
	     unsigned char blue_led);
119
void orb_set(uint8_t red, uint8_t green, uint8_t blue);
120

  
77 121
/** @brief Set orb1 to a specified color **/
78
void orb1_set(unsigned char red_led, unsigned char green_led,
79
	      unsigned char blue_led); 
122
void orb1_set(uint8_t red_led, uint8_t green_led, uint8_t blue_led); 
123

  
80 124
/** @brief Set orb2 to a specified color **/
81
void orb2_set(unsigned char red_led, unsigned char green_led,
82
	      unsigned char blue_led);
125
void orb2_set(uint8_t red_led, uint8_t green_led, uint8_t blue_led);
83 126

  
84
/** @brief Set both orbs to a specified color **/
85
void orb_set_color(int col);
127
void orbs_set (uint8_t red1, uint8_t green1, uint8_t blue1, uint8_t red2, uint8_t green2, uint8_t blue2);
128

  
129

  
130

  
131
// ***** Settings predefined colors *****
132

  
133
/** @brief set the specified orb to the specified color **/
134
void orb_n_set_color(uint8_t num, uint8_t col);
135

  
86 136
/** @brief Set orb1 to a specified color **/
87
void orb1_set_color(int col);
137
void orb1_set_color(uint8_t col);
138

  
88 139
/** @brief Set orb2 to a specified color **/
89
void orb2_set_color(int col);
140
void orb2_set_color(uint8_t col);
90 141

  
91
/** @brief Disable the orbs **/
92
void orb_disable(void);
93
/** @brief Enable the orbs **/
94
void orb_enable(void);
142
/** @brief set the orbs to specified colors **/
143
void orbs_set_color(uint8_t col1, uint8_t col2);
95 144

  
145
/** @brief Set both orbs to a specified color **/
146
void orb_set_color(uint8_t col);
147

  
148

  
149

  
96 150
/** @} **/ //end addtogroup
97 151

  
98 152
#endif
99

  
trunk/code/lib/include/libdragonfly/dragonfly_lib.h
80 80
#include <util/delay.h>
81 81
#include <util/twi.h>
82 82

  
83
// This file is included from the libdragonfly directory because it seems to be
84
// missing from the AVR libc distribution.
85
#include "atomic.h"
86

  
83 87
#include <analog.h>
84 88
#include <dio.h>
85 89
#include <time.h>
......
94 98
#include <reset.h>
95 99
#include <math.h>
96 100
#include <eeprom.h>
101
#include <stdbool.h>
97 102

  
103
/** @brief shortcut for ATOMIC_BLOCK(ATOMIC_RESTORESTATE) **/
104
#define SYNC ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
105

  
106
/** @brief atomically grab a lock if it is free, return otherwise **/
107
#define REQUIRE_LOCK_OR_RETURN(LOCK) do { SYNC { if (LOCK) return; LOCK=1; } } while (0)
108

  
109
/** @brief atomically release a lock **/
110
#define RELEASE_LOCK(LOCK) do { LOCK=0; } while (0)
111

  
112

  
113

  
98 114
#endif
99 115

  
trunk/code/projects/libdragonfly/lights.h
1
// FIXME remove
2
typedef unsigned char uint8_t;
3

  
4

  
1 5
/**
2 6
 * Copyright (c) 2007 Colony Project
3 7
 * 
......
37 41
#ifndef _LIGHTS_H_
38 42
#define _LIGHTS_H_
39 43

  
40

  
41 44
/**
42 45
 * @addtogroup orbs
43 46
 * @{
44 47
 **/
45 48

  
46
//ORB Colors
49
// ***** Predefined colors *****
47 50
/** @brief Red **/
48 51
#define RED       0xE0
49 52
/** @brief Orange **/
......
66 69
#define MAGENTA   0xE3
67 70
/** @brief White **/
68 71
#define WHITE     0xFE
69
/** @brief Turn the orb off (White) **/
70
#define ORB_OFF   0xFE      //ORB_OFF->WHITE
72
/** @brief Turn the orb off **/
73
#define ORB_OFF   0x00
71 74

  
72
/** @brief Enables the orbs **/
75

  
76

  
77
// ***** Initialization *****
78

  
79
/** @brief Enables the orbs in default mode **/
73 80
void orb_init(void);
81

  
82
/** @brief Enables the orbs in binary mode **/
83
void orb_init_binary (void);
84

  
85
/** @brief Enables the orbs in PWM mode **/
86
void orb_init_pwm (void);
87

  
88

  
89

  
90
// ***** Mode setting *****
91

  
92
/** Specification of the orb mode **/
93
typedef uint8_t orb_mode_t;
94

  
95
/** @brief PWM mode **/
96
#define orb_mode_pwm 0
97

  
98
/** @brief Binary mode **/
99
#define orb_mode_binary 1
100

  
101

  
102
/** @brief Switches the orbs to the specified mode **/
103
void orb_set_mode (orb_mode_t mode);
104

  
105
/** @brief Disables the orb timer, but does not change the mode **/
106
void orb_disable_timer (void);
107

  
108
/** @brief Enables the orb timer, but does not change the mode **/
109
void orb_enable_timer (void);
110

  
111

  
112

  
113
// ***** Setting RGB colors *****
114

  
115
/** @brief set the specified orb to a specified color **/
116
void orb_n_set (uint8_t num, uint8_t red, uint8_t green, uint8_t blue);
117

  
74 118
/** @brief Set both orbs to a specified color **/
75
void orb_set(unsigned char red_led, unsigned char green_led,
76
	     unsigned char blue_led);
119
void orb_set(uint8_t red, uint8_t green, uint8_t blue);
120

  
77 121
/** @brief Set orb1 to a specified color **/
78
void orb1_set(unsigned char red_led, unsigned char green_led,
79
	      unsigned char blue_led); 
122
void orb1_set(uint8_t red_led, uint8_t green_led, uint8_t blue_led); 
123

  
80 124
/** @brief Set orb2 to a specified color **/
81
void orb2_set(unsigned char red_led, unsigned char green_led,
82
	      unsigned char blue_led);
125
void orb2_set(uint8_t red_led, uint8_t green_led, uint8_t blue_led);
83 126

  
84
/** @brief Set both orbs to a specified color **/
85
void orb_set_color(int col);
127
void orbs_set (uint8_t red1, uint8_t green1, uint8_t blue1, uint8_t red2, uint8_t green2, uint8_t blue2);
128

  
129

  
130

  
131
// ***** Settings predefined colors *****
132

  
133
/** @brief set the specified orb to the specified color **/
134
void orb_n_set_color(uint8_t num, uint8_t col);
135

  
86 136
/** @brief Set orb1 to a specified color **/
87
void orb1_set_color(int col);
137
void orb1_set_color(uint8_t col);
138

  
88 139
/** @brief Set orb2 to a specified color **/
89
void orb2_set_color(int col);
140
void orb2_set_color(uint8_t col);
90 141

  
91
/** @brief Disable the orbs **/
92
void orb_disable(void);
93
/** @brief Enable the orbs **/
94
void orb_enable(void);
142
/** @brief set the orbs to specified colors **/
143
void orbs_set_color(uint8_t col1, uint8_t col2);
95 144

  
145
/** @brief Set both orbs to a specified color **/
146
void orb_set_color(uint8_t col);
147

  
148

  
149

  
96 150
/** @} **/ //end addtogroup
97 151

  
98 152
#endif
99

  
trunk/code/projects/libdragonfly/dragonfly_lib.h
80 80
#include <util/delay.h>
81 81
#include <util/twi.h>
82 82

  
83
// This file is included from the libdragonfly directory because it seems to be
84
// missing from the AVR libc distribution.
85
#include "atomic.h"
86

  
83 87
#include <analog.h>
84 88
#include <dio.h>
85 89
#include <time.h>
......
94 98
#include <reset.h>
95 99
#include <math.h>
96 100
#include <eeprom.h>
101
#include <stdbool.h>
97 102

  
103
/** @brief shortcut for ATOMIC_BLOCK(ATOMIC_RESTORESTATE) **/
104
#define SYNC ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
105

  
106
/** @brief atomically grab a lock if it is free, return otherwise **/
107
#define REQUIRE_LOCK_OR_RETURN(LOCK) do { SYNC { if (LOCK) return; LOCK=1; } } while (0)
108

  
109
/** @brief atomically release a lock **/
110
#define RELEASE_LOCK(LOCK) do { LOCK=0; } while (0)
111

  
112

  
113

  
98 114
#endif
99 115

  
trunk/code/projects/libdragonfly/eeprom.h
47 47
 unsigned char get_bom_type(void);
48 48
 
49 49
 #endif
50
 
51
 
trunk/code/projects/libdragonfly/atomic.h
1
/* This file is in the dragonfly library directory because it seems to be
2
   missing from the AVR libc distribution */
3
   
4
/* Copyright (c) 2007 Dean Camera
5
   All rights reserved.
6

  
7
   Redistribution and use in source and binary forms, with or without
8
   modification, are permitted provided that the following conditions are met:
9

  
10
   * Redistributions of source code must retain the above copyright
11
     notice, this list of conditions and the following disclaimer.
12

  
13
   * Redistributions in binary form must reproduce the above copyright
14
     notice, this list of conditions and the following disclaimer in
15
     the documentation and/or other materials provided with the
16
     distribution.
17

  
18
   * Neither the name of the copyright holders nor the names of
19
     contributors may be used to endorse or promote products derived
20
     from this software without specific prior written permission.
21

  
22
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
  POSSIBILITY OF SUCH DAMAGE.
33
*/
34

  
35
/* $Id: atomic.h,v 1.3 2007/12/20 14:17:56 joerg_wunsch Exp $ */
36

  
37
#ifndef _UTIL_ATOMIC_H_
38
#define _UTIL_ATOMIC_H_ 1
39

  
40
#include <avr/io.h>
41
#include <avr/interrupt.h>
42

  
43
#if !defined(__DOXYGEN__)
44
/* Internal helper functions. */
45
static __inline__ uint8_t __iSeiRetVal(void)
46
{
47
    sei();
48
    return 1;
49
}
50

  
51
static __inline__ uint8_t __iCliRetVal(void)
52
{
53
    cli();
54
    return 1;
55
}
56

  
57
static __inline__ void __iSeiParam(const uint8_t *__s)
58
{
59
    sei();
60
    __asm__ volatile ("" ::: "memory");
61
    (void)__s;
62
}
63

  
64
static __inline__ void __iCliParam(const uint8_t *__s)
65
{
66
    cli();
67
    __asm__ volatile ("" ::: "memory");
68
    (void)__s;
69
}
70

  
71
static __inline__ void __iRestore(const  uint8_t *__s)
72
{
73
    SREG = *__s;
74
    __asm__ volatile ("" ::: "memory");
75
}
76
#endif	/* !__DOXYGEN__ */
77

  
78
/** \file */
79
/** \defgroup util_atomic <util/atomic.h> Atomically and Non-Atomically Executed Code Blocks
80

  
81
    \code
82
    #include <util/atomic.h>
83
    \endcode
84

  
85
    \note The macros in this header file require the ISO/IEC 9899:1999
86
    ("ISO C99") feature of for loop variables that are declared inside
87
    the for loop itself.  For that reason, this header file can only
88
    be used if the standard level of the compiler (option --std=) is
89
    set to either \c c99 or \c gnu99.
90

  
91
    The macros in this header file deal with code blocks that are
92
    guaranteed to be excuted Atomically or Non-Atmomically.  The term
93
    "Atomic" in this context refers to the unability of the respective
94
    code to be interrupted.
95

  
96
    These macros operate via automatic manipulation of the Global
97
    Interrupt Status (I) bit of the SREG register. Exit paths from
98
    both block types are all managed automatically without the need
99
    for special considerations, i. e. the interrupt status will be
100
    restored to the same value it has been when entering the
101
    respective block.
102

  
103
    A typical example that requires atomic access is a 16 (or more)
104
    bit variable that is shared between the main execution path and an
105
    ISR.  While declaring such a variable as volatile ensures that the
106
    compiler will not optimize accesses to it away, it does not
107
    guarantee atomic access to it.  Assuming the following example:
108

  
109
    \code
110
#include <inttypes.h>
111
#include <avr/interrupt.h>
112
#include <avr/io.h>
113

  
114
volatile uint16_t ctr;
115

  
116
ISR(TIMER1_OVF_vect)
117
{
118
  ctr--;
119
}
120

  
121
...
122
int
123
main(void)
124
{
125
   ...
126
   ctr = 0x200;
127
   start_timer();
128
   while (ctr != 0)
129
     // wait
130
       ;
131
   ...
132
}
133
    \endcode
134

  
135
    There is a chance where the main context will exit its wait loop
136
    when the variable \c ctr just reached the value 0xFF.  This happens
137
    because the compiler cannot natively access a 16-bit variable
138
    atomically in an 8-bit CPU.  So the variable is for example at
139
    0x100, the compiler then tests the low byte for 0, which succeeds.
140
    It then proceeds to test the high byte, but that moment the ISR
141
    triggers, and the main context is interrupted.  The ISR will
142
    decrement the variable from 0x100 to 0xFF, and the main context
143
    proceeds.  It now tests the high byte of the variable which is
144
    (now) also 0, so it concludes the variable has reached 0, and
145
    terminates the loop.
146

  
147
    Using the macros from this header file, the above code can be
148
    rewritten like:
149

  
150
    \code
151
#include <inttypes.h>
152
#include <avr/interrupt.h>
153
#include <avr/io.h>
154
#include <util/atomic.h>
155

  
156
volatile uint16_t ctr;
157

  
158
ISR(TIMER1_OVF_vect)
159
{
160
  ctr--;
161
}
162

  
163
...
164
int
165
main(void)
166
{
167
   ...
168
   ctr = 0x200;
169
   start_timer();
170
   sei();
171
   uint16_t ctr_copy;
172
   do
173
   {
174
     ATOMIC_BLOCK(ATOMIC_FORCEON)
175
     {
176
       ctr_copy = ctr;
177
     }
178
   }
179
   while (ctr_copy != 0);
180
   ...
181
}
182
    \endcode
183

  
184
    This will install the appropriate interrupt protection before
185
    accessing variable \c ctr, so it is guaranteed to be consistently
186
    tested.  If the global interrupt state were uncertain before
187
    entering the ATOMIC_BLOCK, it should be executed with the
188
    parameter ATOMIC_RESTORESTATE rather than ATOMIC_FORCEON.
189

  
190
*/
191

  
192
/** \def ATOMIC_BLOCK(type)
193
    \ingroup util_atomic
194

  
195
    Creates a block of code that is guaranteed to be executed
196
    atomically. Upon entering the block the Global Interrupt Status
197
    flag in SREG is disabled, and re-enabled upon exiting the block
198
    from any exit path.
199

  
200
    Two possible macro parameters are permitted, ATOMIC_RESTORESTATE
201
    and ATOMIC_FORCEON.
202
*/
203
#if defined(__DOXYGEN__)
204
#define ATOMIC_BLOCK(type)
205
#else
206
#define ATOMIC_BLOCK(type) for ( type, __ToDo = __iCliRetVal(); \
207
	                       __ToDo ; __ToDo = 0 )
208
#endif	/* __DOXYGEN__ */
209

  
210
/** \def NONATOMIC_BLOCK(type)
211
    \ingroup util_atomic
212

  
213
    Creates a block of code that is executed non-atomically. Upon
214
    entering the block the Global Interrupt Status flag in SREG is
215
    enabled, and disabled upon exiting the block from any exit
216
    path. This is useful when nested inside ATOMIC_BLOCK sections,
217
    allowing for non-atomic execution of small blocks of code while
218
    maintaining the atomic access of the other sections of the parent
219
    ATOMIC_BLOCK.
220

  
221
    Two possible macro parameters are permitted,
222
    NONATOMIC_RESTORESTATE and NONATOMIC_FORCEOFF.
223
*/
224
#if defined(__DOXYGEN__)
225
#define NONATOMIC_BLOCK(type)
226
#else
227
#define NONATOMIC_BLOCK(type) for ( type, __ToDo = __iSeiRetVal(); \
228
	                          __ToDo ;  __ToDo = 0 )
229
#endif	/* __DOXYGEN__ */
230

  
231
/** \def ATOMIC_RESTORESTATE
232
    \ingroup util_atomic
233

  
234
    This is a possible parameter for ATOMIC_BLOCK. When used, it will
235
    cause the ATOMIC_BLOCK to restore the previous state of the SREG
236
    register, saved before the Global Interrupt Status flag bit was
237
    disabled. The net effect of this is to make the ATOMIC_BLOCK's
238
    contents guaranteed atomic, without changing the state of the
239
    Global Interrupt Status flag when execution of the block
240
    completes.
241
*/
242
#if defined(__DOXYGEN__)
243
#define ATOMIC_RESTORESTATE
244
#else
245
#define ATOMIC_RESTORESTATE uint8_t sreg_save \
246
	__attribute__((__cleanup__(__iRestore))) = SREG
247
#endif	/* __DOXYGEN__ */
248

  
249
/** \def ATOMIC_FORCEON
250
    \ingroup util_atomic
251

  
252
    This is a possible parameter for ATOMIC_BLOCK. When used, it will
253
    cause the ATOMIC_BLOCK to force the state of the SREG register on
254
    exit, enabling the Global Interrupt Status flag bit. This saves on
255
    flash space as the previous value of the SREG register does not
256
    need to be saved at the start of the block.
257

  
258
    Care should be taken that ATOMIC_FORCEON is only used when it is
259
    known that interrupts are enabled before the block's execution or
260
    when the side effects of enabling global interrupts at the block's
261
    completion are known and understood.
262
*/
263
#if defined(__DOXYGEN__)
264
#define ATOMIC_FORCEON
265
#else
266
#define ATOMIC_FORCEON uint8_t sreg_save \
267
	__attribute__((__cleanup__(__iSeiParam))) = 0
268
#endif	/* __DOXYGEN__ */
269

  
270
/** \def NONATOMIC_RESTORESTATE
271
    \ingroup util_atomic
272

  
273
    This is a possible parameter for NONATOMIC_BLOCK. When used, it
274
    will cause the NONATOMIC_BLOCK to restore the previous state of
275
    the SREG register, saved before the Global Interrupt Status flag
276
    bit was enabled. The net effect of this is to make the
277
    NONATOMIC_BLOCK's contents guaranteed non-atomic, without changing
278
    the state of the Global Interrupt Status flag when execution of
279
    the block completes.
280
*/
281
#if defined(__DOXYGEN__)
282
#define NONATOMIC_RESTORESTATE
283
#else
284
#define NONATOMIC_RESTORESTATE uint8_t sreg_save \
285
	__attribute__((__cleanup__(__iRestore))) = SREG
286
#endif	/* __DOXYGEN__ */
287

  
288
/** \def NONATOMIC_FORCEOFF
289
    \ingroup util_atomic
290

  
291
    This is a possible parameter for NONATOMIC_BLOCK. When used, it
292
    will cause the NONATOMIC_BLOCK to force the state of the SREG
293
    register on exit, disabling the Global Interrupt Status flag
294
    bit. This saves on flash space as the previous value of the SREG
295
    register does not need to be saved at the start of the block.
296

  
297
    Care should be taken that NONATOMIC_FORCEOFF is only used when it
298
    is known that interrupts are disabled before the block's execution
299
    or when the side effects of disabling global interrupts at the
300
    block's completion are known and understood.
301
*/
302
#if defined(__DOXYGEN__)
303
#define NONATOMIC_FORCEOFF
304
#else
305
#define NONATOMIC_FORCEOFF uint8_t sreg_save \
306
	__attribute__((__cleanup__(__iCliParam))) = 0
307
#endif	/* __DOXYGEN__ */
308

  
309
#endif
trunk/code/projects/libdragonfly/lights.c
23 23
 * OTHER DEALINGS IN THE SOFTWARE.
24 24
 **/
25 25

  
26

  
27 26
/**
28 27
 * @file ligths.c
29 28
 * @brief Orbs
......
31 30
 * Implemenation for the orbs (tri-colored LEDs)
32 31
 *
33 32
 * @author Colony Project, CMU Robotics Club
34
 * @bug Colors are incorrect, seems to not work with wireless library
33
 * @bug Unfinished
35 34
 **/
36 35

  
37 36
/*
38 37
lights.c
39
Controls orb1 and orb2. Also contains the framework for a software PWM that may be used for servos in the future.
38
Controls orb1 and orb2. Can be extended for a software PWM that may be used for servos in the future (although maybe
39
using a different timer might be preferable).
40 40

  
41 41
author: CMU Robotics Club, Colony Project
42 42

  
43 43
Change Log:
44
2.4.07 - Aaron
45
	Revamped orb code so it works.  Need to check interaction with rtc, and tweak some colors.
44
3/31/2009 - Martin
45
    Rewritten from scratch. Fixes code duplication, long ISRs, bugs, unnecessary synchronized code, memory waste
46
*/
46 47

  
47
2.1.07 - James
48
	Modified sort_buffer() to prune for repeats.  PWM now uses orb_buf_size for the number of orb values in orb_time_arr[].
49
		Changed sorting algorithm used in sort_buffer() to selection sort (faster). And it works now.
48
/**
49
 * Quick start: call orb_init_pwm or orb_init_binary, depending on which mode you want to use. Call orb*set or
50
 * orb*set_color to set the orbs.
51
 * 
52
 * The orbs have two modes of operation: PWM mode and binary mode. In PWM mode, a pwm signal is generated by a hardware
53
 * timer and the orbs can be set to a value of 0 through 255. In binary mode, the orbs can only be turned on or off and
54
 * a value of 0 means "off" and any other value means "on". The mode can be chosen on initialization and can be changed
55
 * at runtime using the orb_set_mode function.
56
 *
57
 * Operation (PWM mode): On timer overflow, all LEDs with a value>0 are turned on and the output compare value for the
58
 * first LED is loaded. On compare match, the corresponding LED is turned off and the next output compare value is
59
 * loaded. All masks are precomputed and sorted by time when setting the values.
60
 *
61
 * The data structure (pwm_t) containing the PWM times and masks is triple buffered. This is because the buffer the ISR
62
 * is reading from may only be modified on timer overflow before the next PWM sequence is started, because otherwise the
63
 * next OCR value might be sed to a value smaller than the current timer value, resulting in the remaining channels not
64
 * being turned off in that PWM period (flash to on). When using two buffers, the page flip can only occur on a timer
65
 * overflow for the same reason. So after writing a buffer and marking it for page flip, neither of the buffers could be
66
 * modified because the front buffer is read by the ISR and the back buffer could be switched at any time. So the
67
 * calling thread would have to be delayed by up to one full PWM period (8ms in the current implementation, but
68
 * 20ms-50ms would be a reasonable value to expect here). To avoid this, triple buffering is used.
69
 *
70
 * The code for applying the orbs is fairly optimized. See the apply_orbs function for some time measurements and
71
 * further nodes.
72
 *
73
 * The PWM frequency is 120Hz (8ms period time). The next lower frequency (determined by the prescaler) is 30 Hz which
74
 * is too slow (orbs flicker).
75
 *
76
 * The orbs code is thread safe, which means that the functions may be called from another interrupt handler. If there
77
 * are multiple concurrent calls to the orb*set* functions, one of them is ignored and the orbs are never left in an
78
 * inconsistent state. For example, if the orbs are set to green by the main thread and to red by an interrupt handler,
79
 * the resulting color will be either red or green, but never yellow.
80
 * Thread safety is achieved by grabbing a lock at the beginning of all functions that modify the orb code and releasing
81
 * the lock at the end. If the lock is already taken, the function just returns doing nothing.
82
 *
83
 * Some performance measurements:
84
 *   - Time for setting new orb values (PWM mode):       35us-72us (depending on the degree to which the array is
85
 *                                                                  already in the correct order)
86
 *   - Time for setting new orb values (binary mode):        5.5us
87
 *
88
 *   - Interrupt time (PWM mode only):                         8us (overflow)
89
 *                                                            10us (output compare)
90
 *                                                             6us (last output compare)
91
 *                                                            30us (output compare, all value equal)
92
 *
93
 *   - Maximum total interrupt time per period:               64us
94
 *   - Maximum CPU usage for interrupts (PWM mode only):     <0.8%
95
 *
96
 *   - Maximum contiguous synchronized block:                 30us (output compare interrupt, all values equal)
97
 *
98
 * There are some potential optimizations left. See the source code for more information.
99
 *
100
 * A note on robustness: if the output compare interrupt is disabled for too long, either due to a long ISR or a long
101
 * synchronized code block, the orbs will flicker to brighter values for being turned off too late. With software PWM,
102
 * there's nothing at all to be done about that. The problem can be alleviated by using a lower PWM frequency, but then
103
 * the orbs will start flickering all the time due to the low update frequency.
104
 * Some measurements: with 100us synchronized blocks, the flickering is accepptably low. Longer synchronized blocks
105
 * mean more flickering. At 1ms synchronized blocks, the flickering is quite bad, especially for low orb values. Note
106
 * that orb value 0 never flickers at all because the corresponding channels are not turned on at all.
107
 * Test code (not the _delay_us restrictions!)
108
 *   orb_set (1,1,1); while (1) { SYNC { for (uint8_t m=0; m<10; ++m) { _delay_us(10); } } }
109
 **/
50 110

  
51
1.25.07 - KWoo
52
	Deleted old FF+ code to make it cleaner. Commented code. This all works. Note however that if you ever plan to use the
53
		software PWM (which is this) you will need to change the implementation of orb_enable() and orb_disable() to not
54
		shutdown the PWM.
111
/*
55 112

  
113
All different:
114

  
115
Overflow: 8us
116

  
117
OC: 5*10+1*6
118

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff