commit 513810e138fbe4b0cbccf3b3ab15930891fde90a Author: Michael Hayes Date: Sat Aug 27 01:46:08 2011 +0000 Generate callgraph diff --git a/README b/README new file mode 100644 index 0000000..9d9c4da --- /dev/null +++ b/README @@ -0,0 +1,9 @@ +apps --- contains a sub-directory for each application +drivers --- device driver modules (hardware independent) +drivers/avr --- device driver modules specifically for AVR architecture +drivers/test --- device driver modules for test scaffold +common --- common modules (utilities, etc.) +doc --- documentation +etc --- miscellaneous scripts +fonts --- fonts and font creation program + diff --git a/apps/README b/apps/README new file mode 100644 index 0000000..83b8ab5 --- /dev/null +++ b/apps/README @@ -0,0 +1,16 @@ +This directory contains a number of test applications contained in +their own sub-directories. Within each sub-directory are two +makefiles; one called Makefile and the other called Makefile.test. By +default when make is run it will read Makefile. + +make --- builds the application for the ATmega8 +make program --- programs the application into the ATmega8 flash memory +make clean --- deletes the object and executable files + + +The other makefile, Makefile.test, will compile the application +natively for the PC with a test scaffold replacing the AVR dependent +modules. This allows the application to be run and debugged on a PC. + +make -f Makefile.test --- builds the application for the PC +make -f Makefile.test clean --- deletes the object and executable files diff --git a/apps/bounce1/Makefile b/apps/bounce1/Makefile new file mode 100644 index 0000000..77d2354 --- /dev/null +++ b/apps/bounce1/Makefile @@ -0,0 +1,54 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for bounce1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: bounce1.out + + +# Compile: create object files from C source files. +bounce1.o: bounce1.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +bounce1.out: bounce1.o pacer.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: bounce1.out + $(OBJCOPY) -O ihex bounce1.out bounce1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash bounce1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/bounce1/Makefile.test b/apps/bounce1/Makefile.test new file mode 100644 index 0000000..ab80f24 --- /dev/null +++ b/apps/bounce1/Makefile.test @@ -0,0 +1,48 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for bounce1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: bounce1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +bounce1-test.o: bounce1.c ../../utils/pacer.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +bounce1: timer-test.o mgetkey-test.o bounce1-test.o pacer-test.o pio-test.o system-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) bounce1 timer-test.o mgetkey-test.o bounce1-test.o pacer-test.o pio-test.o system-test.o + + diff --git a/apps/bounce1/bounce1.c b/apps/bounce1/bounce1.c new file mode 100644 index 0000000..1c96006 --- /dev/null +++ b/apps/bounce1/bounce1.c @@ -0,0 +1,113 @@ +/** @file bounce1.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Simple bouncing dot program + + @defgroup bounce1 Bounce1 application +*/ +#include "system.h" +#include "pacer.h" +#include "pio.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 10 + + +/* Define PIO pins driving LED matrix rows and columns. */ +static pio_t ledmat_rows[] = +{ + LEDMAT_ROW1_PIO, LEDMAT_ROW2_PIO, LEDMAT_ROW3_PIO, LEDMAT_ROW4_PIO, + LEDMAT_ROW5_PIO, LEDMAT_ROW6_PIO, LEDMAT_ROW7_PIO +}; +static pio_t ledmat_cols[] = +{ + LEDMAT_COL1_PIO, LEDMAT_COL2_PIO, LEDMAT_COL3_PIO, + LEDMAT_COL4_PIO, LEDMAT_COL5_PIO +}; + + +/** Turn single LED within matrix on or off. + @param col LED column number + @param row LED row number + @param state LED state */ +static void ledmat_pixel_set (int col, int row, bool state) +{ + if (state) + { + pio_output_low (ledmat_rows[row]); + pio_output_low (ledmat_cols[col]); + } + else + { + pio_output_high (ledmat_rows[row]); + pio_output_high (ledmat_cols[col]); + } +} + + +/** Initialise LED matrix PIO pins. */ +static void ledmat_init (void) +{ + uint8_t row; + uint8_t col; + + for (row = 0; row < 7; row++) + { + pio_config_set (ledmat_rows[row], PIO_OUTPUT_HIGH); + pio_output_high (ledmat_rows[row]); + } + + for (col = 0; col < 5; col++) + { + pio_config_set (ledmat_cols[col], PIO_OUTPUT_HIGH); + pio_output_high (ledmat_cols[col]); + } +} + + +int main (void) +{ + int row; + int col; + int rowinc; + int colinc; + + system_init (); + ledmat_init (); + + row = 3; + col = 2; + rowinc = 1; + colinc = 1; + + ledmat_pixel_set (col, row, 1); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + ledmat_pixel_set (col, row, 0); + + col += colinc; + row += rowinc; + + if (row > 6 || row < 0) + { + row -= rowinc * 2; + rowinc = -rowinc; + } + + if (col > 4 || col < 0) + { + col -= colinc * 2; + colinc = -colinc; + } + + ledmat_pixel_set (col, row, 1); + } +} diff --git a/apps/bounce2/Makefile b/apps/bounce2/Makefile new file mode 100644 index 0000000..d6f20af --- /dev/null +++ b/apps/bounce2/Makefile @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for bounce2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: bounce2.out + + +# Compile: create object files from C source files. +bounce2.o: bounce2.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +bounce2.out: bounce2.o display.o ledmat.o pacer.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: bounce2.out + $(OBJCOPY) -O ihex bounce2.out bounce2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash bounce2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/bounce2/Makefile.test b/apps/bounce2/Makefile.test new file mode 100644 index 0000000..a393149 --- /dev/null +++ b/apps/bounce2/Makefile.test @@ -0,0 +1,54 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for bounce2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: bounce2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +bounce2-test.o: bounce2.c ../../utils/pacer.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +bounce2: timer-test.o display-test.o pio-test.o pacer-test.o ledmat-test.o system-test.o mgetkey-test.o bounce2-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) bounce2 timer-test.o display-test.o pio-test.o pacer-test.o ledmat-test.o system-test.o mgetkey-test.o bounce2-test.o + + diff --git a/apps/bounce2/bounce2.c b/apps/bounce2/bounce2.c new file mode 100644 index 0000000..c600ac2 --- /dev/null +++ b/apps/bounce2/bounce2.c @@ -0,0 +1,74 @@ +/** @file bounce2.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Simple bouncing dot program + + @defgroup bounce2 Bounce2 application +*/ +#include "system.h" +#include "pacer.h" +#include "display.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 200 + + +int main (void) +{ + int row; + int col; + int rowinc; + int colinc; + int tick; + + system_init (); + display_init (); + + row = 3; + col = 2; + rowinc = 1; + colinc = 1; + + display_pixel_set (col, row, 1); + + pacer_init (LOOP_RATE); + tick = 0; + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tick++; + + if (tick >= 10) + { + tick = 0; + + /* Erase previous position. */ + display_pixel_set (col, row, 0); + + col += colinc; + row += rowinc; + + if (row > 6 || row < 0) + { + row -= rowinc * 2; + rowinc = -rowinc; + } + + if (col > 4 || col < 0) + { + col -= colinc * 2; + colinc = -colinc; + } + + /* Draw new position. */ + display_pixel_set (col, row, 1); + } + + display_update (); + } +} diff --git a/apps/bounce3/Makefile b/apps/bounce3/Makefile new file mode 100644 index 0000000..c370a8b --- /dev/null +++ b/apps/bounce3/Makefile @@ -0,0 +1,63 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for bounce3 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: bounce3.out + + +# Compile: create object files from C source files. +bounce3.o: bounce3.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +bounce3.out: bounce3.o display.o ledmat.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: bounce3.out + $(OBJCOPY) -O ihex bounce3.out bounce3.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash bounce3.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/bounce3/Makefile.test b/apps/bounce3/Makefile.test new file mode 100644 index 0000000..4d405e5 --- /dev/null +++ b/apps/bounce3/Makefile.test @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for bounce3 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: bounce3 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +bounce3-test.o: bounce3.c ../../utils/pacer.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +bounce3: timer-test.o display-test.o pio-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o bounce3-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) bounce3 timer-test.o display-test.o pio-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o bounce3-test.o + + diff --git a/apps/bounce3/bounce3.c b/apps/bounce3/bounce3.c new file mode 100644 index 0000000..b7dc0fe --- /dev/null +++ b/apps/bounce3/bounce3.c @@ -0,0 +1,73 @@ +/** @file bounce3.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Simple bouncing dot program. This has a deliberate bug! + + @defgroup bounce3 Bounce3 application +*/ +#include "system.h" +#include "pacer.h" +#include "tinygl.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 200 + + +int main (void) +{ + tinygl_point_t pos; + int xinc; + int yinc; + int tick; + + system_init (); + tinygl_init (LOOP_RATE); + + pos.y = 3; + pos.x = 2; + yinc = 1; + xinc = 1; + + tinygl_draw_point (pos, 1); + + pacer_init (LOOP_RATE); + tick = 0; + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tick++; + + if (tick >= 10) + { + tick = 0; + + /* Erase previous position. */ + tinygl_draw_point (pos, 0); + + pos.x += xinc; + pos.y += yinc; + + if (pos.y > 6) + { + pos.y -= yinc * 2; + yinc = -yinc; + } + + if (pos.x > 4) + { + pos.x -= xinc * 2; + xinc = -xinc; + } + + /* Draw new position. */ + tinygl_draw_point (pos, 1); + } + + tinygl_update (); + } +} diff --git a/apps/bounce4/Makefile b/apps/bounce4/Makefile new file mode 100644 index 0000000..85180d8 --- /dev/null +++ b/apps/bounce4/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for bounce4 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: bounce4.out + + +# Compile: create object files from C source files. +bounce4.o: bounce4.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/boing.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +boing.o: ../../utils/boing.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/boing.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +bounce4.out: boing.o bounce4.o display.o ledmat.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: bounce4.out + $(OBJCOPY) -O ihex bounce4.out bounce4.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash bounce4.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/bounce4/Makefile.test b/apps/bounce4/Makefile.test new file mode 100644 index 0000000..bb764b6 --- /dev/null +++ b/apps/bounce4/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for bounce4 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: bounce4 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +boing-test.o: ../../utils/boing.c ../../drivers/display.h ../../utils/boing.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +bounce4-test.o: bounce4.c ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../utils/boing.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +bounce4: timer-test.o display-test.o pio-test.o pacer-test.o boing-test.o ledmat-test.o tinygl-test.o bounce4-test.o system-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) bounce4 timer-test.o display-test.o pio-test.o pacer-test.o boing-test.o ledmat-test.o tinygl-test.o bounce4-test.o system-test.o mgetkey-test.o + + diff --git a/apps/bounce4/bounce4.c b/apps/bounce4/bounce4.c new file mode 100644 index 0000000..01cb389 --- /dev/null +++ b/apps/bounce4/bounce4.c @@ -0,0 +1,60 @@ +/** @file bounce4.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Multiple bouncing dot program + + @defgroup bounce4 Bounce4 application +*/ +#include "system.h" +#include "pacer.h" +#include "tinygl.h" +#include "boing.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 200 + + +int main (void) +{ + int tick; + boing_state_t balls[2]; + + system_init (); + tinygl_init (LOOP_RATE); + + pacer_init (LOOP_RATE); + tick = 0; + + balls[0] = boing_init (0, 1, DIR_NE); + balls[1] = boing_init (4, 5, DIR_SE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tick++; + + if (tick >= 40) + { + int i; + + tick = 0; + + for (i = 0; i < 2; i++) + { + /* Erase previous position. */ + tinygl_draw_point (balls[i].pos, 0); + + balls[i] = boing_update (balls[i]); + + /* Draw new position. */ + tinygl_draw_point (balls[i].pos, 1); + } + } + + tinygl_update (); + } +} diff --git a/apps/bounce5/Makefile b/apps/bounce5/Makefile new file mode 100644 index 0000000..e07e5cd --- /dev/null +++ b/apps/bounce5/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for bounce5 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: bounce5.out + + +# Compile: create object files from C source files. +bounce5.o: bounce5.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/boing.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +boing.o: ../../utils/boing.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/boing.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +bounce5.out: boing.o bounce5.o display.o ledmat.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: bounce5.out + $(OBJCOPY) -O ihex bounce5.out bounce5.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash bounce5.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/bounce5/Makefile.test b/apps/bounce5/Makefile.test new file mode 100644 index 0000000..2a18831 --- /dev/null +++ b/apps/bounce5/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for bounce5 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: bounce5 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +boing-test.o: ../../utils/boing.c ../../drivers/display.h ../../utils/boing.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +bounce5-test.o: bounce5.c ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../utils/boing.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +bounce5: timer-test.o display-test.o pio-test.o pacer-test.o boing-test.o bounce5-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) bounce5 timer-test.o display-test.o pio-test.o pacer-test.o boing-test.o bounce5-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o + + diff --git a/apps/bounce5/bounce5.c b/apps/bounce5/bounce5.c new file mode 100644 index 0000000..01a0a6f --- /dev/null +++ b/apps/bounce5/bounce5.c @@ -0,0 +1,96 @@ +/** @file bounce5.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Multiple bouncing dot program + + @defgroup bounce5 Bounce5 application +*/ +#include "system.h" +#include "pacer.h" +#include "tinygl.h" +#include "boing.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 200 + + +/* Determine if two balls have collided + @param balls array of all the ball states + @param num_balls number of balls in array + @param this_ball index of ball to check + @return index of ball collided with or -1 for no collision */ +static int collision_detect (boing_state_t *balls, int num_balls, int this_ball) +{ + int i; + + for (i = 0; i < num_balls; i++) + { + /* Cannot collide with self. */ + if (i == this_ball) + continue; + + if (balls[i].pos.x == balls[this_ball].pos.x + && balls[i].pos.y == balls[this_ball].pos.y) + return i; + } + return -1; +} + + + +int main (void) +{ + int tick; + boing_state_t balls[3]; + + system_init (); + tinygl_init (LOOP_RATE); + + pacer_init (LOOP_RATE); + tick = 0; + + balls[0] = boing_init (0, 1, DIR_NE); + balls[1] = boing_init (4, 5, DIR_SE); + balls[2] = boing_init (4, 5, DIR_SW); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tick++; + + /* Flash the first two balls at different rates. */ + tinygl_draw_point (balls[0].pos, tick % 2 < 1); + tinygl_draw_point (balls[1].pos, tick % 4 < 2); + + if (tick >= 40) + { + int i; + + tick = 0; + + for (i = 0; i < 3; i++) + { + /* Erase previous position. */ + tinygl_draw_point (balls[i].pos, 0); + + /* Check for collision; if so reverse direction. */ + balls[i] = boing_update (balls[i]); + + /* Perhaps should make ball that is hit reverse as well? */ + if (collision_detect (balls, 2, i) > 0) + { + balls[i] = boing_reverse (balls[i]); + } + + /* Draw previous position. */ + tinygl_draw_point (balls[i].pos, 1); + } + } + + tinygl_update (); + } +} diff --git a/apps/chooser/Makefile b/apps/chooser/Makefile new file mode 100644 index 0000000..ba8c08b --- /dev/null +++ b/apps/chooser/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for chooser + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: chooser.out + + +# Compile: create object files from C source files. +chooser.o: chooser.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +chooser.out: chooser.o display.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: chooser.out + $(OBJCOPY) -O ihex chooser.out chooser.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash chooser.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/chooser/Makefile.test b/apps/chooser/Makefile.test new file mode 100644 index 0000000..4aa59cd --- /dev/null +++ b/apps/chooser/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for chooser + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: chooser + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +chooser-test.o: chooser.c ../../drivers/navswitch.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +chooser: timer-test.o display-test.o pio-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o navswitch-test.o chooser-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) chooser timer-test.o display-test.o pio-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o navswitch-test.o chooser-test.o + + diff --git a/apps/chooser/chooser.c b/apps/chooser/chooser.c new file mode 100644 index 0000000..df49185 --- /dev/null +++ b/apps/chooser/chooser.c @@ -0,0 +1,81 @@ +/** @file chooser.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Homework winner chooser + + @defgroup chooser Homework winner chooser. +*/ + +#include "system.h" +#include "tinygl.h" +#include "pacer.h" +#include "navswitch.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +static void show_num (char ch, uint8_t count) +{ + char buffer[4]; + + /* FIXME! */ + buffer[0] = ch; + buffer[1] = count / 10 + '0'; + buffer[2] = count % 10 + '0'; + buffer[3] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + int count = 0; + + system_init (); + tinygl_init (LOOP_RATE); + navswitch_init (); + + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + + tinygl_text ("NUM?"); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_PUSH)) + { + show_num ('T', count); + } + else if (navswitch_push_event_p (NAVSWITCH_WEST)) + { + if (count > 0) + count--; + show_num ('N', count); + } + else if (navswitch_push_event_p (NAVSWITCH_EAST)) + { + count++; + show_num ('N', count); + } + + + } + + return 0; +} diff --git a/apps/demo1/Makefile b/apps/demo1/Makefile new file mode 100644 index 0000000..c02d99e --- /dev/null +++ b/apps/demo1/Makefile @@ -0,0 +1,48 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for demo1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: demo1.out + + +# Compile: create object files from C source files. +demo1.o: demo1.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +demo1.out: demo1.o pio.o system.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: demo1.out + $(OBJCOPY) -O ihex demo1.out demo1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash demo1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/demo1/Makefile.test b/apps/demo1/Makefile.test new file mode 100644 index 0000000..f4f73ba --- /dev/null +++ b/apps/demo1/Makefile.test @@ -0,0 +1,42 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for demo1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: demo1 + + +# Compile: create object files from C source files. +demo1-test.o: demo1.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/pio.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +demo1: demo1-test.o mgetkey-test.o pio-test.o system-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) demo1 demo1-test.o mgetkey-test.o pio-test.o system-test.o + + diff --git a/apps/demo1/demo1.c b/apps/demo1/demo1.c new file mode 100644 index 0000000..77234ca --- /dev/null +++ b/apps/demo1/demo1.c @@ -0,0 +1,21 @@ +/** @file demo1.c + @author M.P. Hayes + @date 25 Aug 2011 +*/ + +#include "system.h" +#include "pio.h" + +int main (void) +{ + system_init (); + + pio_config_set (LED1_PIO, PIO_OUTPUT_HIGH); + + while (1) + { + pio_output_toggle (LED1_PIO); + } + + return 0; +} diff --git a/apps/demo2/Makefile b/apps/demo2/Makefile new file mode 100644 index 0000000..28e6c80 --- /dev/null +++ b/apps/demo2/Makefile @@ -0,0 +1,51 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for demo2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: demo2.out + + +# Compile: create object files from C source files. +demo2.o: demo2.c ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +demo2.out: demo2.o led.o pio.o system.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: demo2.out + $(OBJCOPY) -O ihex demo2.out demo2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash demo2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/demo2/Makefile.test b/apps/demo2/Makefile.test new file mode 100644 index 0000000..f7e4a97 --- /dev/null +++ b/apps/demo2/Makefile.test @@ -0,0 +1,45 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for demo2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: demo2 + + +# Compile: create object files from C source files. +demo2-test.o: demo2.c ../../drivers/led.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/pio.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +demo2: demo2-test.o led-test.o mgetkey-test.o pio-test.o system-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) demo2 demo2-test.o led-test.o mgetkey-test.o pio-test.o system-test.o + + diff --git a/apps/demo2/demo2.c b/apps/demo2/demo2.c new file mode 100644 index 0000000..7ef209f --- /dev/null +++ b/apps/demo2/demo2.c @@ -0,0 +1,24 @@ +/** @file demo2.c + @author M.P. Hayes + @date 25 Aug 2011 +*/ + +#include "system.h" +#include "led.h" + +int main (void) +{ + bool state = 0; + + system_init (); + + led_init (); + + while (1) + { + led_set (LED1, state); + state = !state; + } + + return 0; +} diff --git a/apps/fonttest1/Makefile b/apps/fonttest1/Makefile new file mode 100644 index 0000000..27ceac4 --- /dev/null +++ b/apps/fonttest1/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for fonttest1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: fonttest1.out + + +# Compile: create object files from C source files. +fonttest1.o: fonttest1.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font3x5_1.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +fonttest1.out: display.o fonttest1.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: fonttest1.out + $(OBJCOPY) -O ihex fonttest1.out fonttest1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash fonttest1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/fonttest1/Makefile.test b/apps/fonttest1/Makefile.test new file mode 100644 index 0000000..cf1169d --- /dev/null +++ b/apps/fonttest1/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for fonttest1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: fonttest1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +fonttest1-test.o: fonttest1.c ../../drivers/navswitch.h ../../utils/font.h ../../drivers/test/system.h ../../fonts/font3x5_1.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +fonttest1: timer-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o fonttest1-test.o navswitch-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) fonttest1 timer-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o fonttest1-test.o navswitch-test.o mgetkey-test.o + + diff --git a/apps/fonttest1/fonttest1.c b/apps/fonttest1/fonttest1.c new file mode 100644 index 0000000..33db503 --- /dev/null +++ b/apps/fonttest1/fonttest1.c @@ -0,0 +1,105 @@ +/** @file fonttest1.c + @author M.P. Hayes + @date 3 Sep 2010 + @brief Simple font test program + + @defgroup fonttest1 Simple font test program. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "../fonts/font3x5_1.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +static font_t *fonts[] = +{ + &font5x7_1, + &font3x5_1 +}; +static tinygl_text_mode_t modes[] = +{ + TINYGL_TEXT_MODE_STEP, + TINYGL_TEXT_MODE_STEP +}; + + +static void choose_font (int font_num) +{ + tinygl_font_set (fonts[font_num]); + tinygl_text_mode_set (modes[font_num]); + tinygl_clear (); +} + + +static char show_char (int font_num, char ch) +{ + char string[2]; + + if (ch < FONT_FIRST (fonts[font_num])) + ch = FONT_LAST (fonts[font_num]); + else if (ch > FONT_LAST (fonts[font_num])) + ch = FONT_FIRST (fonts[font_num]); + + string[0] = ch; + string[1] = 0; + tinygl_text (string); + return ch; +} + + +int main (void) +{ + char c = 'A'; + unsigned int font_num = 0; + + system_init (); + tinygl_init (LOOP_RATE); + + navswitch_init (); + + pacer_init (LOOP_RATE); + + choose_font (font_num); + tinygl_text_speed_set (10); + + c = show_char (font_num, c); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_PUSH)) + { + font_num++; + if (font_num >= ARRAY_SIZE (fonts)) + font_num = 0; + + choose_font (font_num); + c = show_char (font_num, c); + } + else if (navswitch_push_event_p (NAVSWITCH_WEST) + || navswitch_push_event_p (NAVSWITCH_SOUTH)) + { + c = show_char (font_num, c - 1); + } + else if (navswitch_push_event_p (NAVSWITCH_EAST) + || navswitch_push_event_p (NAVSWITCH_NORTH)) + { + c = show_char (font_num, c + 1); + } + + tinygl_update (); + } + + return 0; +} diff --git a/apps/game/README b/apps/game/README new file mode 100644 index 0000000..4ebac1e --- /dev/null +++ b/apps/game/README @@ -0,0 +1,8 @@ +Use this directory for your final game and its module(s). Only the +files in this directory will be marked. + +Ensure you use the svn add command to add your files to the subversion +repository. For example, + +svn add game.c +svn add Makefile diff --git a/apps/hello1/Makefile b/apps/hello1/Makefile new file mode 100644 index 0000000..f0c7432 --- /dev/null +++ b/apps/hello1/Makefile @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for hello1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: hello1.out + + +# Compile: create object files from C source files. +hello1.o: hello1.c ../../drivers/avr/system.h ../../drivers/ledmat.h ../../utils/pacer.h simplefont.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +hello1.out: hello1.o ledmat.o pacer.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: hello1.out + $(OBJCOPY) -O ihex hello1.out hello1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash hello1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/hello1/Makefile.test b/apps/hello1/Makefile.test new file mode 100644 index 0000000..0f261c5 --- /dev/null +++ b/apps/hello1/Makefile.test @@ -0,0 +1,51 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for hello1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: hello1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +hello1-test.o: hello1.c ../../utils/pacer.h ../../drivers/ledmat.h simplefont.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +hello1: timer-test.o pio-test.o pacer-test.o ledmat-test.o hello1-test.o system-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) hello1 timer-test.o pio-test.o pacer-test.o ledmat-test.o hello1-test.o system-test.o mgetkey-test.o + + diff --git a/apps/hello1/hello1.c b/apps/hello1/hello1.c new file mode 100644 index 0000000..a829353 --- /dev/null +++ b/apps/hello1/hello1.c @@ -0,0 +1,60 @@ +/** @file hello1.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Simple message display program + + @defgroup hello1 Simple message display program +*/ + +#include "system.h" +#include "simplefont.h" +#include "pacer.h" +#include "ledmat.h" + + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate in Hz. */ +#define MESSAGE_RATE 2 + + +int main (void) +{ + char message[] = "HELLO WORLD"; + uint8_t col = 0; + uint8_t index = 0; + uint8_t tick = 0; + + system_init (); + ledmat_init (); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + ledmat_display_column (font[(message[index] - ' ') * 5 + col], + col); + + col++; + if (col > 4) + col = 0; + + /* Advance message. */ + tick++; + if (tick >= LOOP_RATE / MESSAGE_RATE) + { + tick = 0; + index++; + if (!message[index]) + index = 0; + } + } + + return 0; +} diff --git a/apps/hello1/simplefont.h b/apps/hello1/simplefont.h new file mode 100644 index 0000000..386eb0d --- /dev/null +++ b/apps/hello1/simplefont.h @@ -0,0 +1,79 @@ +#ifndef SIMPLEFONT_H_ +#define SIMPLEFONT_H_ + +#include + +static uint8_t font[] = { + /* */ 0x00, 0x00, 0x00, 0x00, 0x00, + /* ! */ 0x00, 0x00, 0x5F, 0x00, 0x00, + /* " */ 0x00, 0x03, 0x00, 0x03, 0x00, + /* # */ 0x12, 0x7F, 0x12, 0x7F, 0x12, + /* $ */ 0x26, 0x49, 0x7F, 0x49, 0x32, + /* % */ 0x43, 0x33, 0x08, 0x66, 0x61, + /* & */ 0x36, 0x49, 0x55, 0x23, 0x50, + /* ' */ 0x00, 0x00, 0x03, 0x00, 0x00, + /* ( */ 0x00, 0x1C, 0x63, 0x41, 0x00, + /* ) */ 0x00, 0x41, 0x63, 0x1C, 0x00, + /* * */ 0x49, 0x2A, 0x7F, 0x2A, 0x49, + /* + */ 0x08, 0x08, 0x7F, 0x08, 0x08, + /* , */ 0x00, 0x40, 0x70, 0x00, 0x00, + /* - */ 0x08, 0x08, 0x08, 0x08, 0x08, + /* . */ 0x00, 0x00, 0x40, 0x00, 0x00, + /* / */ 0x40, 0x30, 0x08, 0x06, 0x01, + /* 0 */ 0x3E, 0x51, 0x49, 0x45, 0x3E, + /* 1 */ 0x00, 0x42, 0x7F, 0x40, 0x00, + /* 2 */ 0x42, 0x61, 0x51, 0x49, 0x46, + /* 3 */ 0x21, 0x41, 0x45, 0x4B, 0x31, + /* 4 */ 0x18, 0x14, 0x12, 0x7F, 0x10, + /* 5 */ 0x27, 0x45, 0x45, 0x45, 0x39, + /* 6 */ 0x3C, 0x4A, 0x49, 0x49, 0x30, + /* 7 */ 0x01, 0x01, 0x79, 0x05, 0x03, + /* 8 */ 0x37, 0x49, 0x49, 0x49, 0x36, + /* 9 */ 0x06, 0x49, 0x49, 0x29, 0x1E, + /* : */ 0x00, 0x00, 0x14, 0x00, 0x00, + /* ; */ 0x00, 0x40, 0x74, 0x00, 0x00, + /* < */ 0x00, 0x08, 0x14, 0x22, 0x41, + /* = */ 0x14, 0x14, 0x14, 0x14, 0x14, + /* > */ 0x41, 0x22, 0x14, 0x08, 0x00, + /* ? */ 0x00, 0x06, 0x59, 0x05, 0x02, + /* @ */ 0x3E, 0x41, 0x4D, 0x51, 0x4E, + /* A */ 0x7E, 0x11, 0x11, 0x11, 0x7E, + /* B */ 0x41, 0x7F, 0x49, 0x49, 0x36, + /* C */ 0x3E, 0x41, 0x41, 0x41, 0x22, + /* D */ 0x41, 0x7F, 0x41, 0x41, 0x3E, + /* E */ 0x7F, 0x49, 0x49, 0x49, 0x49, + /* F */ 0x7F, 0x09, 0x09, 0x09, 0x01, + /* G */ 0x3E, 0x41, 0x41, 0x49, 0x7A, + /* H */ 0x7F, 0x08, 0x08, 0x08, 0x7F, + /* I */ 0x00, 0x41, 0x7F, 0x41, 0x00, + /* J */ 0x20, 0x40, 0x41, 0x3F, 0x01, + /* K */ 0x7F, 0x08, 0x14, 0x22, 0x41, + /* L */ 0x7F, 0x40, 0x40, 0x40, 0x40, + /* M */ 0x7F, 0x02, 0x0C, 0x02, 0x7F, + /* N */ 0x7F, 0x06, 0x08, 0x30, 0x7F, + /* O */ 0x3E, 0x41, 0x41, 0x41, 0x3E, + /* P */ 0x7F, 0x09, 0x09, 0x09, 0x06, + /* Q */ 0x7E, 0x41, 0x51, 0x21, 0x5E, + /* R */ 0x7F, 0x09, 0x19, 0x29, 0x46, + /* S */ 0x26, 0x49, 0x49, 0x49, 0x32, + /* T */ 0x01, 0x01, 0x7F, 0x01, 0x01, + /* U */ 0x3F, 0x40, 0x40, 0x40, 0x3F, + /* V */ 0x1F, 0x20, 0x40, 0x20, 0x1F, + /* W */ 0x7F, 0x20, 0x18, 0x20, 0x7F, + /* X */ 0x63, 0x14, 0x08, 0x14, 0x63, + /* Y */ 0x07, 0x08, 0x70, 0x08, 0x07, + /* Z */ 0x61, 0x51, 0x49, 0x45, 0x43, + /* [ */ 0x00, 0x7F, 0x41, 0x41, 0x00, + /* \ */ 0x01, 0x06, 0x08, 0x30, 0x40, + /* ] */ 0x00, 0x41, 0x41, 0x7F, 0x00, + /* ^ */ 0x00, 0x06, 0x01, 0x06, 0x00, + /* _ */ 0x40, 0x40, 0x40, 0x40, 0x40, + /* ` */ 0x00, 0x01, 0x02, 0x00, 0x00 +}; + +#define FONT_WIDTH 5 +#define FONT_ASCII_OFFSET ' ' +#define FONT_TABLE_SIZE (sizeof(font)/FONT_WIDTH) + +#endif + diff --git a/apps/hello2/Makefile b/apps/hello2/Makefile new file mode 100644 index 0000000..ca0ca8a --- /dev/null +++ b/apps/hello2/Makefile @@ -0,0 +1,63 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for hello2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: hello2.out + + +# Compile: create object files from C source files. +hello2.o: hello2.c ../../drivers/avr/system.h ../../drivers/display.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +hello2.out: display.o hello2.o ledmat.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: hello2.out + $(OBJCOPY) -O ihex hello2.out hello2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash hello2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/hello2/Makefile.test b/apps/hello2/Makefile.test new file mode 100644 index 0000000..3e16a23 --- /dev/null +++ b/apps/hello2/Makefile.test @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for hello2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: hello2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +hello2-test.o: hello2.c ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +hello2: timer-test.o display-test.o pio-test.o hello2-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) hello2 timer-test.o display-test.o pio-test.o hello2-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o + + diff --git a/apps/hello2/hello2.c b/apps/hello2/hello2.c new file mode 100644 index 0000000..c60b41e --- /dev/null +++ b/apps/hello2/hello2.c @@ -0,0 +1,44 @@ +/** @file hello2.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Simple message display program using tinygl + + @defgroup hello2 Simple message display program using tinygl +*/ + +#include "system.h" +#include "tinygl.h" +#include "pacer.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10s). */ +#define MESSAGE_RATE 10 + + +int main (void) +{ + system_init (); + tinygl_init (LOOP_RATE); + + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + + tinygl_text ("HELLO WORLD"); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + } + + return 0; +} diff --git a/apps/hello3/Makefile b/apps/hello3/Makefile new file mode 100644 index 0000000..9841ff1 --- /dev/null +++ b/apps/hello3/Makefile @@ -0,0 +1,63 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for hello3 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: hello3.out + + +# Compile: create object files from C source files. +hello3.o: hello3.c ../../drivers/avr/system.h ../../drivers/display.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +hello3.out: display.o hello3.o ledmat.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: hello3.out + $(OBJCOPY) -O ihex hello3.out hello3.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash hello3.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/hello3/Makefile.test b/apps/hello3/Makefile.test new file mode 100644 index 0000000..1d009a1 --- /dev/null +++ b/apps/hello3/Makefile.test @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for hello3 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: hello3 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +hello3-test.o: hello3.c ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +hello3: timer-test.o display-test.o pio-test.o hello3-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) hello3 timer-test.o display-test.o pio-test.o hello3-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o + + diff --git a/apps/hello3/hello3.c b/apps/hello3/hello3.c new file mode 100644 index 0000000..aca1cca --- /dev/null +++ b/apps/hello3/hello3.c @@ -0,0 +1,45 @@ +/** @file hello3.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Simple message display program using tinygl + + @defgroup hello3 Simple message display program using tinygl +*/ + +#include "system.h" +#include "tinygl.h" +#include "pacer.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +int main (void) +{ + system_init (); + tinygl_init (LOOP_RATE); + + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + + tinygl_text ("HELLO WORLD"); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + } + + return 0; +} diff --git a/apps/hello4/Makefile b/apps/hello4/Makefile new file mode 100644 index 0000000..1ff1ea7 --- /dev/null +++ b/apps/hello4/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for hello4 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: hello4.out + + +# Compile: create object files from C source files. +hello4.o: hello4.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +hello4.out: display.o hello4.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: hello4.out + $(OBJCOPY) -O ihex hello4.out hello4.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash hello4.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/hello4/Makefile.test b/apps/hello4/Makefile.test new file mode 100644 index 0000000..fd35be3 --- /dev/null +++ b/apps/hello4/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for hello4 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: hello4 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +hello4-test.o: hello4.c ../../drivers/navswitch.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +hello4: timer-test.o display-test.o pio-test.o hello4-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) hello4 timer-test.o display-test.o pio-test.o hello4-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/hello4/hello4.c b/apps/hello4/hello4.c new file mode 100644 index 0000000..e981028 --- /dev/null +++ b/apps/hello4/hello4.c @@ -0,0 +1,56 @@ +/** @file hello4.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Simple message display program using display module. + + @defgroup hello4 Simple message display program using tinygl +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +int main (void) +{ + system_init (); + tinygl_init (LOOP_RATE); + + navswitch_init (); + + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + + tinygl_text ("HELLO WORLD"); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + tinygl_text_mode_set (TINYGL_TEXT_MODE_STEP); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + + } + + return 0; +} diff --git a/apps/ir_grab1/Makefile b/apps/ir_grab1/Makefile new file mode 100644 index 0000000..cbf1cc3 --- /dev/null +++ b/apps/ir_grab1/Makefile @@ -0,0 +1,69 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_grab1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_grab1.out + + +# Compile: create object files from C source files. +ir_grab1.o: ir_grab1.c ../../drivers/avr/delay.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_grab1.out: display.o ir.o ir_grab1.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_grab1.out + $(OBJCOPY) -O ihex ir_grab1.out ir_grab1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_grab1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_grab1/Makefile.test b/apps/ir_grab1/Makefile.test new file mode 100644 index 0000000..84b8c09 --- /dev/null +++ b/apps/ir_grab1/Makefile.test @@ -0,0 +1,63 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_grab1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_grab1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_grab1-test.o: ir_grab1.c ../../drivers/navswitch.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/test/delay.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_grab1: timer-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ir-test.o ledmat-test.o system-test.o ir_grab1-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_grab1 timer-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ir-test.o ledmat-test.o system-test.o ir_grab1-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/ir_grab1/ir_grab1.c b/apps/ir_grab1/ir_grab1.c new file mode 100644 index 0000000..3a56cf7 --- /dev/null +++ b/apps/ir_grab1/ir_grab1.c @@ -0,0 +1,135 @@ +/** @file ir_grab1.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_grab1 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir.h" +#include "delay.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + +/* At 2400 baud and 36 kHz modulation, there are 15 cycles per bit. */ +#define CODE_LEN_MAX 2000 +#define CODESEQ_LEN_MAX 200 + +#define IR_MODULATION_PERIOD_US (1e6 / IR_MODULATION_FREQ) +#define TWEAK_US 0.5 + + +typedef struct code +{ + uint16_t on; + uint16_t off; +} code_t; + + +static void transmit (code_t *codeseq, uint8_t size) +{ + uint8_t i; + + for (i = 0; i < size; i++) + { + ir_tx_set (1, codeseq[i].on); + ir_tx_set (0, codeseq[i].off); + } +} + + +static uint8_t capture (code_t *codeseq, uint8_t size) +{ + uint8_t i; + + for (i = 0; i < size; i++) + { + uint16_t count; + + for (count = 0; count < CODE_LEN_MAX && ir_rx_get (); count++) + { + DELAY_US (IR_MODULATION_PERIOD_US - TWEAK_US); + } + codeseq[i].on = count; + + /* Something funny here. */ + if (count >= CODE_LEN_MAX) + return 0; + + for (count = 0; count < CODE_LEN_MAX && !ir_rx_get (); count++) + { + DELAY_US (IR_MODULATION_PERIOD_US - TWEAK_US); + } + codeseq[i].off = count; + + if (count >= CODE_LEN_MAX) + return i + 1; + } + return i; +} + + +static void show_char (char ch) +{ + char buffer[2]; + + buffer[0] = ch; + buffer[1] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + uint8_t size = 0; + code_t codeseq[CODESEQ_LEN_MAX]; + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + + navswitch_init (); + ir_init (); + + pacer_init (LOOP_RATE); + + show_char ('W'); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_PUSH)) + { + transmit (codeseq, size); + show_char ('T'); + } + + if (ir_rx_get ()) + { + size = capture (codeseq, CODESEQ_LEN_MAX); + show_char (size == 0 ? 'E' : 'R'); +// size = capture (codeseq, 9); +// show_char ('0' + size); + } + } + + return 0; +} diff --git a/apps/ir_grab2/Makefile b/apps/ir_grab2/Makefile new file mode 100644 index 0000000..d71d6f2 --- /dev/null +++ b/apps/ir_grab2/Makefile @@ -0,0 +1,72 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_grab2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_grab2.out + + +# Compile: create object files from C source files. +ir_grab2.o: ir_grab2.c ../../drivers/avr/delay.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/navswitch.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h ../../utils/uint8toa.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa.o: ../../utils/uint8toa.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_grab2.out: display.o ir.o ir_grab2.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o uint8toa.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_grab2.out + $(OBJCOPY) -O ihex ir_grab2.out ir_grab2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_grab2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_grab2/Makefile.test b/apps/ir_grab2/Makefile.test new file mode 100644 index 0000000..b9c9d36 --- /dev/null +++ b/apps/ir_grab2/Makefile.test @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_grab2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_grab2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_grab2-test.o: ir_grab2.c ../../drivers/navswitch.h ../../utils/font.h ../../drivers/test/system.h ../../fonts/font3x5_1.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h ../../utils/uint8toa.h ../../drivers/test/delay.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa-test.o: ../../utils/uint8toa.c ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_grab2: timer-test.o ir_grab2-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ir-test.o uint8toa-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_grab2 timer-test.o ir_grab2-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ir-test.o uint8toa-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/ir_grab2/ir_grab2.c b/apps/ir_grab2/ir_grab2.c new file mode 100644 index 0000000..53f1611 --- /dev/null +++ b/apps/ir_grab2/ir_grab2.c @@ -0,0 +1,153 @@ +/** @file ir_grab2.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_grab2 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir.h" +#include "delay.h" +#include "uint8toa.h" +#include "../fonts/font3x5_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 2000 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + +/* At 2400 baud and 36 kHz modulation, there are 15 cycles per bit. + With a Sony start code of length 4.5 x 0.6 ms there are 86 cycles. */ +#define COUNT_MAX 250 +#define CODESEQ_LEN_MAX 40 + +#define IR_MODULATION_PERIOD_US (1e6 / IR_MODULATION_FREQ) +#define TWEAK_US 0.5 + + +typedef uint8_t count_t; + +typedef struct code +{ + count_t on; + count_t off; +} code_t; + + +static void transmit (code_t *codeseq, uint8_t size) +{ + uint8_t i; + + for (i = 0; i < size; i++) + { + ir_tx_set (1, codeseq[i].on); + ir_tx_set (0, codeseq[i].off); + } +} + + +static uint8_t capture (code_t *codeseq, uint8_t size) +{ + uint8_t i; + + for (i = 0; i < size; i++) + { + count_t count; + + for (count = 0; count < COUNT_MAX && ir_rx_get (); count++) + { + DELAY_US (IR_MODULATION_PERIOD_US - TWEAK_US); + } + codeseq[i].on = count; + + /* Something funny here. */ + if (count >= COUNT_MAX) + return 0; + + for (count = 0; count < COUNT_MAX && !ir_rx_get (); count++) + { + DELAY_US (IR_MODULATION_PERIOD_US - TWEAK_US); + } + codeseq[i].off = count; + + if (count >= COUNT_MAX) + return i + 1; + } + return i; +} + + +static void show_char (char ch) +{ + char buffer[2]; + + buffer[0] = ch; + buffer[1] = 0; + tinygl_text (buffer); +} + + +static void show_num (char ch, uint8_t num) +{ + char buffer[5]; + + buffer[0] = ch; + uint8toa (num, buffer + 1, 0); + tinygl_text (buffer); +} + + +int main (void) +{ + uint8_t size = 0; + code_t codeseq[CODESEQ_LEN_MAX]; + uint8_t count = 0; + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font3x5_1); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + tinygl_text_mode_set (TINYGL_TEXT_MODE_ROTATE_SCROLL_DOWN); + tinygl_text_speed_set (MESSAGE_RATE); + + navswitch_init (); + ir_init (); + + pacer_init (LOOP_RATE); + + show_num ('W', count); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_PUSH)) + { + transmit (codeseq, size); + show_char ('T'); + } + + if (ir_rx_get ()) + { + size = capture (codeseq, CODESEQ_LEN_MAX); + show_num (size == 0 ? 'E' : 'R', size); + count++; +// size = capture (codeseq, 9); +// show_char ('0' + size); + } + } + + return 0; +} diff --git a/apps/ir_grab3/Makefile b/apps/ir_grab3/Makefile new file mode 100644 index 0000000..1284e07 --- /dev/null +++ b/apps/ir_grab3/Makefile @@ -0,0 +1,78 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_grab3 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_grab3.out + + +# Compile: create object files from C source files. +ir_grab3.o: ir_grab3.c ../../drivers/avr/delay.h ../../drivers/avr/eeprom.h ../../drivers/avr/system.h ../../drivers/button.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/led.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom.o: ../../drivers/avr/eeprom.c ../../drivers/avr/eeprom.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +button.o: ../../drivers/button.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/button.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_grab3.out: button.o display.o eeprom.o ir.o ir_grab3.o led.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_grab3.out + $(OBJCOPY) -O ihex ir_grab3.out ir_grab3.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_grab3.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_grab3/Makefile.test b/apps/ir_grab3/Makefile.test new file mode 100644 index 0000000..87f8073 --- /dev/null +++ b/apps/ir_grab3/Makefile.test @@ -0,0 +1,72 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_grab3 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_grab3 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +button-test.o: ../../drivers/button.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/button.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom-test.o: ../../drivers/test/eeprom.c ../../drivers/test/eeprom.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_grab3-test.o: ir_grab3.c ../../drivers/navswitch.h ../../drivers/test/delay.h ../../drivers/test/system.h ../../drivers/test/eeprom.h ../../utils/font.h ../../drivers/led.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/button.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_grab3: timer-test.o pio-test.o led-test.o display-test.o button-test.o pacer-test.o tinygl-test.o ir-test.o ledmat-test.o eeprom-test.o system-test.o mgetkey-test.o ir_grab3-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_grab3 timer-test.o pio-test.o led-test.o display-test.o button-test.o pacer-test.o tinygl-test.o ir-test.o ledmat-test.o eeprom-test.o system-test.o mgetkey-test.o ir_grab3-test.o navswitch-test.o + + diff --git a/apps/ir_grab3/ir_grab3.c b/apps/ir_grab3/ir_grab3.c new file mode 100644 index 0000000..54f6d1f --- /dev/null +++ b/apps/ir_grab3/ir_grab3.c @@ -0,0 +1,245 @@ +/** @file ir_grab3.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_grab3 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "button.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir.h" +#include "led.h" +#include "delay.h" +#include "eeprom.h" +#include "../fonts/font5x7_1.h" +#include + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 2000 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + +/* At 2400 baud and 36 kHz modulation, there are 15 cycles per bit. + With a Sony start code of length 4.5 x 0.6 ms there are 86 cycles. */ +#define COUNT_MAX 250 + +#define CODESEQ_LEN_MAX 25 + +#define CODESEQ_NUM 5 + +#define IR_MODULATION_PERIOD_US (1e6 / IR_MODULATION_FREQ) + +#define LOOP_TWEAK_US 1.5 + + +typedef enum {STATE_NORMAL, STATE_LEARN, STATE_STORE} state_t; + + +typedef uint8_t count_t; + +typedef struct code +{ + count_t on; + count_t off; +} code_t; + + +static void transmit (code_t *codeseq) +{ + uint8_t i; + + for (i = 0; codeseq[i].on != 0; i++) + { + ir_tx_set (1, codeseq[i].on); + ir_tx_set (0, codeseq[i].off); + } +} + + +static uint8_t capture (code_t *codeseq, uint8_t size) +{ + uint8_t i; + + for (i = 0; i < size - 1; i++) + { + count_t count; + + for (count = 0; count < COUNT_MAX && ir_rx_get (); count++) + { + DELAY_US (IR_MODULATION_PERIOD_US - LOOP_TWEAK_US); + } + codeseq[i].on = count; + + for (count = 0; count < COUNT_MAX && !ir_rx_get (); count++) + { + DELAY_US (IR_MODULATION_PERIOD_US - LOOP_TWEAK_US - 1.0); + } + codeseq[i].off = count; + + if (count >= COUNT_MAX) + { + /* Mark end of sequence. */ + codeseq[i + 1].on = 0; + return i + 1; + } + } + /* Sequence is too long. */ + return 0; +} + + +static void codeseqs_write (code_t *codeseqs, uint8_t len, uint8_t num) +{ + eeprom_write (0, codeseqs, sizeof (codeseqs[0]) * len * num); +} + + +static void codeseqs_read (code_t *codeseqs, uint8_t len, uint8_t num) +{ + /* When the EEPROM is erased all the bytes are 0xFF so set to + sensible defaults. */ + eeprom_read (0, codeseqs, sizeof (codeseqs[0]) * len * num); + if (codeseqs[0].on == 0xff) + { + uint8_t i; + + for (i = 0; i < num; i++) + codeseqs[i * len].on = 0; + + codeseqs_write (codeseqs, len, num); + } +} + + +static int switch_get (void) +{ + if (navswitch_push_event_p (NAVSWITCH_PUSH)) + return 0; + else if (navswitch_push_event_p (NAVSWITCH_NORTH)) + return 1; + else if (navswitch_push_event_p (NAVSWITCH_EAST)) + return 2; + else if (navswitch_push_event_p (NAVSWITCH_SOUTH)) + return 3; + else if (navswitch_push_event_p (NAVSWITCH_WEST)) + return 4; + + return -1; +} + + +int main (void) +{ + state_t state = STATE_NORMAL; + code_t codeseq[CODESEQ_LEN_MAX]; + code_t codeseqs[CODESEQ_LEN_MAX * CODESEQ_NUM]; + int seq; + static const char *strings[] = {"P", "N", "E", "S", "W"}; + + codeseqs_read (codeseqs, CODESEQ_LEN_MAX, CODESEQ_NUM); + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + + navswitch_init (); + button_init (); + led_init (); + ir_init (); + + pacer_init (LOOP_RATE); + + tinygl_text ("X"); + led_set (LED1, 0); + + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + switch (state) + { + case STATE_NORMAL: + + tinygl_update (); + navswitch_update (); + button_update (); + + seq = switch_get (); + + if (seq != -1) + { + tinygl_text (strings[seq]); + transmit (&codeseqs[seq * CODESEQ_LEN_MAX]); + } + + if (button_push_event_p (BUTTON1)) + { + led_set (LED1, 1); + state = STATE_LEARN; + } + break; + + case STATE_LEARN: + + while (1) + { + /* Loop as fast as possible so that capture start of IR transmission + as soon as possible. */ + button_update (); + + if (ir_rx_get ()) + { + if (capture (codeseq, CODESEQ_LEN_MAX)) + { + tinygl_text ("?"); + led_set (LED1, 1); + state = STATE_STORE; + break; + } + } + + if (button_push_event_p (BUTTON1)) + { + led_set (LED1, 0); + state = STATE_NORMAL; + break; + } + } + break; + + case STATE_STORE: + + tinygl_update (); + navswitch_update (); + button_update (); + + seq = switch_get (); + + if (seq != -1) + { + memcpy (&codeseqs[seq * CODESEQ_LEN_MAX], codeseq, sizeof (codeseq)); + codeseqs_write (codeseqs, CODESEQ_LEN_MAX, CODESEQ_NUM); + tinygl_text (strings[seq]); + led_set (LED1, 0); + state = STATE_NORMAL; + } + + if (button_push_event_p (BUTTON1)) + { + led_set (LED1, 0); + state = STATE_NORMAL; + } + break; + } + } + + return 0; +} diff --git a/apps/ir_serial_test1/Makefile b/apps/ir_serial_test1/Makefile new file mode 100644 index 0000000..6f85bf1 --- /dev/null +++ b/apps/ir_serial_test1/Makefile @@ -0,0 +1,72 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_serial_test1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_serial_test1.out + + +# Compile: create object files from C source files. +ir_serial_test1.o: ir_serial_test1.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/navswitch.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial.o: ../../drivers/ir_serial.c ../../drivers/avr/delay.h ../../drivers/avr/system.h ../../drivers/ir.h ../../drivers/ir_serial.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_serial_test1.out: display.o ir.o ir_serial.o ir_serial_test1.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_serial_test1.out + $(OBJCOPY) -O ihex ir_serial_test1.out ir_serial_test1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_serial_test1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_serial_test1/Makefile.test b/apps/ir_serial_test1/Makefile.test new file mode 100644 index 0000000..645a5dc --- /dev/null +++ b/apps/ir_serial_test1/Makefile.test @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_serial_test1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_serial_test1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial-test.o: ../../drivers/ir_serial.c ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial_test1-test.o: ir_serial_test1.c ../../drivers/navswitch.h ../../utils/font.h ../../drivers/ir_serial.h ../../drivers/test/system.h ../../fonts/font3x5_1.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_serial_test1: timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o ir_serial_test1-test.o tinygl-test.o ir-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_serial_test1 timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o ir_serial_test1-test.o tinygl-test.o ir-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/ir_serial_test1/ir_serial_test1.c b/apps/ir_serial_test1/ir_serial_test1.c new file mode 100644 index 0000000..aa27c62 --- /dev/null +++ b/apps/ir_serial_test1/ir_serial_test1.c @@ -0,0 +1,101 @@ +/** @file ir_serial_test1.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_serial_test1 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir_serial.h" +#include "../fonts/font3x5_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +static void show_count (uint8_t count) +{ + char buffer[3]; + + /* FIXME! */ + buffer[0] = 'S'; + buffer[1] = count + '0'; + buffer[2] = 0; + tinygl_text (buffer); +} + + +static void show_err (uint8_t err) +{ + char buffer[3]; + + buffer[0] = 'E'; + buffer[1] = err + '0'; + buffer[2] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + int count = 5; + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font3x5_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_ROTATE_SCROLL_DOWN); + + navswitch_init (); + ir_serial_init (); + + show_count (count); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + int ret; + uint8_t data; + + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + ir_serial_transmit (1); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + ir_serial_transmit (2); + + ret = ir_serial_receive (&data); + if (ret == IR_SERIAL_OK) + { + if (data == 1) + count--; + else if (data == 2) + count++; + else + count = 0; + show_count (count); + } + else if (ret < 0) + { + show_err (-ret); + } + } + + return 0; +} diff --git a/apps/ir_serial_test2/Makefile b/apps/ir_serial_test2/Makefile new file mode 100644 index 0000000..5969d77 --- /dev/null +++ b/apps/ir_serial_test2/Makefile @@ -0,0 +1,72 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_serial_test2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_serial_test2.out + + +# Compile: create object files from C source files. +ir_serial_test2.o: ir_serial_test2.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial.o: ../../drivers/ir_serial.c ../../drivers/avr/delay.h ../../drivers/avr/system.h ../../drivers/ir.h ../../drivers/ir_serial.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_serial_test2.out: display.o ir.o ir_serial.o ir_serial_test2.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_serial_test2.out + $(OBJCOPY) -O ihex ir_serial_test2.out ir_serial_test2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_serial_test2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_serial_test2/Makefile.test b/apps/ir_serial_test2/Makefile.test new file mode 100644 index 0000000..fce243e --- /dev/null +++ b/apps/ir_serial_test2/Makefile.test @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_serial_test2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_serial_test2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial-test.o: ../../drivers/ir_serial.c ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial_test2-test.o: ir_serial_test2.c ../../drivers/navswitch.h ../../drivers/ir_serial.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_serial_test2: timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o ir_serial_test2-test.o tinygl-test.o ir-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_serial_test2 timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o ir_serial_test2-test.o tinygl-test.o ir-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/ir_serial_test2/ir_serial_test2.c b/apps/ir_serial_test2/ir_serial_test2.c new file mode 100644 index 0000000..d73063d --- /dev/null +++ b/apps/ir_serial_test2/ir_serial_test2.c @@ -0,0 +1,83 @@ +/** @file ir_serial_test2.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_serial_test2 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir_serial.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +static void show_count (uint8_t count) +{ + char buffer[2]; + + /* FIXME! */ + buffer[0] = count + '0'; + buffer[1] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + int count = 5; + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_STEP); + + navswitch_init (); + ir_serial_init (); + + show_count (count); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + int ret; + uint8_t data; + + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + ir_serial_transmit (1); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + ir_serial_transmit (2); + + ret = ir_serial_receive (&data); + if (ret == IR_SERIAL_OK) + { + if (data == 1) + count--; + else if (data == 2) + count++; + show_count (count); + } + } + + return 0; +} diff --git a/apps/ir_serial_test3/Makefile b/apps/ir_serial_test3/Makefile new file mode 100644 index 0000000..be21b31 --- /dev/null +++ b/apps/ir_serial_test3/Makefile @@ -0,0 +1,72 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_serial_test3 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_serial_test3.out + + +# Compile: create object files from C source files. +ir_serial_test3.o: ir_serial_test3.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial.o: ../../drivers/ir_serial.c ../../drivers/avr/delay.h ../../drivers/avr/system.h ../../drivers/ir.h ../../drivers/ir_serial.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_serial_test3.out: display.o ir.o ir_serial.o ir_serial_test3.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_serial_test3.out + $(OBJCOPY) -O ihex ir_serial_test3.out ir_serial_test3.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_serial_test3.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_serial_test3/Makefile.test b/apps/ir_serial_test3/Makefile.test new file mode 100644 index 0000000..e08f94c --- /dev/null +++ b/apps/ir_serial_test3/Makefile.test @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_serial_test3 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_serial_test3 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial-test.o: ../../drivers/ir_serial.c ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial_test3-test.o: ir_serial_test3.c ../../drivers/navswitch.h ../../drivers/ir_serial.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_serial_test3: timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o tinygl-test.o ir-test.o ledmat-test.o ir_serial_test3-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_serial_test3 timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o tinygl-test.o ir-test.o ledmat-test.o ir_serial_test3-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/ir_serial_test3/ir_serial_test3.c b/apps/ir_serial_test3/ir_serial_test3.c new file mode 100644 index 0000000..4c06ca6 --- /dev/null +++ b/apps/ir_serial_test3/ir_serial_test3.c @@ -0,0 +1,77 @@ +/** @file ir_serial_test3.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_serial_test3 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir_serial.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +static void show_count (uint8_t count) +{ + char buffer[2]; + + /* FIXME! */ + buffer[0] = count + '0'; + buffer[1] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + int count = 5; + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_STEP); + + navswitch_init (); + ir_serial_init (); + + show_count (count); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + int ret; + uint8_t data; + + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + ir_serial_transmit (--count); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + ir_serial_transmit (++count); + + ret = ir_serial_receive (&data); + if (ret == IR_SERIAL_OK) + show_count (data); + } + + return 0; +} diff --git a/apps/ir_uart_test1/Makefile b/apps/ir_uart_test1/Makefile new file mode 100644 index 0000000..d139042 --- /dev/null +++ b/apps/ir_uart_test1/Makefile @@ -0,0 +1,78 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_uart_test1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_uart_test1.out + + +# Compile: create object files from C source files. +ir_uart_test1.o: ir_uart_test1.c ../../drivers/avr/ir_uart.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_uart.o: ../../drivers/avr/ir_uart.c ../../drivers/avr/ir_uart.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/avr/timer0.h ../../drivers/avr/usart1.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +prescale.o: ../../drivers/avr/prescale.c ../../drivers/avr/prescale.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer0.o: ../../drivers/avr/timer0.c ../../drivers/avr/bits.h ../../drivers/avr/prescale.h ../../drivers/avr/system.h ../../drivers/avr/timer0.h + $(CC) -c $(CFLAGS) $< -o $@ + +usart1.o: ../../drivers/avr/usart1.c ../../drivers/avr/system.h ../../drivers/avr/usart1.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_uart_test1.out: display.o ir_uart.o ir_uart_test1.o ledmat.o navswitch.o pacer.o pio.o prescale.o system.o timer.o timer0.o tinygl.o usart1.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_uart_test1.out + $(OBJCOPY) -O ihex ir_uart_test1.out ir_uart_test1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_uart_test1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_uart_test1/Makefile.test b/apps/ir_uart_test1/Makefile.test new file mode 100644 index 0000000..31dbe0e --- /dev/null +++ b/apps/ir_uart_test1/Makefile.test @@ -0,0 +1,63 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_uart_test1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_uart_test1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_uart-test.o: ../../drivers/test/ir_uart.c ../../drivers/test/ir_uart.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_uart_test1-test.o: ir_uart_test1.c ../../drivers/navswitch.h ../../drivers/test/system.h ../../utils/font.h ../../drivers/test/ir_uart.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_uart_test1: timer-test.o display-test.o pio-test.o pacer-test.o ir_uart-test.o tinygl-test.o ledmat-test.o system-test.o ir_uart_test1-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_uart_test1 timer-test.o display-test.o pio-test.o pacer-test.o ir_uart-test.o tinygl-test.o ledmat-test.o system-test.o ir_uart_test1-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/ir_uart_test1/ir_uart_test1.c b/apps/ir_uart_test1/ir_uart_test1.c new file mode 100644 index 0000000..11b9091 --- /dev/null +++ b/apps/ir_uart_test1/ir_uart_test1.c @@ -0,0 +1,83 @@ +/** @file ir_uart_test1.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_uart_test1 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir_uart.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +static void show_count (uint8_t count) +{ + char buffer[2]; + + /* FIXME! */ + buffer[0] = count + '0'; + buffer[1] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + int count = 5; + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_STEP); + + navswitch_init (); + ir_uart_init (); + + show_count (count); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + ir_uart_putc ('1'); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + ir_uart_putc ('2'); + + if (ir_uart_read_ready_p ()) + { + uint8_t data; + + data = ir_uart_getc (); + + if (data == '1') + count--; + else if (data == '2') + count++; + show_count (count); + } + } + + return 0; +} diff --git a/apps/ir_uart_test2/Makefile b/apps/ir_uart_test2/Makefile new file mode 100644 index 0000000..80eebf2 --- /dev/null +++ b/apps/ir_uart_test2/Makefile @@ -0,0 +1,78 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for ir_uart_test2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: ir_uart_test2.out + + +# Compile: create object files from C source files. +ir_uart_test2.o: ir_uart_test2.c ../../drivers/avr/ir_uart.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_uart.o: ../../drivers/avr/ir_uart.c ../../drivers/avr/ir_uart.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/avr/timer0.h ../../drivers/avr/usart1.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +prescale.o: ../../drivers/avr/prescale.c ../../drivers/avr/prescale.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer0.o: ../../drivers/avr/timer0.c ../../drivers/avr/bits.h ../../drivers/avr/prescale.h ../../drivers/avr/system.h ../../drivers/avr/timer0.h + $(CC) -c $(CFLAGS) $< -o $@ + +usart1.o: ../../drivers/avr/usart1.c ../../drivers/avr/system.h ../../drivers/avr/usart1.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +ir_uart_test2.out: display.o ir_uart.o ir_uart_test2.o ledmat.o navswitch.o pacer.o pio.o prescale.o system.o timer.o timer0.o tinygl.o usart1.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: ir_uart_test2.out + $(OBJCOPY) -O ihex ir_uart_test2.out ir_uart_test2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash ir_uart_test2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/ir_uart_test2/Makefile.test b/apps/ir_uart_test2/Makefile.test new file mode 100644 index 0000000..c3482ad --- /dev/null +++ b/apps/ir_uart_test2/Makefile.test @@ -0,0 +1,63 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for ir_uart_test2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: ir_uart_test2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +ir_uart_test2-test.o: ir_uart_test2.c ../../drivers/navswitch.h ../../drivers/test/system.h ../../utils/font.h ../../drivers/test/ir_uart.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_uart-test.o: ../../drivers/test/ir_uart.c ../../drivers/test/ir_uart.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +ir_uart_test2: timer-test.o display-test.o pio-test.o ir_uart_test2-test.o pacer-test.o ir_uart-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) ir_uart_test2 timer-test.o display-test.o pio-test.o ir_uart_test2-test.o pacer-test.o ir_uart-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/ir_uart_test2/ir_uart_test2.c b/apps/ir_uart_test2/ir_uart_test2.c new file mode 100644 index 0000000..e552167 --- /dev/null +++ b/apps/ir_uart_test2/ir_uart_test2.c @@ -0,0 +1,77 @@ +/** @file ir_uart_test2.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communnications. + + @defgroup ir_uart_test2 Test program for IR serial communications. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir_uart.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +static void show_char (char ch) +{ + char buffer[2]; + + buffer[0] = ch; + buffer[1] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_STEP); + + navswitch_init (); + ir_uart_init (); + + pacer_init (LOOP_RATE); + + show_char ('M'); + + /* Paced loop. */ + while (1) + { + uint8_t data = 'M'; + + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + ir_uart_putc (--data); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + ir_uart_putc (++data); + + if (ir_uart_read_ready_p ()) + { + uint8_t data; + + data = ir_uart_getc (); + show_char (data); + } + } + + return 0; +} diff --git a/apps/led1/Makefile b/apps/led1/Makefile new file mode 100644 index 0000000..d8a8531 --- /dev/null +++ b/apps/led1/Makefile @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for led1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: led1.out + + +# Compile: create object files from C source files. +led1.o: led1.c ../../drivers/avr/system.h ../../drivers/led.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +led1.out: led.o led1.o pacer.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: led1.out + $(OBJCOPY) -O ihex led1.out led1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash led1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/led1/Makefile.test b/apps/led1/Makefile.test new file mode 100644 index 0000000..d7e11d1 --- /dev/null +++ b/apps/led1/Makefile.test @@ -0,0 +1,51 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for led1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: led1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +led1-test.o: led1.c ../../drivers/led.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +led1: timer-test.o led-test.o pio-test.o pacer-test.o system-test.o mgetkey-test.o led1-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) led1 timer-test.o led-test.o pio-test.o pacer-test.o system-test.o mgetkey-test.o led1-test.o + + diff --git a/apps/led1/led1.c b/apps/led1/led1.c new file mode 100644 index 0000000..7e32e1b --- /dev/null +++ b/apps/led1/led1.c @@ -0,0 +1,40 @@ +/** @file led1.c + @author M.P. Hayes + @date 5 Oct 2010 +*/ + +#include "system.h" +#include "led.h" +#include "pacer.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 1000 + +#define LED_RATE 2 + +int main (void) +{ + unsigned int count = 0; + unsigned int period = LOOP_RATE / LED_RATE; + + system_init (); + + pacer_init (LOOP_RATE); + led_init (); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + led_set (LED1, count < period / 2); + count++; + if (count >= period) + count = 0; + + } + + return 0; +} diff --git a/apps/led2/Makefile b/apps/led2/Makefile new file mode 100644 index 0000000..0a9af1f --- /dev/null +++ b/apps/led2/Makefile @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for led2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: led2.out + + +# Compile: create object files from C source files. +led2.o: led2.c ../../drivers/avr/system.h ../../drivers/led.h ../../drivers/navswitch.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +led2.out: led.o led2.o navswitch.o pacer.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: led2.out + $(OBJCOPY) -O ihex led2.out led2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash led2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/led2/Makefile.test b/apps/led2/Makefile.test new file mode 100644 index 0000000..4688fd4 --- /dev/null +++ b/apps/led2/Makefile.test @@ -0,0 +1,54 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for led2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: led2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led2-test.o: led2.c ../../drivers/led.h ../../utils/pacer.h ../../drivers/navswitch.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +led2: timer-test.o led-test.o pio-test.o pacer-test.o system-test.o led2-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) led2 timer-test.o led-test.o pio-test.o pacer-test.o system-test.o led2-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/led2/led2.c b/apps/led2/led2.c new file mode 100644 index 0000000..1ec982b --- /dev/null +++ b/apps/led2/led2.c @@ -0,0 +1,69 @@ +/** @file led2.c + @author M.P. Hayes + @date 5 Oct 2010 +*/ + +#include "system.h" +#include "navswitch.h" +#include "led.h" +#include "pacer.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 1000 + +#define LED_RATE_INC 2 +#define LED_RATE_MIN 0 +#define LED_RATE_MAX 100 + +typedef struct pen pen_t; + + +int main (void) +{ + int freq = 1; + unsigned int count = 0; + unsigned int period = LOOP_RATE / freq; + + system_init (); + + pacer_init (LOOP_RATE); + led_init (); + navswitch_init (); + + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_SOUTH)) + { + freq -= LED_RATE_INC; + if (freq < LED_RATE_MIN) + freq = LED_RATE_MIN; + + period = LOOP_RATE / freq; + } + + if (navswitch_push_event_p (NAVSWITCH_NORTH)) + { + freq += LED_RATE_INC; + if (freq > LED_RATE_MAX) + freq = LED_RATE_MAX; + + period = LOOP_RATE / freq; + } + + led_set (LED1, count < period / 2); + count++; + if (count >= period) + count = 0; + + } + + return 0; +} diff --git a/apps/led3/Makefile b/apps/led3/Makefile new file mode 100644 index 0000000..2af9acf --- /dev/null +++ b/apps/led3/Makefile @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for led3 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: led3.out + + +# Compile: create object files from C source files. +led3.o: led3.c ../../drivers/avr/system.h ../../drivers/led.h ../../drivers/navswitch.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +led3.out: led.o led3.o navswitch.o pacer.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: led3.out + $(OBJCOPY) -O ihex led3.out led3.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash led3.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/led3/Makefile.test b/apps/led3/Makefile.test new file mode 100644 index 0000000..f6502c9 --- /dev/null +++ b/apps/led3/Makefile.test @@ -0,0 +1,54 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for led3 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: led3 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led3-test.o: led3.c ../../drivers/led.h ../../utils/pacer.h ../../drivers/navswitch.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +led3: timer-test.o led-test.o pio-test.o system-test.o pacer-test.o mgetkey-test.o navswitch-test.o led3-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) led3 timer-test.o led-test.o pio-test.o system-test.o pacer-test.o mgetkey-test.o navswitch-test.o led3-test.o + + diff --git a/apps/led3/led3.c b/apps/led3/led3.c new file mode 100644 index 0000000..f9f8061 --- /dev/null +++ b/apps/led3/led3.c @@ -0,0 +1,68 @@ +/** @file led3.c + @author M.P. Hayes + @date 5 Oct 2010 +*/ + +#include "system.h" +#include "navswitch.h" +#include "led.h" +#include "pacer.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 1000 + +#define LED_RATE 50 +#define LED_DUTY_INC 5 +#define LED_DUTY_MIN 0 +#define LED_DUTY_MAX 100 + + +int main (void) +{ + int duty = 50; + unsigned int count = 0; + unsigned int period = LOOP_RATE / LED_RATE; + unsigned int offcount = period * duty / 100; + + system_init (); + + pacer_init (LOOP_RATE); + led_init (); + navswitch_init (); + + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_SOUTH)) + { + duty -= LED_DUTY_INC; + if (duty < LED_DUTY_MIN) + duty = LED_DUTY_MIN; + + offcount = period * duty / 100; + } + + if (navswitch_push_event_p (NAVSWITCH_NORTH)) + { + duty += LED_DUTY_INC; + if (duty > LED_DUTY_MAX) + duty = LED_DUTY_MAX; + offcount = period * duty / 100; + } + + led_set (LED1, count < offcount); + count++; + if (count >= period) + count = 0; + + } + + return 0; +} diff --git a/apps/led4/Makefile b/apps/led4/Makefile new file mode 100644 index 0000000..f06bdb2 --- /dev/null +++ b/apps/led4/Makefile @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for led4 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: led4.out + + +# Compile: create object files from C source files. +led4.o: led4.c ../../drivers/avr/system.h ../../drivers/led.h ../../drivers/navswitch.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +led4.out: led.o led4.o navswitch.o pacer.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: led4.out + $(OBJCOPY) -O ihex led4.out led4.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash led4.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/led4/Makefile.test b/apps/led4/Makefile.test new file mode 100644 index 0000000..3cc9689 --- /dev/null +++ b/apps/led4/Makefile.test @@ -0,0 +1,54 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for led4 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: led4 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +led4-test.o: led4.c ../../drivers/led.h ../../utils/pacer.h ../../drivers/navswitch.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +led4: timer-test.o led-test.o pio-test.o led4-test.o pacer-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) led4 timer-test.o led-test.o pio-test.o led4-test.o pacer-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/led4/led4.c b/apps/led4/led4.c new file mode 100644 index 0000000..182e4c5 --- /dev/null +++ b/apps/led4/led4.c @@ -0,0 +1,68 @@ +/** @file led4.c + @author M.P. Hayes + @date 5 Oct 2010 +*/ + +#include "system.h" +#include "navswitch.h" +#include "led.h" +#include "pacer.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 4000 + +#define LED_RATE 40 + +typedef struct pen pen_t; + + +int main (void) +{ + unsigned int duty[] = {0, 1, 2, 5, 10, 20, 50, 100}; + unsigned int duty_index = 3; + unsigned int count = 0; + unsigned int period = LOOP_RATE / LED_RATE; + unsigned int offcount = period * duty[duty_index] / 100; + + system_init (); + + pacer_init (LOOP_RATE); + led_init (); + navswitch_init (); + + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + /* There is no need to poll the switches so frequently but it + keeps the code simpler. */ + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_SOUTH)) + { + if (duty_index > 0) + duty_index--; + + offcount = (period * duty[duty_index] + 50) / 100; + } + + if (navswitch_push_event_p (NAVSWITCH_NORTH)) + { + duty_index++; + if (duty_index >= ARRAY_SIZE (duty)) + duty_index = ARRAY_SIZE (duty) - 1; + offcount = (period * duty[duty_index] + 50) / 100; + } + + led_set (LED1, count < offcount); + count++; + if (count >= period) + count = 0; + } + + return 0; +} diff --git a/apps/led5/Makefile b/apps/led5/Makefile new file mode 100644 index 0000000..ed60927 --- /dev/null +++ b/apps/led5/Makefile @@ -0,0 +1,54 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for led5 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: led5.out + + +# Compile: create object files from C source files. +led5.o: led5.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +led5.out: led.o led5.o pio.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: led5.out + $(OBJCOPY) -O ihex led5.out led5.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash led5.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/led5/Makefile.test b/apps/led5/Makefile.test new file mode 100644 index 0000000..22f79f7 --- /dev/null +++ b/apps/led5/Makefile.test @@ -0,0 +1,48 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for led5 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: led5 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +led5-test.o: led5.c ../../drivers/test/timer.h ../../drivers/led.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +led5: timer-test.o mgetkey-test.o led-test.o pio-test.o led5-test.o system-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) led5 timer-test.o mgetkey-test.o led-test.o pio-test.o led5-test.o system-test.o + + diff --git a/apps/led5/led5.c b/apps/led5/led5.c new file mode 100644 index 0000000..a3da777 --- /dev/null +++ b/apps/led5/led5.c @@ -0,0 +1,31 @@ +/** @file led5.c + @author M.P. Hayes + @date 18 Aug 2011 +*/ + +#include "system.h" +#include "timer.h" +#include "led.h" + +int main (void) +{ + timer_tick_t now; + + system_init (); + + timer_init (); + led_init (); + + now = timer_get (); + while (1) + { + led_set (LED1, 1); + + now = timer_wait_until (now + (timer_tick_t)(TIMER_RATE * 0.5)); + + led_set (LED1, 0); + + now = timer_wait_until (now + (timer_tick_t)(TIMER_RATE * 0.75)); + } + return 0; +} diff --git a/apps/pio1/Makefile b/apps/pio1/Makefile new file mode 100644 index 0000000..b1e5326 --- /dev/null +++ b/apps/pio1/Makefile @@ -0,0 +1,48 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for pio1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: pio1.out + + +# Compile: create object files from C source files. +pio1.o: pio1.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +pio1.out: pio.o pio1.o system.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: pio1.out + $(OBJCOPY) -O ihex pio1.out pio1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash pio1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/pio1/Makefile.test b/apps/pio1/Makefile.test new file mode 100644 index 0000000..9ce7261 --- /dev/null +++ b/apps/pio1/Makefile.test @@ -0,0 +1,42 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for pio1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: pio1 + + +# Compile: create object files from C source files. +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio1-test.o: pio1.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +pio1: mgetkey-test.o pio1-test.o pio-test.o system-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) pio1 mgetkey-test.o pio1-test.o pio-test.o system-test.o + + diff --git a/apps/pio1/pio1.c b/apps/pio1/pio1.c new file mode 100644 index 0000000..a1b6e53 --- /dev/null +++ b/apps/pio1/pio1.c @@ -0,0 +1,21 @@ +/** @file pio1.c + @author M.P. Hayes + @date 25 Aug 2011 +*/ + +#include "system.h" +#include "pio.h" + +int main (void) +{ + system_init (); + + pio_config_set (LED1_PIO, PIO_OUTPUT_HIGH); + + while (1) + { + pio_output_toggle (LED1_PIO); + } + + return 0; +} diff --git a/apps/pio2/Makefile b/apps/pio2/Makefile new file mode 100644 index 0000000..cdeaa43 --- /dev/null +++ b/apps/pio2/Makefile @@ -0,0 +1,48 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for pio2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: pio2.out + + +# Compile: create object files from C source files. +pio2.o: pio2.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +pio2.out: pio.o pio2.o system.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: pio2.out + $(OBJCOPY) -O ihex pio2.out pio2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash pio2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/pio2/Makefile.test b/apps/pio2/Makefile.test new file mode 100644 index 0000000..5f19707 --- /dev/null +++ b/apps/pio2/Makefile.test @@ -0,0 +1,42 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for pio2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: pio2 + + +# Compile: create object files from C source files. +pio2-test.o: pio2.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +pio2: pio2-test.o mgetkey-test.o pio-test.o system-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) pio2 pio2-test.o mgetkey-test.o pio-test.o system-test.o + + diff --git a/apps/pio2/pio2.c b/apps/pio2/pio2.c new file mode 100644 index 0000000..324efb0 --- /dev/null +++ b/apps/pio2/pio2.c @@ -0,0 +1,27 @@ +/** @file pio2.c + @author M.P. Hayes + @date 25 Aug 2011 +*/ + +#include "system.h" +#include "pio.h" + +int main (void) +{ + uint16_t count = 0; + + system_init (); + + pio_config_set (LED1_PIO, PIO_OUTPUT_HIGH); + + while (1) + { + if (count > 10000) + { + pio_output_toggle (LED1_PIO); + count = 0; + } + } + + return 0; +} diff --git a/apps/pio3/Makefile b/apps/pio3/Makefile new file mode 100644 index 0000000..6d5f643 --- /dev/null +++ b/apps/pio3/Makefile @@ -0,0 +1,51 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for pio3 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: pio3.out + + +# Compile: create object files from C source files. +pio3.o: pio3.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +pio3.out: pio.o pio3.o system.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: pio3.out + $(OBJCOPY) -O ihex pio3.out pio3.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash pio3.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/pio3/Makefile.test b/apps/pio3/Makefile.test new file mode 100644 index 0000000..0b2c617 --- /dev/null +++ b/apps/pio3/Makefile.test @@ -0,0 +1,45 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for pio3 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: pio3 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pio3-test.o: pio3.c ../../drivers/test/timer.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +pio3: timer-test.o mgetkey-test.o pio-test.o pio3-test.o system-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) pio3 timer-test.o mgetkey-test.o pio-test.o pio3-test.o system-test.o + + diff --git a/apps/pio3/pio3.c b/apps/pio3/pio3.c new file mode 100644 index 0000000..55eb797 --- /dev/null +++ b/apps/pio3/pio3.c @@ -0,0 +1,40 @@ +/** @file pio3.c + @author M.P. Hayes + @date 25 Aug 2011 +*/ + +#include "system.h" +#include "pio.h" +#include "timer.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 1000 + +#define LED_RATE 2 + +int main (void) +{ + unsigned int count = 0; + unsigned int period = LOOP_RATE / LED_RATE; + + system_init (); + + timer_init (); + + pio_config_set (LED1_PIO, PIO_OUTPUT_HIGH); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + timer_wait (TIMER_RATE / LOOP_RATE); + + pio_output_set (LED1_PIO, count < period / 2); + count++; + if (count >= period) + count = 0; + } + + return 0; +} diff --git a/apps/scribble1/Makefile b/apps/scribble1/Makefile new file mode 100644 index 0000000..706ba2f --- /dev/null +++ b/apps/scribble1/Makefile @@ -0,0 +1,72 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for scribble1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: scribble1.out + + +# Compile: create object files from C source files. +scribble1.o: scribble1.c ../../drivers/avr/system.h ../../drivers/button.h ../../drivers/display.h ../../drivers/led.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +button.o: ../../drivers/button.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/button.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +scribble1.out: button.o display.o led.o ledmat.o navswitch.o pacer.o pio.o scribble1.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: scribble1.out + $(OBJCOPY) -O ihex scribble1.out scribble1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash scribble1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/scribble1/Makefile.test b/apps/scribble1/Makefile.test new file mode 100644 index 0000000..a53607f --- /dev/null +++ b/apps/scribble1/Makefile.test @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for scribble1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: scribble1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +button-test.o: ../../drivers/button.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/button.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +scribble1-test.o: scribble1.c ../../drivers/navswitch.h ../../drivers/test/system.h ../../utils/font.h ../../drivers/led.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/button.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +scribble1: timer-test.o led-test.o display-test.o pio-test.o button-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o scribble1-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) scribble1 timer-test.o led-test.o display-test.o pio-test.o button-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o scribble1-test.o + + diff --git a/apps/scribble1/scribble1.c b/apps/scribble1/scribble1.c new file mode 100644 index 0000000..5dadaa6 --- /dev/null +++ b/apps/scribble1/scribble1.c @@ -0,0 +1,104 @@ +/** @file scribble1.c + @author M.P. Hayes + @date 5 Oct 2010 +*/ + +#include "system.h" +#include "button.h" +#include "navswitch.h" +#include "led.h" +#include "tinygl.h" +#include "pacer.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +#define SCRIBBLE_SPEED 2 + + +typedef enum dir dir_t; + +struct pen +{ + /* Current pos of pen. */ + tinygl_point_t pos; + /* Current state of pen. */ + bool state; +}; + +typedef struct pen pen_t; + + +int main (void) +{ + pen_t pen; + + system_init (); + + pen.pos.x = TINYGL_WIDTH / 2; + pen.pos.y = TINYGL_HEIGHT / 2; + pen.state = 1; + + pacer_init (LOOP_RATE); + led_init (); + button_init (); + navswitch_init (); + + tinygl_init (LOOP_RATE); + tinygl_draw_point (pen.pos, pen.state); + + led_set (LED1, pen.state); + + /* Paced loop. */ + while (1) + { + bool draw = 0; + + /* Wait for next tick. */ + pacer_wait (); + + navswitch_update (); + button_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST) && pen.pos.x > 0) + { + pen.pos.x--; + draw = 1; + } + + if (navswitch_push_event_p (NAVSWITCH_EAST) && pen.pos.x < TINYGL_WIDTH - 1) + { + pen.pos.x++; + draw = 1; + } + + if (navswitch_push_event_p (NAVSWITCH_SOUTH) && pen.pos.y < TINYGL_HEIGHT - 1) + { + pen.pos.y++; + draw = 1; + } + + if (navswitch_push_event_p (NAVSWITCH_NORTH) && pen.pos.y > 0) + { + pen.pos.y--; + draw = 1; + } + + if (navswitch_push_event_p (NAVSWITCH_PUSH) + || button_push_event_p (BUTTON1)) + { + pen.state = !pen.state; + led_set (LED1, pen.state); + } + + if (draw) + tinygl_draw_point (pen.pos, pen.state); + + + tinygl_update (); + } + + return 0; +} diff --git a/apps/snake1/Makefile b/apps/snake1/Makefile new file mode 100644 index 0000000..2d244c9 --- /dev/null +++ b/apps/snake1/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for snake1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: snake1.out + + +# Compile: create object files from C source files. +snake1.o: snake1.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +snake1.out: display.o ledmat.o navswitch.o pacer.o pio.o snake1.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: snake1.out + $(OBJCOPY) -O ihex snake1.out snake1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash snake1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/snake1/Makefile.test b/apps/snake1/Makefile.test new file mode 100644 index 0000000..82d16fd --- /dev/null +++ b/apps/snake1/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for snake1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: snake1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +snake1-test.o: snake1.c ../../drivers/navswitch.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +snake1: timer-test.o display-test.o pio-test.o system-test.o pacer-test.o tinygl-test.o ledmat-test.o snake1-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) snake1 timer-test.o display-test.o pio-test.o system-test.o pacer-test.o tinygl-test.o ledmat-test.o snake1-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/snake1/snake1.c b/apps/snake1/snake1.c new file mode 100644 index 0000000..79d0928 --- /dev/null +++ b/apps/snake1/snake1.c @@ -0,0 +1,127 @@ +/** @file snake1.c + @author M.P. Hayes + @date 5 Oct 2010 + @note The sneake head deliberately moves off screen unless turned. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +#define SNAKE_SPEED 2 + +enum dir {DIR_N, DIR_E, DIR_S, DIR_W}; + +typedef enum dir dir_t; + +struct snake +{ + /* Current head of snake. */ + tinygl_point_t pos; + /* Current direction. */ + enum dir dir; +}; + +typedef struct snake snake_t; + + +static snake_t snake_move (snake_t snake) +{ + switch (snake.dir) + { + case DIR_N: + snake.pos.y = snake.pos.y - 1; + break; + + case DIR_E: + snake.pos.x = snake.pos.x + 1; + break; + + case DIR_S: + snake.pos.y = snake.pos.y + 1; + break; + + case DIR_W: + snake.pos.x = snake.pos.x - 1; + break; + } + tinygl_draw_point (snake.pos, 1); + return snake; +} + + +static snake_t snake_turn_left (snake_t snake) +{ + dir_t newdir[] = {DIR_W, DIR_N, DIR_E, DIR_S}; + + snake.dir = newdir[snake.dir]; + return snake; +} + + +static snake_t snake_turn_right (snake_t snake) +{ + dir_t newdir[] = {DIR_E, DIR_S, DIR_W, DIR_N}; + + snake.dir = newdir[snake.dir]; + return snake; +} + + +int main (void) +{ + snake_t snake; + int tick = 0; + + system_init (); + + snake.dir = DIR_N; + snake.pos.x = TINYGL_WIDTH / 2; + snake.pos.y = TINYGL_HEIGHT - 1; + + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + + navswitch_init (); + + pacer_init (LOOP_RATE); + + tinygl_draw_point (snake.pos, 1); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + navswitch_update (); + + tick = tick + 1; + if (tick > LOOP_RATE / SNAKE_SPEED) + { + tick = 0; + snake = snake_move (snake); + } + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + { + snake = snake_turn_left (snake); + } + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + { + snake = snake_turn_right (snake); + } + + + tinygl_update (); + } + + return 0; +} diff --git a/apps/space10/Makefile b/apps/space10/Makefile new file mode 100644 index 0000000..77e9056 --- /dev/null +++ b/apps/space10/Makefile @@ -0,0 +1,81 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for space10 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: space10.out + + +# Compile: create object files from C source files. +space10.o: space10.c ../../drivers/avr/eeprom.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/ir_serial.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h ../../utils/uint8toa.h flasher.h spacey.h + $(CC) -c $(CFLAGS) $< -o $@ + +flasher.o: flasher.c ../../drivers/avr/system.h flasher.h + $(CC) -c $(CFLAGS) $< -o $@ + +spacey.o: spacey.c ../../drivers/avr/system.h spacey.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom.o: ../../drivers/avr/eeprom.c ../../drivers/avr/eeprom.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial.o: ../../drivers/ir_serial.c ../../drivers/avr/delay.h ../../drivers/avr/system.h ../../drivers/ir.h ../../drivers/ir_serial.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa.o: ../../utils/uint8toa.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +space10.out: display.o eeprom.o flasher.o ir.o ir_serial.o ledmat.o pacer.o pio.o space10.o spacey.o system.o timer.o tinygl.o uint8toa.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: space10.out + $(OBJCOPY) -O ihex space10.out space10.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash space10.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/space10/Makefile.test b/apps/space10/Makefile.test new file mode 100644 index 0000000..e2fdf5d --- /dev/null +++ b/apps/space10/Makefile.test @@ -0,0 +1,75 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for space10 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: space10 + + +# Compile: create object files from C source files. +space10-test.o: space10.c ../../utils/font.h ../../drivers/ir_serial.h ../../drivers/test/system.h ../../drivers/test/eeprom.h ../../fonts/font3x5_1.h flasher.h ../../utils/tinygl.h spacey.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h ../../utils/uint8toa.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +spacey-test.o: spacey.c spacey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial-test.o: ../../drivers/ir_serial.c ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +flasher-test.o: flasher.c flasher.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa-test.o: ../../utils/uint8toa.c ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom-test.o: ../../drivers/test/eeprom.c ../../drivers/test/eeprom.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +space10: space10-test.o timer-test.o display-test.o spacey-test.o pio-test.o ir_serial-test.o pacer-test.o flasher-test.o tinygl-test.o uint8toa-test.o ledmat-test.o eeprom-test.o system-test.o ir-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) space10 space10-test.o timer-test.o display-test.o spacey-test.o pio-test.o ir_serial-test.o pacer-test.o flasher-test.o tinygl-test.o uint8toa-test.o ledmat-test.o eeprom-test.o system-test.o ir-test.o mgetkey-test.o + + diff --git a/apps/space10/flasher.c b/apps/space10/flasher.c new file mode 100644 index 0000000..2cdebd4 --- /dev/null +++ b/apps/space10/flasher.c @@ -0,0 +1,100 @@ +/** @file flasher.c + @author M. P. Hayes, UCECE + @date 13 March 2005 + @brief +*/ + +#include "flasher.h" + + +/* These routines are for flashing a LED or beeping a piezo tweeter. + Perhaps they should be separated into software PWM and flash + pattern sequencing. */ + +int8_t +flasher_pattern_set (flasher_t flasher, flasher_pattern_t *pattern) +{ + flasher->pattern = pattern; + flasher->mod_count = 0; + flasher->flasher_count = 0; + flasher->flashes_count = 0; + flasher->flasher_prescale = 0; + return 1; +} + + +flasher_pattern_t * +flasher_pattern_get (flasher_t flasher) +{ + return flasher->pattern; +} + + +/* FIXME. */ +int8_t +flasher_phase_set (flasher_t flasher, uint8_t phase) +{ + flasher->mod_count = 0; + flasher->flasher_count = 0; + flasher->flashes_count = phase; + return 1; +} + + +/* Return the next state for the associated device. For example, + to control the flashing of a LED use: + + led_set (led, flasher_update (flasher)); */ +bool +flasher_update (flasher_t flasher) +{ + if (!flasher->pattern) + return 0; + + flasher->mod_count++; + if (flasher->mod_count >= flasher->pattern->mod_period) + { + flasher->mod_count = 0; + flasher->flasher_prescale++; + + if (flasher->flasher_prescale >= FLASHER_PRESCALE) + { + flasher->flasher_prescale = 0; + flasher->flasher_count++; + + if (flasher->flasher_count >= flasher->pattern->flasher_period) + { + flasher->flasher_count = 0; + flasher->flashes_count++; + + if (!flasher->pattern->period) + { + /* One shot mode. */ + if (flasher->flashes_count >= flasher->pattern->flashes) + { + /* Disable pattern. */ + flasher->pattern = 0; + return 1; + } + } + else if (flasher->flashes_count >= flasher->pattern->period) + { + flasher->flashes_count = 0; + } + } + } + } + + return flasher->mod_count < flasher->pattern->mod_duty + && flasher->flasher_count < flasher->pattern->flasher_duty + && flasher->flashes_count < flasher->pattern->flashes; +} + + +/* Create a new flasher device. */ +flasher_t +flasher_init (flasher_obj_t *flasher) +{ + flasher_pattern_set (flasher, 0); + return flasher; +} diff --git a/apps/space10/flasher.h b/apps/space10/flasher.h new file mode 100644 index 0000000..4cfd6f8 --- /dev/null +++ b/apps/space10/flasher.h @@ -0,0 +1,97 @@ +/** @file flasher.h + @author M. P. Hayes, UCECE + @date 13 March 2005 + @brief Combined software PWM and flashing module. Use at your peril! +*/ +#ifndef FLASHER_H +#define FLASHER_H + +#include "system.h" + +/* This parameter is for internal use only. It's purpose is to + reduce the chances of flasher_period and flasher_duty overflow. + It could possibly be made an additional parameter for flasher_pattern_t + and calculated by FLASHER_PATTERN. */ +#define FLASHER_PRESCALE 8 + +/* POLL_RATE (Hz) + MOD_FREQ (Hz) + MOD_DUTY (percent) + FLASHER_PERIOD (s) - period between flashes + FLASHER_DUTY (percent) - proportion of flash period that is lit + FLASHES (integer) - how many flashes per flash pattern + PERIOD (s) - how often the flash pattern repeats +*/ + +#define FLASHER_PATTERN(POLL_RATE, MOD_FREQ, MOD_DUTY, FLASHER_PERIOD, \ + FLASHER_DUTY, FLASHES, PERIOD) \ + (POLL_RATE) / (double)(MOD_FREQ) + 0.5, \ + (POLL_RATE) * (double)(MOD_DUTY) / (MOD_FREQ) / 100.0 + 0.5, \ + (MOD_FREQ) * (FLASHER_PERIOD) / (double)FLASHER_PRESCALE + 0.5, \ + (MOD_FREQ) * (FLASHER_PERIOD) * (FLASHER_DUTY) / 100.0 / FLASHER_PRESCALE + 0.5, \ + (FLASHES), \ + (PERIOD) / (double)(FLASHER_PERIOD) + 0.5 + + +typedef struct +{ + /* This is the modulation period. It determines the frequency + of a tone or flicker rate of a LED. */ + uint8_t mod_period; + /* This is the modulation duty. It determines the luminance of a LED. */ + uint8_t mod_duty; + /* This is the period between the start of two flashes in a sequence. */ + uint8_t flasher_period; + /* This is the flash period. */ + uint8_t flasher_duty; + /* This is the number of flashes in the sequence. */ + uint8_t flashes; + /* This is the number of flasher periods before the sequence repeats. */ + uint8_t period; +} flasher_pattern_t; + + +#define FLASHER_ACTIVE_P(FLASHER) \ + (((flasher_obj_t *)(FLASHER))->pattern != 0) + + +#define FLASHER_PATTERN_FLASHES_SET(PATTERN, FLASHES) \ + (PATTERN)->flashes = (FLASHES) + +/* This structure is defined here so the compiler can allocate enough + memory for it. However, its fields should be treated as + private. */ +typedef struct +{ + flasher_pattern_t *pattern; + uint8_t mod_count; + uint8_t flasher_count; + uint8_t flashes_count; + uint8_t flasher_prescale; +} flasher_private_t; + + +typedef flasher_private_t flasher_obj_t; +typedef flasher_obj_t *flasher_t; + + +extern int8_t +flasher_pattern_set (flasher_t flasher, flasher_pattern_t *pattern); + +extern flasher_pattern_t * +flasher_pattern_get (flasher_t flasher); + +extern int8_t +flasher_phase_set (flasher_t flasher, uint8_t phase); + +extern bool +flasher_update (flasher_t); + + +/* INFO is a pointer into RAM that stores the state of the FLASH. + CFG is a pointer into ROM to define the port the FLASH is connected to. + The returned handle is passed to the other flasher_xxx routines to denote + the FLASH to operate on. */ +extern flasher_t +flasher_init (flasher_obj_t *info); +#endif diff --git a/apps/space10/space10.c b/apps/space10/space10.c new file mode 100644 index 0000000..60b78e3 --- /dev/null +++ b/apps/space10/space10.c @@ -0,0 +1,363 @@ +/** @file space10.c + @author M. P. Hayes, UCECE + @date 20 April 2007 + @brief A simple space invaders game with different difficulty levels + and IR remote control. + + @defgroup space10 A simple space invaders game controlled by the @ref spacey_remote1 "spacey_remote1" application. +*/ + +#include +#include "system.h" +#include "display.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir_serial.h" +#include "flasher.h" +#include "spacey.h" +#include "eeprom.h" +#include "uint8toa.h" +#include "../fonts/font3x5_1.h" + + +#define VERSION "1.6" + +/** Define polling rates in Hz. */ +enum {LOOP_RATE = 500}; +enum {FLASHER_UPDATE_RATE = LOOP_RATE}; +enum {GAME_UPDATE_RATE = 100}; +enum {GAME_OVER_PERIOD = 2}; + + +/** Define flasher modes. */ +static flasher_pattern_t flasher_patterns[] = +{ + /** POLL_RATE, MOD_FREQ, MOD_DUTY, FLASHER_PERIOD, + FLASHER_DUTY, FLASHES, PERIOD. */ + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 100, 100, 0.4, 100, 1, 0.4)}, + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 100, 100, 0.4, 100, 1, 0.4)}, + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 200, 100, 0.1, 50, 1, 0.1)}, +}; + +typedef enum {FLASH_MODE_GUN, FLASH_MODE_SHELL, + FLASH_MODE_ALIEN, FLASH_MODE_NUM} flash_mode_t; + + +typedef enum {STATE_DUMMY, STATE_INIT, STATE_START, + STATE_PLAYING, STATE_OVER, + STATE_READY, STATE_MENU_LEVEL} state_t; + +enum {GAME_LEVEL_MAX = 5}; + + +typedef struct +{ + uint8_t level; + uint8_t games; +} game_data_t; + + + +/** Draw pixel on display. */ +static void +display_handler (void *data, uint8_t col, uint8_t row, spacey_pix_t type) +{ + uint8_t *display = data; + uint8_t pixel; + + pixel = row * TINYGL_WIDTH + col; + display[pixel] = type; +} + + +/** Display the game over message. */ +static void +game_over_display (char *buffer) +{ + char *str = buffer; + + strcpy (str, "GAME OVER "); + while (*str) + str++; + *str++ = 'K'; + uint8toa (spacey_aliens_killed_get (), str, 0); + while (*str) + str++; + *str++ = 'F'; + uint8toa (spacey_shells_fired_get (), str, 0); + tinygl_clear (); + tinygl_text (buffer); +} + + +static void +game_text_display (uint8_t num, char *buffer, char *msg) +{ + char *str = buffer; + + while (*msg) + *str++ = *msg++; + uint8toa (num, str, 0); + tinygl_clear (); + tinygl_text (buffer); +} + + +/** Display the game level of difficulty. */ +static void +game_level_display (uint8_t level, char *buffer) +{ + game_text_display (level, buffer, "LEVEL"); +} + + +/** Set the game level of difficulty. */ +static void +game_level_set (uint8_t level) +{ + spacey_options_t options; + uint8_t alien_num = 3; + uint8_t alien_steps = 4; + + switch (level) + { + default: + case 0: + options.aliens_wrap = 0; + options.aliens_evasive = 0; + break; + + case 1: + options.aliens_wrap = 0; + options.aliens_evasive = 1; + alien_steps = 3; + break; + + case 2: + options.aliens_wrap = 1; + options.aliens_evasive = 0; + alien_steps = 3; + break; + + case 3: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 3; + break; + + case 4: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 3; + alien_num = 4; + break; + + case 5: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 2; + alien_num = 4; + break; + } + + spacey_alien_num_set (alien_num); + spacey_alien_create_steps_set (alien_steps); + spacey_options_set (options); +} + + +static void +game_start (game_data_t *data) +{ + tinygl_clear (); + data->games++; + game_level_set (data->level); + spacey_start (); + eeprom_write (0, data, sizeof (*data)); +} + + +void game_event (__unused__ void *data, spacey_event_t event) +{ + ir_serial_transmit (event); +} + + +int +main (void) +{ + uint8_t game_ticks; + uint8_t game_over_ticks; + state_t state = STATE_INIT; + flasher_t flashers[SPACEY_PIX_TYPE_NUM]; + uint8_t flasher_state[SPACEY_PIX_TYPE_NUM]; + flasher_obj_t flashers_info[SPACEY_PIX_TYPE_NUM]; + uint8_t display[TINYGL_WIDTH * TINYGL_HEIGHT]; + uint8_t i; + uint8_t j; + game_data_t data; + char message[44]; + ir_serial_ret_t ret; + uint8_t ir_data; + + system_init (); + + /* The first time EEPROM is read all the bytes are 0xFF so set to + sensible defaults. */ + eeprom_read (0, &data, sizeof (data)); + if (data.level == 0xff) + { + data.level = 0; + data.games = 0; + } + + for (i = 0; i < ARRAY_SIZE (flashers); i++) + { + flashers[i] = flasher_init (&flashers_info[i]); + flasher_state[i] = 0; + } + + for (i = 0; i < ARRAY_SIZE (display); i++) + display[i] = 0; + + /* Set up flash patterns for different pixel types. */ + flasher_pattern_set (flashers[SPACEY_PIX_GUN], + &flasher_patterns[FLASH_MODE_GUN]); + flasher_pattern_set (flashers[SPACEY_PIX_SHELL], + &flasher_patterns[FLASH_MODE_SHELL]); + flasher_pattern_set (flashers[SPACEY_PIX_ALIEN], + &flasher_patterns[FLASH_MODE_ALIEN]); + + tinygl_init (LOOP_RATE); + tinygl_font_set (&font3x5_1); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + tinygl_text_mode_set (TINYGL_TEXT_MODE_ROTATE_SCROLL_DOWN); + tinygl_text_speed_set (10); + + spacey_init (GAME_UPDATE_RATE, TINYGL_WIDTH, TINYGL_HEIGHT, + display_handler, display); + + spacey_event_handler_set (game_event, 0); + + game_ticks = 0; + game_over_ticks = 0; + + pacer_init (LOOP_RATE); + + while (1) + { + pacer_wait (); + + if (state == STATE_PLAYING) + { + uint8_t *src; + + /* Update flasher states. NB, the first flasher is always off. */ + for (i = 1; i < ARRAY_SIZE (flashers); i++) + flasher_state[i] = flasher_update (flashers[i]); + + /* Update display. */ + src = display; + for (j = 0; j < TINYGL_HEIGHT; j++) + for (i = 0; i < TINYGL_WIDTH; i++) + { + tinygl_point_t point = {i, j}; + + tinygl_draw_point (point, flasher_state[*src++]); + } + } + + /* Advance messages and refresh display. */ + tinygl_update (); + + game_ticks++; + if (game_ticks >= LOOP_RATE / GAME_UPDATE_RATE) + { + game_ticks = 0; + + switch (state) + { + case STATE_PLAYING: + if (! spacey_update ()) + { + game_over_display (message); + game_over_ticks = 0; + state = STATE_OVER; + } + break; + + case STATE_INIT: + tinygl_text ("SPACEY READY V" VERSION " BY MPH "); + state = STATE_READY; + break; + + case STATE_OVER: + game_over_ticks ++; + if (game_over_ticks >= GAME_UPDATE_RATE * GAME_OVER_PERIOD) + state = STATE_READY; + /* Fall through. */ + + case STATE_READY: + case STATE_MENU_LEVEL: + default: + break; + + case STATE_START: + /* Turn that bloody blimey space invader off... */ + game_start (&data); + state = STATE_PLAYING; + break; + } + } + + ret = ir_serial_receive (&ir_data); + if (ret == IR_SERIAL_OK) + { + if (ir_data == 1) + { + switch (state) + { + case STATE_READY: + state = STATE_MENU_LEVEL; + game_level_display (data.level, message); + break; + + case STATE_MENU_LEVEL: + state = STATE_INIT; + break; + + case STATE_PLAYING: + spacey_gun_move_right (); + break; + + default: + break; + } + } + + if (ir_data == 2) + { + switch (state) + { + case STATE_READY: + state = STATE_START; + break; + + case STATE_PLAYING: + spacey_gun_fire (); + break; + + case STATE_MENU_LEVEL: + data.level++; + if (data.level > GAME_LEVEL_MAX) + data.level = 0; + game_level_display (data.level, message); + break; + + default: + break; + } + } + } + } +} diff --git a/apps/space10/spacey.c b/apps/space10/spacey.c new file mode 100644 index 0000000..cb96d91 --- /dev/null +++ b/apps/space10/spacey.c @@ -0,0 +1,578 @@ +/** @file spacey.c + @author M. P. Hayes, UCECE + @date 13 March 2007 + @brief This implements a simple space invaders game. +*/ + +#include +#include "spacey.h" + +/* This function implements a simple space invades program. Aliens + randomly appear on the top row of the display and work their way + randomly down the display. The game ends when 5 aliens have + reached the bottom of the display. To kill the aliens, shells can + be fired at them from a gun on the bottom of the display. The gun + can only move across the bottom and when it gets to the side it + wraps around to the other side. + + The aliens could move at different speeds but currently they are + set at the same speed to keep things simple. +*/ + + +#ifndef DISPLAY_INTERLACE +#define DISPLAY_INTERLACE 0 +#endif + + +#if DISPLAY_INTERLACE +/* With an interlaced display we do not have odd numbered rows and + columns. */ +enum {SPACEY_SHELL_INC = 2, SPACEY_GUN_INC = 2}; +#else +enum {SPACEY_SHELL_INC = 1, SPACEY_GUN_INC = 1}; +#endif + + +enum {SPACEY_LIVES_DEFAULT = 5}; +enum {SPACEY_SHELL_SPEED_DEFAULT = 16}; +enum {SPACEY_ALIEN_SPEED_DEFAULT = 2}; +enum {SPACEY_ALIEN_CREATE_STEPS_DEFAULT = 4}; +enum {SPACEY_ALIEN_NUM_DEFAULT = 3}; +enum {SPACEY_SHELL_NUM_DEFAULT = 2}; + + +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static spacey_t spacey_data; +static spacey_t * const spacey = &spacey_data; + + +void +spacey_lives_set (uint8_t lives) +{ + spacey->lives = lives; +} + + +void +spacey_alien_speed_set (uint8_t alien_speed) +{ + spacey->aliens.move_period = spacey->poll_rate / alien_speed; +} + + +void +spacey_shell_speed_set (uint8_t shell_speed) +{ + spacey->shells.move_period = spacey->poll_rate / shell_speed; +} + + +void +spacey_alien_create_steps_set (uint8_t alien_create_steps) +{ + spacey->alien_create_steps = alien_create_steps; +} + + +void +spacey_alien_num_set (uint8_t aliens_num) +{ + spacey->aliens.num = min (aliens_num, SPACEY_ALIENS_MAX); +} + + +void +spacey_shell_num_set (uint8_t shells_num) +{ + spacey->shells.num = min (shells_num, SPACEY_SHELLS_MAX); +} + + +void +spacey_options_set (spacey_options_t options) +{ + spacey->options = options; +} + + +void +spacey_init (uint16_t poll_rate, + uint8_t x_size, uint8_t y_size, + void (*display_handler) (void *data, uint8_t row, uint8_t col, + spacey_pix_t type), + void *display_data) +{ + spacey->size.x = x_size; + spacey->size.y = y_size; + spacey->display_hook = display_handler; + spacey->display_data = display_data; + spacey->active = 0; + spacey->poll_rate = poll_rate; + spacey->event_hook = NULL; + + spacey->options.aliens_wrap = 0; + spacey->options.aliens_evasive = 0; + + spacey_alien_num_set (SPACEY_ALIEN_NUM_DEFAULT); + spacey_shell_num_set (SPACEY_SHELL_NUM_DEFAULT); + spacey_shell_speed_set (SPACEY_SHELL_SPEED_DEFAULT); + spacey_alien_speed_set (SPACEY_ALIEN_SPEED_DEFAULT); + spacey_alien_create_steps_set (SPACEY_ALIEN_CREATE_STEPS_DEFAULT); + spacey->lives = SPACEY_LIVES_DEFAULT; +} + + +void +spacey_event_handler_set (void (*event_handler) (void *, spacey_event_t), + void *event_data) +{ + spacey->event_hook = event_handler; + spacey->event_data = event_data; +} + + +static void +spacey_pixel_set (spacey_pos_t *pos, + spacey_pix_t type) +{ + spacey->display_hook (spacey->display_data, pos->x, pos->y, type); +} + + +/* Return if obj is at the same point as another alien. */ +static spacey_obj_t * +spacey_alien_conflict_p (spacey_obj_t *obj) +{ + int8_t i; + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active || alien == obj) + continue; + + if (alien->pos.x == obj->pos.x + && alien->pos.y == obj->pos.y) + return alien; + } + return 0; +} + + +/* Return if obj is at the same point as another shell. */ +static spacey_obj_t * +spacey_shell_conflict_p (spacey_obj_t *obj) +{ + int8_t i; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (!shell->active || shell == obj) + continue; + + if (shell->pos.x == obj->pos.x + && shell->pos.y == obj->pos.y) + return shell; + } + return 0; +} + + +static void +spacey_gun_move (int8_t inc) +{ + int8_t gun_x; + + spacey_pixel_set (&spacey->gun, SPACEY_PIX_OFF); + + gun_x = spacey->gun.x + inc; + if (gun_x >= spacey->size.x) + gun_x = 0; + else if (gun_x < 0) + gun_x = spacey->size.x - 1; + spacey->gun.x = gun_x; + + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); +} + + +/* Return true if move off display. */ +static bool +spacey_shell_move (spacey_obj_t *shell) +{ + /* Erase the previous position of the shell except if still + at gun. */ + if (shell->pos.x != spacey->gun.x + || shell->pos.y != spacey->gun.y) + spacey_pixel_set (&shell->pos, SPACEY_PIX_OFF); + + /* Shells only go straight up. */ + shell->pos.y -= SPACEY_SHELL_INC; + + if (shell->pos.y < 0) + return 1; + + spacey_pixel_set (&shell->pos, SPACEY_PIX_SHELL); + return 0; +} + + +static void +spacey_alien_erase (spacey_obj_t *alien) +{ + spacey_pixel_set (&alien->pos, SPACEY_PIX_OFF); +} + + +/* Return true if move off display or get to the bottom. */ +static bool +spacey_alien_move (spacey_obj_t *alien) +{ + int8_t x_jump; + + /* Aliens move down randomly zig zagging. */ + alien->pos.y++; + + /* Randomly move left or right. */ + x_jump = 2 * (rand () & 1) - 1; + + /* Don't move into line of gun if being evasive. */ + if (spacey->options.aliens_evasive && + spacey->gun.x == alien->pos.x + x_jump) + x_jump = -x_jump; + + alien->pos.x += x_jump; + + /* Keep the alien within bounds. */ + if (alien->pos.x < 0 || alien->pos.x >= spacey->size.x) + { + if (spacey->options.aliens_wrap) + alien->pos.x = spacey->size.x - abs (alien->pos.x); + else + alien->pos.x -= 2 * x_jump; + } + + if (alien->pos.y < spacey->size.y) + spacey_pixel_set (&alien->pos, SPACEY_PIX_ALIEN); + + if (alien->pos.y >= (spacey->size.y - 1)) + return 1; + + return 0; +} + + +static void +spacey_alien_create (void) +{ + int8_t i; + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (alien->active) + continue; + + /* Aliens start at the top. */ + alien->pos.y = 0; + + while (1) + { + /* Choose random x position. */ + alien->pos.x = rand () % spacey->size.x; +#if DISPLAY_INTERLACE + /* Ensure x position is even. */ + alien->pos.x &= ~1; +#endif + alien->active = 1; + + /* Ensure aliens start at different spots to be fair! */ + if (!spacey_alien_conflict_p (alien)) + break; + } + spacey->stats.aliens_live++; + spacey_pixel_set (&alien->pos, SPACEY_PIX_ALIEN); + return; + } + /* If we get to here then we already have too many aliens. */ +} + + +static void +spacey_shell_create (void) +{ + int8_t i; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (shell->active) + continue; + + shell->pos = spacey->gun; + shell->active = 1; + spacey->stats.shells_fired++; + /* Don't turn shell on initially since it will erase the gun. */ + return; + } + /* If we get to here then we already have too many shells. */ +} + + +static void +spacey_alien_kill (spacey_obj_t *alien) +{ + alien->active = 0; + spacey->stats.aliens_live--; +} + + +static void +spacey_shell_kill (spacey_obj_t *shell) +{ + shell->active = 0; +} + + +static void +spacey_event (spacey_event_t event) +{ + if (spacey->event_hook) + spacey->event_hook (spacey->event_data, event); +} + + +static void +spacey_alien_hit (spacey_obj_t *alien, spacey_obj_t *shell) +{ + spacey_alien_kill (alien); + spacey->stats.aliens_killed++; + + spacey_shell_kill (shell); + spacey_pixel_set (&shell->pos, SPACEY_PIX_OFF); + + spacey_event (SPACEY_EVENT_ALIEN_HIT); +} + + +static void +spacey_alien_landed (void) +{ + spacey->stats.aliens_landed++; + if (spacey->stats.aliens_landed >= spacey->lives) + spacey->active = 0; + + spacey_event (SPACEY_EVENT_ALIEN_LANDED); +} + + +static void +spacey_shells_move (void) +{ + int8_t i; + + spacey->shells.move_clock++; + if (spacey->shells.move_clock < spacey->shells.move_period) + return; + spacey->shells.move_clock = 0; + + /* Shells move until they hit an alien or move off the display. */ + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (!shell->active) + continue; + + if (spacey_shell_move (shell)) + spacey_shell_kill (shell); + else + { + spacey_obj_t *alien; + + /* Check if we've hit an alien. */ + while ((alien = spacey_alien_conflict_p (shell))) + { + /* We've hit an alien so kill it and the shell. */ + spacey_alien_hit (alien, shell); + } + } + } +} + + +static void +spacey_aliens_move (void) +{ + int8_t i; + uint8_t steps; + + spacey->aliens.move_clock++; + if (spacey->aliens.move_clock < spacey->aliens.move_period) + return; + spacey->aliens.move_clock = 0; + + /* Erase all aliens before moving them. */ + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active) + continue; + + spacey_alien_erase (alien); + } + + /* Now move and redraw aliens. */ + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active) + continue; + + if (spacey_alien_move (alien)) + { + if (alien->pos.y == spacey->gun.y) + { + /* The alien has reached Earth. */ + spacey_alien_landed (); + } + else + { + /* The alien has moved off the display so disable it. */ + spacey_alien_kill (alien); + + /* Redraw the gun in case it got hit by the alien. */ + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); + } + } + else + { + spacey_obj_t *shell; + + while ((shell = spacey_shell_conflict_p (alien))) + { + /* The alien hit a shell so kill it and the shell. */ + spacey_alien_hit (alien, shell); + } + } + } + + /* Randomly create an alien. If there are no aliens create a new + one more rapidly. */ + if (!spacey->stats.aliens_live) + steps = 2; + else + steps = spacey->alien_create_steps; + + if ((rand () % steps) == 0) + spacey_alien_create (); +} + + +/* Update the state of the game. */ +bool +spacey_update (void) +{ + /* Allow playing with the gun even if game inactive. */ + spacey_shells_move (); + + if (!spacey->active) + return 0; + + spacey_aliens_move (); + return 1; +} + + +/* Move the gun position to the right wrapping back around on left. */ +void +spacey_gun_move_right (void) +{ + spacey_gun_move (SPACEY_GUN_INC); +} + + +/* Move the gun position to the left wrapping back around on right. */ +void +spacey_gun_move_left (void) +{ + spacey_gun_move (-SPACEY_GUN_INC); +} + + +/* Fire the gun. */ +void +spacey_gun_fire (void) +{ + spacey_shell_create (); +} + + +/* Start a new game. */ +void +spacey_start (void) +{ + int8_t i; + int8_t j; + + spacey->shells.move_clock = 0; + spacey->aliens.move_clock = 0; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + shell->active = 0; + } + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + alien->active = 0; + } + + /* Turn all pixels off. */ + for (i = 0; i < spacey->size.x; i++) + for (j = 0; j < spacey->size.y; j++) + { + spacey_pos_t pos = {i, j}; + + spacey_pixel_set (&pos, SPACEY_PIX_OFF); + } + + /* Display gun in centre of display. */ + spacey->gun.x = (spacey->size.x / 2) & ~1; + spacey->gun.y = spacey->size.y - 1; + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); + + spacey->stats.aliens_live = 0; + spacey->stats.aliens_killed = 0; + spacey->stats.aliens_landed = 0; + spacey->stats.shells_fired = 0; + spacey->active = 1; +} + + +uint8_t +spacey_aliens_killed_get (void) +{ + return spacey->stats.aliens_killed; +} + + +uint8_t +spacey_shells_fired_get (void) +{ + return spacey->stats.shells_fired; +} diff --git a/apps/space10/spacey.h b/apps/space10/spacey.h new file mode 100644 index 0000000..5b8b868 --- /dev/null +++ b/apps/space10/spacey.h @@ -0,0 +1,152 @@ +/** @file spacey.h + @author M. P. Hayes, UCECE + @date 13 March 2007 + @brief This is the interface for a simple space invaders game. +*/ + +#ifndef SPACEY_H +#define SPACEY_H + +#include "system.h" + + +enum {SPACEY_ALIENS_MAX = 4, SPACEY_SHELLS_MAX = 4}; + + +typedef enum {SPACEY_PIX_OFF, SPACEY_PIX_GUN, SPACEY_PIX_ALIEN, + SPACEY_PIX_SHELL, SPACEY_PIX_TYPE_NUM} spacey_pix_t; + +typedef enum {SPACEY_EVENT_ALIEN_HIT, SPACEY_EVENT_ALIEN_LANDED} spacey_event_t; + + +typedef enum {SPACEY_ALIEN, SPACEY_SHELL} spacey_type_t; + +/* Positions must be signed. */ +typedef struct +{ + int8_t x; + int8_t y; +} spacey_pos_t; + + +typedef struct +{ + spacey_pos_t pos; + bool active; +} spacey_obj_t; + + +typedef struct +{ + spacey_obj_t array[SPACEY_ALIENS_MAX]; + uint8_t num; + uint16_t move_period; + uint16_t move_clock; +} spacey_objs_t; + + +typedef struct +{ + uint8_t aliens_killed; + uint8_t aliens_landed; + uint8_t shells_fired; + uint8_t aliens_live; +} spacey_stats_t; + + +typedef struct +{ + int aliens_wrap:1; + int aliens_evasive:1; +} spacey_options_t; + + +typedef struct +{ + /* If we have lots of objects then a linked list would be more + efficient for the aliens and shells. */ + spacey_objs_t aliens; + spacey_objs_t shells; + spacey_pos_t gun; + spacey_pos_t size; + spacey_stats_t stats; + uint16_t poll_rate; /* Hz */ + uint8_t alien_create_steps; + uint8_t lives; + void (*display_hook) (void *data, uint8_t row, uint8_t col, spacey_pix_t type); + void *display_data; + void (*event_hook) (void *data, spacey_event_t event); + void *event_data; + spacey_options_t options; + bool active; +} spacey_t; + + +void +spacey_event_handler_set (void (*event_handler) (void *, spacey_event_t), + void *event_data); + +void +spacey_init (uint16_t poll_rate, + uint8_t x_size, uint8_t y_size, + void (*display_handler) (void *data, uint8_t row, uint8_t col, + spacey_pix_t type), + void *display_data); + +/** Start a new game. */ +void +spacey_start (void); + +/** Update state of game. */ +bool +spacey_update (void); + +/** Specify number of lives we have before we die. */ +void +spacey_lives_set (uint8_t lives); + +/** Set alien speed in Hz. */ +void +spacey_alien_speed_set (uint8_t alien_speed); + +/** Set shell speed in Hz. */ +void +spacey_shell_speed_set (uint8_t shell_speed); + +/** Set number of steps that a new alien is created on average. */ +void +spacey_alien_create_steps_set (uint8_t alien_create_steps); + +/** Set maximum number of aliens on display at once. */ +void +spacey_alien_num_set (uint8_t aliens_num); + +/** Set maximum number of shells on display at once. */ +void +spacey_shell_num_set (uint8_t shells_num); + +/** Set game options. */ +void +spacey_options_set (spacey_options_t options); + +/** Move gun to right. */ +void +spacey_gun_move_right (void); + +/** Move gun to left. */ +void +spacey_gun_move_left (void); + +/** Fire gun. */ +void +spacey_gun_fire (void); + +/** Return number of aliens killed in current game. */ +uint8_t +spacey_aliens_killed_get (void); + +/** Return number of shells fired in current game. */ +uint8_t +spacey_shells_fired_get (void); + +#endif diff --git a/apps/space10/ticker.c b/apps/space10/ticker.c new file mode 100644 index 0000000..25c741e --- /dev/null +++ b/apps/space10/ticker.c @@ -0,0 +1,6 @@ +/** @file ticker.c + @author M. P. Hayes, UCECE + @date 2 April 2007 + @brief +*/ + diff --git a/apps/space10/ticker.h b/apps/space10/ticker.h new file mode 100644 index 0000000..ac86df5 --- /dev/null +++ b/apps/space10/ticker.h @@ -0,0 +1,45 @@ +/** @file ticker.h + @author M. P. Hayes, UCECE + @date 2 April 2007 + @brief +*/ +#ifndef TICKER_H +#define TICKER_H + +#include + +typedef struct +{ + uint16_t period; + uint16_t clock; +} ticker_t; + + +typedef struct +{ + uint16_t period; + uint16_t clock; +} ticker16_t; + + +typedef struct +{ + uint8_t period; + uint8_t clock; +} ticker8_t; + + +#define TICKER_INIT(DEV, PERIOD) \ + (DEV)->period = (PERIOD); \ + (DEV)->clock = (DEV)->period; + + +/* Return non-zero when the ticker rolls over otherwise return 0. */ +#define TICKER_UPDATE(DEV) \ + (--(DEV)->clock ? 0 : ((DEV)->clock = (DEV)->period)) + + +#define TICKER_START(DEV) \ + (DEV)->clock = (DEV)->period; + +#endif diff --git a/apps/space11/Makefile b/apps/space11/Makefile new file mode 100644 index 0000000..956d66a --- /dev/null +++ b/apps/space11/Makefile @@ -0,0 +1,81 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for space11 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: space11.out + + +# Compile: create object files from C source files. +space11.o: space11.c ../../drivers/avr/eeprom.h ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../drivers/display.h ../../drivers/led.h ../../drivers/navswitch.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/task.h ../../utils/tinygl.h ../../utils/uint8toa.h flasher.h spacey.h + $(CC) -c $(CFLAGS) $< -o $@ + +flasher.o: flasher.c ../../drivers/avr/system.h flasher.h + $(CC) -c $(CFLAGS) $< -o $@ + +spacey.o: spacey.c ../../drivers/avr/system.h spacey.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom.o: ../../drivers/avr/eeprom.c ../../drivers/avr/eeprom.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +task.o: ../../utils/task.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/task.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa.o: ../../utils/uint8toa.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +space11.out: display.o eeprom.o flasher.o led.o ledmat.o navswitch.o pio.o space11.o spacey.o system.o task.o timer.o tinygl.o uint8toa.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: space11.out + $(OBJCOPY) -O ihex space11.out space11.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash space11.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/space11/Makefile.test b/apps/space11/Makefile.test new file mode 100644 index 0000000..a447dcf --- /dev/null +++ b/apps/space11/Makefile.test @@ -0,0 +1,75 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for space11 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: space11 + + +# Compile: create object files from C source files. +space11-test.o: space11.c ../../drivers/navswitch.h ../../utils/task.h ../../drivers/test/system.h ../../drivers/test/eeprom.h ../../fonts/font3x5_1.h ../../drivers/led.h ../../drivers/test/timer.h ../../utils/font.h ../../utils/tinygl.h spacey.h flasher.h ../../drivers/display.h ../../utils/uint8toa.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +task-test.o: ../../utils/task.c ../../drivers/test/timer.h ../../utils/task.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa-test.o: ../../utils/uint8toa.c ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +spacey-test.o: spacey.c spacey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom-test.o: ../../drivers/test/eeprom.c ../../drivers/test/eeprom.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +flasher-test.o: flasher.c flasher.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +space11: space11-test.o timer-test.o led-test.o display-test.o pio-test.o task-test.o tinygl-test.o uint8toa-test.o ledmat-test.o spacey-test.o eeprom-test.o system-test.o mgetkey-test.o navswitch-test.o flasher-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) space11 space11-test.o timer-test.o led-test.o display-test.o pio-test.o task-test.o tinygl-test.o uint8toa-test.o ledmat-test.o spacey-test.o eeprom-test.o system-test.o mgetkey-test.o navswitch-test.o flasher-test.o + + diff --git a/apps/space11/flasher.c b/apps/space11/flasher.c new file mode 100644 index 0000000..2cdebd4 --- /dev/null +++ b/apps/space11/flasher.c @@ -0,0 +1,100 @@ +/** @file flasher.c + @author M. P. Hayes, UCECE + @date 13 March 2005 + @brief +*/ + +#include "flasher.h" + + +/* These routines are for flashing a LED or beeping a piezo tweeter. + Perhaps they should be separated into software PWM and flash + pattern sequencing. */ + +int8_t +flasher_pattern_set (flasher_t flasher, flasher_pattern_t *pattern) +{ + flasher->pattern = pattern; + flasher->mod_count = 0; + flasher->flasher_count = 0; + flasher->flashes_count = 0; + flasher->flasher_prescale = 0; + return 1; +} + + +flasher_pattern_t * +flasher_pattern_get (flasher_t flasher) +{ + return flasher->pattern; +} + + +/* FIXME. */ +int8_t +flasher_phase_set (flasher_t flasher, uint8_t phase) +{ + flasher->mod_count = 0; + flasher->flasher_count = 0; + flasher->flashes_count = phase; + return 1; +} + + +/* Return the next state for the associated device. For example, + to control the flashing of a LED use: + + led_set (led, flasher_update (flasher)); */ +bool +flasher_update (flasher_t flasher) +{ + if (!flasher->pattern) + return 0; + + flasher->mod_count++; + if (flasher->mod_count >= flasher->pattern->mod_period) + { + flasher->mod_count = 0; + flasher->flasher_prescale++; + + if (flasher->flasher_prescale >= FLASHER_PRESCALE) + { + flasher->flasher_prescale = 0; + flasher->flasher_count++; + + if (flasher->flasher_count >= flasher->pattern->flasher_period) + { + flasher->flasher_count = 0; + flasher->flashes_count++; + + if (!flasher->pattern->period) + { + /* One shot mode. */ + if (flasher->flashes_count >= flasher->pattern->flashes) + { + /* Disable pattern. */ + flasher->pattern = 0; + return 1; + } + } + else if (flasher->flashes_count >= flasher->pattern->period) + { + flasher->flashes_count = 0; + } + } + } + } + + return flasher->mod_count < flasher->pattern->mod_duty + && flasher->flasher_count < flasher->pattern->flasher_duty + && flasher->flashes_count < flasher->pattern->flashes; +} + + +/* Create a new flasher device. */ +flasher_t +flasher_init (flasher_obj_t *flasher) +{ + flasher_pattern_set (flasher, 0); + return flasher; +} diff --git a/apps/space11/flasher.h b/apps/space11/flasher.h new file mode 100644 index 0000000..4cfd6f8 --- /dev/null +++ b/apps/space11/flasher.h @@ -0,0 +1,97 @@ +/** @file flasher.h + @author M. P. Hayes, UCECE + @date 13 March 2005 + @brief Combined software PWM and flashing module. Use at your peril! +*/ +#ifndef FLASHER_H +#define FLASHER_H + +#include "system.h" + +/* This parameter is for internal use only. It's purpose is to + reduce the chances of flasher_period and flasher_duty overflow. + It could possibly be made an additional parameter for flasher_pattern_t + and calculated by FLASHER_PATTERN. */ +#define FLASHER_PRESCALE 8 + +/* POLL_RATE (Hz) + MOD_FREQ (Hz) + MOD_DUTY (percent) + FLASHER_PERIOD (s) - period between flashes + FLASHER_DUTY (percent) - proportion of flash period that is lit + FLASHES (integer) - how many flashes per flash pattern + PERIOD (s) - how often the flash pattern repeats +*/ + +#define FLASHER_PATTERN(POLL_RATE, MOD_FREQ, MOD_DUTY, FLASHER_PERIOD, \ + FLASHER_DUTY, FLASHES, PERIOD) \ + (POLL_RATE) / (double)(MOD_FREQ) + 0.5, \ + (POLL_RATE) * (double)(MOD_DUTY) / (MOD_FREQ) / 100.0 + 0.5, \ + (MOD_FREQ) * (FLASHER_PERIOD) / (double)FLASHER_PRESCALE + 0.5, \ + (MOD_FREQ) * (FLASHER_PERIOD) * (FLASHER_DUTY) / 100.0 / FLASHER_PRESCALE + 0.5, \ + (FLASHES), \ + (PERIOD) / (double)(FLASHER_PERIOD) + 0.5 + + +typedef struct +{ + /* This is the modulation period. It determines the frequency + of a tone or flicker rate of a LED. */ + uint8_t mod_period; + /* This is the modulation duty. It determines the luminance of a LED. */ + uint8_t mod_duty; + /* This is the period between the start of two flashes in a sequence. */ + uint8_t flasher_period; + /* This is the flash period. */ + uint8_t flasher_duty; + /* This is the number of flashes in the sequence. */ + uint8_t flashes; + /* This is the number of flasher periods before the sequence repeats. */ + uint8_t period; +} flasher_pattern_t; + + +#define FLASHER_ACTIVE_P(FLASHER) \ + (((flasher_obj_t *)(FLASHER))->pattern != 0) + + +#define FLASHER_PATTERN_FLASHES_SET(PATTERN, FLASHES) \ + (PATTERN)->flashes = (FLASHES) + +/* This structure is defined here so the compiler can allocate enough + memory for it. However, its fields should be treated as + private. */ +typedef struct +{ + flasher_pattern_t *pattern; + uint8_t mod_count; + uint8_t flasher_count; + uint8_t flashes_count; + uint8_t flasher_prescale; +} flasher_private_t; + + +typedef flasher_private_t flasher_obj_t; +typedef flasher_obj_t *flasher_t; + + +extern int8_t +flasher_pattern_set (flasher_t flasher, flasher_pattern_t *pattern); + +extern flasher_pattern_t * +flasher_pattern_get (flasher_t flasher); + +extern int8_t +flasher_phase_set (flasher_t flasher, uint8_t phase); + +extern bool +flasher_update (flasher_t); + + +/* INFO is a pointer into RAM that stores the state of the FLASH. + CFG is a pointer into ROM to define the port the FLASH is connected to. + The returned handle is passed to the other flasher_xxx routines to denote + the FLASH to operate on. */ +extern flasher_t +flasher_init (flasher_obj_t *info); +#endif diff --git a/apps/space11/space11.c b/apps/space11/space11.c new file mode 100644 index 0000000..85eb6d0 --- /dev/null +++ b/apps/space11/space11.c @@ -0,0 +1,459 @@ +/** @file space11.c + @author M. P. Hayes, UCECE + @date 20 April 2007 + @brief A simple space invaders game with different difficulty levels. + + @defgroup space11 A simple space invaders game. +*/ + +#include +#include "system.h" +#include "display.h" +#include "tinygl.h" +#include "task.h" +#include "navswitch.h" +#include "led.h" +#include "flasher.h" +#include "spacey.h" +#include "eeprom.h" +#include "uint8toa.h" +#include "../fonts/font3x5_1.h" + + +#define VERSION "1.6" + +/** Define polling rates in Hz. */ +enum {DISPLAY_UPDATE_RATE = 500}; +enum {FLASHER_UPDATE_RATE = 500}; +enum {BUTTON_POLL_RATE = 100}; +enum {GAME_UPDATE_RATE = 100}; +enum {GAME_OVER_PERIOD = 2}; +enum {BUTTON_HOLD_PERIOD = 1}; + + +/** Define flasher modes. */ +static flasher_pattern_t flasher_patterns[] = +{ + /** POLL_RATE, MOD_FREQ, MOD_DUTY, FLASHER_PERIOD, + FLASHER_DUTY, FLASHES, PERIOD. */ + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 100, 100, 0.4, 100, 1, 0.4)}, + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 100, 100, 0.4, 100, 1, 0.4)}, + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 200, 100, 0.1, 50, 1, 0.1)}, +}; + +typedef enum {FLASH_MODE_GUN, FLASH_MODE_SHELL, + FLASH_MODE_ALIEN, FLASH_MODE_NUM} flash_mode_t; + + +typedef enum {STATE_DUMMY, STATE_INIT, STATE_START, + STATE_PLAYING, STATE_OVER, + STATE_READY, STATE_MENU_LEVEL} state_t; + +enum {GAME_LEVEL_MAX = 5}; + + +typedef struct +{ + uint8_t level; + uint8_t games; +} game_data_t; + + +static state_t state = STATE_INIT; +static game_data_t game_data; +static uint8_t display[TINYGL_WIDTH * TINYGL_HEIGHT]; + + +/** Draw pixel on display. */ +static void +display_handler (void *data, uint8_t col, uint8_t row, spacey_pix_t type) +{ + uint8_t *display = data; + uint8_t pixel; + + pixel = row * TINYGL_WIDTH + col; + display[pixel] = type; +} + + +/** Display the game over message. */ +static void +game_over_display (char *buffer) +{ + char *str = buffer; + + strcpy (str, "GAME OVER "); + while (*str) + str++; + uint8toa (spacey_aliens_killed_get (), str, 0); + while (*str) + str++; + *str++ = '/'; + uint8toa (spacey_shells_fired_get (), str, 0); + tinygl_clear (); + tinygl_text (buffer); +} + + +static void +game_text_display (uint8_t num, char *buffer, char *msg) +{ + char *str = buffer; + + while (*msg) + *str++ = *msg++; + uint8toa (num, str, 0); + tinygl_clear (); + tinygl_text (buffer); +} + + +/** Display the game level of difficulty. */ +static void +game_level_display (uint8_t level, char *buffer) +{ + game_text_display (level, buffer, "L"); +} + + +/** Set the game level of difficulty. */ +static void +game_level_set (uint8_t level) +{ + spacey_options_t options; + uint8_t alien_num = 3; + uint8_t alien_steps = 4; + + switch (level) + { + default: + case 0: + options.aliens_wrap = 0; + options.aliens_evasive = 0; + break; + + case 1: + options.aliens_wrap = 0; + options.aliens_evasive = 1; + alien_steps = 3; + break; + + case 2: + options.aliens_wrap = 1; + options.aliens_evasive = 0; + alien_steps = 3; + break; + + case 3: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 3; + break; + + case 4: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 3; + alien_num = 4; + break; + + case 5: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 2; + alien_num = 4; + break; + } + + spacey_alien_num_set (alien_num); + spacey_alien_create_steps_set (alien_steps); + spacey_options_set (options); +} + + +static void +game_start (game_data_t *data) +{ + tinygl_clear (); + data->games++; + game_level_set (data->level); + spacey_start (); + eeprom_write (0, data, sizeof (*data)); +} + + +static void game_event (__unused__ void *data, spacey_event_t event) +{ + switch (event) + { + case SPACEY_EVENT_ALIEN_HIT: + break; + + case SPACEY_EVENT_ALIEN_LANDED: + break; + } +} + + + +static void game_task (__unused__ void *data) +{ + static bool init = 0; + static uint8_t game_over_ticks; + char message[44]; + + if (!init) + { + led_init (); + + led_set (LED1, 1); + + /* When the EEPROM is erased all the bytes are 0xFF so set to + sensible defaults. */ + eeprom_read (0, &game_data, sizeof (game_data)); + if (game_data.level == 0xff) + { + game_data.level = 0; + game_data.games = 0; + } + + spacey_init (GAME_UPDATE_RATE, TINYGL_WIDTH, TINYGL_HEIGHT, + display_handler, display); + + spacey_event_handler_set (game_event, 0); + + init = 1; + } + + switch (state) + { + case STATE_PLAYING: + if (! spacey_update ()) + { + game_over_display (message); + game_over_ticks = 0; + led_set (LED1, 1); + state = STATE_OVER; + } + break; + + case STATE_INIT: + tinygl_text ("SPACEY READY V" VERSION " BY MPH "); + state = STATE_READY; + break; + + case STATE_OVER: + game_over_ticks ++; + if (game_over_ticks >= GAME_UPDATE_RATE * GAME_OVER_PERIOD) + state = STATE_READY; + /* Fall through. */ + + case STATE_READY: + case STATE_MENU_LEVEL: + default: + break; + + case STATE_START: + /* Turn that bloody blimey space invader off... */ + game_start (&game_data); + led_set (LED1, 0); + state = STATE_PLAYING; + break; + } +} + + + +static void display_task (__unused__ void *data) +{ + static bool init = 0; + static flasher_t flashers[SPACEY_PIX_TYPE_NUM]; + static uint8_t flasher_state[SPACEY_PIX_TYPE_NUM]; + static flasher_obj_t flashers_info[SPACEY_PIX_TYPE_NUM]; + + if (!init) + { + uint8_t i; + + tinygl_init (DISPLAY_UPDATE_RATE); + tinygl_font_set (&font3x5_1); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + tinygl_text_mode_set (TINYGL_TEXT_MODE_ROTATE_SCROLL_DOWN); + tinygl_text_speed_set (10); + + for (i = 0; i < ARRAY_SIZE (flashers); i++) + { + flashers[i] = flasher_init (&flashers_info[i]); + flasher_state[i] = 0; + } + + for (i = 0; i < ARRAY_SIZE (display); i++) + display[i] = 0; + + /* Set up flash patterns for different pixel types. */ + flasher_pattern_set (flashers[SPACEY_PIX_GUN], + &flasher_patterns[FLASH_MODE_GUN]); + flasher_pattern_set (flashers[SPACEY_PIX_SHELL], + &flasher_patterns[FLASH_MODE_SHELL]); + flasher_pattern_set (flashers[SPACEY_PIX_ALIEN], + &flasher_patterns[FLASH_MODE_ALIEN]); + + init = 1; + } + + if (state == STATE_PLAYING) + { + uint8_t *src; + uint8_t i; + uint8_t j; + + /* Update flasher states. NB, the first flasher is always off. */ + for (i = 1; i < ARRAY_SIZE (flashers); i++) + flasher_state[i] = flasher_update (flashers[i]); + + /* Update display. */ + src = display; + for (j = 0; j < TINYGL_HEIGHT; j++) + for (i = 0; i < TINYGL_WIDTH; i++) + { + tinygl_point_t point = {i, j}; + + tinygl_draw_point (point, flasher_state[*src++]); + } + } + + + /* Advance messages and refresh display. */ + tinygl_update (); +} + + + +static void navswitch_task (__unused__ void *data) +{ + static bool init = 0; + char message[44]; + + if (!init) + { + navswitch_init (); + init = 1; + } + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + { + switch (state) + { + case STATE_READY: + break; + + case STATE_MENU_LEVEL: + if (game_data.level < GAME_LEVEL_MAX - 1) + game_data.level++; + game_level_display (game_data.level, message); + break; + + case STATE_PLAYING: + spacey_gun_move_right (); + break; + + default: + break; + } + } + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + { + switch (state) + { + case STATE_READY: + break; + + case STATE_MENU_LEVEL: + if (game_data.level > 1) + game_data.level--; + game_level_display (game_data.level, message); + break; + + case STATE_PLAYING: + spacey_gun_move_left (); + break; + + default: + break; + } + } + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + { + switch (state) + { + case STATE_READY: + state = STATE_MENU_LEVEL; + game_level_display (game_data.level, message); + break; + + case STATE_MENU_LEVEL: + break; + + case STATE_PLAYING: + break; + + default: + break; + } + } + + if (navswitch_push_event_p (NAVSWITCH_PUSH)) + { + switch (state) + { + case STATE_READY: + state = STATE_START; + break; + + case STATE_PLAYING: + spacey_gun_fire (); + break; + + case STATE_MENU_LEVEL: + state = STATE_READY; + break; + + default: + break; + } + } +} + + +int +main (void) +{ + task_t tasks[] = + { + { + .func = display_task, + .period = TASK_RATE / DISPLAY_UPDATE_RATE, + .data = 0 + }, + { + .func = navswitch_task, + .period = TASK_RATE / BUTTON_POLL_RATE, + .data = 0 + }, + { + .func = game_task, + .period = TASK_RATE / GAME_UPDATE_RATE, + .data = 0 + }, + }; + + + system_init (); + + task_schedule (tasks, ARRAY_SIZE (tasks)); + return 0; +} diff --git a/apps/space11/spacey.c b/apps/space11/spacey.c new file mode 100644 index 0000000..cb96d91 --- /dev/null +++ b/apps/space11/spacey.c @@ -0,0 +1,578 @@ +/** @file spacey.c + @author M. P. Hayes, UCECE + @date 13 March 2007 + @brief This implements a simple space invaders game. +*/ + +#include +#include "spacey.h" + +/* This function implements a simple space invades program. Aliens + randomly appear on the top row of the display and work their way + randomly down the display. The game ends when 5 aliens have + reached the bottom of the display. To kill the aliens, shells can + be fired at them from a gun on the bottom of the display. The gun + can only move across the bottom and when it gets to the side it + wraps around to the other side. + + The aliens could move at different speeds but currently they are + set at the same speed to keep things simple. +*/ + + +#ifndef DISPLAY_INTERLACE +#define DISPLAY_INTERLACE 0 +#endif + + +#if DISPLAY_INTERLACE +/* With an interlaced display we do not have odd numbered rows and + columns. */ +enum {SPACEY_SHELL_INC = 2, SPACEY_GUN_INC = 2}; +#else +enum {SPACEY_SHELL_INC = 1, SPACEY_GUN_INC = 1}; +#endif + + +enum {SPACEY_LIVES_DEFAULT = 5}; +enum {SPACEY_SHELL_SPEED_DEFAULT = 16}; +enum {SPACEY_ALIEN_SPEED_DEFAULT = 2}; +enum {SPACEY_ALIEN_CREATE_STEPS_DEFAULT = 4}; +enum {SPACEY_ALIEN_NUM_DEFAULT = 3}; +enum {SPACEY_SHELL_NUM_DEFAULT = 2}; + + +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static spacey_t spacey_data; +static spacey_t * const spacey = &spacey_data; + + +void +spacey_lives_set (uint8_t lives) +{ + spacey->lives = lives; +} + + +void +spacey_alien_speed_set (uint8_t alien_speed) +{ + spacey->aliens.move_period = spacey->poll_rate / alien_speed; +} + + +void +spacey_shell_speed_set (uint8_t shell_speed) +{ + spacey->shells.move_period = spacey->poll_rate / shell_speed; +} + + +void +spacey_alien_create_steps_set (uint8_t alien_create_steps) +{ + spacey->alien_create_steps = alien_create_steps; +} + + +void +spacey_alien_num_set (uint8_t aliens_num) +{ + spacey->aliens.num = min (aliens_num, SPACEY_ALIENS_MAX); +} + + +void +spacey_shell_num_set (uint8_t shells_num) +{ + spacey->shells.num = min (shells_num, SPACEY_SHELLS_MAX); +} + + +void +spacey_options_set (spacey_options_t options) +{ + spacey->options = options; +} + + +void +spacey_init (uint16_t poll_rate, + uint8_t x_size, uint8_t y_size, + void (*display_handler) (void *data, uint8_t row, uint8_t col, + spacey_pix_t type), + void *display_data) +{ + spacey->size.x = x_size; + spacey->size.y = y_size; + spacey->display_hook = display_handler; + spacey->display_data = display_data; + spacey->active = 0; + spacey->poll_rate = poll_rate; + spacey->event_hook = NULL; + + spacey->options.aliens_wrap = 0; + spacey->options.aliens_evasive = 0; + + spacey_alien_num_set (SPACEY_ALIEN_NUM_DEFAULT); + spacey_shell_num_set (SPACEY_SHELL_NUM_DEFAULT); + spacey_shell_speed_set (SPACEY_SHELL_SPEED_DEFAULT); + spacey_alien_speed_set (SPACEY_ALIEN_SPEED_DEFAULT); + spacey_alien_create_steps_set (SPACEY_ALIEN_CREATE_STEPS_DEFAULT); + spacey->lives = SPACEY_LIVES_DEFAULT; +} + + +void +spacey_event_handler_set (void (*event_handler) (void *, spacey_event_t), + void *event_data) +{ + spacey->event_hook = event_handler; + spacey->event_data = event_data; +} + + +static void +spacey_pixel_set (spacey_pos_t *pos, + spacey_pix_t type) +{ + spacey->display_hook (spacey->display_data, pos->x, pos->y, type); +} + + +/* Return if obj is at the same point as another alien. */ +static spacey_obj_t * +spacey_alien_conflict_p (spacey_obj_t *obj) +{ + int8_t i; + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active || alien == obj) + continue; + + if (alien->pos.x == obj->pos.x + && alien->pos.y == obj->pos.y) + return alien; + } + return 0; +} + + +/* Return if obj is at the same point as another shell. */ +static spacey_obj_t * +spacey_shell_conflict_p (spacey_obj_t *obj) +{ + int8_t i; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (!shell->active || shell == obj) + continue; + + if (shell->pos.x == obj->pos.x + && shell->pos.y == obj->pos.y) + return shell; + } + return 0; +} + + +static void +spacey_gun_move (int8_t inc) +{ + int8_t gun_x; + + spacey_pixel_set (&spacey->gun, SPACEY_PIX_OFF); + + gun_x = spacey->gun.x + inc; + if (gun_x >= spacey->size.x) + gun_x = 0; + else if (gun_x < 0) + gun_x = spacey->size.x - 1; + spacey->gun.x = gun_x; + + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); +} + + +/* Return true if move off display. */ +static bool +spacey_shell_move (spacey_obj_t *shell) +{ + /* Erase the previous position of the shell except if still + at gun. */ + if (shell->pos.x != spacey->gun.x + || shell->pos.y != spacey->gun.y) + spacey_pixel_set (&shell->pos, SPACEY_PIX_OFF); + + /* Shells only go straight up. */ + shell->pos.y -= SPACEY_SHELL_INC; + + if (shell->pos.y < 0) + return 1; + + spacey_pixel_set (&shell->pos, SPACEY_PIX_SHELL); + return 0; +} + + +static void +spacey_alien_erase (spacey_obj_t *alien) +{ + spacey_pixel_set (&alien->pos, SPACEY_PIX_OFF); +} + + +/* Return true if move off display or get to the bottom. */ +static bool +spacey_alien_move (spacey_obj_t *alien) +{ + int8_t x_jump; + + /* Aliens move down randomly zig zagging. */ + alien->pos.y++; + + /* Randomly move left or right. */ + x_jump = 2 * (rand () & 1) - 1; + + /* Don't move into line of gun if being evasive. */ + if (spacey->options.aliens_evasive && + spacey->gun.x == alien->pos.x + x_jump) + x_jump = -x_jump; + + alien->pos.x += x_jump; + + /* Keep the alien within bounds. */ + if (alien->pos.x < 0 || alien->pos.x >= spacey->size.x) + { + if (spacey->options.aliens_wrap) + alien->pos.x = spacey->size.x - abs (alien->pos.x); + else + alien->pos.x -= 2 * x_jump; + } + + if (alien->pos.y < spacey->size.y) + spacey_pixel_set (&alien->pos, SPACEY_PIX_ALIEN); + + if (alien->pos.y >= (spacey->size.y - 1)) + return 1; + + return 0; +} + + +static void +spacey_alien_create (void) +{ + int8_t i; + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (alien->active) + continue; + + /* Aliens start at the top. */ + alien->pos.y = 0; + + while (1) + { + /* Choose random x position. */ + alien->pos.x = rand () % spacey->size.x; +#if DISPLAY_INTERLACE + /* Ensure x position is even. */ + alien->pos.x &= ~1; +#endif + alien->active = 1; + + /* Ensure aliens start at different spots to be fair! */ + if (!spacey_alien_conflict_p (alien)) + break; + } + spacey->stats.aliens_live++; + spacey_pixel_set (&alien->pos, SPACEY_PIX_ALIEN); + return; + } + /* If we get to here then we already have too many aliens. */ +} + + +static void +spacey_shell_create (void) +{ + int8_t i; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (shell->active) + continue; + + shell->pos = spacey->gun; + shell->active = 1; + spacey->stats.shells_fired++; + /* Don't turn shell on initially since it will erase the gun. */ + return; + } + /* If we get to here then we already have too many shells. */ +} + + +static void +spacey_alien_kill (spacey_obj_t *alien) +{ + alien->active = 0; + spacey->stats.aliens_live--; +} + + +static void +spacey_shell_kill (spacey_obj_t *shell) +{ + shell->active = 0; +} + + +static void +spacey_event (spacey_event_t event) +{ + if (spacey->event_hook) + spacey->event_hook (spacey->event_data, event); +} + + +static void +spacey_alien_hit (spacey_obj_t *alien, spacey_obj_t *shell) +{ + spacey_alien_kill (alien); + spacey->stats.aliens_killed++; + + spacey_shell_kill (shell); + spacey_pixel_set (&shell->pos, SPACEY_PIX_OFF); + + spacey_event (SPACEY_EVENT_ALIEN_HIT); +} + + +static void +spacey_alien_landed (void) +{ + spacey->stats.aliens_landed++; + if (spacey->stats.aliens_landed >= spacey->lives) + spacey->active = 0; + + spacey_event (SPACEY_EVENT_ALIEN_LANDED); +} + + +static void +spacey_shells_move (void) +{ + int8_t i; + + spacey->shells.move_clock++; + if (spacey->shells.move_clock < spacey->shells.move_period) + return; + spacey->shells.move_clock = 0; + + /* Shells move until they hit an alien or move off the display. */ + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (!shell->active) + continue; + + if (spacey_shell_move (shell)) + spacey_shell_kill (shell); + else + { + spacey_obj_t *alien; + + /* Check if we've hit an alien. */ + while ((alien = spacey_alien_conflict_p (shell))) + { + /* We've hit an alien so kill it and the shell. */ + spacey_alien_hit (alien, shell); + } + } + } +} + + +static void +spacey_aliens_move (void) +{ + int8_t i; + uint8_t steps; + + spacey->aliens.move_clock++; + if (spacey->aliens.move_clock < spacey->aliens.move_period) + return; + spacey->aliens.move_clock = 0; + + /* Erase all aliens before moving them. */ + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active) + continue; + + spacey_alien_erase (alien); + } + + /* Now move and redraw aliens. */ + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active) + continue; + + if (spacey_alien_move (alien)) + { + if (alien->pos.y == spacey->gun.y) + { + /* The alien has reached Earth. */ + spacey_alien_landed (); + } + else + { + /* The alien has moved off the display so disable it. */ + spacey_alien_kill (alien); + + /* Redraw the gun in case it got hit by the alien. */ + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); + } + } + else + { + spacey_obj_t *shell; + + while ((shell = spacey_shell_conflict_p (alien))) + { + /* The alien hit a shell so kill it and the shell. */ + spacey_alien_hit (alien, shell); + } + } + } + + /* Randomly create an alien. If there are no aliens create a new + one more rapidly. */ + if (!spacey->stats.aliens_live) + steps = 2; + else + steps = spacey->alien_create_steps; + + if ((rand () % steps) == 0) + spacey_alien_create (); +} + + +/* Update the state of the game. */ +bool +spacey_update (void) +{ + /* Allow playing with the gun even if game inactive. */ + spacey_shells_move (); + + if (!spacey->active) + return 0; + + spacey_aliens_move (); + return 1; +} + + +/* Move the gun position to the right wrapping back around on left. */ +void +spacey_gun_move_right (void) +{ + spacey_gun_move (SPACEY_GUN_INC); +} + + +/* Move the gun position to the left wrapping back around on right. */ +void +spacey_gun_move_left (void) +{ + spacey_gun_move (-SPACEY_GUN_INC); +} + + +/* Fire the gun. */ +void +spacey_gun_fire (void) +{ + spacey_shell_create (); +} + + +/* Start a new game. */ +void +spacey_start (void) +{ + int8_t i; + int8_t j; + + spacey->shells.move_clock = 0; + spacey->aliens.move_clock = 0; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + shell->active = 0; + } + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + alien->active = 0; + } + + /* Turn all pixels off. */ + for (i = 0; i < spacey->size.x; i++) + for (j = 0; j < spacey->size.y; j++) + { + spacey_pos_t pos = {i, j}; + + spacey_pixel_set (&pos, SPACEY_PIX_OFF); + } + + /* Display gun in centre of display. */ + spacey->gun.x = (spacey->size.x / 2) & ~1; + spacey->gun.y = spacey->size.y - 1; + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); + + spacey->stats.aliens_live = 0; + spacey->stats.aliens_killed = 0; + spacey->stats.aliens_landed = 0; + spacey->stats.shells_fired = 0; + spacey->active = 1; +} + + +uint8_t +spacey_aliens_killed_get (void) +{ + return spacey->stats.aliens_killed; +} + + +uint8_t +spacey_shells_fired_get (void) +{ + return spacey->stats.shells_fired; +} diff --git a/apps/space11/spacey.h b/apps/space11/spacey.h new file mode 100644 index 0000000..5b8b868 --- /dev/null +++ b/apps/space11/spacey.h @@ -0,0 +1,152 @@ +/** @file spacey.h + @author M. P. Hayes, UCECE + @date 13 March 2007 + @brief This is the interface for a simple space invaders game. +*/ + +#ifndef SPACEY_H +#define SPACEY_H + +#include "system.h" + + +enum {SPACEY_ALIENS_MAX = 4, SPACEY_SHELLS_MAX = 4}; + + +typedef enum {SPACEY_PIX_OFF, SPACEY_PIX_GUN, SPACEY_PIX_ALIEN, + SPACEY_PIX_SHELL, SPACEY_PIX_TYPE_NUM} spacey_pix_t; + +typedef enum {SPACEY_EVENT_ALIEN_HIT, SPACEY_EVENT_ALIEN_LANDED} spacey_event_t; + + +typedef enum {SPACEY_ALIEN, SPACEY_SHELL} spacey_type_t; + +/* Positions must be signed. */ +typedef struct +{ + int8_t x; + int8_t y; +} spacey_pos_t; + + +typedef struct +{ + spacey_pos_t pos; + bool active; +} spacey_obj_t; + + +typedef struct +{ + spacey_obj_t array[SPACEY_ALIENS_MAX]; + uint8_t num; + uint16_t move_period; + uint16_t move_clock; +} spacey_objs_t; + + +typedef struct +{ + uint8_t aliens_killed; + uint8_t aliens_landed; + uint8_t shells_fired; + uint8_t aliens_live; +} spacey_stats_t; + + +typedef struct +{ + int aliens_wrap:1; + int aliens_evasive:1; +} spacey_options_t; + + +typedef struct +{ + /* If we have lots of objects then a linked list would be more + efficient for the aliens and shells. */ + spacey_objs_t aliens; + spacey_objs_t shells; + spacey_pos_t gun; + spacey_pos_t size; + spacey_stats_t stats; + uint16_t poll_rate; /* Hz */ + uint8_t alien_create_steps; + uint8_t lives; + void (*display_hook) (void *data, uint8_t row, uint8_t col, spacey_pix_t type); + void *display_data; + void (*event_hook) (void *data, spacey_event_t event); + void *event_data; + spacey_options_t options; + bool active; +} spacey_t; + + +void +spacey_event_handler_set (void (*event_handler) (void *, spacey_event_t), + void *event_data); + +void +spacey_init (uint16_t poll_rate, + uint8_t x_size, uint8_t y_size, + void (*display_handler) (void *data, uint8_t row, uint8_t col, + spacey_pix_t type), + void *display_data); + +/** Start a new game. */ +void +spacey_start (void); + +/** Update state of game. */ +bool +spacey_update (void); + +/** Specify number of lives we have before we die. */ +void +spacey_lives_set (uint8_t lives); + +/** Set alien speed in Hz. */ +void +spacey_alien_speed_set (uint8_t alien_speed); + +/** Set shell speed in Hz. */ +void +spacey_shell_speed_set (uint8_t shell_speed); + +/** Set number of steps that a new alien is created on average. */ +void +spacey_alien_create_steps_set (uint8_t alien_create_steps); + +/** Set maximum number of aliens on display at once. */ +void +spacey_alien_num_set (uint8_t aliens_num); + +/** Set maximum number of shells on display at once. */ +void +spacey_shell_num_set (uint8_t shells_num); + +/** Set game options. */ +void +spacey_options_set (spacey_options_t options); + +/** Move gun to right. */ +void +spacey_gun_move_right (void); + +/** Move gun to left. */ +void +spacey_gun_move_left (void); + +/** Fire gun. */ +void +spacey_gun_fire (void); + +/** Return number of aliens killed in current game. */ +uint8_t +spacey_aliens_killed_get (void); + +/** Return number of shells fired in current game. */ +uint8_t +spacey_shells_fired_get (void); + +#endif diff --git a/apps/space11/ticker.c b/apps/space11/ticker.c new file mode 100644 index 0000000..25c741e --- /dev/null +++ b/apps/space11/ticker.c @@ -0,0 +1,6 @@ +/** @file ticker.c + @author M. P. Hayes, UCECE + @date 2 April 2007 + @brief +*/ + diff --git a/apps/space11/ticker.h b/apps/space11/ticker.h new file mode 100644 index 0000000..ac86df5 --- /dev/null +++ b/apps/space11/ticker.h @@ -0,0 +1,45 @@ +/** @file ticker.h + @author M. P. Hayes, UCECE + @date 2 April 2007 + @brief +*/ +#ifndef TICKER_H +#define TICKER_H + +#include + +typedef struct +{ + uint16_t period; + uint16_t clock; +} ticker_t; + + +typedef struct +{ + uint16_t period; + uint16_t clock; +} ticker16_t; + + +typedef struct +{ + uint8_t period; + uint8_t clock; +} ticker8_t; + + +#define TICKER_INIT(DEV, PERIOD) \ + (DEV)->period = (PERIOD); \ + (DEV)->clock = (DEV)->period; + + +/* Return non-zero when the ticker rolls over otherwise return 0. */ +#define TICKER_UPDATE(DEV) \ + (--(DEV)->clock ? 0 : ((DEV)->clock = (DEV)->period)) + + +#define TICKER_START(DEV) \ + (DEV)->clock = (DEV)->period; + +#endif diff --git a/apps/space9/Makefile b/apps/space9/Makefile new file mode 100644 index 0000000..7e9c3d6 --- /dev/null +++ b/apps/space9/Makefile @@ -0,0 +1,81 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for space9 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: space9.out + + +# Compile: create object files from C source files. +space9.o: space9.c ../../drivers/avr/eeprom.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/led.h ../../drivers/navswitch.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h ../../utils/uint8toa.h flasher.h spacey.h + $(CC) -c $(CFLAGS) $< -o $@ + +flasher.o: flasher.c ../../drivers/avr/system.h flasher.h + $(CC) -c $(CFLAGS) $< -o $@ + +spacey.o: spacey.c ../../drivers/avr/system.h spacey.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom.o: ../../drivers/avr/eeprom.c ../../drivers/avr/eeprom.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa.o: ../../utils/uint8toa.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +space9.out: display.o eeprom.o flasher.o led.o ledmat.o navswitch.o pacer.o pio.o space9.o spacey.o system.o timer.o tinygl.o uint8toa.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: space9.out + $(OBJCOPY) -O ihex space9.out space9.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash space9.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/space9/Makefile.test b/apps/space9/Makefile.test new file mode 100644 index 0000000..5e81b90 --- /dev/null +++ b/apps/space9/Makefile.test @@ -0,0 +1,75 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for space9 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: space9 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +flasher-test.o: flasher.c flasher.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +uint8toa-test.o: ../../utils/uint8toa.c ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +spacey-test.o: spacey.c spacey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +space9-test.o: space9.c ../../drivers/navswitch.h ../../utils/font.h ../../drivers/test/system.h ../../drivers/test/eeprom.h ../../fonts/font3x5_1.h ../../drivers/led.h flasher.h ../../utils/tinygl.h spacey.h ../../utils/pacer.h ../../drivers/display.h ../../utils/uint8toa.h + $(CC) -c $(CFLAGS) $< -o $@ + +eeprom-test.o: ../../drivers/test/eeprom.c ../../drivers/test/eeprom.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +space9: timer-test.o led-test.o display-test.o pio-test.o flasher-test.o pacer-test.o tinygl-test.o uint8toa-test.o ledmat-test.o spacey-test.o space9-test.o eeprom-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) space9 timer-test.o led-test.o display-test.o pio-test.o flasher-test.o pacer-test.o tinygl-test.o uint8toa-test.o ledmat-test.o spacey-test.o space9-test.o eeprom-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/space9/flasher.c b/apps/space9/flasher.c new file mode 100644 index 0000000..2cdebd4 --- /dev/null +++ b/apps/space9/flasher.c @@ -0,0 +1,100 @@ +/** @file flasher.c + @author M. P. Hayes, UCECE + @date 13 March 2005 + @brief +*/ + +#include "flasher.h" + + +/* These routines are for flashing a LED or beeping a piezo tweeter. + Perhaps they should be separated into software PWM and flash + pattern sequencing. */ + +int8_t +flasher_pattern_set (flasher_t flasher, flasher_pattern_t *pattern) +{ + flasher->pattern = pattern; + flasher->mod_count = 0; + flasher->flasher_count = 0; + flasher->flashes_count = 0; + flasher->flasher_prescale = 0; + return 1; +} + + +flasher_pattern_t * +flasher_pattern_get (flasher_t flasher) +{ + return flasher->pattern; +} + + +/* FIXME. */ +int8_t +flasher_phase_set (flasher_t flasher, uint8_t phase) +{ + flasher->mod_count = 0; + flasher->flasher_count = 0; + flasher->flashes_count = phase; + return 1; +} + + +/* Return the next state for the associated device. For example, + to control the flashing of a LED use: + + led_set (led, flasher_update (flasher)); */ +bool +flasher_update (flasher_t flasher) +{ + if (!flasher->pattern) + return 0; + + flasher->mod_count++; + if (flasher->mod_count >= flasher->pattern->mod_period) + { + flasher->mod_count = 0; + flasher->flasher_prescale++; + + if (flasher->flasher_prescale >= FLASHER_PRESCALE) + { + flasher->flasher_prescale = 0; + flasher->flasher_count++; + + if (flasher->flasher_count >= flasher->pattern->flasher_period) + { + flasher->flasher_count = 0; + flasher->flashes_count++; + + if (!flasher->pattern->period) + { + /* One shot mode. */ + if (flasher->flashes_count >= flasher->pattern->flashes) + { + /* Disable pattern. */ + flasher->pattern = 0; + return 1; + } + } + else if (flasher->flashes_count >= flasher->pattern->period) + { + flasher->flashes_count = 0; + } + } + } + } + + return flasher->mod_count < flasher->pattern->mod_duty + && flasher->flasher_count < flasher->pattern->flasher_duty + && flasher->flashes_count < flasher->pattern->flashes; +} + + +/* Create a new flasher device. */ +flasher_t +flasher_init (flasher_obj_t *flasher) +{ + flasher_pattern_set (flasher, 0); + return flasher; +} diff --git a/apps/space9/flasher.h b/apps/space9/flasher.h new file mode 100644 index 0000000..4cfd6f8 --- /dev/null +++ b/apps/space9/flasher.h @@ -0,0 +1,97 @@ +/** @file flasher.h + @author M. P. Hayes, UCECE + @date 13 March 2005 + @brief Combined software PWM and flashing module. Use at your peril! +*/ +#ifndef FLASHER_H +#define FLASHER_H + +#include "system.h" + +/* This parameter is for internal use only. It's purpose is to + reduce the chances of flasher_period and flasher_duty overflow. + It could possibly be made an additional parameter for flasher_pattern_t + and calculated by FLASHER_PATTERN. */ +#define FLASHER_PRESCALE 8 + +/* POLL_RATE (Hz) + MOD_FREQ (Hz) + MOD_DUTY (percent) + FLASHER_PERIOD (s) - period between flashes + FLASHER_DUTY (percent) - proportion of flash period that is lit + FLASHES (integer) - how many flashes per flash pattern + PERIOD (s) - how often the flash pattern repeats +*/ + +#define FLASHER_PATTERN(POLL_RATE, MOD_FREQ, MOD_DUTY, FLASHER_PERIOD, \ + FLASHER_DUTY, FLASHES, PERIOD) \ + (POLL_RATE) / (double)(MOD_FREQ) + 0.5, \ + (POLL_RATE) * (double)(MOD_DUTY) / (MOD_FREQ) / 100.0 + 0.5, \ + (MOD_FREQ) * (FLASHER_PERIOD) / (double)FLASHER_PRESCALE + 0.5, \ + (MOD_FREQ) * (FLASHER_PERIOD) * (FLASHER_DUTY) / 100.0 / FLASHER_PRESCALE + 0.5, \ + (FLASHES), \ + (PERIOD) / (double)(FLASHER_PERIOD) + 0.5 + + +typedef struct +{ + /* This is the modulation period. It determines the frequency + of a tone or flicker rate of a LED. */ + uint8_t mod_period; + /* This is the modulation duty. It determines the luminance of a LED. */ + uint8_t mod_duty; + /* This is the period between the start of two flashes in a sequence. */ + uint8_t flasher_period; + /* This is the flash period. */ + uint8_t flasher_duty; + /* This is the number of flashes in the sequence. */ + uint8_t flashes; + /* This is the number of flasher periods before the sequence repeats. */ + uint8_t period; +} flasher_pattern_t; + + +#define FLASHER_ACTIVE_P(FLASHER) \ + (((flasher_obj_t *)(FLASHER))->pattern != 0) + + +#define FLASHER_PATTERN_FLASHES_SET(PATTERN, FLASHES) \ + (PATTERN)->flashes = (FLASHES) + +/* This structure is defined here so the compiler can allocate enough + memory for it. However, its fields should be treated as + private. */ +typedef struct +{ + flasher_pattern_t *pattern; + uint8_t mod_count; + uint8_t flasher_count; + uint8_t flashes_count; + uint8_t flasher_prescale; +} flasher_private_t; + + +typedef flasher_private_t flasher_obj_t; +typedef flasher_obj_t *flasher_t; + + +extern int8_t +flasher_pattern_set (flasher_t flasher, flasher_pattern_t *pattern); + +extern flasher_pattern_t * +flasher_pattern_get (flasher_t flasher); + +extern int8_t +flasher_phase_set (flasher_t flasher, uint8_t phase); + +extern bool +flasher_update (flasher_t); + + +/* INFO is a pointer into RAM that stores the state of the FLASH. + CFG is a pointer into ROM to define the port the FLASH is connected to. + The returned handle is passed to the other flasher_xxx routines to denote + the FLASH to operate on. */ +extern flasher_t +flasher_init (flasher_obj_t *info); +#endif diff --git a/apps/space9/space9.c b/apps/space9/space9.c new file mode 100644 index 0000000..a2f0f6b --- /dev/null +++ b/apps/space9/space9.c @@ -0,0 +1,432 @@ +/** @file space9.c + @author M. P. Hayes, UCECE + @date 20 April 2007 + @brief A simple space invaders game with different difficulty levels. + + @defgroup space9 A simple space invaders game. +*/ + +#include +#include "system.h" +#include "display.h" +#include "tinygl.h" +#include "pacer.h" +#include "navswitch.h" +#include "led.h" +#include "flasher.h" +#include "spacey.h" +#include "eeprom.h" +#include "uint8toa.h" +#include "../fonts/font3x5_1.h" + + +#define VERSION "1.6" + +/** Define polling rates in Hz. */ +enum {LOOP_RATE = 500}; +enum {FLASHER_UPDATE_RATE = LOOP_RATE}; +enum {BUTTON_POLL_RATE = 100}; +enum {GAME_UPDATE_RATE = 100}; +enum {GAME_OVER_PERIOD = 2}; +enum {BUTTON_HOLD_PERIOD = 1}; + + +/** Define flasher modes. */ +static flasher_pattern_t flasher_patterns[] = +{ + /** POLL_RATE, MOD_FREQ, MOD_DUTY, FLASHER_PERIOD, + FLASHER_DUTY, FLASHES, PERIOD. */ + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 100, 100, 0.4, 100, 1, 0.4)}, + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 100, 100, 0.4, 100, 1, 0.4)}, + {FLASHER_PATTERN (FLASHER_UPDATE_RATE, 200, 100, 0.1, 50, 1, 0.1)}, +}; + +typedef enum {FLASH_MODE_GUN, FLASH_MODE_SHELL, + FLASH_MODE_ALIEN, FLASH_MODE_NUM} flash_mode_t; + + +typedef enum {STATE_DUMMY, STATE_INIT, STATE_START, + STATE_PLAYING, STATE_OVER, + STATE_READY, STATE_MENU_LEVEL} state_t; + +enum {GAME_LEVEL_MAX = 5}; + + +typedef struct +{ + uint8_t level; + uint8_t games; +} game_data_t; + + + +/** Draw pixel on display. */ +static void +display_handler (void *data, uint8_t col, uint8_t row, spacey_pix_t type) +{ + uint8_t *display = data; + uint8_t pixel; + + pixel = row * TINYGL_WIDTH + col; + display[pixel] = type; +} + + +/** Display the game over message. */ +static void +game_over_display (char *buffer) +{ + char *str = buffer; + + strcpy (str, "GAME OVER "); + while (*str) + str++; + uint8toa (spacey_aliens_killed_get (), str, 0); + while (*str) + str++; + *str++ = '/'; + uint8toa (spacey_shells_fired_get (), str, 0); + tinygl_clear (); + tinygl_text (buffer); +} + + +static void +game_text_display (uint8_t num, char *buffer, char *msg) +{ + char *str = buffer; + + while (*msg) + *str++ = *msg++; + uint8toa (num, str, 0); + tinygl_clear (); + tinygl_text (buffer); +} + + +/** Display the game level of difficulty. */ +static void +game_level_display (uint8_t level, char *buffer) +{ + game_text_display (level, buffer, "L"); +} + + +/** Set the game level of difficulty. */ +static void +game_level_set (uint8_t level) +{ + spacey_options_t options; + uint8_t alien_num = 3; + uint8_t alien_steps = 4; + + switch (level) + { + default: + case 0: + options.aliens_wrap = 0; + options.aliens_evasive = 0; + break; + + case 1: + options.aliens_wrap = 0; + options.aliens_evasive = 1; + alien_steps = 3; + break; + + case 2: + options.aliens_wrap = 1; + options.aliens_evasive = 0; + alien_steps = 3; + break; + + case 3: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 3; + break; + + case 4: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 3; + alien_num = 4; + break; + + case 5: + options.aliens_wrap = 1; + options.aliens_evasive = 1; + alien_steps = 2; + alien_num = 4; + break; + } + + spacey_alien_num_set (alien_num); + spacey_alien_create_steps_set (alien_steps); + spacey_options_set (options); +} + + +static void +game_start (game_data_t *data) +{ + tinygl_clear (); + data->games++; + game_level_set (data->level); + spacey_start (); + eeprom_write (0, data, sizeof (*data)); +} + + +void game_event (__unused__ void *data, spacey_event_t event) +{ + switch (event) + { + case SPACEY_EVENT_ALIEN_HIT: + break; + + case SPACEY_EVENT_ALIEN_LANDED: + break; + } +} + + +int +main (void) +{ + uint8_t navswitch_ticks; + uint8_t game_ticks; + uint8_t game_over_ticks; + uint8_t navswitch_down_count; + state_t state = STATE_INIT; + flasher_t flashers[SPACEY_PIX_TYPE_NUM]; + uint8_t flasher_state[SPACEY_PIX_TYPE_NUM]; + flasher_obj_t flashers_info[SPACEY_PIX_TYPE_NUM]; + uint8_t display[TINYGL_WIDTH * TINYGL_HEIGHT]; + uint8_t i; + uint8_t j; + game_data_t data; + char message[44]; + + system_init (); + led_init (); + + led_set (LED1, 1); + + /* When the EEPROM is erased all the bytes are 0xFF so set to + sensible defaults. */ + eeprom_read (0, &data, sizeof (data)); + if (data.level == 0xff) + { + data.level = 0; + data.games = 0; + } + + for (i = 0; i < ARRAY_SIZE (flashers); i++) + { + flashers[i] = flasher_init (&flashers_info[i]); + flasher_state[i] = 0; + } + + for (i = 0; i < ARRAY_SIZE (display); i++) + display[i] = 0; + + /* Set up flash patterns for different pixel types. */ + flasher_pattern_set (flashers[SPACEY_PIX_GUN], + &flasher_patterns[FLASH_MODE_GUN]); + flasher_pattern_set (flashers[SPACEY_PIX_SHELL], + &flasher_patterns[FLASH_MODE_SHELL]); + flasher_pattern_set (flashers[SPACEY_PIX_ALIEN], + &flasher_patterns[FLASH_MODE_ALIEN]); + + tinygl_init (LOOP_RATE); + tinygl_font_set (&font3x5_1); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + tinygl_text_mode_set (TINYGL_TEXT_MODE_ROTATE_SCROLL_DOWN); + tinygl_text_speed_set (10); + + navswitch_init (); + + spacey_init (GAME_UPDATE_RATE, TINYGL_WIDTH, TINYGL_HEIGHT, + display_handler, display); + + spacey_event_handler_set (game_event, 0); + + navswitch_ticks = 0; + game_ticks = 0; + game_over_ticks = 0; + navswitch_down_count = 0; + + pacer_init (LOOP_RATE); + + while (1) + { + pacer_wait (); + + if (state == STATE_PLAYING) + { + uint8_t *src; + + /* Update flasher states. NB, the first flasher is always off. */ + for (i = 1; i < ARRAY_SIZE (flashers); i++) + flasher_state[i] = flasher_update (flashers[i]); + + /* Update display. */ + src = display; + for (j = 0; j < TINYGL_HEIGHT; j++) + for (i = 0; i < TINYGL_WIDTH; i++) + { + tinygl_point_t point = {i, j}; + + tinygl_draw_point (point, flasher_state[*src++]); + } + } + + /* Advance messages and refresh display. */ + tinygl_update (); + + game_ticks++; + if (game_ticks >= LOOP_RATE / GAME_UPDATE_RATE) + { + game_ticks = 0; + + switch (state) + { + case STATE_PLAYING: + if (! spacey_update ()) + { + game_over_display (message); + game_over_ticks = 0; + led_set (LED1, 1); + state = STATE_OVER; + } + break; + + case STATE_INIT: + tinygl_text ("SPACEY READY V" VERSION " BY MPH "); + state = STATE_READY; + break; + + case STATE_OVER: + game_over_ticks ++; + if (game_over_ticks >= GAME_UPDATE_RATE * GAME_OVER_PERIOD) + state = STATE_READY; + /* Fall through. */ + + case STATE_READY: + case STATE_MENU_LEVEL: + default: + break; + + case STATE_START: + /* Turn that bloody blimey space invader off... */ + game_start (&data); + led_set (LED1, 0); + state = STATE_PLAYING; + break; + } + } + + /* Poll navswitch. */ + navswitch_ticks++; + if (navswitch_ticks >= LOOP_RATE / BUTTON_POLL_RATE) + { + navswitch_ticks = 0; + + navswitch_update (); + + if (navswitch_down_p (NAVSWITCH_EAST)) + navswitch_down_count++; + else + navswitch_down_count = 0; + + if (navswitch_down_count >= BUTTON_POLL_RATE * BUTTON_HOLD_PERIOD) + state = STATE_INIT; + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + { + switch (state) + { + case STATE_READY: + break; + + case STATE_MENU_LEVEL: + if (data.level < GAME_LEVEL_MAX - 1) + data.level++; + game_level_display (data.level, message); + break; + + case STATE_PLAYING: + spacey_gun_move_right (); + break; + + default: + break; + } + } + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + { + switch (state) + { + case STATE_READY: + break; + + case STATE_MENU_LEVEL: + if (data.level > 1) + data.level--; + game_level_display (data.level, message); + break; + + case STATE_PLAYING: + spacey_gun_move_left (); + break; + + default: + break; + } + } + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + { + switch (state) + { + case STATE_READY: + state = STATE_MENU_LEVEL; + game_level_display (data.level, message); + break; + + case STATE_MENU_LEVEL: + break; + + case STATE_PLAYING: + break; + + default: + break; + } + } + + if (navswitch_push_event_p (NAVSWITCH_PUSH)) + { + switch (state) + { + case STATE_READY: + state = STATE_START; + break; + + case STATE_PLAYING: + spacey_gun_fire (); + break; + + case STATE_MENU_LEVEL: + state = STATE_READY; + break; + + default: + break; + } + } + } + } +} diff --git a/apps/space9/spacey.c b/apps/space9/spacey.c new file mode 100644 index 0000000..cb96d91 --- /dev/null +++ b/apps/space9/spacey.c @@ -0,0 +1,578 @@ +/** @file spacey.c + @author M. P. Hayes, UCECE + @date 13 March 2007 + @brief This implements a simple space invaders game. +*/ + +#include +#include "spacey.h" + +/* This function implements a simple space invades program. Aliens + randomly appear on the top row of the display and work their way + randomly down the display. The game ends when 5 aliens have + reached the bottom of the display. To kill the aliens, shells can + be fired at them from a gun on the bottom of the display. The gun + can only move across the bottom and when it gets to the side it + wraps around to the other side. + + The aliens could move at different speeds but currently they are + set at the same speed to keep things simple. +*/ + + +#ifndef DISPLAY_INTERLACE +#define DISPLAY_INTERLACE 0 +#endif + + +#if DISPLAY_INTERLACE +/* With an interlaced display we do not have odd numbered rows and + columns. */ +enum {SPACEY_SHELL_INC = 2, SPACEY_GUN_INC = 2}; +#else +enum {SPACEY_SHELL_INC = 1, SPACEY_GUN_INC = 1}; +#endif + + +enum {SPACEY_LIVES_DEFAULT = 5}; +enum {SPACEY_SHELL_SPEED_DEFAULT = 16}; +enum {SPACEY_ALIEN_SPEED_DEFAULT = 2}; +enum {SPACEY_ALIEN_CREATE_STEPS_DEFAULT = 4}; +enum {SPACEY_ALIEN_NUM_DEFAULT = 3}; +enum {SPACEY_SHELL_NUM_DEFAULT = 2}; + + +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static spacey_t spacey_data; +static spacey_t * const spacey = &spacey_data; + + +void +spacey_lives_set (uint8_t lives) +{ + spacey->lives = lives; +} + + +void +spacey_alien_speed_set (uint8_t alien_speed) +{ + spacey->aliens.move_period = spacey->poll_rate / alien_speed; +} + + +void +spacey_shell_speed_set (uint8_t shell_speed) +{ + spacey->shells.move_period = spacey->poll_rate / shell_speed; +} + + +void +spacey_alien_create_steps_set (uint8_t alien_create_steps) +{ + spacey->alien_create_steps = alien_create_steps; +} + + +void +spacey_alien_num_set (uint8_t aliens_num) +{ + spacey->aliens.num = min (aliens_num, SPACEY_ALIENS_MAX); +} + + +void +spacey_shell_num_set (uint8_t shells_num) +{ + spacey->shells.num = min (shells_num, SPACEY_SHELLS_MAX); +} + + +void +spacey_options_set (spacey_options_t options) +{ + spacey->options = options; +} + + +void +spacey_init (uint16_t poll_rate, + uint8_t x_size, uint8_t y_size, + void (*display_handler) (void *data, uint8_t row, uint8_t col, + spacey_pix_t type), + void *display_data) +{ + spacey->size.x = x_size; + spacey->size.y = y_size; + spacey->display_hook = display_handler; + spacey->display_data = display_data; + spacey->active = 0; + spacey->poll_rate = poll_rate; + spacey->event_hook = NULL; + + spacey->options.aliens_wrap = 0; + spacey->options.aliens_evasive = 0; + + spacey_alien_num_set (SPACEY_ALIEN_NUM_DEFAULT); + spacey_shell_num_set (SPACEY_SHELL_NUM_DEFAULT); + spacey_shell_speed_set (SPACEY_SHELL_SPEED_DEFAULT); + spacey_alien_speed_set (SPACEY_ALIEN_SPEED_DEFAULT); + spacey_alien_create_steps_set (SPACEY_ALIEN_CREATE_STEPS_DEFAULT); + spacey->lives = SPACEY_LIVES_DEFAULT; +} + + +void +spacey_event_handler_set (void (*event_handler) (void *, spacey_event_t), + void *event_data) +{ + spacey->event_hook = event_handler; + spacey->event_data = event_data; +} + + +static void +spacey_pixel_set (spacey_pos_t *pos, + spacey_pix_t type) +{ + spacey->display_hook (spacey->display_data, pos->x, pos->y, type); +} + + +/* Return if obj is at the same point as another alien. */ +static spacey_obj_t * +spacey_alien_conflict_p (spacey_obj_t *obj) +{ + int8_t i; + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active || alien == obj) + continue; + + if (alien->pos.x == obj->pos.x + && alien->pos.y == obj->pos.y) + return alien; + } + return 0; +} + + +/* Return if obj is at the same point as another shell. */ +static spacey_obj_t * +spacey_shell_conflict_p (spacey_obj_t *obj) +{ + int8_t i; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (!shell->active || shell == obj) + continue; + + if (shell->pos.x == obj->pos.x + && shell->pos.y == obj->pos.y) + return shell; + } + return 0; +} + + +static void +spacey_gun_move (int8_t inc) +{ + int8_t gun_x; + + spacey_pixel_set (&spacey->gun, SPACEY_PIX_OFF); + + gun_x = spacey->gun.x + inc; + if (gun_x >= spacey->size.x) + gun_x = 0; + else if (gun_x < 0) + gun_x = spacey->size.x - 1; + spacey->gun.x = gun_x; + + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); +} + + +/* Return true if move off display. */ +static bool +spacey_shell_move (spacey_obj_t *shell) +{ + /* Erase the previous position of the shell except if still + at gun. */ + if (shell->pos.x != spacey->gun.x + || shell->pos.y != spacey->gun.y) + spacey_pixel_set (&shell->pos, SPACEY_PIX_OFF); + + /* Shells only go straight up. */ + shell->pos.y -= SPACEY_SHELL_INC; + + if (shell->pos.y < 0) + return 1; + + spacey_pixel_set (&shell->pos, SPACEY_PIX_SHELL); + return 0; +} + + +static void +spacey_alien_erase (spacey_obj_t *alien) +{ + spacey_pixel_set (&alien->pos, SPACEY_PIX_OFF); +} + + +/* Return true if move off display or get to the bottom. */ +static bool +spacey_alien_move (spacey_obj_t *alien) +{ + int8_t x_jump; + + /* Aliens move down randomly zig zagging. */ + alien->pos.y++; + + /* Randomly move left or right. */ + x_jump = 2 * (rand () & 1) - 1; + + /* Don't move into line of gun if being evasive. */ + if (spacey->options.aliens_evasive && + spacey->gun.x == alien->pos.x + x_jump) + x_jump = -x_jump; + + alien->pos.x += x_jump; + + /* Keep the alien within bounds. */ + if (alien->pos.x < 0 || alien->pos.x >= spacey->size.x) + { + if (spacey->options.aliens_wrap) + alien->pos.x = spacey->size.x - abs (alien->pos.x); + else + alien->pos.x -= 2 * x_jump; + } + + if (alien->pos.y < spacey->size.y) + spacey_pixel_set (&alien->pos, SPACEY_PIX_ALIEN); + + if (alien->pos.y >= (spacey->size.y - 1)) + return 1; + + return 0; +} + + +static void +spacey_alien_create (void) +{ + int8_t i; + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (alien->active) + continue; + + /* Aliens start at the top. */ + alien->pos.y = 0; + + while (1) + { + /* Choose random x position. */ + alien->pos.x = rand () % spacey->size.x; +#if DISPLAY_INTERLACE + /* Ensure x position is even. */ + alien->pos.x &= ~1; +#endif + alien->active = 1; + + /* Ensure aliens start at different spots to be fair! */ + if (!spacey_alien_conflict_p (alien)) + break; + } + spacey->stats.aliens_live++; + spacey_pixel_set (&alien->pos, SPACEY_PIX_ALIEN); + return; + } + /* If we get to here then we already have too many aliens. */ +} + + +static void +spacey_shell_create (void) +{ + int8_t i; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (shell->active) + continue; + + shell->pos = spacey->gun; + shell->active = 1; + spacey->stats.shells_fired++; + /* Don't turn shell on initially since it will erase the gun. */ + return; + } + /* If we get to here then we already have too many shells. */ +} + + +static void +spacey_alien_kill (spacey_obj_t *alien) +{ + alien->active = 0; + spacey->stats.aliens_live--; +} + + +static void +spacey_shell_kill (spacey_obj_t *shell) +{ + shell->active = 0; +} + + +static void +spacey_event (spacey_event_t event) +{ + if (spacey->event_hook) + spacey->event_hook (spacey->event_data, event); +} + + +static void +spacey_alien_hit (spacey_obj_t *alien, spacey_obj_t *shell) +{ + spacey_alien_kill (alien); + spacey->stats.aliens_killed++; + + spacey_shell_kill (shell); + spacey_pixel_set (&shell->pos, SPACEY_PIX_OFF); + + spacey_event (SPACEY_EVENT_ALIEN_HIT); +} + + +static void +spacey_alien_landed (void) +{ + spacey->stats.aliens_landed++; + if (spacey->stats.aliens_landed >= spacey->lives) + spacey->active = 0; + + spacey_event (SPACEY_EVENT_ALIEN_LANDED); +} + + +static void +spacey_shells_move (void) +{ + int8_t i; + + spacey->shells.move_clock++; + if (spacey->shells.move_clock < spacey->shells.move_period) + return; + spacey->shells.move_clock = 0; + + /* Shells move until they hit an alien or move off the display. */ + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + if (!shell->active) + continue; + + if (spacey_shell_move (shell)) + spacey_shell_kill (shell); + else + { + spacey_obj_t *alien; + + /* Check if we've hit an alien. */ + while ((alien = spacey_alien_conflict_p (shell))) + { + /* We've hit an alien so kill it and the shell. */ + spacey_alien_hit (alien, shell); + } + } + } +} + + +static void +spacey_aliens_move (void) +{ + int8_t i; + uint8_t steps; + + spacey->aliens.move_clock++; + if (spacey->aliens.move_clock < spacey->aliens.move_period) + return; + spacey->aliens.move_clock = 0; + + /* Erase all aliens before moving them. */ + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active) + continue; + + spacey_alien_erase (alien); + } + + /* Now move and redraw aliens. */ + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + if (!alien->active) + continue; + + if (spacey_alien_move (alien)) + { + if (alien->pos.y == spacey->gun.y) + { + /* The alien has reached Earth. */ + spacey_alien_landed (); + } + else + { + /* The alien has moved off the display so disable it. */ + spacey_alien_kill (alien); + + /* Redraw the gun in case it got hit by the alien. */ + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); + } + } + else + { + spacey_obj_t *shell; + + while ((shell = spacey_shell_conflict_p (alien))) + { + /* The alien hit a shell so kill it and the shell. */ + spacey_alien_hit (alien, shell); + } + } + } + + /* Randomly create an alien. If there are no aliens create a new + one more rapidly. */ + if (!spacey->stats.aliens_live) + steps = 2; + else + steps = spacey->alien_create_steps; + + if ((rand () % steps) == 0) + spacey_alien_create (); +} + + +/* Update the state of the game. */ +bool +spacey_update (void) +{ + /* Allow playing with the gun even if game inactive. */ + spacey_shells_move (); + + if (!spacey->active) + return 0; + + spacey_aliens_move (); + return 1; +} + + +/* Move the gun position to the right wrapping back around on left. */ +void +spacey_gun_move_right (void) +{ + spacey_gun_move (SPACEY_GUN_INC); +} + + +/* Move the gun position to the left wrapping back around on right. */ +void +spacey_gun_move_left (void) +{ + spacey_gun_move (-SPACEY_GUN_INC); +} + + +/* Fire the gun. */ +void +spacey_gun_fire (void) +{ + spacey_shell_create (); +} + + +/* Start a new game. */ +void +spacey_start (void) +{ + int8_t i; + int8_t j; + + spacey->shells.move_clock = 0; + spacey->aliens.move_clock = 0; + + for (i = 0; i < spacey->shells.num; i++) + { + spacey_obj_t *shell = &spacey->shells.array[i]; + + shell->active = 0; + } + + for (i = 0; i < spacey->aliens.num; i++) + { + spacey_obj_t *alien = &spacey->aliens.array[i]; + + alien->active = 0; + } + + /* Turn all pixels off. */ + for (i = 0; i < spacey->size.x; i++) + for (j = 0; j < spacey->size.y; j++) + { + spacey_pos_t pos = {i, j}; + + spacey_pixel_set (&pos, SPACEY_PIX_OFF); + } + + /* Display gun in centre of display. */ + spacey->gun.x = (spacey->size.x / 2) & ~1; + spacey->gun.y = spacey->size.y - 1; + spacey_pixel_set (&spacey->gun, SPACEY_PIX_GUN); + + spacey->stats.aliens_live = 0; + spacey->stats.aliens_killed = 0; + spacey->stats.aliens_landed = 0; + spacey->stats.shells_fired = 0; + spacey->active = 1; +} + + +uint8_t +spacey_aliens_killed_get (void) +{ + return spacey->stats.aliens_killed; +} + + +uint8_t +spacey_shells_fired_get (void) +{ + return spacey->stats.shells_fired; +} diff --git a/apps/space9/spacey.h b/apps/space9/spacey.h new file mode 100644 index 0000000..5b8b868 --- /dev/null +++ b/apps/space9/spacey.h @@ -0,0 +1,152 @@ +/** @file spacey.h + @author M. P. Hayes, UCECE + @date 13 March 2007 + @brief This is the interface for a simple space invaders game. +*/ + +#ifndef SPACEY_H +#define SPACEY_H + +#include "system.h" + + +enum {SPACEY_ALIENS_MAX = 4, SPACEY_SHELLS_MAX = 4}; + + +typedef enum {SPACEY_PIX_OFF, SPACEY_PIX_GUN, SPACEY_PIX_ALIEN, + SPACEY_PIX_SHELL, SPACEY_PIX_TYPE_NUM} spacey_pix_t; + +typedef enum {SPACEY_EVENT_ALIEN_HIT, SPACEY_EVENT_ALIEN_LANDED} spacey_event_t; + + +typedef enum {SPACEY_ALIEN, SPACEY_SHELL} spacey_type_t; + +/* Positions must be signed. */ +typedef struct +{ + int8_t x; + int8_t y; +} spacey_pos_t; + + +typedef struct +{ + spacey_pos_t pos; + bool active; +} spacey_obj_t; + + +typedef struct +{ + spacey_obj_t array[SPACEY_ALIENS_MAX]; + uint8_t num; + uint16_t move_period; + uint16_t move_clock; +} spacey_objs_t; + + +typedef struct +{ + uint8_t aliens_killed; + uint8_t aliens_landed; + uint8_t shells_fired; + uint8_t aliens_live; +} spacey_stats_t; + + +typedef struct +{ + int aliens_wrap:1; + int aliens_evasive:1; +} spacey_options_t; + + +typedef struct +{ + /* If we have lots of objects then a linked list would be more + efficient for the aliens and shells. */ + spacey_objs_t aliens; + spacey_objs_t shells; + spacey_pos_t gun; + spacey_pos_t size; + spacey_stats_t stats; + uint16_t poll_rate; /* Hz */ + uint8_t alien_create_steps; + uint8_t lives; + void (*display_hook) (void *data, uint8_t row, uint8_t col, spacey_pix_t type); + void *display_data; + void (*event_hook) (void *data, spacey_event_t event); + void *event_data; + spacey_options_t options; + bool active; +} spacey_t; + + +void +spacey_event_handler_set (void (*event_handler) (void *, spacey_event_t), + void *event_data); + +void +spacey_init (uint16_t poll_rate, + uint8_t x_size, uint8_t y_size, + void (*display_handler) (void *data, uint8_t row, uint8_t col, + spacey_pix_t type), + void *display_data); + +/** Start a new game. */ +void +spacey_start (void); + +/** Update state of game. */ +bool +spacey_update (void); + +/** Specify number of lives we have before we die. */ +void +spacey_lives_set (uint8_t lives); + +/** Set alien speed in Hz. */ +void +spacey_alien_speed_set (uint8_t alien_speed); + +/** Set shell speed in Hz. */ +void +spacey_shell_speed_set (uint8_t shell_speed); + +/** Set number of steps that a new alien is created on average. */ +void +spacey_alien_create_steps_set (uint8_t alien_create_steps); + +/** Set maximum number of aliens on display at once. */ +void +spacey_alien_num_set (uint8_t aliens_num); + +/** Set maximum number of shells on display at once. */ +void +spacey_shell_num_set (uint8_t shells_num); + +/** Set game options. */ +void +spacey_options_set (spacey_options_t options); + +/** Move gun to right. */ +void +spacey_gun_move_right (void); + +/** Move gun to left. */ +void +spacey_gun_move_left (void); + +/** Fire gun. */ +void +spacey_gun_fire (void); + +/** Return number of aliens killed in current game. */ +uint8_t +spacey_aliens_killed_get (void); + +/** Return number of shells fired in current game. */ +uint8_t +spacey_shells_fired_get (void); + +#endif diff --git a/apps/space9/ticker.c b/apps/space9/ticker.c new file mode 100644 index 0000000..25c741e --- /dev/null +++ b/apps/space9/ticker.c @@ -0,0 +1,6 @@ +/** @file ticker.c + @author M. P. Hayes, UCECE + @date 2 April 2007 + @brief +*/ + diff --git a/apps/space9/ticker.h b/apps/space9/ticker.h new file mode 100644 index 0000000..ac86df5 --- /dev/null +++ b/apps/space9/ticker.h @@ -0,0 +1,45 @@ +/** @file ticker.h + @author M. P. Hayes, UCECE + @date 2 April 2007 + @brief +*/ +#ifndef TICKER_H +#define TICKER_H + +#include + +typedef struct +{ + uint16_t period; + uint16_t clock; +} ticker_t; + + +typedef struct +{ + uint16_t period; + uint16_t clock; +} ticker16_t; + + +typedef struct +{ + uint8_t period; + uint8_t clock; +} ticker8_t; + + +#define TICKER_INIT(DEV, PERIOD) \ + (DEV)->period = (PERIOD); \ + (DEV)->clock = (DEV)->period; + + +/* Return non-zero when the ticker rolls over otherwise return 0. */ +#define TICKER_UPDATE(DEV) \ + (--(DEV)->clock ? 0 : ((DEV)->clock = (DEV)->period)) + + +#define TICKER_START(DEV) \ + (DEV)->clock = (DEV)->period; + +#endif diff --git a/apps/spacey_remote1/Makefile b/apps/spacey_remote1/Makefile new file mode 100644 index 0000000..7ef951f --- /dev/null +++ b/apps/spacey_remote1/Makefile @@ -0,0 +1,72 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for spacey_remote1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: spacey_remote1.out + + +# Compile: create object files from C source files. +spacey_remote1.o: spacey_remote1.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/navswitch.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir.o: ../../drivers/ir.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ir.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial.o: ../../drivers/ir_serial.c ../../drivers/avr/delay.h ../../drivers/avr/system.h ../../drivers/ir.h ../../drivers/ir_serial.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +spacey_remote1.out: display.o ir.o ir_serial.o ledmat.o navswitch.o pacer.o pio.o spacey_remote1.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: spacey_remote1.out + $(OBJCOPY) -O ihex spacey_remote1.out spacey_remote1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash spacey_remote1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/spacey_remote1/Makefile.test b/apps/spacey_remote1/Makefile.test new file mode 100644 index 0000000..c781bbf --- /dev/null +++ b/apps/spacey_remote1/Makefile.test @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for spacey_remote1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: spacey_remote1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +ir_serial-test.o: ../../drivers/ir_serial.c ../../drivers/ir.h ../../drivers/ir_serial.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +spacey_remote1-test.o: spacey_remote1.c ../../drivers/navswitch.h ../../drivers/ir_serial.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/ir.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +ir-test.o: ../../drivers/ir.c ../../drivers/test/pio.h ../../drivers/ir.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +spacey_remote1: timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o spacey_remote1-test.o ir-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) spacey_remote1 timer-test.o display-test.o pio-test.o ir_serial-test.o pacer-test.o spacey_remote1-test.o ir-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/spacey_remote1/spacey_remote1.c b/apps/spacey_remote1/spacey_remote1.c new file mode 100644 index 0000000..8e4f83a --- /dev/null +++ b/apps/spacey_remote1/spacey_remote1.c @@ -0,0 +1,92 @@ +/** @file spacey_remote1.c + @author M. P. Hayes, UCECE + @date 24 August 2009 + @brief Test program for IR serial communications. + + @defgroup spacey_remote1 Remote control for the @ref spacey10 "spacey10" application. +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "ir_serial.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + +typedef enum {SPACEY_EVENT_ALIEN_HIT, SPACEY_EVENT_ALIEN_LANDED} spacey_event_t; + + +int main (void) +{ + int tick = 0; + + system_init (); + tinygl_init (LOOP_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_STEP); + + navswitch_init (); + ir_serial_init (); + + pacer_init (LOOP_RATE); + + tinygl_text ("#"); + + /* Paced loop. */ + while (1) + { + int ret; + uint8_t data; + + /* Wait for next tick. */ + pacer_wait (); + + tinygl_update (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + ir_serial_transmit (1); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + ir_serial_transmit (2); + + ret = ir_serial_receive (&data); + if (ret == 1) + { + spacey_event_t event = data; + + tick = 1; + + switch (event) + { + case SPACEY_EVENT_ALIEN_HIT: + tinygl_text ("*"); + break; + + case SPACEY_EVENT_ALIEN_LANDED: + tinygl_text ("@"); + break; + } + + } + + if (tick) + tick++; + if (tick > LOOP_RATE / 2) + { + tinygl_clear (); + tick = 0; + } + } + + return 0; +} diff --git a/apps/steer1/Makefile b/apps/steer1/Makefile new file mode 100644 index 0000000..b823e31 --- /dev/null +++ b/apps/steer1/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for steer1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: steer1.out + + +# Compile: create object files from C source files. +steer1.o: steer1.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +steer1.out: display.o ledmat.o navswitch.o pacer.o pio.o steer1.o system.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: steer1.out + $(OBJCOPY) -O ihex steer1.out steer1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash steer1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/steer1/Makefile.test b/apps/steer1/Makefile.test new file mode 100644 index 0000000..dce8574 --- /dev/null +++ b/apps/steer1/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for steer1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: steer1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +steer1-test.o: steer1.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../utils/font.h ../../drivers/test/system.h ../../fonts/font3x5_1.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/test/avrtest.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +steer1: timer-test.o display-test.o pio-test.o steer1-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) steer1 timer-test.o display-test.o pio-test.o steer1-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/steer1/steer1.c b/apps/steer1/steer1.c new file mode 100644 index 0000000..aff36af --- /dev/null +++ b/apps/steer1/steer1.c @@ -0,0 +1,118 @@ +/** @file steer1.c + @author M.P. Hayes + @date 28 Aug 2008 + + @defgroup steer1 Simple steering program using navswitchs +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "pio.h" +#include "../fonts/font3x5_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + +#define SIZE 35 + +static tinygl_point_t buffer[SIZE]; +static int in = 0; +static int out = 0; + + +void point_add (tinygl_point_t pos) +{ + int old = in; + + tinygl_draw_point (pos, 1); + buffer[in] = pos; + in++; + if (in >= SIZE) + in = 0; + if (in == out) + in = old; +} + + +void point_remove (void) +{ + if (in == out) + return; + + tinygl_draw_point (buffer[out], 0); + out++; + if (out >= SIZE) + out = 0; +} + + +int main (void) +{ + uint16_t tick = 0; + tinygl_point_t pos = tinygl_point (2, 3); + + system_init (); + pio_config_set (LED1_PIO, PIO_OUTPUT_HIGH); + + tinygl_init (LOOP_RATE); + tinygl_font_set (&font3x5_1); + + navswitch_init (); + + pacer_init (LOOP_RATE); + + point_add (pos); + + /* Paced loop. */ + while (1) + { + bool push = 0; + + /* Wait for next tick. */ + pacer_wait (); + + tick++; + if (tick > LOOP_RATE / 2) + { + tick = 0; + pio_output_toggle (LED1_PIO); + point_remove (); + } + + navswitch_update (); + + if (navswitch_push_event_p (2) && pos.x < TINYGL_WIDTH) + { + pos.x++; + push = 1; + } + if (navswitch_push_event_p (3) && pos.x > 0) + { + pos.x--; + push = 1; + } + if (navswitch_push_event_p (NAVSWITCH_EAST) && pos.y < TINYGL_HEIGHT) + { + pos.y++; + push = 1; + } + if (navswitch_push_event_p (4) && pos.y > 0) + { + pos.y--; + push = 1; + } + + if (push) + { + push = 0; + point_add (pos); + } + + tinygl_update (); + } + + return 0; +} diff --git a/apps/task1/Makefile b/apps/task1/Makefile new file mode 100644 index 0000000..efe6beb --- /dev/null +++ b/apps/task1/Makefile @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for task1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: task1.out + + +# Compile: create object files from C source files. +task1.o: task1.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../drivers/led.h ../../utils/task.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +task.o: ../../utils/task.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/task.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +task1.out: led.o pio.o system.o task.o task1.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: task1.out + $(OBJCOPY) -O ihex task1.out task1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash task1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/task1/Makefile.test b/apps/task1/Makefile.test new file mode 100644 index 0000000..93b26c1 --- /dev/null +++ b/apps/task1/Makefile.test @@ -0,0 +1,51 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for task1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: task1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +task-test.o: ../../utils/task.c ../../drivers/test/timer.h ../../utils/task.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +task1-test.o: task1.c ../../drivers/led.h ../../drivers/test/timer.h ../../utils/task.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +task1: timer-test.o led-test.o pio-test.o task-test.o task1-test.o system-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) task1 timer-test.o led-test.o pio-test.o task-test.o task1-test.o system-test.o mgetkey-test.o + + diff --git a/apps/task1/task1.c b/apps/task1/task1.c new file mode 100644 index 0000000..2e9f455 --- /dev/null +++ b/apps/task1/task1.c @@ -0,0 +1,36 @@ +/** @file task1.c + @author M.P. Hayes + @date 5 Oct 2010 +*/ + +#include "system.h" +#include "led.h" +#include "task.h" + + +/* Define polling rate in Hz. */ +#define LED_TASK_RATE 2 + + +static void led_flash_task (__unused__ void *data) +{ + static uint8_t state = 0; + + led_set (LED1, state); + state = !state; +} + + +int main (void) +{ + task_t tasks[] = + { + {.func = led_flash_task, .period = TASK_RATE / LED_TASK_RATE, .data = 0}, + }; + + system_init (); + led_init (); + + task_schedule (tasks, 1); + return 0; +} diff --git a/apps/task2/Makefile b/apps/task2/Makefile new file mode 100644 index 0000000..ad075de --- /dev/null +++ b/apps/task2/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for task2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: task2.out + + +# Compile: create object files from C source files. +task2.o: task2.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../drivers/display.h ../../drivers/led.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/task.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +led.o: ../../drivers/led.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/led.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +task.o: ../../utils/task.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/task.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +task2.out: display.o led.o ledmat.o pio.o system.o task.o task2.o timer.o tinygl.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: task2.out + $(OBJCOPY) -O ihex task2.out task2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash task2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/task2/Makefile.test b/apps/task2/Makefile.test new file mode 100644 index 0000000..1a6d99a --- /dev/null +++ b/apps/task2/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for task2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: task2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +led-test.o: ../../drivers/led.c ../../drivers/led.h ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +task-test.o: ../../utils/task.c ../../drivers/test/timer.h ../../utils/task.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +task2-test.o: task2.c ../../utils/task.h ../../drivers/test/system.h ../../drivers/test/timer.h ../../utils/font.h ../../drivers/led.h ../../utils/tinygl.h ../../drivers/display.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +task2: timer-test.o led-test.o display-test.o pio-test.o task-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o task2-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) task2 timer-test.o led-test.o display-test.o pio-test.o task-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o task2-test.o + + diff --git a/apps/task2/task2.c b/apps/task2/task2.c new file mode 100644 index 0000000..6de0409 --- /dev/null +++ b/apps/task2/task2.c @@ -0,0 +1,69 @@ +/** @file task2.c + @author M.P. Hayes + @date 5 Oct 2010 +*/ + +#include "system.h" +#include "led.h" +#include "task.h" +#include "tinygl.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LED_TASK_RATE 2 + +#define DISPLAY_TASK_RATE 400 + +/* Define text update rate (characters per 10 s). */ +#define MESSAGE_RATE 10 + + +static void led_flash_task_init (void) +{ + led_init (); +} + + +static void led_flash_task (__unused__ void *data) +{ + static uint8_t state = 0; + + led_set (LED1, state); + state = !state; +} + + +static void display_task_init (void) +{ + tinygl_init (DISPLAY_TASK_RATE); + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (MESSAGE_RATE); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + + tinygl_text ("HELLO WORLD "); +} + + +static void display_task (__unused__ void *data) +{ + tinygl_update (); +} + + +int main (void) +{ + task_t tasks[] = + { + {.func = display_task, .period = TASK_RATE / DISPLAY_TASK_RATE, .data = 0}, + {.func = led_flash_task, .period = TASK_RATE / LED_TASK_RATE, .data = 0}, + }; + + system_init (); + + led_flash_task_init (); + display_task_init (); + + task_schedule (tasks, 2); + return 0; +} diff --git a/apps/tdmdemo1/Makefile b/apps/tdmdemo1/Makefile new file mode 100644 index 0000000..da52441 --- /dev/null +++ b/apps/tdmdemo1/Makefile @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for tdmdemo1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: tdmdemo1.out + + +# Compile: create object files from C source files. +tdmdemo1.o: tdmdemo1.c ../../drivers/avr/system.h ../../drivers/ledmat.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +tdmdemo1.out: ledmat.o pacer.o pio.o system.o tdmdemo1.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: tdmdemo1.out + $(OBJCOPY) -O ihex tdmdemo1.out tdmdemo1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash tdmdemo1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/tdmdemo1/Makefile.test b/apps/tdmdemo1/Makefile.test new file mode 100644 index 0000000..e91d41e --- /dev/null +++ b/apps/tdmdemo1/Makefile.test @@ -0,0 +1,51 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for tdmdemo1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: tdmdemo1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +tdmdemo1-test.o: tdmdemo1.c ../../utils/pacer.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +tdmdemo1: timer-test.o pio-test.o pacer-test.o ledmat-test.o system-test.o mgetkey-test.o tdmdemo1-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) tdmdemo1 timer-test.o pio-test.o pacer-test.o ledmat-test.o system-test.o mgetkey-test.o tdmdemo1-test.o + + diff --git a/apps/tdmdemo1/tdmdemo1.c b/apps/tdmdemo1/tdmdemo1.c new file mode 100644 index 0000000..f17094a --- /dev/null +++ b/apps/tdmdemo1/tdmdemo1.c @@ -0,0 +1,80 @@ +/** @file tdmdemo1.c + @author M. P. Hayes, UCECE + @date 10 August 2011 + @brief Time division multiplexing of display demo + + @defgroup tdmdemo1 Time division multiplexing of display demo +*/ + +#include "system.h" +#include "pacer.h" +#include "ledmat.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 1000 + +/* Define display refresh rate in Hz. */ +#define REFRESH_RATE 1 + +#define UPDATE_PERIOD (LOOP_RATE / (LEDMAT_COLS_NUM * REFRESH_RATE)) + + +int main (void) +{ + uint8_t col = 0; + uint8_t tick = 0; + + system_init (); + ledmat_init (); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + tick++; + if (tick >= UPDATE_PERIOD) + { + tick = 0; + + /* Display an 'H' character by time division multiplexing + the columns of the LED matrix. */ + switch (col) + { + case 0: + ledmat_display_column (0x7f, 0); + break; + + case 1: + ledmat_display_column (0x08, 1); + break; + + case 2: + ledmat_display_column (0x08, 2); + break; + + case 3: + ledmat_display_column (0x08, 3); + break; + + case 4: + ledmat_display_column (0x7f, 4); + break; + + default: + break; + } + + col++; + if (col >= LEDMAT_COLS_NUM ) + col = 0; + } + + } + + return 0; +} diff --git a/apps/tdmdemo2/Makefile b/apps/tdmdemo2/Makefile new file mode 100644 index 0000000..1cff4f4 --- /dev/null +++ b/apps/tdmdemo2/Makefile @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for tdmdemo2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: tdmdemo2.out + + +# Compile: create object files from C source files. +tdmdemo2.o: tdmdemo2.c ../../drivers/avr/system.h ../../drivers/ledmat.h ../../drivers/navswitch.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +tdmdemo2.out: ledmat.o navswitch.o pacer.o pio.o system.o tdmdemo2.o timer.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: tdmdemo2.out + $(OBJCOPY) -O ihex tdmdemo2.out tdmdemo2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash tdmdemo2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/tdmdemo2/Makefile.test b/apps/tdmdemo2/Makefile.test new file mode 100644 index 0000000..ae549be --- /dev/null +++ b/apps/tdmdemo2/Makefile.test @@ -0,0 +1,54 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for tdmdemo2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: tdmdemo2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tdmdemo2-test.o: tdmdemo2.c ../../utils/pacer.h ../../drivers/ledmat.h ../../drivers/navswitch.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +tdmdemo2: timer-test.o pio-test.o pacer-test.o ledmat-test.o system-test.o tdmdemo2-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) tdmdemo2 timer-test.o pio-test.o pacer-test.o ledmat-test.o system-test.o tdmdemo2-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/tdmdemo2/tdmdemo2.c b/apps/tdmdemo2/tdmdemo2.c new file mode 100644 index 0000000..774c8d2 --- /dev/null +++ b/apps/tdmdemo2/tdmdemo2.c @@ -0,0 +1,97 @@ +/** @file tdmdemo2.c + @author M. P. Hayes, UCECE + @date 10 August 2011 + @brief Time division multiplexing of display demo + + @defgroup tdmdemo2 Time division multiplexing of display demo +*/ + +#include "system.h" +#include "pacer.h" +#include "navswitch.h" +#include "ledmat.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 1000 + + +int main (void) +{ + uint8_t col = 0; + uint8_t tick = 0; + uint8_t refresh_rate = 1; + uint16_t update_period; + + system_init (); + ledmat_init (); + navswitch_init (); + + pacer_init (LOOP_RATE); + + update_period = LOOP_RATE / (LEDMAT_COLS_NUM * refresh_rate); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + { + refresh_rate++; + update_period = LOOP_RATE / (LEDMAT_COLS_NUM * refresh_rate); + } + + if (navswitch_push_event_p (NAVSWITCH_WEST) && refresh_rate > 0) + { + /* Allow refresh_rate to go to zero so can stop display + refreshing. */ + refresh_rate--; + update_period = LOOP_RATE / (LEDMAT_COLS_NUM * refresh_rate); + } + + tick++; + if (tick >= update_period) + { + tick = 0; + + /* Display an 'H' character by time division multiplexing + the columns of the LED matrix. */ + switch (col) + { + case 0: + ledmat_display_column (0x7f, 0); + break; + + case 1: + ledmat_display_column (0x08, 1); + break; + + case 2: + ledmat_display_column (0x08, 2); + break; + + case 3: + ledmat_display_column (0x08, 3); + break; + + case 4: + ledmat_display_column (0x7f, 4); + break; + + default: + break; + } + + col++; + if (col >= LEDMAT_COLS_NUM ) + col = 0; + } + + } + + return 0; +} diff --git a/apps/updown1/Makefile b/apps/updown1/Makefile new file mode 100644 index 0000000..8677813 --- /dev/null +++ b/apps/updown1/Makefile @@ -0,0 +1,63 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for updown1 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: updown1.out + + +# Compile: create object files from C source files. +updown1.o: updown1.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/display.h ../../fonts/font5x7_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +updown1.out: display.o ledmat.o pacer.o pio.o system.o timer.o tinygl.o updown1.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: updown1.out + $(OBJCOPY) -O ihex updown1.out updown1.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash updown1.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/updown1/Makefile.test b/apps/updown1/Makefile.test new file mode 100644 index 0000000..e92684d --- /dev/null +++ b/apps/updown1/Makefile.test @@ -0,0 +1,57 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for updown1 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: updown1 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +updown1-test.o: updown1.c ../../drivers/test/pio.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/test/avrtest.h ../../fonts/font5x7_1.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +updown1: timer-test.o updown1-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) updown1 timer-test.o updown1-test.o display-test.o pio-test.o pacer-test.o tinygl-test.o ledmat-test.o system-test.o mgetkey-test.o + + diff --git a/apps/updown1/updown1.c b/apps/updown1/updown1.c new file mode 100644 index 0000000..4ba362d --- /dev/null +++ b/apps/updown1/updown1.c @@ -0,0 +1,68 @@ +/** @file updown1.c + @author M.P. Hayes + @date 28 Aug 2008 + + @defgroup updown1 Simple counting program using button. +*/ + +#include "system.h" +#include "pacer.h" +#include "pio.h" +#include "tinygl.h" +#include "../fonts/font5x7_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + + +static void show_count (uint8_t count) +{ + char buffer[2]; + + /* FIXME! */ + buffer[0] = count + '0'; + buffer[1] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + bool state; + bool prev_state; + uint8_t count = 0; + + system_init (); + tinygl_init (LOOP_RATE); + + tinygl_font_set (&font5x7_1); + + pio_config_set (BUTTON1_PIO, PIO_INPUT); + + state = !pio_input_get (BUTTON1_PIO); + prev_state = state; + + show_count (count); + + pacer_init (LOOP_RATE); + + /* Paced loop. */ + while (1) + { + /* Wait for next tick. */ + pacer_wait (); + + state = pio_input_get (BUTTON1_PIO); + if (state && !prev_state) + { + count++; + show_count (count); + } + prev_state = state; + + tinygl_update (); + } + + return 0; +} diff --git a/apps/updown2/Makefile b/apps/updown2/Makefile new file mode 100644 index 0000000..92601e2 --- /dev/null +++ b/apps/updown2/Makefile @@ -0,0 +1,66 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for updown2 + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: updown2.out + + +# Compile: create object files from C source files. +updown2.o: updown2.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/navswitch.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/pacer.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio.o: ../../drivers/avr/pio.c ../../drivers/avr/pio.h ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system.o: ../../drivers/avr/system.c ../../drivers/avr/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +timer.o: ../../drivers/avr/timer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h + $(CC) -c $(CFLAGS) $< -o $@ + +display.o: ../../drivers/display.c ../../drivers/avr/system.h ../../drivers/display.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat.o: ../../drivers/ledmat.c ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/ledmat.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch.o: ../../drivers/navswitch.c ../../drivers/avr/delay.h ../../drivers/avr/pio.h ../../drivers/avr/system.h ../../drivers/navswitch.h + $(CC) -c $(CFLAGS) $< -o $@ + +pacer.o: ../../utils/pacer.c ../../drivers/avr/system.h ../../drivers/avr/timer.h ../../utils/pacer.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl.o: ../../utils/tinygl.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h + $(CC) -c $(CFLAGS) $< -o $@ + + + +# Link: create ELF output file from object files. +updown2.out: display.o ledmat.o navswitch.o pacer.o pio.o system.o timer.o tinygl.o updown2.o + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: updown2.out + $(OBJCOPY) -O ihex updown2.out updown2.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash updown2.hex; dfu-programmer atmega32u2 start + + diff --git a/apps/updown2/Makefile.test b/apps/updown2/Makefile.test new file mode 100644 index 0000000..380f272 --- /dev/null +++ b/apps/updown2/Makefile.test @@ -0,0 +1,60 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for updown2 + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test + +DEL = rm + + +# Default target. +all: updown2 + + +# Compile: create object files from C source files. +timer-test.o: ../../drivers/test/timer.c ../../drivers/test/timer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +display-test.o: ../../drivers/display.c ../../drivers/ledmat.h ../../drivers/display.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +updown2-test.o: updown2.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../utils/font.h ../../drivers/test/system.h ../../fonts/font3x5_1.h ../../utils/tinygl.h ../../utils/pacer.h ../../drivers/display.h ../../drivers/test/avrtest.h + $(CC) -c $(CFLAGS) $< -o $@ + +pio-test.o: ../../drivers/test/pio.c + $(CC) -c $(CFLAGS) $< -o $@ + +pacer-test.o: ../../utils/pacer.c ../../drivers/test/timer.h ../../utils/pacer.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +ledmat-test.o: ../../drivers/ledmat.c ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/ledmat.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +system-test.o: ../../drivers/test/system.c ../../drivers/test/pio.h ../../drivers/test/avrtest.h ../../drivers/test/mgetkey.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + +mgetkey-test.o: ../../drivers/test/mgetkey.c ../../drivers/test/mgetkey.h + $(CC) -c $(CFLAGS) $< -o $@ + +navswitch-test.o: ../../drivers/navswitch.c ../../drivers/test/pio.h ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.h ../../drivers/test/system.h + $(CC) -c $(CFLAGS) $< -o $@ + + + + +# Link: create executable file from object files. +updown2: timer-test.o display-test.o updown2-test.o pio-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o navswitch-test.o + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) updown2 timer-test.o display-test.o updown2-test.o pio-test.o pacer-test.o ledmat-test.o tinygl-test.o system-test.o mgetkey-test.o navswitch-test.o + + diff --git a/apps/updown2/updown2.c b/apps/updown2/updown2.c new file mode 100644 index 0000000..f72c070 --- /dev/null +++ b/apps/updown2/updown2.c @@ -0,0 +1,80 @@ +/** @file updown2.c + @author M.P. Hayes + @date 28 Aug 2008 + + @defgroup updown2 Simple counting program using navswitch +*/ + +#include "system.h" +#include "navswitch.h" +#include "tinygl.h" +#include "pacer.h" +#include "pio.h" +#include "../fonts/font3x5_1.h" + + +/* Define polling rate in Hz. */ +#define LOOP_RATE 300 + + +static void show_count (uint8_t count) +{ + char buffer[2]; + + /* FIXME! */ + buffer[0] = count + '0'; + buffer[1] = 0; + tinygl_text (buffer); +} + + +int main (void) +{ + uint8_t count = 5; + uint16_t tick = 0; + + system_init (); + pio_config_set (LED1_PIO, PIO_OUTPUT_HIGH); + + tinygl_init (LOOP_RATE); + tinygl_font_set (&font3x5_1); + + navswitch_init (); + pacer_init (LOOP_RATE); + + show_count (count); + + + /* Paced loop. */ + while (1) + { + + /* Wait for next tick. */ + pacer_wait (); + + tick++; + if (tick > LOOP_RATE / 2) + { + tick = 0; + pio_output_toggle (LED1_PIO); + } + + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + { + count--; + show_count (count); + } + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + { + count++; + show_count (count); + } + + tinygl_update (); + } + + return 0; +} diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..93be787 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,15 @@ +all: docs + + +docs: + doxygen doxygen.config + + +zip: ucfk3.zip + + +ucfk3.zip: html/* + zip -r $@ html/ + +clean: + rm -r html diff --git a/doc/README b/doc/README new file mode 100644 index 0000000..850718e --- /dev/null +++ b/doc/README @@ -0,0 +1,4 @@ +To create the online documentation run make then load the file +html/index.html into a web browser, for example, +$ make +$ firefox html/index.html diff --git a/doc/UCFK4.pdf b/doc/UCFK4.pdf new file mode 100644 index 0000000..71f5362 Binary files /dev/null and b/doc/UCFK4.pdf differ diff --git a/doc/doxygen.config b/doc/doxygen.config new file mode 100644 index 0000000..67729db --- /dev/null +++ b/doc/doxygen.config @@ -0,0 +1,1241 @@ +# Doxyfile 1.4.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "UCFK4" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +# EXTRACT_ALL = NO +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES +# SHOW_INCLUDE_FILES = NO ? + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = NO + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . ../utils ../drivers ../drivers/avr ../apps/bounce1 ../apps/bounce2 ../apps/bounce3 ../apps/bounce4 ../apps/bounce5 ../apps/chooser ../apps/demo1 ../apps/demo2 ../apps/fonttest1 ../apps/game ../apps/hello1 ../apps/hello2 ../apps/hello3../apps/hello4 ../apps/ir_blat1 ../apps/ir_grab1 ../apps/ir_grab2 ../apps/ir_grab3 ../apps/ir_serial_test1 ../apps/ir_serial_test2 ../apps/ir_serial_test3 ../apps/ir_uart_test1 ../apps/ir_uart_test2 ../apps/led0 ../apps/led1 ../apps/led2 ../apps/led3 ../apps/led4 ../apps/led5 ../apps/led6 ../apps/pio1 ../apps/pio2 ../apps/pio3 ../apps/scribble1 ../apps/snake1 ../apps/space10 ../apps/space11 ../apps/space9 ../apps/spacey_remote1 ../apps/steer1 ../apps/task1 ../apps/task2 ../apps/task3 ../apps/tdmdemo1 ../apps/tdmdemo2 ../apps/updown1 ../apps/updown2 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.c *.h *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = ../drivers/avr/pio-simple.c ../drivers/avr/pio-simple.h ../drivers/avr/pio-opt.h ../drivers/avr/pio-alt.h ../drivers/avr/pio-opt.c + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES +#REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +#REFERENCES_RELATION = YES +REFERENCES_RELATION = NO + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/doc/main_page.dox b/doc/main_page.dox new file mode 100644 index 0000000..f3f6098 --- /dev/null +++ b/doc/main_page.dox @@ -0,0 +1,259 @@ +/** \mainpage UCFK4 + +@section intro Introduction + +@section structure Directory structure + +- @c apps --- contains a sub-directory for each example application +- @c drivers --- generic device driver modules +- @c drivers/avr --- AVR dependent device driver modules +- @c drivers/test --- test scaffold modules +- @c utils --- utility modules +- @c doc --- documentation +- @c etc --- miscellaneous scripts +- @c fonts --- fonts and font creation program + + +@section examples Example applications + + +There are a number of example applications of increasing complexity in the @c apps directory: +- @ref bounce1 "bounce1" --- a simple application that +drives the LED matrix display directly. +- @ref bounce2 "bounce2" --- this does not worry about refreshing the display; instead this is +performed by the @ref display "display" and @ref ledmat "ledmat" +modules. +- @ref hello1 "hello1" --- displays a message using the @ref ledmat "ledmat" module. +- @ref updown1 "updown1" --- increments or decrements a count depending on button pushes. +- @ref bounce3 "bounce3" --- uses a higher abstraction for driving the display; a tiny graphics library (@ref tinygl "tinygl") built on top of the @ref display "display" and @ref ledmat "ledmat" modules. +- @ref hello2 "hello2" --- displays a message using the @ref tinygl "tinygl" module. +- @ref updown2 "updown2" --- increments or decrements a count depending on button pushes provided by the @ref button "button" module. +- @ref hello4 "hello4" --- displays a message using the @ref tinygl "tinygl" module. It also switches from text step to text scroll modes using the @ref button "button" module to detect button presses. +- @ref bounce4 "bounce4" --- controls two balls using the +@ref boing "boing" module to update the state of a bouncing ball. +- @ref bounce5 "bounce5" --- controls three balls, again using +the @ref boing "boing" module. It also flashes the balls at different +rates and detects collisions. +- @ref fonttest1 "fonttest1" --- displays each character in two fonts. +- @ref ir_serial_test1 "ir_serial_test1" --- tests the @ref IR_serial "ir_serial" module. +- @ref ir_serial_test2 "ir_serial_test2" --- tests the @ref IR_serial "ir_serial" module. +- @ref ir_serial_test3 "ir_serial_test3" --- tests the @ref IR_serial "ir_serial" module. +- @ref space9 "space9" --- a space invaders style game. +- @ref space10 "space10" --- a space invaders style game remotely controlled using the @ref IR_serial "ir_serial" module from the @ref spacey_remote1 "spacey_remote1" application. +- @ref space11 "space11" --- similar to @ref space9 but using @ref task "task" module instead of @ref pacer "pacer" module. + + +Each application sub-directory contains a makefile called @c Makefile. +This contains rules for the @c make program to compile the application. +For example, an application can be compiled using +@verbatim +$ make +@endverbatim + +Similarly, the application can be programmed into the flash memory of +the ATmega32u2 using +@verbatim +$ make program +@endverbatim + +The executable and object files can be deleted using +@verbatim +$ make clean +@endverbatim + +Here's an example of building and programming the application @c hello1.hex: +@verbatim +$ cd apps/hello1 +$ ls +hello1.c Makefile Makefile.test simplefont.h +$ makeavr-gcc -c -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr hello1.c -o hello1.o +avr-gcc -c -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr ../../drivers/avr/target.c -o target.o +avr-gcc -c -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr ../../drivers/pacer.c -o pacer.o +avr-gcc -c -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr ../../drivers/avr/timer.c -o timer.o +avr-gcc -c -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr ../../drivers/led.c -o led.o +avr-gcc -c -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr ../../drivers/avr/pio.c -o pio.o +avr-gcc -c -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr ../../drivers/ledmat.c -o ledmat.o +avr-gcc -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../fonts -I../../drivers -I../../drivers/avr hello1.o target.o pacer.o timer.o led.o pio.o ledmat.o -o hello1.out -lm +avr-size hello1.out + text data bss dec hex filename + 1038 374 5 1417 589 hello1.out +avr-objcopy -O ihex hello1.out hello1.hex +$ ls +hello1.c hello1.o ledmat.o Makefile.test pio.o +hello1.hex hello1.out Makefile pacer.o simplefont.h +$ make program +make program +dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash hello1.hex; dfu-programmer atmega32u2 start +Validating... +1236 bytes used (4.31%) +$ make clean +rm *.o *.out *.hex +$ ls +hello1.c Makefile Makefile.test simplefont.h +@endverbatim + +@section utils Utility modules + +Useful utility modules are grouped in the directory +called @c utils. These include: +- @ref boing "boing" --- @ref boing +- @ref pacer "pacer" --- @ref pacer +- @ref task "task" --- @ref task +- @ref tinygl "tinygl" --- @ref tinygl +- @ref uint8toa "uint8toa" --- @ref uint8toa (this uses much less memory than @c sprintf) + + +@section drivers Device drivers + +Device drivers are grouped in the directory called @c drivers. These include: +- @ref button "button" --- @ref button +- @ref display "display" --- @ref display +- @ref LED "LED" --- @ref LED +- @ref ledmat "ledmat" --- @ref ledmat +- @ref IR "IR" --- @ref IR +- @ref IR_serial "IR serial" --- @ref IR_serial (this has been superseded by @ref IR_uart "IR uart") +- @ref IR_uart "IR uart" --- @ref IR_uart +- @ref navswitch "navswitch" --- @ref navswitch + + +@section HAL Hardware abstraction layer + + +Hardware dependent modules are grouped in the directory @c drivers/avr. These provide a hardware abstraction layer (HAL) and include: +- @ref delay "delay" --- @ref delay (useful for short relative delays) +- @ref eeprom "eeprom" --- @ref eeprom (useful for storing high-scores etc. in non-volatile EEPROM memory) +- @ref timer "timer" --- @ref timer (useful for absolute delays) +- @ref pio "pio" --- @ref pio (provides an abstraction of the I/O ports. Note @c pio.h uses advanced techniques to reduce memory usage; I suggest looking at @c pio-simple.h and @c pio-simple.c for a much simpler implementation.) + + +@section documentation Documentation + +This documentation has been created by a program called doxygen. This +is derived from comment information specified in the program files. +Special comment block markers are required by doxygen. These start +with \** . Inside these comment blocks, doxygen looks for +special names such as \@file or \\file. + +Running the @c make program in the @c doc directory will run doxygen. +It will generate html files that can be viewed by a web browser in the +@c doc/html directory. The main page is called @c index.html. Note, +you may need to edit the INPUT field in @c doc/doxygen.config to +specify new directories. + + +@section Testing + +I have created a simple test-scaffold so that programs can be run +natively on a PC. The test-scaffold files in drivers/test replaces the +hardware specific modules in avr_test, such as @ref timer "timer". +Each example application has a makefile called Makefile.test. This is +selected using the -f option to make. For example, +@verbatim +$ make -f Makefile.test +@endverbatim +will produce a native application that will run in a terminal window +of a PC. When the program runs, the output of the display is shown in +the terminal window. The arrow keys correspond to the four directions +of the navswitch and the spacebar corresponds to the push of the +navswitch. The period key corresponds to the pushbutton. + +Here's an example of building the test application @c hello1. + +@verbatim +$ cd apps/hello1 +$ make -f Makefile.test +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test hello1.c -o hello1-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/test/target.c -o target-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/test/avrtest.c -o avrtest-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/test/pio.c -o pio-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/test/mgetkey.c -o mgetkey-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/pacer.c -o pacer-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/test/timer.c -o timer-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/led.c -o led-test.o +gcc -c -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test ../../drivers/ledmat.c -o ledmat-test.o +gcc -Wall -Wstrict-prototypes -Wextra -g -I. -I../../utils -I../../drivers -I../../drivers/test hello1-test.o target-test.o avrtest-test.o pio-test.o mgetkey-test.o pacer-test.o timer-test.o led-test.o ledmat-test.o -o hello1 -lrt +$ ls +avrtest-test.d hello1-test.d Makefile pio-test.d ucfktest-test.o +avrtest-test.o hello1-test.o Makefile.test pio-test.o +hello1 ledmat-test.d pacer-test.d simplefont.h +hello1.c ledmat-test.o pacer-test.o ucfktest-test.d +@endverbatim + +The test application is called @c hello1. It can be run using: +@verbatim +$ ./hello1 +..... +..... +..... +..... +..... +..... +..... + +@.... +@.... +@.... +@.... +@.... +@.... +@.... + +@.... +@.... +@.... +@@... +@.... +@.... +@.... + +@endverbatim + + +@section Fonts + +The @c font directory contains a program (@c fontgen.c) that will +convert custom fonts specified in a text file into a header file with +a lookup table that can be loaded into an application. For further +details, see @c font/README. + +For example, here's a custom face font mapped to the ASCII characters +'A', 'B', and 'C'. + +
+width=5
+height=7
+A
+.#.#.
+.#.#.
+.#.#.
+.....
+.....
+#...#
+.###.
+B
+.....
+##.##
+##.##
+.....
+..#..
+#...#
+.###.
+C
+.....
+##.##
+##.##
+.....
+..#..
+.###.
+#...#
+
+ + +@section bugs Bugs + +If you think you've found a bug, or have a suggestion for an +improvement, either in this documentation or in the code itself, +please email michael.hayes@canterbury.ac.nz. + +*/ + diff --git a/drivers/avr/README b/drivers/avr/README new file mode 100644 index 0000000..5e81646 --- /dev/null +++ b/drivers/avr/README @@ -0,0 +1,10 @@ +This is a collection of modules to provide a hardware abstraction +layer for the AVR architecture. + +delay.h --- provides timing delay routines. +eeprom.h --- provides routines for reading/writing EEPROM memory for non-volatile storage. +pacer.h --- provides routines for constructing paced loops using timer 1. +pio.h --- provides routines for accessing the I/O ports. Note pio.h uses + advanced techniques; I suggest looking at pio-simple.h and pio-simple.c for a much simpler implementation. +system.h --- system dependent definitions, such as CPU speed and pin allocations. +config.h --- common configuration definitions. diff --git a/drivers/avr/adc.c b/drivers/avr/adc.c new file mode 100644 index 0000000..23bdb95 --- /dev/null +++ b/drivers/avr/adc.c @@ -0,0 +1,90 @@ +/** @file adc.c + @author Michael Hayes + @date 3 Feb 2005 + @brief Routines to use AVR onboard ADC in polling mode. +*/ + +#include "system.h" +#include "adc.h" +#include "bits.h" + +/* ADC Clock Prescaler : 2, 2, 4, 8, 16, 32, 64, 128 = + 2^ADCCLKPRE. Prescale ADC clock by 64 (13 cycles * (64 + prescaler) / 12MHz = 70 us conversion time). */ +#define ADCCLKPRE 6 + + +void adc_reference_select (adc_ref_mode_t mode) +{ + BITS_INSERT (ADMUX, mode, 6, 7); +} + + +/* Initalise the ADC. */ +void adc_init (uint8_t channels) +{ + adc_reference_select (ADC_REF_AVCC); + + /* Right adjust result. */ + ADMUX &= ~BIT (ADLAR); + + /* Enable ADC, prescale ADC clock by 64. */ + ADCSRA |= BIT (ADEN) | BIT (ADPS2) | BIT (ADPS1); + +#ifdef ADATE + /* Disable ADC auto trigger, disable ADC interrupt. */ + ADCSRA &= ~ (BIT (ADATE) | BIT (ADIE) | BIT (ADPS0)); +#else + ADCSRA &= ~ (BIT (ADIE) | BIT (ADPS0)); +#endif + + /* Disable digital input buffers for selected ADC channels. */ +#ifdef DIDR0 + DIDR0 = channels; +#endif +} + + +/* Starts a conversion in the ADC on the specified channel. */ +bool adc_start (adc_channel_t channel) +{ + if (channel >= ADC_NUM) + return 0; + + BITS_INSERT (ADMUX, channel, 0, 3); + + if (!adc_ready_p ()) + return 0; + + /* Start conversion. */ + ADCSRA |= BIT (ADSC); + return 1; +} + + +/* Returns true if a conversion is not in progress. */ +bool adc_ready_p (void) +{ + return ! (ADCSRA & BIT (ADSC)); +} + + +/** Read the current ADC value. + @return the ADC value. + @note this blocks until the ADC has finished a conversion. */ +adc_sample_t +adc_read (void) +{ + while (!adc_ready_p ()) + continue; + + return ADC; +} + + +/** Disables the ADC. */ +void adc_disable (void) +{ + /* Disable ADC, Disable ADC Interrupt. */ + ADCSRA &= ~ (BIT (ADEN) | BIT (ADIE)); +} diff --git a/drivers/avr/adc.h b/drivers/avr/adc.h new file mode 100644 index 0000000..ae12038 --- /dev/null +++ b/drivers/avr/adc.h @@ -0,0 +1,63 @@ +/** @file adc.h + @author M. P. Hayes, UCECE + @date 3 Feb 2005 + + @brief Routines to use AVR onboard ADC in both a polling mode + and automatically updating mode. +*/ + +#ifndef ADC_H +#define ADC_H + +#include "system.h" + +/** ADC channels. */ +typedef enum {ADC0 = 0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC_NUM} + adc_channel_t; + +/** ADC reference modes. */ +typedef enum {ADC_REF_EXT = 0, ADC_REF_AVCC, ADC_REF_RESERVED, ADC_REF_2V56} + adc_ref_mode_t; + +/** ADC bits per conversion. */ +enum {ADC_BITS = 10}; + +/** ADC sample size. */ +typedef uint16_t adc_sample_t; + + +/** Select ADC reference mode. */ +extern void +adc_reference_select (adc_ref_mode_t mode); + + +/** Initalises the ADC registers for polling operation. */ +extern void +adc_init (uint8_t channels); + + +/** Starts a conversion in the ADC on the specified channel. */ +extern bool +adc_conversion_start (adc_channel_t channel); + + +/** Returns true if a conversion is not in progress. */ +extern bool +adc_ready_p (void); + + +/** Returns 1 if valid sample read. */ +extern int8_t +adc_read (adc_sample_t *value); + + +/** Halts any currently running conversion. */ +extern void +adc_stop (void); + + +/** Disables the ADC from doing anything. Requires reinitalisation. */ +extern void +adc_disable (void); + +#endif diff --git a/drivers/avr/bits.h b/drivers/avr/bits.h new file mode 100644 index 0000000..680c131 --- /dev/null +++ b/drivers/avr/bits.h @@ -0,0 +1,22 @@ +/** @file bits.h + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief Macros for manipulating bit fields. +*/ +#ifndef BITS_H +#define BITS_H + +#define BITS_MASK(first, last) ((1 << ((last) + 1)) - (1 << (first))) + +#define BITS_CLEAR(reg, first, last) ((reg) &= BITS_MASK (first, last)) + +#define BITS_SET(reg, first, last) ((reg) |= BITS_MASK (first, last)) + +#define BITS_EXTRACT(reg, first, last) \ + (((reg) & BITS_MASK (first, last)) >> (first)) + +#define BITS_INSERT(reg, val, first, last) \ + (reg) = ((reg) & ~BITS_MASK (first, last)) \ + | (((val) & BITS_MASK (0, last - first)) << (first)) + +#endif diff --git a/drivers/avr/delay.h b/drivers/avr/delay.h new file mode 100644 index 0000000..ac00736 --- /dev/null +++ b/drivers/avr/delay.h @@ -0,0 +1,93 @@ +/** @file delay.h + @author M. P. Hayes, UCECE + @date 08 June 2002 + @brief Delay routines for timing. + @note All files that use DELAY_US must be compiled with full optimisation. + + @defgroup delay Delay routines + + This module provides routines for short timing delays. These are + implemented as delay loops. DELAY_US must not be called with a variable + argument since the run-time floating point calculation will almost certainly + swamp the delay you require. + + @note The macro F_CPU defines the CPU clock frequency (in Hertz). +*/ +#ifndef DELAY_H +#define DELAY_H + +#include "system.h" +#include + +/* There are two timing loop routines provided in delay.h: + + _delay_loop_1 uses an 8-bit counter and requires 3 cycles per + iteration but has a maximum of 256 iterations. With F_CPU = 8e6 + then the range of delays is 0.375 us to 96.0 us in steps of 0.375 us. + + _delay_loop_2 uses a 16-bit counter, requires 4 cycles per + iteration and has a maximum of 65536 iterations. With F_CPU = 8e6 + then the range of delays is 0.5 us to 32.768 ms in steps of 0.5 us. */ + +#define DELAY1_LOOP_CYCLES 3 +#define DELAY1_LOOPS_MAX 256 +#define DELAY1_US_MAX (DELAY1_LOOPS_MAX * DELAY1_LOOP_CYCLES * 1e6 / (F_CPU)) + +#define DELAY2_LOOP_CYCLES 4 +#define DELAY2_LOOPS_MAX 65536 +#define DELAY2_US_MAX (DELAY2_LOOPS_MAX * DELAY2_LOOP_CYCLES * 1e6 / (F_CPU)) + + +/** Delay a selected number of microseconds + @param us number of microseconds to delay. This must be a constant. + @note This should be only used with a constant argument otherwise + it will expand to a lot of code and require slow floating point operations to compute + the number of cycles to delay. */ +#define DELAY_US(us) \ +do \ +{ \ + if ((us) > DELAY1_US_MAX) \ + { \ + double __tmp2 = ((double)F_CPU * (us)) / (DELAY2_LOOP_CYCLES * 1e6); \ + uint16_t __ticks2; \ + \ + if ((us) > DELAY2_US_MAX) \ + __ticks2 = 0; \ + else \ + __ticks2 = (uint16_t)__tmp2; \ + _delay_loop_2 (__ticks2); \ + } \ + else \ + { \ + double __tmp1 = ((double)F_CPU * (us)) / (DELAY1_LOOP_CYCLES * 1e6); \ + uint8_t __ticks1; \ + \ + if (__tmp1 < 1.0) \ + __ticks1 = 1; \ + else \ + __ticks1 = (uint8_t)__tmp1; \ + _delay_loop_1 (__ticks1); \ + } \ +} \ +while (0) + + +/** Delay a selected number of milliseconds + @param ms number of milliseconds to delay. This can be a variable. */ +static __inline__ void +delay_ms (uint8_t ms) +{ + /* FIXME: "i" should only need to be a uint8_t + Some bug has occured using a newer version of the avr-gcc that + causes this routine to only delay 1ms if both "ms" and "i" + are uint8_t. */ + uint16_t i; + + for (i = 0; i < ms; i++) + { + DELAY_US (1000); + } +} + + +#endif /* DELAY_H */ diff --git a/drivers/avr/eeprom.c b/drivers/avr/eeprom.c new file mode 100644 index 0000000..42aeda7 --- /dev/null +++ b/drivers/avr/eeprom.c @@ -0,0 +1,71 @@ +/** @file eeprom.c + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief +*/ +#include "system.h" +#include +#include "eeprom.h" + +static void +eeprom_write_byte (eeprom_addr_t addr, uint8_t data) +{ + /* Wait for completion of previous write. */ + while (EECR & _BV (EEPE)) + continue; + + /* Set up address and data registers */ + EEAR = addr; + EEDR = data; + + EECR |= _BV (EEMPE); + + /* Start eeprom write. */ + EECR |= _BV (EEPE); +} + + +static uint8_t eeprom_read_byte (eeprom_addr_t addr) +{ + /* Wait for completion of previous write. */ + while (EECR & _BV (EEPE)) + continue; + + /* Set up address register */ + EEAR = addr; + + /* Start eeprom read. */ + EECR |= _BV (EERE); + + /* Return data from data register */ + return EEDR; +} + + +/* Read SIZE bytes from ADDR into BUFFER. */ +eeprom_size_t +eeprom_read (eeprom_addr_t addr, void *buffer, eeprom_size_t size) +{ + eeprom_size_t i; + uint8_t *data = buffer; + + for (i = 0; i < size; i++) + data[i] = eeprom_read_byte (addr++); + + return i; + +} + + +/* Write SIZE bytes to ADDR from BUFFER. */ +eeprom_size_t +eeprom_write (eeprom_addr_t addr, const void *buffer, eeprom_size_t size) +{ + eeprom_size_t i; + const uint8_t *data = buffer; + + for (i = 0; i < size; i++) + eeprom_write_byte (addr++, data[i]); + + return i; +} diff --git a/drivers/avr/eeprom.h b/drivers/avr/eeprom.h new file mode 100644 index 0000000..20bbcff --- /dev/null +++ b/drivers/avr/eeprom.h @@ -0,0 +1,30 @@ +/** @file eeprom.h + @author Michael Hayes + @date 13 Nov 2006 + @brief Routines to read/write internal EEPROM. + + @defgroup eeprom EEPROM driver + + This module implements a driver to read/write the EEPROM of an + ATmega microcontroller. The EEPROM is useful for storing + persistent data when the power is removed. + */ + +#ifndef EEPROM_H +#define EEPROM_H + +#include "system.h" + +typedef uint16_t eeprom_addr_t; +typedef uint16_t eeprom_size_t; + +/* Read SIZE bytes from ADDR into BUFFER. */ +extern eeprom_size_t +eeprom_read (eeprom_addr_t addr, void *buffer, eeprom_size_t size); + + +/* Write SIZE bytes to ADDR from BUFFER. */ +extern eeprom_size_t +eeprom_write (eeprom_addr_t addr, const void *buffer, eeprom_size_t size); + +#endif diff --git a/drivers/avr/ir_uart.c b/drivers/avr/ir_uart.c new file mode 100644 index 0000000..34ef792 --- /dev/null +++ b/drivers/avr/ir_uart.c @@ -0,0 +1,85 @@ +/** @file ir_uart.c + @author Michael Hayes + @date 10 December 2004 +*/ +#include "system.h" +#include "ir_uart.h" +#include "usart1.h" +#include "timer0.h" +#include "pio.h" + + +/* Return non-zero if there is a character ready to be read. */ +bool +ir_uart_read_ready_p (void) +{ + return usart1_read_ready_p (); +} + + +/* Read character from IR_UART. This blocks if nothing + is available to read. */ +int8_t +ir_uart_getc (void) +{ + return usart1_getc (); +} + + +/* Return non-zero if a character can be written without blocking. */ +bool +ir_uart_write_ready_p (void) +{ + return usart1_write_ready_p (); +} + + +/* Return non-zero if transmitter finished. */ +bool +ir_uart_write_finished_p (void) +{ + return usart1_write_finished_p (); +} + + +/* Write character to IR_UART. This returns zero if + the character could not be written. */ +int8_t +ir_uart_putc (char ch) +{ + return usart1_putc (ch); +} + + +/* Write string to IR_UART. */ +void +ir_uart_puts (const char *str) +{ + usart1_puts (str); +} + + +/* Initialise ir_uart and set baud rate. */ +uint8_t +ir_uart_init (void) +{ + usart1_cfg_t usart1_cfg = + { + .baud_divisor = USART1_BAUD_DIVISOR (IR_UART_BAUD_RATE), + .bits = 8 + }; + + + /* Need to configure DDR so pin is an output. + The state is controlled by the timer. */ + pio_config_set (IR_TX_HIGH_PIO, PIO_OUTPUT_HIGH); + timer0_init (); + + timer0_period_set (F_CPU / (IR_MODULATION_FREQ * 2)); + timer0_mode_set (TIMER0_MODE_CTC); + timer0_output_set (TIMER0_OUTPUT_B, TIMER0_OUTPUT_MODE_TOGGLE); + + timer0_start (); + + return usart1_init (&usart1_cfg); +} diff --git a/drivers/avr/ir_uart.h b/drivers/avr/ir_uart.h new file mode 100644 index 0000000..800bbe3 --- /dev/null +++ b/drivers/avr/ir_uart.h @@ -0,0 +1,95 @@ +/** @file ir_uart.h + @author Michael Hayes + @date 10 December 2004 + + @defgroup IR_uart Infrared uart driver + + Here's a simple application that transmits the ASCII code '?' repeatedly. + + @code + #include "ir_uart.h" + + void main (void) + { + system_init (); + ir_uart_init (); + + while (1) + { + ir_uart_putc ('?'); + } + } + @endcode + + Here's another simple application that receives data bytes. + + @code + #include "ir_uart.h" + + void main (void) + { + system_init (); + ir_uart_init (); + + while (1) + { + if (ir_uart_read_ready_p ()) + { + char ch; + + ch = ir_uart_getc (); + + // Process the received byte. + } + } + } + @endcode +*/ + +#ifndef IR_UART_H +#define IR_UART_H + +#include "system.h" + +#ifndef IR_UART_BAUD_RATE +#define IR_UART_BAUD_RATE 2400 +#endif + + +/* Return non-zero if there is a character ready to be read. */ +bool +ir_uart_read_ready_p (void); + + +/* Read character from IR_UART. This blocks if nothing + is available to read. */ +int8_t +ir_uart_getc (void); + + +/* Return non-zero if a character can be written without blocking. */ +bool +ir_uart_write_ready_p (void); + + +/* Return non-zero if transmitter finished. */ +bool +ir_uart_write_finished_p (void); + + +/* Write character to IR_UART. This returns zero if + the character could not be written. */ +int8_t +ir_uart_putc (char ch); + + +/* Write string to IR_UART. */ +void +ir_uart_puts (const char *str); + + +/* Initialise ir_uart and set baud rate. */ +uint8_t +ir_uart_init (void); + +#endif diff --git a/drivers/avr/pio-simple.c b/drivers/avr/pio-simple.c new file mode 100644 index 0000000..5ae6716 --- /dev/null +++ b/drivers/avr/pio-simple.c @@ -0,0 +1,306 @@ +/** @file pio-simple.c + @author M. P. Hayes, UCECE + @date 13 Aug 2009 + @brief PIO hardware abstraction for AVR microcontroller. + @note This implementation is written for clarity not efficiency. +*/ + +#include "pio-simple.h" + + +/** Configure pio + @param pio */ +bool pio_config_set (pio_t pio, pio_config_t config) +{ + uint8_t bitmask; + + bitmask = BIT (pio.bit); + + switch (pio.port) + { + case PORT_B: + switch (config) + { + case PIO_INPUT: + DDRB &= ~bitmask; + PORTB &= ~bitmask; + break; + + case PIO_PULLUP: + DDRB &= ~bitmask; + PORTB |= bitmask; + break; + + case PIO_OUTPUT_LOW: + PORTB &= ~bitmask; + DDRB |= bitmask; + break; + + case PIO_OUTPUT_HIGH: + PORTB |= bitmask; + DDRB |= bitmask; + break; + + default: + return 0; + } + break; + + case PORT_C: + switch (config) + { + case PIO_INPUT: + DDRC &= ~bitmask; + PORTC &= ~bitmask; + break; + + case PIO_PULLUP: + DDRC &= ~bitmask; + PORTC |= bitmask; + break; + + case PIO_OUTPUT_LOW: + PORTC &= ~bitmask; + DDRC |= bitmask; + break; + + case PIO_OUTPUT_HIGH: + PORTC |= bitmask; + DDRC |= bitmask; + break; + + default: + return 0; + } + break; + + case PORT_D: + switch (config) + { + case PIO_INPUT: + DDRD &= ~bitmask; + PORTD &= ~bitmask; + break; + + case PIO_PULLUP: + DDRD &= ~bitmask; + PORTD |= bitmask; + break; + + case PIO_OUTPUT_LOW: + PORTD &= ~bitmask; + DDRD |= bitmask; + break; + + case PIO_OUTPUT_HIGH: + PORTD |= bitmask; + DDRD |= bitmask; + break; + + default: + return 0; + } + break; + + default: + return 0; + } + return 1; +} + + +/** Set pio high. + @param pio */ +void pio_output_high (pio_t pio) +{ + uint8_t bitmask; + + bitmask = BIT (pio.bit); + + switch (pio.port) + { + case PORT_B: + PORTB |= bitmask; + break; + + case PORT_C: + PORTC |= bitmask; + break; + + case PORT_D: + PORTD |= bitmask; + break; + + default: + break; + } +} + + +/** Set pio low. + @param pio */ +void pio_output_low (pio_t pio) +{ + uint8_t bitmask; + + bitmask = BIT (pio.bit); + + switch (pio.port) + { + case PORT_B: + PORTB &= ~bitmask; + break; + + case PORT_C: + PORTC &= ~bitmask; + break; + + case PORT_D: + PORTD &= ~bitmask; + break; + + default: + break; + } +} + + +/** Toggle pio. + @param pio */ +void pio_output_toggle (pio_t pio) +{ + uint8_t bitmask; + + bitmask = BIT (pio.bit); + + switch (pio.port) + { + case PORT_B: + PORTB ^= bitmask; + break; + + case PORT_C: + PORTC ^= bitmask; + break; + + case PORT_D: + PORTD ^= bitmask; + break; + + default: + break; + } +} + + +/** Read input state from pio. + @param pio + @return input state of pio */ +bool pio_input_get (pio_t pio) +{ + uint8_t bitmask; + + bitmask = BIT (pio.bit); + + switch (pio.port) + { + case PORT_B: + return (PINB & bitmask) != 0; + + case PORT_C: + return (PINC & bitmask) != 0; + + case PORT_D: + return (PIND & bitmask) != 0; + + default: + return 0; + } +} + + +/** Set pio to desired state + @param pio + @param state value to write pio */ +void pio_output_set (pio_t pio, bool state) +{ + if (state) + pio_output_high (pio); + else + pio_output_low (pio); +} + + +/** Return pio configuration + @param pio + @return config */ +pio_config_t pio_config_get (pio_t pio) +{ + bool ddr; + bool port; + uint8_t bitmask; + + bitmask = BIT (pio.bit); + + switch (pio.port) + { + case PORT_B: + ddr = (DDRB & bitmask) != 0; + port = (DDRB & bitmask) != 0; + break; + + case PORT_C: + ddr = (DDRC & bitmask) != 0; + port = (DDRC & bitmask) != 0; + break; + + case PORT_D: + ddr = (DDRD & bitmask) != 0; + port = (DDRD & bitmask) != 0; + break; + + default: + return 0; + } + + if (ddr) + { + if (port) + return PIO_OUTPUT_HIGH; + else + return PIO_OUTPUT_LOW; + } + + if (port) + return PIO_PULLUP; + + return PIO_INPUT; +} + + +/** Get output state of pio. + @param pio + @return output state of pio */ +bool pio_output_get (pio_t pio) +{ + uint8_t bitmask; + + bitmask = BIT (pio.bit); + + switch (pio.port) + { + case PORT_B: + return (PORTB & bitmask) != 0; + + case PORT_C: + return (PORTC & bitmask) != 0; + + case PORT_D: + return (PORTD & bitmask) != 0; + + default: + return 0; + } +} + + diff --git a/drivers/avr/pio-simple.h b/drivers/avr/pio-simple.h new file mode 100644 index 0000000..f5c0c84 --- /dev/null +++ b/drivers/avr/pio-simple.h @@ -0,0 +1,77 @@ +/** @file pio-simple.h + @author M. P. Hayes, UCECE + @date 11 Jan 2006 + @brief PIO hardware abstraction. +*/ +#ifndef PIO_H +#define PIO_H + +#include "system.h" + +typedef enum pio_port_enum +{ + PORT_A, PORT_B, PORT_C, PORT_D, PORT_E +} pio_port_t; + +typedef uint8_t pio_bit_t; + +typedef struct pio_struct +{ + pio_port_t port; + pio_bit_t bit; +} pio_t; + +typedef enum pio_config_enum +{ + PIO_INPUT = 1, PIO_OUTPUT_LOW, PIO_OUTPUT_HIGH, PIO_PULLUP +} pio_config_t; + + +/* Define a PIO as a structure in terms of a port and a bit. */ +#define PIO_DEFINE(PORT, PORTBIT) (pio_t){PORT, PORTBIT} + + +/** Configure pio. + @param pio */ +bool pio_config_set (pio_t pio, pio_config_t config); + + +/** Configure pio. + @param pio + @return config */ +pio_config_t pio_config_get (pio_t pio); + + +/** Set pio high. + @param pio */ +void pio_output_high (pio_t pio); + + +/** Set pio low. + @param pio */ +void pio_output_low (pio_t pio); + + +/** Toggle pio. + @param pio */ +void pio_output_toggle (pio_t pio); + + +/** Read input state from pio. + @param pio + @return input state of pio */ +bool pio_input_get (pio_t pio); + + +/** Set pio to desired state + @param pio + @param state value to write pio */ +void pio_output_set (pio_t pio, bool state); + + +/** Get output state of pio. + @param pio + @return output state of pio */ +bool pio_output_get (pio_t pio); + +#endif diff --git a/drivers/avr/pio.c b/drivers/avr/pio.c new file mode 100644 index 0000000..cde2a3c --- /dev/null +++ b/drivers/avr/pio.c @@ -0,0 +1,9 @@ +/** @file pio.c + @author M. P. Hayes, UCECE + @date 11 Jan 2006 + @brief PIO hardware abstraction for AVR microcontroller. + @note This implementation is empty; inline functions are used + in pio.h instead for performance. +*/ +#include "system.h" +#include "pio.h" diff --git a/drivers/avr/pio.h b/drivers/avr/pio.h new file mode 100644 index 0000000..131713f --- /dev/null +++ b/drivers/avr/pio.h @@ -0,0 +1,253 @@ +/** @file pio.h + @author M. P. Hayes, UCECE + @date 11 Jan 2006 + @brief PIO hardware abstraction for AVR microcontroller. + @note Macros and inline functions are used to avoid function + call overhead and to allow compile-time constant folding. + + @defgroup pio PIO driver + + This module implements a driver for general purpose I/O ports. + Its purpose is to provide a microcontroller independent + abstraction of a PIO pin. Here's an example: + + @code + #include "pio.h" + + #define LED_PIO PIO_DEFINE (PORT_B, 5) + + void main (void) + { + system_init (); + pio_config_set (LED_PIO, PIO_OUTPUT_LOW); + + pio_output_high (LED_PIO); + + while (1); + } + @endcode + + In this example, when port B5 is configured as an output it is set + low. +*/ +#ifndef PIO_H +#define PIO_H + +#include "system.h" +#ifdef AVR +#include +#endif + + +/** Define port names, note not all the ports are available on some AVRs. */ + +#ifdef PORTA +#define PORT_A &PORTA +#endif + +#ifdef PORTB +#define PORT_B &PORTB +#endif + +#ifdef PORTC +#define PORT_C &PORTC +#endif + +#ifdef PORTD +#define PORT_D &PORTD +#endif + +#ifdef PORTE +#define PORT_E &PORTE +#endif + +#ifdef PORTF +#define PORT_F &PORTF +#endif + +#ifdef PORTG +#define PORT_G &PORTG +#endif + + +typedef volatile uint8_t *pio_port_t; +typedef uint8_t pio_mask_t; + + +typedef struct +{ + pio_port_t port; + pio_mask_t bitmask; +} pio_t; + + +/** Define PIO pin types. The two flavours of PIO_OUTPUT are to + ensure the port is configured without glitching due to the time + taken before calling pio_output_set. */ +typedef enum pio_config_enum +{ + PIO_INPUT = 1, /** Configure as input pin. */ + PIO_PULLUP, /** Configure as input pin with pullup. */ + PIO_OUTPUT_LOW, /** Configure as output, initially low. */ + PIO_OUTPUT_HIGH, /** Configure as output, initially high. */ +} pio_config_t; + + +/** DDR PORT Comment + 0 0 High impedance input + 0 1 Weak pullup input + 1 0 Output low + 1 1 Output high +*/ + + +/** Define a PIO as a compound literal structure in terms of a port and + a bitmask. */ +#define PIO_DEFINE(PORT, PORTBIT) (pio_t){.port = PORT, .bitmask = BIT (PORTBIT)} + + +/** Private macro to lookup bitmask. */ +#define PIO_BITMASK_(pio) (pio.bitmask) + + +/** Private macro to lookup port register. */ +#define PIO_PORT_(pio) (pio.port) + + +/** Private macro to map a pio to its corresponding data direction + register (DDR). NB, the DDR and PORT registers must be separated + by the same number of bytes in all cases. PORTB is used for the + pattern since PORTA is not always defined for some AVRs. */ +#define PIO_DDR_(pio) (*(PIO_PORT_ (pio) + (&DDRB - &PORTB))) + +/** Private macro to map a pio to its input register (PIN). NB, the + PIN and PORT registers must be separated by the same number of + bytes in all cases. PORTB is used for the pattern since PORTA is + not always defined for some AVRs. */ +#define PIO_PIN_(pio) (*(PIO_PORT_ (pio) + (&PINB - &PORTB))) + +/** Private macro to access a pio data register. */ +#define PIO_DATA_(pio) (*PIO_PORT_ (pio)) + + + +/** Configure pio. + @param pio PIO to configure + @param config PIO configuration type + @return non-zero for success. */ +static inline +bool pio_config_set (pio_t pio, pio_config_t config) +{ + switch (config) + { + case PIO_OUTPUT_LOW: + PIO_DATA_ (pio) &= ~PIO_BITMASK_ (pio); + PIO_DDR_ (pio) |= PIO_BITMASK_ (pio); + return 1; + + case PIO_OUTPUT_HIGH: + PIO_DATA_ (pio) |= PIO_BITMASK_ (pio); + PIO_DDR_ (pio) |= PIO_BITMASK_ (pio); + return 1; + + case PIO_INPUT: + PIO_DDR_ (pio) &= ~PIO_BITMASK_ (pio); + PIO_DATA_ (pio) &= ~PIO_BITMASK_ (pio); + return 1; + + case PIO_PULLUP: + PIO_DDR_ (pio) &= ~PIO_BITMASK_ (pio); + PIO_DATA_ (pio) |= PIO_BITMASK_ (pio); + return 1; + + default: + return 0; + } +} + + +/** Return pio configuration + @param pio + @return config */ +static inline +pio_config_t pio_config_get (pio_t pio) +{ + bool ddr; + bool port; + + ddr = PIO_DDR_ (pio) & PIO_BITMASK_ (pio); + port = PIO_DATA_ (pio) & PIO_BITMASK_ (pio); + + if (ddr) + { + if (port) + return PIO_OUTPUT_HIGH; + else + return PIO_OUTPUT_LOW; + } + + if (port) + return PIO_PULLUP; + + return PIO_INPUT; +} + + + +/** Set pio high. + @param pio */ +static inline +void pio_output_high (pio_t pio) +{ + PIO_DATA_ (pio) |= PIO_BITMASK_ (pio); +} + + +/** Set pio low. + @param pio */ +static inline +void pio_output_low (pio_t pio) +{ + PIO_DATA_ (pio) &= ~PIO_BITMASK_ (pio); +} + + +/** Toggle pio. + @param pio */ +static inline +void pio_output_toggle (pio_t pio) +{ + PIO_DATA_ (pio) ^= PIO_BITMASK_ (pio); +} + + +/** Read input state from pio. + @param pio + @return input state of pio */ +static inline +bool pio_input_get (pio_t pio) +{ + return (PIO_PIN_ (pio) & PIO_BITMASK_ (pio)) != 0; +} + + +/** Get output state of pio. + @param pio + @return output state of pio */ +static inline +bool pio_output_get (pio_t pio) +{ + return (PIO_DATA_ (pio) & PIO_BITMASK_ (pio)) != 0; +} + + +/** Set pio to desired state. + @param pio + @param state value to write pio */ +static inline +void pio_output_set (pio_t pio, bool state) +{ + state ? pio_output_high (pio) : pio_output_low (pio); +} + +#endif diff --git a/drivers/avr/prescale.c b/drivers/avr/prescale.c new file mode 100644 index 0000000..f2d2454 --- /dev/null +++ b/drivers/avr/prescale.c @@ -0,0 +1,35 @@ +/** @file prescale.c + @author M. P. Hayes, UCECE + @date 3 Aug 2011 + @brief Prescaler selection for 8-bit timer/counters. +*/ +#include "system.h" +#include "prescale.h" +#include + +uint8_t prescale_select (uint16_t period, const uint8_t *log_prescales, + uint8_t num_prescales, uint8_t *pcounter) +{ + uint8_t i; + uint16_t counter = 0; + + /* If the desired period is T we need to choose the counter value + c and the prescale value s to minimise |T - c x 2^p| with the + constraints that 0 < c < 256 and 2^p is one of the available + prescale values. */ + + /* Search through prescaler options looking for first one + where the counter value is < 256. */ + for (i = 0; i < num_prescales; i++) + { + uint16_t divisor; + + divisor = 1 << log_prescales[i]; + counter = (period + (divisor + 1) / 2) >> log_prescales[i]; + if (counter < 256) + break; + } + + *pcounter = counter; + return i; +} diff --git a/drivers/avr/prescale.h b/drivers/avr/prescale.h new file mode 100644 index 0000000..6423432 --- /dev/null +++ b/drivers/avr/prescale.h @@ -0,0 +1,15 @@ +/** @file prescale.h + @author M. P. Hayes, UCECE + @date 3 Aug 2011 + @brief Prescaler selection for timer/counters. +*/ + +#ifndef PRESCALE_H +#define PRESCALE_H + +#include "system.h" + +uint8_t prescale_select (uint16_t period, const uint8_t *log_prescales, + uint8_t num_prescales, uint8_t *pcounter); + +#endif diff --git a/drivers/avr/system.c b/drivers/avr/system.c new file mode 100644 index 0000000..f7b30af --- /dev/null +++ b/drivers/avr/system.c @@ -0,0 +1,40 @@ +/** @file system.c + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief UCFK system initialisation +*/ +#include "system.h" +#include + + +static void system_clock_init (void) +{ + /* Switch 1 MHz CPU clock to 8 MHz. */ + CLKPR = BIT (CLKPCE); + CLKPR = 0; +} + + +static void system_watchdog_timer_init (void) +{ + wdt_reset (); + + /* Clear WDRF in MCUSR. */ + MCUSR &= ~BIT (WDRF); + /* Write logical one to WDCE and WDE and keep old prescaler + setting to prevent unintentional time-out. */ + WDTCSR |= BIT (WDCE) | BIT (WDE); + + /* Turn off watchdog timer. */ + WDTCSR = 0x00; +} + + +void system_init (void) +{ + system_clock_init (); + system_watchdog_timer_init (); +} + + + diff --git a/drivers/avr/system.h b/drivers/avr/system.h new file mode 100644 index 0000000..7afbebf --- /dev/null +++ b/drivers/avr/system.h @@ -0,0 +1,74 @@ +/** @file system.h + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief System specific definitions +*/ +#ifndef SYSTEM_H +#define SYSTEM_H + +/* Data typedefs. */ +#include + +typedef uint8_t bool; + + +/* Useful macros. */ +#define BIT(X) (1 << (X)) + +#define ARRAY_SIZE(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0])) + +#define __unused__ __attribute__ ((unused)) + + +/* Clock frequency Hz. */ +#define F_CPU 8000000 + + +/* LED matrix columns. */ +#define LEDMAT_COL1_PIO PIO_DEFINE(PORT_C, 6) +#define LEDMAT_COL2_PIO PIO_DEFINE(PORT_B, 7) +#define LEDMAT_COL3_PIO PIO_DEFINE(PORT_C, 4) +#define LEDMAT_COL4_PIO PIO_DEFINE(PORT_C, 7) +#define LEDMAT_COL5_PIO PIO_DEFINE(PORT_C, 5) +#define LEDMAT_COLS_NUM 5 + + +/* LED matrix rows. */ +#define LEDMAT_ROW1_PIO PIO_DEFINE(PORT_B, 6) +#define LEDMAT_ROW2_PIO PIO_DEFINE(PORT_B, 5) +#define LEDMAT_ROW3_PIO PIO_DEFINE(PORT_B, 4) +#define LEDMAT_ROW4_PIO PIO_DEFINE(PORT_B, 3) +#define LEDMAT_ROW5_PIO PIO_DEFINE(PORT_B, 2) +#define LEDMAT_ROW6_PIO PIO_DEFINE(PORT_B, 1) +#define LEDMAT_ROW7_PIO PIO_DEFINE(PORT_B, 0) +#define LEDMAT_ROWS_NUM 7 + + +/* Button. */ +#define BUTTON1 0 +#define BUTTON1_PIO PIO_DEFINE(PORT_D, 7) + + +/* Navswitch. */ +#define NAVSWITCH_PUSH_PIO LEDMAT_COL3_PIO +#define NAVSWITCH_EAST_PIO LEDMAT_COL1_PIO +#define NAVSWITCH_WEST_PIO LEDMAT_COL2_PIO +#define NAVSWITCH_NORTH_PIO LEDMAT_COL4_PIO +#define NAVSWITCH_SOUTH_PIO LEDMAT_COL5_PIO + + +/* LED (active high). */ +#define LED1 0 +#define LED1_PIO PIO_DEFINE(PORT_C, 2) + + +/* Infrared transmitter LED and receiver. */ +#define IR_TX_LOW_PIO PIO_DEFINE(PORT_D, 3) +#define IR_TX_HIGH_PIO PIO_DEFINE(PORT_D, 0) +#define IR_RX_PIO PIO_DEFINE(PORT_D, 2) + +#define IR_MODULATION_FREQ 36e3 + +void system_init (void); + +#endif diff --git a/drivers/avr/target.h b/drivers/avr/target.h new file mode 100644 index 0000000..a3e9df0 --- /dev/null +++ b/drivers/avr/target.h @@ -0,0 +1,73 @@ +/** @file system.h + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief System specific definitions +*/ +#ifndef SYSTEM_H +#define SYSTEM_H + +/* Data typedefs. */ +#include + +typedef uint8_t bool; + + +/* Useful macros. */ +#define BIT(X) (1 << (X)) + +#define ARRAY_SIZE(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0])) + +#define __unused__ __attribute__ ((unused)) + + +/* Clock frequency Hz. */ +#define F_CPU 8000000 + + +/* LED matrix columns. */ +#define LEDMAT_COL1_PIO PIO_DEFINE(PORT_C, 6) +#define LEDMAT_COL2_PIO PIO_DEFINE(PORT_B, 7) +#define LEDMAT_COL3_PIO PIO_DEFINE(PORT_C, 4) +#define LEDMAT_COL4_PIO PIO_DEFINE(PORT_C, 7) +#define LEDMAT_COL5_PIO PIO_DEFINE(PORT_C, 5) +#define LEDMAT_COLS_NUM 5 + + +/* LED matrix rows. */ +#define LEDMAT_ROW1_PIO PIO_DEFINE(PORT_B, 6) +#define LEDMAT_ROW2_PIO PIO_DEFINE(PORT_B, 5) +#define LEDMAT_ROW3_PIO PIO_DEFINE(PORT_B, 4) +#define LEDMAT_ROW4_PIO PIO_DEFINE(PORT_B, 3) +#define LEDMAT_ROW5_PIO PIO_DEFINE(PORT_B, 2) +#define LEDMAT_ROW6_PIO PIO_DEFINE(PORT_B, 1) +#define LEDMAT_ROW7_PIO PIO_DEFINE(PORT_B, 0) +#define LEDMAT_ROWS_NUM 7 + + +/* Button. */ +#define BUTTON1 0 +#define BUTTON1_PIO PIO_DEFINE(PORT_D, 7) + + +/* Navswitch. */ +#define NAVSWITCH_PUSH_PIO LEDMAT_COL3_PIO +#define NAVSWITCH_EAST_PIO LEDMAT_COL1_PIO +#define NAVSWITCH_WEST_PIO LEDMAT_COL2_PIO +#define NAVSWITCH_NORTH_PIO LEDMAT_COL4_PIO +#define NAVSWITCH_SOUTH_PIO LEDMAT_COL5_PIO + + +/* LED (active high). */ +#define LED1 0 +#define LED1_PIO PIO_DEFINE(PORT_C, 2) + + +/* Infrared transmitter LED and receiver. */ +#define IR_TX_LOW_PIO PIO_DEFINE(PORT_D, 3) +#define IR_TX_HIGH_PIO PIO_DEFINE(PORT_D, 0) +#define IR_RX_PIO PIO_DEFINE(PORT_D, 2) + +#define IR_MODULATION_FREQ 36e3 + + +#endif diff --git a/drivers/avr/timer.c b/drivers/avr/timer.c new file mode 100644 index 0000000..e8bf725 --- /dev/null +++ b/drivers/avr/timer.c @@ -0,0 +1,74 @@ +/** @file timer.c + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Timer module +*/ +#include +#include "timer.h" +#include "system.h" + +/* Timer/counter1 is a 16-bit counter with prescale options 1, 8, 64, + 256, and 1024. With F_CPU = 8e6 this corresponds to clock rates of + 8 MHz, 1 MHz, 125 kHz, 31.25 kHz, 7.8125 kHz. The counter will + roll over every 8.192 ms, 65.536 ms, 524.288 ms, 2.097s, and 8.389 s. */ + +#if TIMER_CLOCK_DIVISOR == 1 +#define TCCR1B_INIT 0x01 +#elif TIMER_CLOCK_DIVISOR == 8 +#define TCCR1B_INIT 0x02 +#elif TIMER_CLOCK_DIVISOR == 64 +#define TCCR1B_INIT 0x03 +#elif TIMER_CLOCK_DIVISOR == 256 +#define TCCR1B_INIT 0x04 +#elif TIMER_CLOCK_DIVISOR == 1024 +#define TCCR1B_INIT 0x05 +#else +#error Invalid TIMER_CLOCK_DIVISOR +#endif + + +/** Initialise timer. */ +void timer_init (void) +{ + /* Start timer in normal mode so that it rolls over at 65535 to 0. */ + TCCR1A = 0x00; + TCCR1B = TCCR1B_INIT; + TCNT1 = 0; +} + + +/** Get current time: + @return current time in ticks. */ +timer_tick_t timer_get (void) +{ + return TCNT1; +} + + +/** Wait until specified time: + @param when time to sleep until + @return current time. */ +timer_tick_t timer_wait_until (timer_tick_t when) +{ + while (1) + { + timer_tick_t diff; + timer_tick_t now; + + now = timer_get (); + + diff = now - when; + + if (diff < TIMER_OVERRUN_MAX) + return now; + } +} + + +/** Wait for specified period: + @param period how long to wait + @return current time. */ +timer_tick_t timer_wait (timer_tick_t period) +{ + return timer_wait_until (timer_get () + period); +} diff --git a/drivers/avr/timer.h b/drivers/avr/timer.h new file mode 100644 index 0000000..b01c1ff --- /dev/null +++ b/drivers/avr/timer.h @@ -0,0 +1,97 @@ +/** @file timer.h + @author M. P. Hayes, UCECE + @date 18 August 2011 + @brief Timer support. + + @defgroup timer Timer module + + This module provides simple timer support by abstracting a + hardware timer. + + The rate that the timer is incremented is specified by the + macro TIMER_CLOCK_DIVISOR in the header file system.h This + must be a value supported by the timer clock prescaler. + + The rate that the timer is incremented can be found using the + macro TIMER_RATE. + + The timer is free-running and will increment TIMER_RATE times + per second. When the timer reaches 65535 on the next increment + it rolls over to 0. + + Here's a simple example for turning an LED on for 0.5 second + and then off for 0.75 second. + + @code + #include "timer.h" + #include "led.h" + + void main (void) + { + timer_tick_t now; + + system_init (); + timer_init (); + led_init (); + + now = timer_get (); + while (1) + { + led_set (LED1, 1); + + now = timer_wait_until (now + (timer_tick_t)(TIMER_RATE * 0.5)); + + led_set (LED1, 0); + + now = timer_wait_until (now + (timer_tick_t)(TIMER_RATE * 0.75)); + } + } + @endcode +*/ +#ifndef TIMER_H +#define TIMER_H + +#include "system.h" + + +#ifndef TIMER_CLOCK_DIVISOR +#define TIMER_CLOCK_DIVISOR 256 +#endif + +/** Rate in Hz that the timer is incremented. */ +#define TIMER_RATE (F_CPU / TIMER_CLOCK_DIVISOR) + + +/** The maximum overrun (in ticks). */ +#define TIMER_OVERRUN_MAX 1000 + + +/** The maximum delay (in ticks). */ +#define TIMER_DELAY_MAX (65536u - TIMER_OVERRUN_MAX) + + +/** Define timer ticks. */ +typedef uint16_t timer_tick_t; + + +/** Get current time: + @return current time in ticks. */ +timer_tick_t timer_get (void); + + +/** Wait until specified time: + @param when time to sleep until + @return current time. */ +timer_tick_t timer_wait_until (timer_tick_t when); + + +/** Wait for specified period: + @param period how long to wait + @return current time. */ +timer_tick_t timer_wait (timer_tick_t period); + + +/** Initialise timer. */ +void timer_init (void); + +#endif /* TIMER_H */ diff --git a/drivers/avr/timer0.c b/drivers/avr/timer0.c new file mode 100644 index 0000000..898f4c0 --- /dev/null +++ b/drivers/avr/timer0.c @@ -0,0 +1,182 @@ +/** @file timer0.c + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief +*/ +#include "system.h" +#include "timer0.h" +#include "bits.h" +#include "prescale.h" +#include + +/* Timer/Counter0 is a general purpose, single channel, 8-bit + Timer/Counter module. + + It has two output compare registers and two corresponding outputs: + OC0A and OCOB. However, the counter can only be reset by the A + output compure register, OCRA. + + TODO: rewrite driver to provide standard modes, such as: + * generate square wave on OCOA + * generate square wave on OCOB + * generate PWM on OCOA + * generate PWM on OCOB + * programmable timer (for delays) + + */ + + +/* Prescale values: + 1, 8, 64, 256, or 1024. + + 2^0, 2^3, 2^6, 2^8, 2^10. */ + +static const uint8_t log_prescales[] = {0, 3, 6, 8, 10}; +static uint8_t prescale_bits = 1; + + + +static inline void +timer0_prescaler_set (uint8_t value) +{ + BITS_INSERT (TCCR0B, value, CS00, CS02); +} + + +static inline uint8_t +timer0_prescaler_get (void) +{ + return BITS_EXTRACT (TCCR0B, CS00, CS02); +} + + +static inline bool +timer0_running_p (void) +{ + return timer0_prescaler_get () != 0; +} + + +/* Set the desired period in terms of clocks. The closest + suitable period is returned. */ +uint16_t timer0_period_set (uint16_t period) +{ + uint8_t counter; + uint8_t index; + + index = prescale_select (period, log_prescales, + ARRAY_SIZE (log_prescales), &counter); + + prescale_bits = index + 1; + + + /* F = F_CPU / (2 * prescale * (1 + OCR0A)) + Maximum frequency of F_CPU / 2 when OCR0A = 0. */ + OCR0A = counter - 1; + OCR0B = 0; + + /* A prescale value of 0 selects no clock source and is used to + stop the timer. The cheapskates haven't provided a start/stop + bit so we cannot set the prescaler if the timer is stopped. */ + if (timer0_running_p ()) + timer0_prescaler_set (prescale_bits); + + /* Return the quantised period. */ + return counter << log_prescales[index]; +} + + +void +timer0_start (void) +{ + /* Clear overflow flags. */ + TIFR0 &= ~(BIT (OCF0A) | BIT (OCF0B)); + + /* Enable timer by supplying a clock from the prescaler. */ + timer0_prescaler_set (prescale_bits); +} + + +void +timer0_stop (void) +{ + /* Disable clock source. */ + timer0_prescaler_set (0); +} + + +bool +timer0_compare_p (void) +{ + return (TIFR0 & BIT (OCF0B)) != 0; +} + + +void timer0_output_set (timer0_output_t output, timer0_output_mode_t mode) +{ + switch (output) + { + case TIMER0_OUTPUT_A: + /* Select output mode for 0C0A. + The port pin must also be configured as an output. */ + BITS_INSERT (TCCR0A, mode, COM0A0, COM0A1); + break; + + case TIMER0_OUTPUT_B: + /* Select output mode for 0C0B. + The port pin must also be configured as an output. */ + BITS_INSERT (TCCR0A, mode, COM0B0, COM0B1); + break; + + default: + break; + } +} + + +int8_t +timer0_mode_set (timer0_mode_t mode) +{ + switch (mode) + { + case TIMER0_MODE_NORMAL: + /* Normal mode---counter not reset. It rolls over when it + gets to 0xFF and thus there is limited frequency control + for waveform generation. */ + TCCR0A &= ~(BIT (WGM01) | BIT (WGM00)); + + /* Need WGM02 bit set to 0 (default) in TCCR0B. */ + break; + + case TIMER0_MODE_CTC: + /* Set CTC mode. Clear timer in compare mode---counter reset + on match with OCRA. */ + TCCR0A &= ~BIT (WGM00); + TCCR0A |= BIT (WGM01); + + /* Need WGM02 bit set to 0 (default) in TCCR0B. */ + break; + + default: + return 0; + } + + return 1; +} + + +int8_t +timer0_init (void) +{ + /* Set to normal mode, clock source disabled, output compare match + to not trigger OC pin. */ + TCCR0A = 0; + TCCR0B = 0; + TCNT0 = 0; + + OCR0B = 0; + + timer0_mode_set (TIMER0_MODE_CTC); + + return 1; +} diff --git a/drivers/avr/timer0.h b/drivers/avr/timer0.h new file mode 100644 index 0000000..a7f23ed --- /dev/null +++ b/drivers/avr/timer0.h @@ -0,0 +1,48 @@ +/** @file timer0.h + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief +*/ +#ifndef TIMER0_H +#define TIMER0_H + +#include "system.h" + + +#define TIMER0_DIVISOR(FREQ) ((uint16_t) (F_CPU / (FREQ))) + + +typedef enum {TIMER0_MODE_NORMAL, + TIMER0_MODE_CTC, + TIMER0_MODE_PWM} timer0_mode_t; + +typedef enum {TIMER0_OUTPUT_A, + TIMER0_OUTPUT_B} timer0_output_t; + +typedef enum {TIMER0_OUTPUT_MODE_DISABLE, + TIMER0_OUTPUT_MODE_TOGGLE, + TIMER0_OUTPUT_MODE_CLEAR, + TIMER0_OUTPUT_MODE_SET} timer0_output_mode_t; + + +uint16_t timer0_period_set (uint16_t period); + + +void timer0_start (void); + + +void timer0_stop (void); + + +bool timer0_compare_p (void); + + +void timer0_output_set (timer0_output_t output, timer0_output_mode_t mode); + + +int8_t timer0_mode_set (timer0_mode_t mode); + + +int8_t timer0_init (void); + +#endif diff --git a/drivers/avr/usart1.c b/drivers/avr/usart1.c new file mode 100644 index 0000000..005ba72 --- /dev/null +++ b/drivers/avr/usart1.c @@ -0,0 +1,98 @@ +/** @file usart1.c + @author Michael Hayes + @date 10 March 2005 + + @brief Routines for interfacing with the usart1 on an Atmega32u2 +*/ +#include "system.h" +#include "usart1.h" +#include + +void +usart1_baud_divisor_set (uint16_t divisor) +{ + UBRR1H = (divisor - 1) >> 8; + UBRR1L = (divisor - 1) & 0xFF; +} + + +uint8_t +usart1_init (const usart1_cfg_t *cfg) +{ + uint8_t bits; + + usart1_baud_divisor_set (cfg->baud_divisor); + + /* Default to 8 bits. */ + bits = cfg->bits; + if (bits < 5 || bits > 8) + bits = 8; + + /* Enable receiver and transmitter. */ + UCSR1B = BIT (RXEN1) | BIT (TXEN1); + + /* Set frame format: asynchronous USART, 1 stop bit, no parity. */ + UCSR1C = ((bits - 5) << UCSZ10) | (0 << UPM10); + + return 1; +} + + +/* Return non-zero if there is a character ready to be read. */ +bool +usart1_read_ready_p (void) +{ + return (UCSR1A & BIT (RXC1)) != 0; +} + + +/* Return non-zero if a character can be written without blocking. */ +bool +usart1_write_ready_p (void) +{ + return (UCSR1A & BIT (UDRE1)) != 0; +} + + +/* Return non-zero if transmitter finished. */ +bool +usart1_write_finished_p (void) +{ + return (UCSR1A & BIT (TXC1)) != 0; +} + + +/* Write character to USART1. */ +int8_t +usart1_putc (char ch) +{ + if (ch == '\n') + usart1_putc ('\r'); + + while (!usart1_write_ready_p ()) + continue; + + UDR1 = ch; + return 1; +} + + +/* Read character from USART1. This blocks until a character is read. */ +int8_t +usart1_getc (void) +{ + /* Wait for something in receive buffer. */ + while (!usart1_read_ready_p ()) + continue; + + return UDR1; +} + + +/* Write string to USART1. This blocks until the string is written. */ +void +usart1_puts (const char *str) +{ + while (*str) + usart1_putc (*str++); +} diff --git a/drivers/avr/usart1.h b/drivers/avr/usart1.h new file mode 100644 index 0000000..6eb14ff --- /dev/null +++ b/drivers/avr/usart1.h @@ -0,0 +1,60 @@ +/** @file usart1.h + @author Michael Hayes + @date 10 December 2004 + + @brief Routines for interfacing with the usart1 on an Atmega32u2 +*/ + +#ifndef USART1_H +#define USART1_H + +#include "system.h" + +typedef struct usart1_cfg_struct +{ + uint16_t baud_divisor; + uint8_t bits; +} usart1_cfg_t; + + + +#define USART1_BAUD_DIVISOR(BAUD_RATE) ((F_CPU / 16) / (BAUD_RATE)) + + +/* Return non-zero if there is a character ready to be read. */ +bool +usart1_read_ready_p (void); + + +/* Read character from USART1. This blocks if nothing is available to + read. */ +int8_t +usart1_getc (void); + + +/* Return non-zero if a character can be written without blocking. */ +bool +usart1_write_ready_p (void); + + +/* Return non-zero if transmitter finished. */ +bool +usart1_write_finished_p (void); + + +/* Write character to USART1. This returns zero if the character + could not be written. */ +int8_t +usart1_putc (char ch); + + +/* Write string to USART1. */ +void +usart1_puts (const char *str); + + +/* Initialise usart1 and set baud rate. */ +uint8_t +usart1_init (const usart1_cfg_t *cfg); + +#endif diff --git a/drivers/button.c b/drivers/button.c new file mode 100644 index 0000000..d12d8fd --- /dev/null +++ b/drivers/button.c @@ -0,0 +1,123 @@ +/** @file button.c + @author M.P. Hayes + @date 28 Aug 2008 + @brief Button polling (no debouncing). + @note This polls pushbutton switches but does not do debouncing. +*/ + +#include "system.h" +#include "button.h" +#include "pio.h" + + +/* Button configuration structure. */ +typedef struct +{ + pio_t pio; + /* True for active high, false for active low. */ + bool active_high; +} button_cfg_t; + + +/** Button state structure. */ +typedef struct +{ + bool current; + bool previous; +} button_state_t; + + +/* Define buttons. */ +static const button_cfg_t buttons_cfg[] = +{ + {.pio = BUTTON1_PIO, .active_high = 1}, + /* Add config data for additional buttons here. */ +}; + +#define BUTTONS_NUM ARRAY_SIZE (buttons_cfg) + +static button_state_t buttons_state[BUTTONS_NUM]; + + +/** Return true if button state changed from up to down since + last call to button_update + @param button index of button to select + @return 1 if button changed from up to down otherwise 0 */ +bool +button_push_event_p (uint8_t button) +{ + if (button >= BUTTONS_NUM) + return 0; + return buttons_state[button].current && !buttons_state[button].previous; +} + + +/** Return true if button state changed from down to up since + last call to button_update + @param button index of button to select + @return 1 if button changed from down to up otherwise 0 */ +bool +button_release_event_p (uint8_t button) +{ + if (button >= BUTTONS_NUM) + return 0; + return !buttons_state[button].current && buttons_state[button].previous; +} + + +/** Return true if button down (pushed). + @param button index of button to select + @return 1 if button down otherwise 0 */ +bool +button_down_p (uint8_t button) +{ + if (button >= BUTTONS_NUM) + return 0; + return buttons_state[button].current; +} + + +/** Return true if button up (released). + @param button index of button to select + @return 1 if button down otherwise 0 */ +bool +button_up_p (uint8_t button) +{ + if (button >= BUTTONS_NUM) + return 0; + return !buttons_state[button].current; +} + + +/** Poll all the buttons and update their state. */ +void +button_update (void) +{ + uint8_t i; + + for (i = 0; i < BUTTONS_NUM; i++) + { + buttons_state[i].previous = buttons_state[i].current; + + buttons_state[i].current = ! (pio_input_get (buttons_cfg[i].pio) + ^ buttons_cfg[i].active_high); + } +} + + +/** Initialise button driver. */ +void button_init (void) +{ + uint8_t i; + + for (i = 0; i < BUTTONS_NUM; i++) + { + /* Configure pio for input and enable internal pullup resistor + if active low. If button is active high it is assumed + there is an external pulldon resistor. */ + pio_config_set (buttons_cfg[i].pio, + buttons_cfg[i].active_high ? PIO_INPUT : PIO_PULLUP); + } +} + + diff --git a/drivers/button.h b/drivers/button.h new file mode 100644 index 0000000..c93fc9d --- /dev/null +++ b/drivers/button.h @@ -0,0 +1,74 @@ +/** @file button.h + @author M. P. Hayes, UCECE + @date 15 Feb 2003 + @brief Button polling (no debouncing). + + @defgroup button Pushbutton driver + + This module implements a simple pushbutton driver. Note, no + debouncing is performed. + + Here's an example application where the buttons are polled at 50 Hz: + + @code + #include "pacer.h" + #include "button.h" + + void main (void) + { + system_init (); + button_init (); + pacer_init (50); + + while (1) + { + pacer_wait (); + button_update (); + + if (button_push_event_p (0)) + // Do something + } + } + @endcode +*/ + + +#ifndef BUTTON_H +#define BUTTON_H + +#include "system.h" + + +/** Poll all the buttons and update their state. */ +void button_update (void); + + +/** Return true if button state changed from up to down since + last call to button_update + @param button index of button to select + @return 1 if button changed from up to down otherwise 0 */ +bool button_push_event_p (uint8_t button); + + +/** Return true if button state changed from down to up since + last call to button_update + @param button index of button to select + @return 1 if button changed from down to up otherwise 0 */ +bool button_release_event_p (uint8_t button); + + +/** Return true if button down (pushed). + @param button index of button to select + @return 1 if button down otherwise 0 */ +bool button_down_p (uint8_t button); + + +/** Return true if button up (released). + @param button index of button to select + @return 1 if button down otherwise 0 */ +bool button_up_p (uint8_t button); + + +/** Initialise button driver. */ +void button_init (void); +#endif diff --git a/drivers/display.c b/drivers/display.c new file mode 100644 index 0000000..2bf2324 --- /dev/null +++ b/drivers/display.c @@ -0,0 +1,101 @@ +/** @file display.c + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Bit-mapped display driver. +*/ +#include "system.h" +#include "ledmat.h" +#include "display.h" + +/** The state of the display (frame buffer). */ +static uint8_t display[DISPLAY_WIDTH]; + + +/** Set state of a display pixel. + @param col pixel column + @param row pixel row + @param val pixel state. */ +void display_pixel_set (uint8_t col, uint8_t row, bool val) +{ + uint8_t bitmask; + uint8_t pattern; + + if (col >= DISPLAY_WIDTH || row >= DISPLAY_HEIGHT) + return; + + bitmask = BIT (row); + pattern = display[col] & ~bitmask; + + if (val) + pattern |= bitmask; + + display[col] = pattern; +} + + +/** Get state of a display pixel. + @param col pixel column + @param row pixel row + @return pixel state or zero if outside display. */ +bool display_pixel_get (uint8_t col, uint8_t row) +{ + uint8_t bitmask; + + if (col >= DISPLAY_WIDTH || row >= DISPLAY_HEIGHT) + return 0; + + bitmask = BIT (row); + + return (display[col] & bitmask) != 0; +} + + +/** Scroll display contents one column to left. */ +void display_scroll_left (void) +{ + int col; + + for (col = 0; col < DISPLAY_WIDTH - 1; col++) + display[col] = display[col + 1]; +} + + +/** Scroll display contents one row down. */ +void display_scroll_down (void) +{ + int col; + + for (col = 0; col < DISPLAY_WIDTH; col++) + display[col] <<= 1; +} + + +/** Update display (perform refreshing). */ +void display_update (void) +{ + static uint8_t col = 0; + + ledmat_display_column (display[col], col); + + col++; + if (col >= DISPLAY_WIDTH) + col = 0; +} + + +/** Clear display. */ +void display_clear (void) +{ + int col; + + for (col = 0; col < DISPLAY_WIDTH; col++) + display[col] = 0; +} + + +/** Initialise display. */ +void display_init (void) +{ + ledmat_init (); + display_clear (); +} diff --git a/drivers/display.h b/drivers/display.h new file mode 100644 index 0000000..81c89c2 --- /dev/null +++ b/drivers/display.h @@ -0,0 +1,52 @@ +/** @file display.h + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Bit-mapped display driver. + + @defgroup display Bit-mapped display driver + + This module implements a simple display frame-buffer. It abstracts the + multiplexing of a LED matrix display. +*/ +#ifndef DISPLAY_H +#define DISPLAY_H + +#include "system.h" + +#define DISPLAY_WIDTH LEDMAT_COLS_NUM +#define DISPLAY_HEIGHT LEDMAT_ROWS_NUM + +/** Set state of a display pixel. + @param col pixel column (0 left) + @param row pixel row (0 top) + @param val pixel state. */ +void display_pixel_set (uint8_t col, uint8_t row, bool val); + + +/** Get state of a display pixel. + @param col pixel column (0 left) + @param row pixel row (0 top) + @return pixel state or zero if outside display. */ +bool display_pixel_get (uint8_t col, uint8_t row); + + +/** Scroll display contents one column to left. */ +void display_scroll_left (void); + + +/** Scroll display contents one row down. */ +void display_scroll_down (void); + + +/** Update display (perform refreshing). */ +void display_update (void); + + +/** Clear display. */ +void display_clear (void); + + +/** Initialise display. */ +void display_init (void); + +#endif diff --git a/drivers/ir.c b/drivers/ir.c new file mode 100644 index 0000000..8c265da --- /dev/null +++ b/drivers/ir.c @@ -0,0 +1,95 @@ +/** @file ir.c + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Infrared driver. + @note This should be compiled with optimisation enabled to make the + modulation frequency more accurate. +*/ +#include "system.h" +#include "delay.h" +#include "ir.h" +#include "pio.h" + +#define IR_MODULATION_PERIOD_US (1e6 / IR_MODULATION_FREQ) + +#define IR_SET_TWEAK_US 0.2 +#define LOOP_TWEAK_US 0.8 + + +/** Turn IR transmitter LED on. */ +static inline void ir_tx_on (void) +{ + pio_output_high (IR_TX_HIGH_PIO); +} + + +/** Turn IR transmitter LED off. */ +static inline void ir_tx_off (void) +{ + pio_output_low (IR_TX_HIGH_PIO); +} + + +/** Modulate the IR transmitter LED at IR_MODULATION_FREQ. + @param state is 1 to enable modulation, 0 to disable modulation + @param count is the number of modulation periods + @note This returns after @c count modulation periods. */ +void ir_tx_set (uint8_t state, uint16_t count) +{ + uint16_t i = 0; + + /* This modulates the IR LED by bit bashing the IR LED PIO. + Alternatively, we could use the timer0 peripheral for a more + accurate modulation frequency. + + The timing could be made more accurate by tweaking the delays + to compensate for the other instructions. */ + + if (state) + { + for (i = 0; i < count; i++) + { + ir_tx_on (); + DELAY_US (IR_MODULATION_PERIOD_US / 2 - IR_SET_TWEAK_US); + ir_tx_off (); + DELAY_US (IR_MODULATION_PERIOD_US / 2 - IR_SET_TWEAK_US - LOOP_TWEAK_US); + } + } + else + { + for (i = 0; i < count; i++) + { + DELAY_US (IR_MODULATION_PERIOD_US - LOOP_TWEAK_US); + } + } +} + + +/** Return output state of IR receiver. + @return IR receiver state (1 = IR modulation detected). */ +uint8_t ir_rx_get (void) +{ + /* The output of the IR receiver (TSOP6136TR) is inverted. It is + normally high but goes low when it detects modulated IR light. */ + + return !pio_input_get (IR_RX_PIO); +} + + +/** Initialise PIOs for IR transmitter LED and receiver. */ +void ir_init (void) +{ + /* Configure transmitter PIOs as outputs and ensure IR LED off. + Note that the IR LED is driven by two PIOs; to turn on the LED + IR_TX_HIGH_PIO must be high and IR_TX_LOW_PIO must be low. + IR_TX_HIGH_PIO is also connected to the timer 0 output so + we can modulate the LED by the timer. IR_TX_LOW_PIO is also + connected to the UART TXD output so we can drive it from the UART. */ + + pio_config_set (IR_TX_HIGH_PIO, PIO_OUTPUT_LOW); + pio_config_set (IR_TX_LOW_PIO, PIO_OUTPUT_LOW); + + /* Configure receiver PIO as input. IR_RX_PIO is also connected to the + UART RXD input. */ + pio_config_set (IR_RX_PIO, PIO_INPUT); +} diff --git a/drivers/ir.h b/drivers/ir.h new file mode 100644 index 0000000..c2c5f7e --- /dev/null +++ b/drivers/ir.h @@ -0,0 +1,38 @@ +/** @file ir.h + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Infrared driver. + + @defgroup IR Infrared (IR) driver + + This module implements a simple hardware abstraction of an IR LED and + IR receiver. +*/ + +#ifndef IR_H +#define IR_H + +#include "system.h" + +#ifndef IR_MODULATION_FREQ +/** The nominal modulation frequency. This can be defined in system.h. */ +#define IR_MODULATION_FREQ 36e3 +#endif + + +/** Modulate the IR transmitter LED at IR_MODULATION_FREQ. + @param state is 1 to enable modulation, 0 to disable modulation + @param count is the number of modulation periods + @note This returns after @c count modulation periods. */ +void ir_tx_set (uint8_t state, uint16_t count); + + +/** Return output state of IR receiver. + @return IR receiver state (1 = IR modulation detected). */ +uint8_t ir_rx_get (void); + + +/* Initialise PIOs for IR transmitter LED and receiver. */ +void ir_init (void); + +#endif diff --git a/drivers/ir_serial.c b/drivers/ir_serial.c new file mode 100644 index 0000000..963c7d3 --- /dev/null +++ b/drivers/ir_serial.c @@ -0,0 +1,152 @@ +/** @file ir_serial.c + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Infrared serial driver. +*/ + +/* This should probably be compiled with optimisation enabled + otherwise some of the timing may be dodgy. + For documentation of the protocol see ir_serial.h */ + + +#include "ir_serial.h" +#include "delay.h" + +#define IR_SERIAL_DIT_PERIOD 0.6e-3 +#define IR_SERIAL_MODULATIONS_PER_DIT ((int)(IR_SERIAL_DIT_PERIOD * IR_MODULATION_FREQ)) +#define IR_SERIAL_MODULATIONS_PER_START (IR_SERIAL_MODULATIONS_PER_DIT * 4) +#define IR_SERIAL_MODULATIONS_PER_ONE (IR_SERIAL_MODULATIONS_PER_DIT * 2) +#define IR_SERIAL_MODULATIONS_PER_ZERO (IR_SERIAL_MODULATIONS_PER_DIT) +#define IR_SERIAL_MODULATIONS_PER_BREAK (IR_SERIAL_MODULATIONS_PER_DIT) + +#define IR_SERIAL_DELAY_US 10 +#define IR_SERIAL_DIT_COUNT (1e6 * IR_SERIAL_DIT_PERIOD / IR_SERIAL_DELAY_US) +#define IR_SERIAL_START_COUNT_MAX ((int)(4.5 * IR_SERIAL_DIT_COUNT)) +#define IR_SERIAL_ONE_COUNT_MAX ((int)(2.5 * IR_SERIAL_DIT_COUNT)) +#define IR_SERIAL_ZERO_COUNT_MAX ((int)(1.25 * IR_SERIAL_DIT_COUNT)) +#define IR_SERIAL_BREAK_COUNT_MAX ((int)(1.5 * IR_SERIAL_DIT_COUNT)) + + +/** Transmit a start code. */ +static inline void ir_serial_tx_start (void) +{ + ir_tx_set (1, IR_SERIAL_MODULATIONS_PER_START); + ir_tx_set (0, IR_SERIAL_MODULATIONS_PER_BREAK); +} + + +/** Transmit a data bit. */ +static inline void ir_serial_tx_bit (uint8_t state) +{ + ir_tx_set (1, state ? IR_SERIAL_MODULATIONS_PER_ONE + : IR_SERIAL_MODULATIONS_PER_ZERO); + ir_tx_set (0, IR_SERIAL_MODULATIONS_PER_BREAK); +} + + +/** Transmit a stop code. */ +static inline void ir_serial_tx_stop (void) +{ + ir_tx_set (0, IR_SERIAL_MODULATIONS_PER_BREAK); +} + + +/** Transmit 8 bits of data over IR serial link. + @param data byte to transmit + @note No error checking is performed. This function blocks until + the frame is transmitted. */ +void ir_serial_transmit (uint8_t data) +{ + int i; + + /* Send start code. */ + ir_serial_tx_start (); + + /* Eight data bits LSB first. */ + for (i = 0; i < 8; i++) + { + ir_serial_tx_bit (data & 1); + data >>= 1; + } + + /* Send stop code. */ + ir_serial_tx_stop (); +} + + +/** Receive 8 bits of data over IR serial link. + @param pdata pointer to byte to store received data + @return status code + @note No error checking is performed. If there is no activity on the + IR serial link, this function returns immediately. Otherwise, this + function blocks until the entire frame is received. */ +ir_serial_ret_t ir_serial_receive (uint8_t *pdata) +{ + int i; + int count; + uint8_t data; + bool data_err; + + /* Check for start code; if not present return. */ + if (!ir_rx_get ()) + return IR_SERIAL_NONE; + + /* Wait for end of start code or timeout. */ + for (count = 0; ir_rx_get (); count++) + { + if (count >= IR_SERIAL_START_COUNT_MAX) + return IR_SERIAL_START_ERR; + + DELAY_US (IR_SERIAL_DELAY_US); + } + + /* We may have received a rogue short pulse but we may have been + called closed to the falling transition. */ + + data_err = 0; + data = 0; + + /* Eight data bits LSB first. */ + for (i = 0; i < 8; i++) + { + data >>= 1; + + /* Wait for IR modulation to start or timeout (indicating + detection of a false start code). */ + for (count = 0; !ir_rx_get (); count++) + { + if (count >= IR_SERIAL_BREAK_COUNT_MAX) + return IR_SERIAL_BREAK_ERR; + + DELAY_US (IR_SERIAL_DELAY_US); + } + + /* If there is another transmission in this slot we will get + too small a value for dit_count. This is likely to trigger + a bit error. */ + for (count = 0; count < IR_SERIAL_ONE_COUNT_MAX + && ir_rx_get (); count++) + { + DELAY_US (IR_SERIAL_DELAY_US); + } + + if (count >= IR_SERIAL_ONE_COUNT_MAX) + data_err = 1; + + if (count >= IR_SERIAL_ZERO_COUNT_MAX) + data |= 0x80; + } + + /* Perhaps should check for stop code. If not found, there is + likely to have been interference from another transmitter. */ + + *pdata = data; + return data_err ? IR_SERIAL_DATA_ERR : IR_SERIAL_OK; +} + + +/** Initialise IR serial driver. */ +void ir_serial_init (void) +{ + ir_init (); +} diff --git a/drivers/ir_serial.h b/drivers/ir_serial.h new file mode 100644 index 0000000..125a407 --- /dev/null +++ b/drivers/ir_serial.h @@ -0,0 +1,117 @@ +/** @file ir_serial.h + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Infrared serial driver. + + @defgroup IR_serial Infrared serial driver + + This module implements a simple serial protocol over an IR link. + It uses a pulse width modulation technique similar to the Sony + SIRC protocol. A message consists of a start code, 8 data bits + (transmitted LSB first), and a stop code. Each code is comprised + of 0.6 ms intervals called a dit: + + Start bit: four dits on, one dit off + + One bit: two dits on, one dit off + + Zero bit: one dit on, one dit off + + Stop bit: one dit off + + Note, the duration of a message depends on the number of non-zero + bits in the data byte. The shortest message duration is 22 dits + (13.2 ms) and the longest message is 30 dits (18 ms). No error + detection or correction is performed apart from checking of + invalid codes. + + Here's a simple application that transmits a data byte of value 7. + + @code + #include "ir_serial.h" + + void main (void) + { + system_init (); + ir_serial_init (); + + ir_serial_transmit (7); + + while (1) + { + } + } + @endcode + + Here's another simple application that receives a data byte. + + @code + #include "ir_serial.h" + #include "pacer.h" + + void main (void) + { + system_init (); + ir_serial_init (); + + pacer_init (1000); + + while (1) + { + ir_serial_ret_t ret; + + pacer_wait (); + + ret = ir_serial_receive (&data); + if (ret == IR_SERIAL_OK) + { + // Process the received byte. + } + } + } + @endcode +*/ + +#ifndef IR_SERIAL_H +#define IR_SERIAL_H + +#include "ir.h" + +/** Status return codes. */ +typedef enum ir_serial_ret +{ + /** A valid frame has been received. */ + IR_SERIAL_OK = 1, + /** No data to read. */ + IR_SERIAL_NONE = 0, + /** Invalid start code detected. */ + IR_SERIAL_START_ERR = -1, + /** Invalid data code detected. */ + IR_SERIAL_DATA_ERR = -2, + /** Invalid break code detected. */ + IR_SERIAL_BREAK_ERR = -3, + /** Invalid stop code detected. */ + IR_SERIAL_STOP_ERR = -4 +} ir_serial_ret_t; + + +/** Transmit 8 bits of data over IR serial link. + @param data byte to transmit + @note No error checking is performed. This function blocks until + the frame is transmitted. */ +void ir_serial_transmit (uint8_t data); + + +/** Receive 8 bits of data over IR serial link. + @param pdata pointer to byte to store received data + @return status code + @note No error checking is performed. If there is no activity on the + IR serial link, this function returns immediately. Otherwise, this + function blocks until the entire frame is received. */ +ir_serial_ret_t ir_serial_receive (uint8_t *pdata); + + +/** Initialise IR serial driver. */ +void ir_serial_init (void); + +#endif diff --git a/drivers/led.c b/drivers/led.c new file mode 100644 index 0000000..64e3fd3 --- /dev/null +++ b/drivers/led.c @@ -0,0 +1,50 @@ +/** @file led.c + @author M. P. Hayes, UCECE + @date 15 Feb 2003 + @brief LED driver. +*/ + +#include "system.h" +#include "pio.h" +#include "led.h" + + +typedef struct +{ + pio_t pio; + /* True for active high, false for active low. */ + bool active_high; +} led_cfg_t; + + +/* Define LEDs. */ +static const led_cfg_t leds_cfg[] = +{ + {.pio = LED1_PIO, .active_high = 1}, + /* Add config data for additional LEDs here. */ +}; + +#define LEDS_NUM ARRAY_SIZE (leds_cfg) + + +void led_set (uint8_t led, bool state) +{ + if (led >= LEDS_NUM) + return; + pio_output_set (leds_cfg[led].pio, + leds_cfg[led].active_high ? state : !state); +} + + +/** Initialise LED driver. */ +void led_init (void) +{ + uint8_t i; + + for (i = 0; i < LEDS_NUM; i++) + { + pio_config_set (leds_cfg[i].pio, + leds_cfg[i].active_high ? PIO_OUTPUT_HIGH + : PIO_OUTPUT_LOW); + } +} diff --git a/drivers/led.h b/drivers/led.h new file mode 100644 index 0000000..fcd07be --- /dev/null +++ b/drivers/led.h @@ -0,0 +1,44 @@ +/** @file led.h + @author M. P. Hayes, UCECE + @date 15 Feb 2003 + @brief LED driver. + + @defgroup LED LED driver + + This module implements a simple LED driver. + + Here's an example application that turns on a LED: + + @code + #include "led.h" + + void main (void) + { + system_init (); + led_init (); + + led_set (LED1, 1); + + while (1) + { + } + } + @endcode +*/ + +#ifndef LED_H +#define LED_H + +#include "system.h" + + +/** Set LED to desired state. + @param led LED to select + @param state desired state (non-zero for on). */ +void led_set (uint8_t led, bool state); + + +/** Initialise LED driver. */ +void led_init (void); + +#endif diff --git a/drivers/ledmat.c b/drivers/ledmat.c new file mode 100644 index 0000000..7879d9b --- /dev/null +++ b/drivers/ledmat.c @@ -0,0 +1,78 @@ +/** @file ledmat.c + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief LED matrix driver. +*/ +#include "system.h" +#include "pio.h" +#include "ledmat.h" + + +/** Define PIO pins driving LED matrix rows. */ +static const pio_t ledmat_rows[] = +{ + LEDMAT_ROW1_PIO, LEDMAT_ROW2_PIO, LEDMAT_ROW3_PIO, + LEDMAT_ROW4_PIO, LEDMAT_ROW5_PIO, LEDMAT_ROW6_PIO, + LEDMAT_ROW7_PIO +}; + + +/** Define PIO pins driving LED matrix columns. */ +static const pio_t ledmat_cols[] = +{ + LEDMAT_COL1_PIO, LEDMAT_COL2_PIO, LEDMAT_COL3_PIO, + LEDMAT_COL4_PIO, LEDMAT_COL5_PIO +}; + + +/** Initialise PIO pins to drive LED matrix. */ +void ledmat_init (void) +{ + uint8_t row; + uint8_t col; + + for (row = 0; row < LEDMAT_ROWS_NUM; row++) + { + /* The rows are active low so configure PIO as an initially + high output. */ + pio_config_set (ledmat_rows[row], PIO_OUTPUT_HIGH); + } + + for (col = 0; col < LEDMAT_COLS_NUM; col++) + { + /* The columns are active low so configure PIO as an initially + high output. */ + pio_config_set (ledmat_cols[col], PIO_OUTPUT_HIGH); + } +} + + +/** Display pattern on specified column. + @param pattern bit pattern to display for selected column + @param col selected column. */ +void ledmat_display_column (uint8_t pattern, uint8_t col) +{ + static uint8_t col_prev = 0; + uint8_t row; + + /* Disable previous column to prevent ghosting while rows modified. */ + pio_output_high (ledmat_cols[col_prev]); + + /* Activate desired rows based on desired pattern. */ + for (row = 0; row < LEDMAT_ROWS_NUM; row++) + { + /* The rows are active low. */ + if (pattern & 1) + pio_output_low (ledmat_rows[row]); + else + pio_output_high (ledmat_rows[row]); + + pattern >>= 1; + } + + /* Enable new column. */ + pio_output_low (ledmat_cols[col]); + col_prev = col; +} + + diff --git a/drivers/ledmat.h b/drivers/ledmat.h new file mode 100644 index 0000000..cd838e6 --- /dev/null +++ b/drivers/ledmat.h @@ -0,0 +1,25 @@ +/** @file ledmat.h + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief LED matrix driver. + + @defgroup ledmat LED matrix driver + + This module implements a simple hardware abstraction of a LED matrix. +*/ +#ifndef LEDMAT_H +#define LEDMAT_H + +#include "system.h" + +/** Initialise PIO pins to drive LED matrix. */ +void ledmat_init (void); + + +/** Display pattern on specified column. + @param pattern bit pattern to display for selected column + @param col selected column. */ +void ledmat_display_column (uint8_t pattern, uint8_t col); + + +#endif diff --git a/drivers/navswitch.c b/drivers/navswitch.c new file mode 100644 index 0000000..2780cf7 --- /dev/null +++ b/drivers/navswitch.c @@ -0,0 +1,140 @@ +/** @file navswitch.c + @author M.P. Hayes + @date 28 Aug 2008 + @brief Navswitch driver. + @note This polls the 5-way navigation switch + but does not do debouncing. +*/ + +#include "system.h" +#include "navswitch.h" +#include "delay.h" +#include "pio.h" + + +/* Navswitch configuration structure. */ +typedef struct +{ + pio_t pio; +} navswitch_cfg_t; + + +/** Navswitch state structure. */ +typedef struct +{ + bool current; + bool previous; +} navswitch_state_t; + + +/* Define navswitch PIO connections. */ +static const navswitch_cfg_t navswitch_cfg[] = +{ + {NAVSWITCH_NORTH_PIO}, + {NAVSWITCH_EAST_PIO}, + {NAVSWITCH_SOUTH_PIO}, + {NAVSWITCH_WEST_PIO}, + {NAVSWITCH_PUSH_PIO} +}; + +#define NAVSWITCH_NUM ARRAY_SIZE (navswitch_cfg) + +static navswitch_state_t navswitch_state[NAVSWITCH_NUM]; + + +/** Return true if navswitch state changed from up to down since + last call to navswitch_update + @param navswitch index of navswitch to select + @return 1 if navswitch changed from up to down otherwise 0 */ +bool +navswitch_push_event_p (uint8_t navswitch) +{ + return navswitch_state[navswitch].current + && !navswitch_state[navswitch].previous; +} + + +/** Return true if navswitch state changed from down to up since + last call to navswitch_update + @param navswitch index of navswitch to select + @return 1 if navswitch changed from down to up otherwise 0 */ +bool +navswitch_release_event_p (uint8_t navswitch) +{ + return !navswitch_state[navswitch].current + && navswitch_state[navswitch].previous; +} + + +/** Return true if navswitch down (pushed). + @param navswitch index of navswitch to select + @return 1 if navswitch down otherwise 0 */ +bool +navswitch_down_p (uint8_t navswitch) +{ + return navswitch_state[navswitch].current; +} + + +/** Return true if navswitch up (released). + @param navswitch index of navswitch to select + @return 1 if navswitch down otherwise 0 */ +bool +navswitch_up_p (uint8_t navswitch) +{ + return !navswitch_state[navswitch].current; +} + + +/** Poll all the navswitches and update their state. */ +void +navswitch_update (void) +{ + uint8_t i; + + /* The switch is a 5-way navigation switch with push. The common + connection is connected to ground. The 5 switch outputs share + the LED matrix display column drive pins so we need to save the + state of the column outputs, switch them to inputs, read the + switch states, switch them back to outputs, and restore the + output state. + + When a switch is pushed it will pull its associated PIO pin low + via a 2.2 kohm resistor. When the PIO pin is configured as an + input with pullup, pushing the switch will also turn on the + column MOSFET driver. This will cause some ghosting of the + display. This can be avoided by driving all the LED matrix + rows low while we read the switches. */ + + for (i = 0; i < NAVSWITCH_NUM; i++) + { + pio_config_t config; + + navswitch_state[i].previous = navswitch_state[i].current; + + config = pio_config_get (navswitch_cfg[i].pio); + + /* Momentarily force PIO pin high to charge gate capacitance of + MOSFET otherwise will always read logic low and think the + switch is pushed. Alternatively, we need to wait 10 us or + more so that the gate capacitance of the MOSFET charges via + the pullup resistor. */ + pio_config_set (navswitch_cfg[i].pio, PIO_OUTPUT_HIGH); + + /* Switch PIO to an input to read switch. */ + pio_config_set (navswitch_cfg[i].pio, PIO_PULLUP); + navswitch_state[i].current = pio_input_get (navswitch_cfg[i].pio) == 0; + + /* Restore PIO state. */ + pio_config_set (navswitch_cfg[i].pio, config); + } +} + + +/** Initialise navswitch driver. */ +void navswitch_init (void) +{ + /* Nothing to do since we configure PIOs when polling the switch. */ +} + + diff --git a/drivers/navswitch.h b/drivers/navswitch.h new file mode 100644 index 0000000..a943d3b --- /dev/null +++ b/drivers/navswitch.h @@ -0,0 +1,81 @@ +/** @file navswitch.h + @author M. P. Hayes, UCECE + @date 15 Feb 2003 + @brief Navswitch polling (no debouncing). + + @defgroup navswitch Navswitch driver + + This module implements a simple navswitch driver. Note, no + debouncing is performed. + + Here's an example application where the navswitches are polled at 50 Hz: + + @code + #include "pacer.h" + #include "navswitch.h" + + void main (void) + { + system_init (); + navswitch_init (); + pacer_init (50); + + while (1) + { + pacer_wait (); + navswitch_update (); + + if (navswitch_push_event_p (NAVSWITCH_EAST)) + // Do something + + if (navswitch_push_event_p (NAVSWITCH_WEST)) + // Do something + } + } + @endcode +*/ + + +#ifndef NAVSWITCH_H +#define NAVSWITCH_H + +#include "system.h" + + +enum {NAVSWITCH_NORTH, NAVSWITCH_EAST, NAVSWITCH_SOUTH, NAVSWITCH_WEST, + NAVSWITCH_PUSH}; + + +/** Poll all the navswitches and update their state. */ +void navswitch_update (void); + + +/** Return true if navswitch state changed from up to down since + last call to navswitch_update + @param navswitch index of navswitch to select + @return 1 if navswitch changed from up to down otherwise 0 */ +bool navswitch_push_event_p (uint8_t navswitch); + + +/** Return true if navswitch state changed from down to up since + last call to navswitch_update + @param navswitch index of navswitch to select + @return 1 if navswitch changed from down to up otherwise 0 */ +bool navswitch_release_event_p (uint8_t navswitch); + + +/** Return true if navswitch down (pushed). + @param navswitch index of navswitch to select + @return 1 if navswitch down otherwise 0 */ +bool navswitch_down_p (uint8_t navswitch); + + +/** Return true if navswitch up (released). + @param navswitch index of navswitch to select + @return 1 if navswitch down otherwise 0 */ +bool navswitch_up_p (uint8_t navswitch); + + +/** Initialise navswitch driver. */ +void navswitch_init (void); +#endif diff --git a/drivers/test/avrtest.h b/drivers/test/avrtest.h new file mode 100644 index 0000000..7e5e433 --- /dev/null +++ b/drivers/test/avrtest.h @@ -0,0 +1,33 @@ +#ifndef AVRTEST_H +#define AVRTEST_H + +#include "system.h" + +typedef struct SFR +{ + uint8_t PORTB; + uint8_t DDRB; + uint8_t PINB; + uint8_t PORTC; + uint8_t DDRC; + uint8_t PINC; + uint8_t PORTD; + uint8_t DDRD; + uint8_t PIND; +} SFR_t; + + +#define PORTB SFR.PORTB +#define PORTC SFR.PORTC +#define PORTD SFR.PORTD +#define DDRB SFR.DDRB +#define DDRC SFR.DDRC +#define DDRD SFR.DDRD +#define PINB SFR.PINB +#define PINC SFR.PINC +#define PIND SFR.PINC + +extern SFR_t SFR; + + +#endif diff --git a/drivers/test/delay.h b/drivers/test/delay.h new file mode 100644 index 0000000..7b5186e --- /dev/null +++ b/drivers/test/delay.h @@ -0,0 +1 @@ +#define DELAY_US(US) diff --git a/drivers/test/eeprom.c b/drivers/test/eeprom.c new file mode 100644 index 0000000..72eb8dd --- /dev/null +++ b/drivers/test/eeprom.c @@ -0,0 +1,85 @@ +/** @file eeprom.c + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief +*/ +#include "system.h" +#include "eeprom.h" +#include +#include + + +#define EEPROM_SIZE 512 +#define EEPROM_FILENAME "ucfk_eeprom.dat" + + +static void +eeprom_file_write (void *buffer, eeprom_size_t size) +{ + FILE *fp; + + fp = fopen (EEPROM_FILENAME, "w"); + if (fp) + { + fwrite (buffer, size, 1, fp); + fclose (fp); + } +} + + +static void +eeprom_file_read (void *buffer, eeprom_size_t size) +{ + FILE *fp; + + fp = fopen (EEPROM_FILENAME, "r"); + if (!fp) + { + /* If file not present assume EEPROM is erased and thus + contains the values 0xff. */ + memset (buffer, 0xff, size); + eeprom_file_write (buffer, size); + } + else + { + fread (buffer, size, 1, fp); + fclose (fp); + } +} + + +/* Read SIZE bytes from ADDR into BUFFER. */ +eeprom_size_t +eeprom_read (eeprom_addr_t addr, void *buffer, eeprom_size_t size) +{ + eeprom_size_t i; + uint8_t *data = buffer; + uint8_t eeprom[EEPROM_SIZE]; + + eeprom_file_read (eeprom, EEPROM_SIZE); + + for (i = 0; i < size && addr < EEPROM_SIZE; i++) + data[i] = eeprom[addr++]; + + return i; + +} + + +/* Write SIZE bytes to ADDR from BUFFER. */ +eeprom_size_t +eeprom_write (eeprom_addr_t addr, const void *buffer, eeprom_size_t size) +{ + eeprom_size_t i; + const uint8_t *data = buffer; + uint8_t eeprom[EEPROM_SIZE]; + + eeprom_file_read (eeprom, EEPROM_SIZE); + + for (i = 0; i < size && addr < EEPROM_SIZE; i++) + eeprom[addr++] = data[i]; + + eeprom_file_write (eeprom, EEPROM_SIZE); + + return i; +} diff --git a/drivers/test/eeprom.h b/drivers/test/eeprom.h new file mode 100644 index 0000000..20bbcff --- /dev/null +++ b/drivers/test/eeprom.h @@ -0,0 +1,30 @@ +/** @file eeprom.h + @author Michael Hayes + @date 13 Nov 2006 + @brief Routines to read/write internal EEPROM. + + @defgroup eeprom EEPROM driver + + This module implements a driver to read/write the EEPROM of an + ATmega microcontroller. The EEPROM is useful for storing + persistent data when the power is removed. + */ + +#ifndef EEPROM_H +#define EEPROM_H + +#include "system.h" + +typedef uint16_t eeprom_addr_t; +typedef uint16_t eeprom_size_t; + +/* Read SIZE bytes from ADDR into BUFFER. */ +extern eeprom_size_t +eeprom_read (eeprom_addr_t addr, void *buffer, eeprom_size_t size); + + +/* Write SIZE bytes to ADDR from BUFFER. */ +extern eeprom_size_t +eeprom_write (eeprom_addr_t addr, const void *buffer, eeprom_size_t size); + +#endif diff --git a/drivers/test/ir_uart.c b/drivers/test/ir_uart.c new file mode 100644 index 0000000..5a01999 --- /dev/null +++ b/drivers/test/ir_uart.c @@ -0,0 +1,64 @@ +/** @file ir_uart.c + @author M. P. Hayes, UCECE + @date 1 Aug 2011 + @brief This is just a stub that does nothing. +*/ +#include "system.h" +#include "ir_uart.h" + + +/* Return non-zero if there is a character ready to be read. */ +bool +ir_uart_read_ready_p (void) +{ + return 0; +} + + +/* Read character from IR_UART. This blocks if nothing + is available to read. */ +int8_t +ir_uart_getc (void) +{ + return 0; +} + + +/* Return non-zero if a character can be written without blocking. */ +bool +ir_uart_write_ready_p (void) +{ + return 0; +} + + +/* Return non-zero if transmitter finished. */ +bool +ir_uart_write_finished_p (void) +{ + return 1; +} + + +/* Write character to IR_UART. This returns zero if + the character could not be written. */ +int8_t +ir_uart_putc (__unused__ char ch) +{ + return 0; +} + + +/* Write string to IR_UART. */ +void +ir_uart_puts (__unused__ const char *str) +{ +} + + +/* Initialise ir_uart and set baud rate. */ +uint8_t +ir_uart_init (void) +{ + return 0; +} diff --git a/drivers/test/ir_uart.h b/drivers/test/ir_uart.h new file mode 100644 index 0000000..fbb1b41 --- /dev/null +++ b/drivers/test/ir_uart.h @@ -0,0 +1,52 @@ +/** @file ir_uart.h + @author Michael Hayes + @date 10 December 2004 +*/ + +#ifndef IR_UART_H +#define IR_UART_H + +#include "system.h" + +#ifndef IR_UART_BAUD_RATE +#define IR_UART_BAUD_RATE 2400 +#endif + + +/* Return non-zero if there is a character ready to be read. */ +bool +ir_uart_read_ready_p (void); + + +/* Read character from IR_UART. This blocks if nothing + is available to read. */ +int8_t +ir_uart_getc (void); + + +/* Return non-zero if a character can be written without blocking. */ +bool +ir_uart_write_ready_p (void); + + +/* Return non-zero if transmitter finished. */ +bool +ir_uart_write_finished_p (void); + + +/* Write character to IR_UART. This returns zero if + the character could not be written. */ +int8_t +ir_uart_putc (char ch); + + +/* Write string to IR_UART. */ +void +ir_uart_puts (const char *str); + + +/* Initialise ir_uart and set baud rate. */ +uint8_t +ir_uart_init (void); + +#endif diff --git a/drivers/test/mgetkey.c b/drivers/test/mgetkey.c new file mode 100644 index 0000000..45e65e5 --- /dev/null +++ b/drivers/test/mgetkey.c @@ -0,0 +1,94 @@ +/** @file mgetkey.c + @author M. P. Hayes, UCECE + @date 17 July 2011 + @brief Non-blocking raw keyboard reading. +*/ + +#include +#include + +#include +#include +#include +#include + +#include "mgetkey.h" + +static struct termios tty_attr_save; +static int tty_init = 0; + + +/* Get the terminal attributes. */ +static int mgetkey_attr_get (struct termios *ptty_attr) +{ + if (tcgetattr (STDIN_FILENO, ptty_attr) == -1) + { + perror ("mgetkey: Cannot get tty attributes"); + return 0; + } + return 1; +} + + +/* Set terminal attributes ensuring that the original attributes are + saved. */ +static int mgetkey_attr_set (struct termios *ptty_attr) +{ + if (tcsetattr (STDIN_FILENO, TCSANOW, ptty_attr) == -1) + { + perror ("mgetkey: Cannot set tty attributes"); + return 0; + } + return 1; +} + + +int mgetkey_init (void) +{ + struct termios tty_attr; + + if (!tty_init) + { + if (!mgetkey_attr_get (&tty_attr_save)) + return 0; + + /* Restore terminal attributes on exit. */ + atexit (mgetkey_reset); + tty_init = 1; + } + + /* Get terminal attributes. */ + if (!mgetkey_attr_get (&tty_attr)) + return 0; + + tty_attr.c_lflag &= ~ECHO; /* No echo. */ + tty_attr.c_lflag &= ~ICANON; /* No canonical processing. */ + tty_attr.c_cc[VMIN] = 0; /* Don't block. */ + tty_attr.c_cc[VTIME] = 0; /* Don't block. */ + + /* Set terminal attributes. */ + return mgetkey_attr_set (&tty_attr); +} + + +/* Restore the terminal attributes. */ +void mgetkey_reset (void) +{ + mgetkey_attr_set (&tty_attr_save); +} + + +/* Read a single key stroke from the keyboard. This blocks until + a key is typed. Note that the key is not echoed. */ +int mgetkey (void) +{ + int key; + + if (!tty_init) + mgetkey_init (); + + key = getchar (); + if (key == -1) + key = 0; + return key; +} diff --git a/drivers/test/mgetkey.h b/drivers/test/mgetkey.h new file mode 100644 index 0000000..88e3299 --- /dev/null +++ b/drivers/test/mgetkey.h @@ -0,0 +1,19 @@ +/** @file mgetkey.h + @author M. P. Hayes, UCECE + @date 17 July 2011 + @brief Non-blocking raw keyboard reading. +*/ + +#ifndef MGETKEY_H +#define MGETKEY_H + +/* Read a single key stroke from the keyboard. If no key has been + pressed then zero is returned. Note that the key is not + echoed. */ +int mgetkey (void); + + +/* Restore terminal settings. */ +void mgetkey_reset (void); + +#endif diff --git a/drivers/test/pio.c b/drivers/test/pio.c new file mode 100644 index 0000000..f5d1115 --- /dev/null +++ b/drivers/test/pio.c @@ -0,0 +1,7 @@ +/** @file pio.c + @author M. P. Hayes, UCECE + @date 11 Jan 2006 + @brief PIO hardware abstraction for AVR microcontroller. + @note This implementation is empty; inline functions are used + in pio.h instead for performance. +*/ diff --git a/drivers/test/pio.h b/drivers/test/pio.h new file mode 100644 index 0000000..b9b2d63 --- /dev/null +++ b/drivers/test/pio.h @@ -0,0 +1,265 @@ +/** @file pio.h + @author M. P. Hayes, UCECE + @date 11 Jan 2006 + @brief PIO hardware abstraction for AVR microcontroller. + @note Macros and inline functions are used to avoid function + call overhead and to allow compile-time constant folding. + + @defgroup pio PIO driver + + This module implements a driver for general purpose I/O ports. + Its purpose is to provide a microcontroller independent + abstraction of a PIO pin. Here's an example: + + @code + #include "pio.h" + + #define LED_PIO PIO_DEFINE (PORT_B, 5) + + void main (void) + { + system_init (); + pio_config_set (LED_PIO, PIO_OUTPUT_LOW); + + pio_output_high (LED_PIO); + + while (1); + } + @endcode + + In this example, when port B5 is configured as an output it is set + low. +*/ +#ifndef PIO_H +#define PIO_H + +#include "system.h" +#include "avrtest.h" + + +/** Define port names, note not all the ports are available on some AVRs. */ + +#ifdef PORTA +#define PORT_A &PORTA +#endif + +#ifdef PORTB +#define PORT_B &PORTB +#endif + +#ifdef PORTC +#define PORT_C &PORTC +#endif + +#ifdef PORTD +#define PORT_D &PORTD +#endif + +#ifdef PORTE +#define PORT_E &PORTE +#endif + +#ifdef PORTF +#define PORT_F &PORTF +#endif + +#ifdef PORTG +#define PORT_G &PORTG +#endif + + +typedef volatile uint8_t *pio_port_t; +typedef uint8_t pio_mask_t; + + +typedef struct +{ + pio_port_t port; + pio_mask_t bitmask; +} pio_t; + + +/** Define PIO pin types. The two flavours of PIO_OUTPUT are to + ensure the port is configured without glitching due to the time + taken before calling pio_output_set. */ +typedef enum pio_config_enum +{ + PIO_INPUT = 1, /** Configure as input pin. */ + PIO_PULLUP, /** Configure as input pin with pullup. */ + PIO_OUTPUT_LOW, /** Configure as output, initially low. */ + PIO_OUTPUT_HIGH, /** Configure as output, initially high. */ +} pio_config_t; + + +/** DDR PORT Comment + 0 0 High impedance input + 0 1 Weak pullup input + 1 0 Output low + 1 1 Output high +*/ + + +/** Define a PIO as a compound literal structure in terms of a port and + a bitmask. */ +#define PIO_DEFINE(PORT, PORTBIT) (pio_t){.port = PORT, .bitmask = BIT (PORTBIT)} + + +/** Private macro to lookup bitmask. */ +#define PIO_BITMASK_(pio) (pio.bitmask) + + +/** Private macro to lookup port register. */ +#define PIO_PORT_(pio) (pio.port) + + +/** Private macro to map a pio to its corresponding data direction + register (DDR). NB, the DDR and PORT registers must be separated + by the same number of bytes in all cases. PORTB is used for the + pattern since PORTA is not always defined for some AVRs. */ +#define PIO_DDR_(pio) (*(PIO_PORT_ (pio) + (&DDRB - &PORTB))) + +/** Private macro to map a pio to its input register (PIN). NB, the + PIN and PORT registers must be separated by the same number of + bytes in all cases. PORTB is used for the pattern since PORTA is + not always defined for some AVRs. */ +#define PIO_PIN_(pio) (*(PIO_PORT_ (pio) + (&PINB - &PORTB))) + +/** Private macro to access a pio data register. */ +#define PIO_DATA_(pio) (*PIO_PORT_ (pio)) + + + +/** Configure pio. + @param pio PIO to configure + @param config PIO configuration type + @return non-zero for success. */ +static inline +bool pio_config_set (pio_t pio, pio_config_t config) +{ + switch (config) + { + case PIO_OUTPUT_LOW: + PIO_DATA_ (pio) &= ~PIO_BITMASK_ (pio); + PIO_DDR_ (pio) |= PIO_BITMASK_ (pio); + return 1; + + case PIO_OUTPUT_HIGH: + PIO_DATA_ (pio) |= PIO_BITMASK_ (pio); + PIO_DDR_ (pio) |= PIO_BITMASK_ (pio); + return 1; + + case PIO_INPUT: + PIO_DDR_ (pio) &= ~PIO_BITMASK_ (pio); + PIO_DATA_ (pio) &= ~PIO_BITMASK_ (pio); + return 1; + + case PIO_PULLUP: + PIO_DDR_ (pio) &= ~PIO_BITMASK_ (pio); + PIO_DATA_ (pio) |= PIO_BITMASK_ (pio); + return 1; + + default: + return 0; + } +} + + +/** Return pio configuration + @param pio + @return config */ +static inline +pio_config_t pio_config_get (pio_t pio) +{ + bool ddr; + bool port; + + ddr = PIO_DDR_ (pio) & PIO_BITMASK_ (pio); + port = PIO_DATA_ (pio) & PIO_BITMASK_ (pio); + + if (ddr) + { + if (port) + return PIO_OUTPUT_HIGH; + else + return PIO_OUTPUT_LOW; + } + + if (port) + return PIO_PULLUP; + + return PIO_INPUT; +} + + + +/** Set pio high. + @param pio */ +static inline +void pio_output_high (pio_t pio) +{ + PIO_DATA_ (pio) |= PIO_BITMASK_ (pio); +} + + +/** Set pio low. + @param pio */ +static inline +void pio_output_low (pio_t pio) +{ + PIO_DATA_ (pio) &= ~PIO_BITMASK_ (pio); +} + + +/** Toggle pio. + @param pio */ +static inline +void pio_output_toggle (pio_t pio) +{ + PIO_DATA_ (pio) ^= PIO_BITMASK_ (pio); +} + + +/** Read input state from pio. + @param pio + @return input state of pio */ +static inline +bool pio_input_get (pio_t pio) +{ + return (PIO_PIN_ (pio) & PIO_BITMASK_ (pio)) != 0; +} + + +/** Get output state of pio. + @param pio + @return output state of pio */ +static inline +bool pio_output_get (pio_t pio) +{ + return (PIO_DATA_ (pio) & PIO_BITMASK_ (pio)) != 0; +} + + +/** Set pio to desired state. + @param pio + @param state value to write pio */ +static inline +void pio_output_set (pio_t pio, bool state) +{ + state ? pio_output_high (pio) : pio_output_low (pio); +} + + +/** Set input state for pio (this is only for use by the test scaffold). + @param pio + @param state value for pio input */ +static inline +void pio_input_set (pio_t pio, bool state) +{ + if (state) + PIO_PIN_ (pio) |= PIO_BITMASK_ (pio); + else + PIO_PIN_ (pio) &= ~PIO_BITMASK_ (pio); +} + + +#endif diff --git a/drivers/test/system.c b/drivers/test/system.c new file mode 100644 index 0000000..c13f3c9 --- /dev/null +++ b/drivers/test/system.c @@ -0,0 +1,402 @@ +/** @file system.c + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief Test scaffold for UCFK4. +*/ + +#include "system.h" +#include "avrtest.h" +#include "pio.h" +#include "mgetkey.h" +#include +#include +#include +#include +#include + + +/** This needs to be at least 50 * 5 for a refresh rate of 50 Hz. */ +#define SYSTEM_UPDATE_RATE 400 + +#define SYSTEM_KEYBOARD_RELEASE_PERIOD 0.2 + +#define SYSTEM_DISPLAY_PERSISTENCE_PERIOD 0.01 + + +SFR_t SFR = {0, 0, ~0, 0, 0, ~0, 0, 0, ~0}; + + +/* Define PIO pins driving LED matrix rows and columns. */ +static const pio_t ledmat_rows[] = +{ + LEDMAT_ROW1_PIO, + LEDMAT_ROW2_PIO, + LEDMAT_ROW3_PIO, + LEDMAT_ROW4_PIO, + LEDMAT_ROW5_PIO, + LEDMAT_ROW6_PIO, + LEDMAT_ROW7_PIO +}; + +static const pio_t ledmat_cols[] = +{ + LEDMAT_COL1_PIO, + LEDMAT_COL2_PIO, + LEDMAT_COL3_PIO, + LEDMAT_COL4_PIO, + LEDMAT_COL5_PIO +}; + + +typedef enum {NAVSWITCH_NONE, NAVSWITCH_EAST, NAVSWITCH_SOUTH, + NAVSWITCH_WEST, NAVSWITCH_NORTH, NAVSWITCH_PUSH} system_navswitch_t; + +typedef enum {BUTTON_NONE, BUTTON_1} system_button_t; + + +static void system_display_update (void) +{ + int row; + int col; + /* Persistence time (s). */ + double tau = SYSTEM_DISPLAY_PERSISTENCE_PERIOD; + /* Sample period (s). */ + double delta_t; + /* Exponential filter parameter. */ + double alpha; + static uint8_t tdisplay[LEDMAT_ROWS_NUM][LEDMAT_COLS_NUM]; + + delta_t = 1.0 / SYSTEM_UPDATE_RATE; + alpha = tau / (tau + delta_t); + + for (row = 0; row < LEDMAT_ROWS_NUM; row++) + { + for (col = 0; col < LEDMAT_COLS_NUM; col++) + { + uint8_t on; + + /* Determine if pixel is on. */ + on = !pio_output_get (ledmat_rows[row]) + && !pio_output_get (ledmat_cols[col]); + + /* Apply exponential filter to provide some persistence. + This has an impulse response of exp(-t / tau) u(t). */ + tdisplay[row][col] = tdisplay[row][col] * alpha + (1 - alpha) * 100 * on; + + printf ("%c", tdisplay[row][col] > 1 ? '@' : '.'); + } + printf ("\n"); + } + printf ("\n"); + /* Move cursor up. */ + printf ("\e[%dA", LEDMAT_ROWS_NUM + 1); +} + + +static void system_navswitch_set (system_navswitch_t navswitch, bool state) +{ + switch (navswitch) + { + case NAVSWITCH_NONE: + break; + + case NAVSWITCH_NORTH: + pio_input_set (NAVSWITCH_NORTH_PIO, !state); + break; + + case NAVSWITCH_EAST: + pio_input_set (NAVSWITCH_EAST_PIO, !state); + break; + + case NAVSWITCH_SOUTH: + pio_input_set (NAVSWITCH_SOUTH_PIO, !state); + break; + + case NAVSWITCH_WEST: + pio_input_set (NAVSWITCH_WEST_PIO, !state); + break; + + case NAVSWITCH_PUSH: + pio_input_set (NAVSWITCH_PUSH_PIO, !state); + break; + } + +} + + +static void system_navswitch_press (system_navswitch_t navswitch) +{ + system_navswitch_set (navswitch, 1); +} + + +static void system_navswitch_release (system_navswitch_t navswitch) +{ + system_navswitch_set (navswitch, 0); +} + + +static void system_navswitch_select (system_navswitch_t navswitch) +{ + static system_navswitch_t last = NAVSWITCH_NONE; + static int counter; + + if (navswitch == NAVSWITCH_NONE) + { + if (counter) + { + counter--; + if (!counter) + { + system_navswitch_release (last); + last = NAVSWITCH_NONE; + } + } + return; + } + + counter = SYSTEM_UPDATE_RATE * SYSTEM_KEYBOARD_RELEASE_PERIOD; + + if (last == navswitch) + return; + + system_navswitch_release (last); + + last = navswitch; + + system_navswitch_press (navswitch); +} + + +static void system_button_set (system_button_t button, bool state) +{ + switch (button) + { + case BUTTON_NONE: + break; + + case BUTTON_1: + /* Active high. */ + pio_input_set (BUTTON1_PIO, state); + break; + } + +} + + +static void system_button_press (system_button_t button) +{ + system_button_set (button, 1); +} + + +static void system_button_release (system_button_t button) +{ + system_button_set (button, 0); +} + + +static void system_button_select (system_button_t button) +{ + static system_button_t last = BUTTON_NONE; + static int counter; + + if (button == BUTTON_NONE) + { + if (counter) + { + counter--; + if (!counter) + { + system_button_release (last); + last = BUTTON_NONE; + } + } + return; + } + + counter = SYSTEM_UPDATE_RATE * SYSTEM_KEYBOARD_RELEASE_PERIOD; + + if (last == button) + return; + + system_button_release (last); + + last = button; + + system_button_press (button); +} + + +static void system_keyboard_init (void) +{ + system_navswitch_release (NAVSWITCH_PUSH); + system_navswitch_release (NAVSWITCH_NORTH); + system_navswitch_release (NAVSWITCH_EAST); + system_navswitch_release (NAVSWITCH_SOUTH); + system_navswitch_release (NAVSWITCH_WEST); + + system_button_release (BUTTON_1); +} + + +static void system_keyboard_update (void) +{ + static int state = 0; + int key; + + system_navswitch_select (NAVSWITCH_NONE); + system_button_select (BUTTON_NONE); + + key = mgetkey (); + + switch (state) + { + case 0: + switch (key) + { + case '\e': + /* Have escape character. */ + state = 1; + break; + + case ' ': + system_navswitch_select (NAVSWITCH_PUSH); + break; + + case '.': + system_button_select (BUTTON_1); + break; + + default: + break; + } + break; + + case 1: + if (key == '[') + state = 2; + else + state = 0; + break; + + case 2: + state = 0; + switch (key) + { + case 'A': + system_navswitch_select (NAVSWITCH_NORTH); + break; + + case 'B': + system_navswitch_select (NAVSWITCH_SOUTH); + break; + + case 'C': + system_navswitch_select (NAVSWITCH_EAST); + break; + + case 'D': + system_navswitch_select (NAVSWITCH_WEST); + break; + + default: + break; + } + break; + } +} + + +static void system_update (void) +{ + system_display_update (); + system_keyboard_update (); +} + + +static void +system_handler (__unused__ int sig, __unused__ siginfo_t *si, + __unused__ void *uc) +{ + system_update (); +} + + +typedef void (*sighandler_t)(int, siginfo_t *, void *); + +static int system_interrupt_init (sighandler_t handler, int rate) +{ + timer_t timerid; + struct sigevent sev; + struct itimerspec its; + long long period_ns; + sigset_t mask; + struct sigaction sa; + static int signum = 0; + + /* When debugging with gdb use "handle SIG34 noprint". */ + + if (!signum) + signum = SIGRTMIN; + + /* Establish handler for timer signal. */ + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = handler; + sigemptyset (&sa.sa_mask); + if (sigaction (signum, &sa, NULL) == -1) + { + perror ("sigaction"); + exit (EXIT_FAILURE); + } + + /* Block timer signal temporarily. */ + sigemptyset (&mask); + sigaddset (&mask, signum); + if (sigprocmask (SIG_SETMASK, &mask, NULL) == -1) + { + perror ("sigprocmask"); + exit (EXIT_FAILURE); + } + + /* Create the timer. */ + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = signum; + sev.sigev_value.sival_ptr = &timerid; + if (timer_create (CLOCK_REALTIME, &sev, &timerid) == -1) + { + perror ("timer_create"); + exit (EXIT_FAILURE); + } + + /* Start the timer */ + period_ns = 1000000000 / rate; + its.it_value.tv_sec = period_ns / 1000000000; + its.it_value.tv_nsec = period_ns % 1000000000; + its.it_interval.tv_sec = its.it_value.tv_sec; + its.it_interval.tv_nsec = its.it_value.tv_nsec; + if (timer_settime (timerid, 0, &its, NULL) == -1) + { + perror ("timer_settime"); + exit (EXIT_FAILURE); + } + + /* Unlock the timer signal, so that timer notification + can be delivered. */ + if (sigprocmask (SIG_UNBLOCK, &mask, NULL) == -1) + { + perror ("sigprocmask"); + exit (EXIT_FAILURE); + } + + signum++; + return signum; +} + + +void system_init (void) +{ + system_keyboard_init (); + + system_interrupt_init (system_handler, SYSTEM_UPDATE_RATE); +} diff --git a/drivers/test/system.h b/drivers/test/system.h new file mode 100644 index 0000000..7afbebf --- /dev/null +++ b/drivers/test/system.h @@ -0,0 +1,74 @@ +/** @file system.h + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief System specific definitions +*/ +#ifndef SYSTEM_H +#define SYSTEM_H + +/* Data typedefs. */ +#include + +typedef uint8_t bool; + + +/* Useful macros. */ +#define BIT(X) (1 << (X)) + +#define ARRAY_SIZE(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0])) + +#define __unused__ __attribute__ ((unused)) + + +/* Clock frequency Hz. */ +#define F_CPU 8000000 + + +/* LED matrix columns. */ +#define LEDMAT_COL1_PIO PIO_DEFINE(PORT_C, 6) +#define LEDMAT_COL2_PIO PIO_DEFINE(PORT_B, 7) +#define LEDMAT_COL3_PIO PIO_DEFINE(PORT_C, 4) +#define LEDMAT_COL4_PIO PIO_DEFINE(PORT_C, 7) +#define LEDMAT_COL5_PIO PIO_DEFINE(PORT_C, 5) +#define LEDMAT_COLS_NUM 5 + + +/* LED matrix rows. */ +#define LEDMAT_ROW1_PIO PIO_DEFINE(PORT_B, 6) +#define LEDMAT_ROW2_PIO PIO_DEFINE(PORT_B, 5) +#define LEDMAT_ROW3_PIO PIO_DEFINE(PORT_B, 4) +#define LEDMAT_ROW4_PIO PIO_DEFINE(PORT_B, 3) +#define LEDMAT_ROW5_PIO PIO_DEFINE(PORT_B, 2) +#define LEDMAT_ROW6_PIO PIO_DEFINE(PORT_B, 1) +#define LEDMAT_ROW7_PIO PIO_DEFINE(PORT_B, 0) +#define LEDMAT_ROWS_NUM 7 + + +/* Button. */ +#define BUTTON1 0 +#define BUTTON1_PIO PIO_DEFINE(PORT_D, 7) + + +/* Navswitch. */ +#define NAVSWITCH_PUSH_PIO LEDMAT_COL3_PIO +#define NAVSWITCH_EAST_PIO LEDMAT_COL1_PIO +#define NAVSWITCH_WEST_PIO LEDMAT_COL2_PIO +#define NAVSWITCH_NORTH_PIO LEDMAT_COL4_PIO +#define NAVSWITCH_SOUTH_PIO LEDMAT_COL5_PIO + + +/* LED (active high). */ +#define LED1 0 +#define LED1_PIO PIO_DEFINE(PORT_C, 2) + + +/* Infrared transmitter LED and receiver. */ +#define IR_TX_LOW_PIO PIO_DEFINE(PORT_D, 3) +#define IR_TX_HIGH_PIO PIO_DEFINE(PORT_D, 0) +#define IR_RX_PIO PIO_DEFINE(PORT_D, 2) + +#define IR_MODULATION_FREQ 36e3 + +void system_init (void); + +#endif diff --git a/drivers/test/target.h b/drivers/test/target.h new file mode 100644 index 0000000..9646226 --- /dev/null +++ b/drivers/test/target.h @@ -0,0 +1,57 @@ +/** @file system.h + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief Target specific definitions +*/ +#ifndef TARGET_H +#define TARGET_H + +#define F_CPU 8000000 + + +/* LED matrix columns. */ +#define LEDMAT_COL1_PIO PIO_DEFINE(PORT_C, 5) +#define LEDMAT_COL2_PIO PIO_DEFINE(PORT_C, 7) +#define LEDMAT_COL3_PIO PIO_DEFINE(PORT_C, 4) +#define LEDMAT_COL4_PIO PIO_DEFINE(PORT_B, 7) +#define LEDMAT_COL5_PIO PIO_DEFINE(PORT_C, 6) +#define LEDMAT_COLS_NUM 5 + + +/* LED matrix rows. */ +#define LEDMAT_ROW1_PIO PIO_DEFINE(PORT_B, 0) +#define LEDMAT_ROW2_PIO PIO_DEFINE(PORT_B, 1) +#define LEDMAT_ROW3_PIO PIO_DEFINE(PORT_B, 2) +#define LEDMAT_ROW4_PIO PIO_DEFINE(PORT_B, 3) +#define LEDMAT_ROW5_PIO PIO_DEFINE(PORT_B, 4) +#define LEDMAT_ROW6_PIO PIO_DEFINE(PORT_B, 5) +#define LEDMAT_ROW7_PIO PIO_DEFINE(PORT_B, 6) +#define LEDMAT_ROWS_NUM 7 + + +/* Button. */ +#define BUTTON1 0 +#define BUTTON1_PIO PIO_DEFINE(PORT_D, 7) + + +/* Navswitch. */ +#define NAVSWITCH_PUSH_PIO LEDMAT_COL3_PIO +#define NAVSWITCH_EAST_PIO LEDMAT_COL1_PIO +#define NAVSWITCH_WEST_PIO LEDMAT_COL2_PIO +#define NAVSWITCH_NORTH_PIO LEDMAT_COL4_PIO +#define NAVSWITCH_SOUTH_PIO LEDMAT_COL5_PIO + + +/* LED (active high). */ +#define LED1 0 +#define LED1_PIO PIO_DEFINE(PORT_C, 2) + + +/* Infrared transmitter LED and receiver. */ +#define IR_TX_HIGH_PIO PIO_DEFINE(PORT_D, 3) +#define IR_TX_LOW_PIO PIO_DEFINE(PORT_D, 0) +#define IR_RX_PIO PIO_DEFINE(PORT_D, 2) + +#define IR_MODULATION_FREQ 36e3 + +#endif diff --git a/drivers/test/timer.c b/drivers/test/timer.c new file mode 100644 index 0000000..756312b --- /dev/null +++ b/drivers/test/timer.c @@ -0,0 +1,72 @@ +/** @file timer.c + @author M. P. Hayes, UCECE + @date 21 August 2007 + Description: Support for timer. +*/ +#include "timer.h" +#include "unistd.h" +#include "time.h" +#include "system.h" + +#include + +static timer_tick_t offset; + + +/* Initialise timer. */ +void timer_init (void) +{ + /* Save offset so timer starts around 0. */ + offset = timer_get (); +} + + +/** Get current time: + @return current time in ticks. */ +timer_tick_t timer_get (void) +{ + struct timespec time; + uint64_t time_us; + uint64_t ticks; + + clock_gettime (CLOCK_MONOTONIC, &time); + + time_us = time.tv_sec * 1000000 + time.tv_nsec / 1000; + ticks = time_us * TIMER_RATE / 1000000; + + return (timer_tick_t) ticks - offset; +} + + +/** Wait until specified time: + @param when time to sleep until + @return current time. */ +timer_tick_t timer_wait_until (timer_tick_t when) +{ + while (1) + { + timer_tick_t diff; + timer_tick_t now; + + now = timer_get (); + + diff = now - when; + + /* Allow for 1000 tick overrun. */ + if (diff < TIMER_OVERRUN_MAX) + return now; + + diff = when - now; + + usleep (diff * 1e6 / TIMER_RATE); + } +} + + +/** Wait for specified period: + @param period how long to wait + @return current time. */ +timer_tick_t timer_wait (timer_tick_t period) +{ + return timer_wait_until (timer_get () + period); +} diff --git a/drivers/test/timer.h b/drivers/test/timer.h new file mode 100644 index 0000000..b01c1ff --- /dev/null +++ b/drivers/test/timer.h @@ -0,0 +1,97 @@ +/** @file timer.h + @author M. P. Hayes, UCECE + @date 18 August 2011 + @brief Timer support. + + @defgroup timer Timer module + + This module provides simple timer support by abstracting a + hardware timer. + + The rate that the timer is incremented is specified by the + macro TIMER_CLOCK_DIVISOR in the header file system.h This + must be a value supported by the timer clock prescaler. + + The rate that the timer is incremented can be found using the + macro TIMER_RATE. + + The timer is free-running and will increment TIMER_RATE times + per second. When the timer reaches 65535 on the next increment + it rolls over to 0. + + Here's a simple example for turning an LED on for 0.5 second + and then off for 0.75 second. + + @code + #include "timer.h" + #include "led.h" + + void main (void) + { + timer_tick_t now; + + system_init (); + timer_init (); + led_init (); + + now = timer_get (); + while (1) + { + led_set (LED1, 1); + + now = timer_wait_until (now + (timer_tick_t)(TIMER_RATE * 0.5)); + + led_set (LED1, 0); + + now = timer_wait_until (now + (timer_tick_t)(TIMER_RATE * 0.75)); + } + } + @endcode +*/ +#ifndef TIMER_H +#define TIMER_H + +#include "system.h" + + +#ifndef TIMER_CLOCK_DIVISOR +#define TIMER_CLOCK_DIVISOR 256 +#endif + +/** Rate in Hz that the timer is incremented. */ +#define TIMER_RATE (F_CPU / TIMER_CLOCK_DIVISOR) + + +/** The maximum overrun (in ticks). */ +#define TIMER_OVERRUN_MAX 1000 + + +/** The maximum delay (in ticks). */ +#define TIMER_DELAY_MAX (65536u - TIMER_OVERRUN_MAX) + + +/** Define timer ticks. */ +typedef uint16_t timer_tick_t; + + +/** Get current time: + @return current time in ticks. */ +timer_tick_t timer_get (void); + + +/** Wait until specified time: + @param when time to sleep until + @return current time. */ +timer_tick_t timer_wait_until (timer_tick_t when); + + +/** Wait for specified period: + @param period how long to wait + @return current time. */ +timer_tick_t timer_wait (timer_tick_t period); + + +/** Initialise timer. */ +void timer_init (void); + +#endif /* TIMER_H */ diff --git a/etc/Makefile b/etc/Makefile new file mode 100644 index 0000000..c3f42aa --- /dev/null +++ b/etc/Makefile @@ -0,0 +1,102 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile to create application Makefiles from a template. + +# Abandon all hope ye who look in here. +# This Makefile builds all the application Makefiles +# using template Makefiles and a python script makemake.py that parses +# the applications looking for #includes. + +APPS = $(filter-out ../apps/README, $(wildcard ../apps/*)) + +MAKEAPPS = $(addsuffix .apps, $(APPS)) +MAKETEST = $(addsuffix .test, $(APPS)) +CLEANAPPS = $(addsuffix .cleanapps, $(APPS)) +CLEANTEST = $(addsuffix .cleantest, $(APPS)) + +TESTMAKEFILES = $(addsuffix /Makefile.test, $(APPS)) +APPMAKEFILES = $(addsuffix /Makefile, $(APPS)) + +APPFILEDEPS = $(addsuffix /file_dependencies.pdf, $(APPS)) +APPMODULEDEPS = $(addsuffix /module_dependencies.pdf, $(APPS)) +APPMAKEFILEDEPS = $(addsuffix /makefile_dependencies.pdf, $(APPS)) +APPBUILDDEPS = $(addsuffix /build_dependencies.pdf, $(APPS)) +APPCALLGRAPHDDEPS = $(addsuffix /callgraph.pdf, $(APPS)) + +all: testmakefiles appmakefiles apps test appfiledeps appmoduledeps appmakefiledeps appbuilddeps appcallgraph + +clean: cleanapps cleantest + +testmakefiles: $(TESTMAKEFILES) + +appmakefiles: $(APPMAKEFILES) + +../%/Makefile.test: Makefile.test.template Makefile + (cd $(dir $@); ../../etc/makemake.py --relpath --objext=-test.o --template ../../etc/Makefile.test.template . . ../../utils ../../drivers ../../drivers/test > Makefile.test) + + +../%/Makefile: Makefile.template Makefile makemake.py + (cd $(dir $@); ../../etc/makemake.py --relpath --template ../../etc/Makefile.template . . ../../utils ../../fonts ../../drivers ../../drivers/avr > Makefile) + + +appfiledeps: $(APPFILEDEPS) +appmoduledeps: $(APPMODULEDEPS) +appmakefiledeps: $(APPMAKEFILEDEPS) +appbuilddeps: $(APPBUILDDEPS) +appcallgraph: $(APPCALLGRAPH) + +../%/file_dependencies.pdf: ../%/files.d + ./graphdeps.py $< --out $@ + +../%/module_dependencies.pdf: ../%/modules.d + ./graphdeps.py $< --modules --out $@ + +../%/makefile_dependencies.pdf: ../%/Makefile + ./graphdeps.py $< --out $@ + +../%/build_dependencies.pdf: ../%/Makefile + ./graphdeps.py $< --out $@ --showops + +../%/callgraph.pdf: ../%/callgraph.d + (cd $(dir $@); ../../etc/graphdeps.py $(notdir $<) --out $(notdir $@)) + +../%/files.d: ../%/Makefile + (cd $(dir $@); ../../etc/makemake.py --relpath --files . . ../../drivers ../../drivers/avr ../../utils --exclude system.h > files.d) + + +../%/modules.d: ../%/Makefile + (cd $(dir $@); ../../etc/makemake.py --relpath --modules . . ../../drivers ../../drivers/avr ../../utils --exclude system > modules.d) + +../%/callgraph.d: ../%/Makefile + (cd $(dir $@); ../../etc/makemake.py --relpath --calls . . ../../drivers ../../drivers/avr ../../utils --exclude system > callgraph.d) + + +# Compile all the applications. +apps: $(MAKEAPPS) + +.PHONY: $(MAKEAPPS) +$(MAKEAPPS): + -@$(MAKE) -C $(subst .apps,,$@) + +# Compile all the test applications. +test: $(MAKETEST) + +.PHONY: $(MAKETEST) +$(MAKETEST): + -@$(MAKE) -f Makefile.test -C $(subst .test,,$@) + +# Clean all the applications. +cleanapps: $(CLEANAPPS) + +.PHONY: $(CLEANAPPS) +$(CLEANAPPS): + -@$(MAKE) -C $(subst .cleanapps,,$@) clean + +# Clean all the test applications. +cleantest: $(CLEANTEST) + +.PHONY: $(CLEANTEST) +$(CLEANTEST): + -@$(MAKE) -f Makefile.test -C $(subst .cleantest,,$@) clean + diff --git a/etc/Makefile.template b/etc/Makefile.template new file mode 100644 index 0000000..4fa959c --- /dev/null +++ b/etc/Makefile.template @@ -0,0 +1,38 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 12 Sep 2010 +# Descr: Makefile for @PROJECT@ + +# Definitions. +CC = avr-gcc +CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g @INCLUDES@ +OBJCOPY = avr-objcopy +SIZE = avr-size +DEL = rm + + +# Default target. +all: @PROJECT@.out + + +# Compile: create object files from C source files. +@CCRULES@ + +# Link: create ELF output file from object files. +@PROJECT@.out: @OBJ@ + $(CC) $(CFLAGS) $^ -o $@ -lm + $(SIZE) $@ + + +# Target: clean project. +.PHONY: clean +clean: + -$(DEL) *.o *.out *.hex + + +# Target: program project. +.PHONY: program +program: @PROJECT@.out + $(OBJCOPY) -O ihex @PROJECT@.out @PROJECT@.hex + dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash @PROJECT@.hex; dfu-programmer atmega32u2 start + diff --git a/etc/Makefile.test.template b/etc/Makefile.test.template new file mode 100644 index 0000000..9985704 --- /dev/null +++ b/etc/Makefile.test.template @@ -0,0 +1,30 @@ +# File: Makefile +# Author: M. P. Hayes, UCECE +# Date: 11 Sep 2010 +# Descr: Makefile for @PROJECT@ + +CC = gcc +CFLAGS = -Wall -Wstrict-prototypes -Wextra -g @INCLUDES@ + +DEL = rm + + +# Default target. +all: @PROJECT@ + + +# Compile: create object files from C source files. +@CCRULES@ + + +# Link: create executable file from object files. +@PROJECT@: @OBJ@ + $(CC) $(CFLAGS) $^ -o $@ -lrt + + +# Clean: delete derived files. +.PHONY: clean +clean: + -$(DEL) @PROJECT@ @OBJ@ + + diff --git a/etc/README b/etc/README new file mode 100644 index 0000000..087a55f --- /dev/null +++ b/etc/README @@ -0,0 +1,2 @@ +This is used for creating all the makefiles for compiling all the +applications. Beware all ye who enter here! diff --git a/etc/graphdeps.py b/etc/graphdeps.py new file mode 100755 index 0000000..475efe7 --- /dev/null +++ b/etc/graphdeps.py @@ -0,0 +1,213 @@ +#!/usr/bin/python +"""graphdeps V0.04 +Copyright (c) 2011 Michael P. Hayes, UC ECE, NZ + +Usage: graphdeps Makefile + +Options: + --outfile filename filename of .dot outputfile + +Examples: +""" + +# This is a quick and dirty program. It should be rewritten in +# an object-oriented manner. + +import sys +import os +import re +from optparse import OptionParser + + +def parse_rules (filename): + + infile = open (filename, 'r') + + text = infile.read () + infile.close () + + # Look for targets ignoring targets starting with dot (.PHONY, etc). + # This expects the command to be a single line. + matches = re.findall (r'^([a-z0-9._/\-]*):\s(.*)\n(.*)', text, re.MULTILINE) + + rules = [] + for match in matches: + # Target, dependencies, command. + rule = (match[0], match[1].strip().split (' '), match[2].strip ()) + rules.append (rule) + + return rules + + +def node_output (dotfile, name, options): + + # Should check if creating a duplicate although graphviz will + # weed them out. + + (file, ext) = os.path.splitext (name) + + cmap = {'.c' : 'green', + '.h' : 'skyblue', + '.o' : 'orange', + '.out' : 'red'} + + colour = 'purple' + if ext in cmap.keys (): + colour = cmap[ext] + + shape = 'ellipse' + if options.modules: + # Maybe magenta + colour = 'orange' + shape = 'rectangle' + + dotfile.write ('\t"' + name + '"\t [style=filled,shape=' + shape + ',color=' + colour + '];\n') + + return name + + +def op_output (dotfile, op, name): + + dotfile.write ('\t"' + op + '"\t[shape=rectangle,label="' + name + '"];\n') + + +def edge_output (dotfile, target, dep): + +# dotfile.write ('\t"' + target + '" ->\t"' + dep + '"\t[dir=back];\n') + dotfile.write ('\t"' + target + '" ->\t"' + dep + '";\n') + + +def dep_output (dotfile, target, dep, modules, options): + + if not options.fullpaths: + target = os.path.basename (target) + dep = os.path.basename (dep) + + target = node_output (dotfile, target, options) + + if dep == '': + return + + dep = node_output (dotfile, dep, options) + + (file, ext) = os.path.splitext (target) + + if not options.showops: + edge_output (dotfile, target, dep) + else: + if ext == '.o': + op = 'Compiler' + elif ext == '.out': + op = 'Linker' + elif ext == '.hex': + op = 'Objcopy' + else: + op = '' + + if op == '': + edge_output (dotfile, target, dep) + else: + op_output (dotfile, op + target, op) + edge_output (dotfile, target, op + target) + edge_output (dotfile, op + target, dep) + + +def target_output (dotfile, target, targets, modules, options, seen = {}): + + if not target or seen.has_key (target): + return + + deps = targets[target] + + for dep in deps: + if targets.has_key (dep): + target_output (dotfile, dep, targets, modules, options, seen) + + for dep in deps: + dep_output (dotfile, target, dep, modules, options) + + + +def main(argv = None): + if argv is None: + argv = sys.argv + + version = __doc__.split ('\n')[0] + + parser = OptionParser (usage = '%prog', version = version, + description = __doc__) + + parser.add_option('--showops', action = 'store_true', + dest = 'showops', default = False, + help = 'show operations') + + parser.add_option('--modules', action = 'store_true', + dest = 'modules', default = False, + help = 'show module dependencies') + + parser.add_option('--fullpaths', action = 'store_true', + dest = 'fullpaths', default = False, + help = 'show full paths') + + parser.add_option('--outfile', dest = 'outfilename', + default = 'graphdeps.dot', + help = 'output filename') + + parser.add_option('--target', dest = 'target', + default = None, + help = 'target to start from; if unspecified all targets are displayed') + + (options, args) = parser.parse_args () + + rules = parse_rules (args[0]) + + cfiles = [] + hfiles = [] + for rule in rules: + target = rule[0] + (file, ext) = os.path.splitext (os.path.basename (target)) + if ext == '.o': + cfiles.append (file + '.c') + for dep in rule[1]: + (file, ext) = os.path.splitext (os.path.basename (dep)) + if ext == '.h': + hfiles.append (file + '.h') + + modules = [] + for cfile in cfiles: + (modname, ext) = os.path.splitext (cfile) + hfile = modname + '.h' + if hfile in hfiles and modname not in modules: + modules.append (modname) + + targets = {} + wantedtargets = [] + for rule in rules: + target = rule[0] + targets[target] = rule[1] + if options.target == None or target == options.target: + wantedtargets.append (target) + + dopdf = options.outfilename[-4:] == '.pdf' + dotfilename = options.outfilename + if dopdf: + dotfilename = '/tmp/tmp.dot' + + dotfile = open (dotfilename, 'w') + dotfile.write ('strict digraph {\n\tgraph [rankdir=LR];\n') + + for target in wantedtargets: + target_output (dotfile, target, targets, modules, options) + + dotfile.write ('}\n') + dotfile.close () + + print ('Creating outfile ' + options.outfilename) + + if dopdf: + os.system ('dot -T pdf -o ' + options.outfilename + ' ' + dotfilename) + os.system ('rm ' + dotfilename) + + +if __name__ == '__main__': + main() diff --git a/etc/makemake.py b/etc/makemake.py new file mode 100755 index 0000000..1e10a87 --- /dev/null +++ b/etc/makemake.py @@ -0,0 +1,481 @@ +#!/usr/bin/env python +"""makemake V0.03 +Copyright (c) 2010 Michael P. Hayes, UC ECE, NZ + +This program tries to make a Makefile from a template. Given a C file +(or a directory which searched to find a C file containing a main +function) the included header files are recursively searched. The for +each header file, a search is made for a similarly named C file. The +header files for each C file are recursively searched and addded to +the list of found header files. Again, similarly named C files are +searched until all the C files required for the program are found. + +Usage: makemake --template template cfile search-dirs +or makemake --template template directory search-dirs +or makemake --builddir builddir --objext objext --template template directory search-dirs +or makemake --builddir builddir --modules --relpath directory search-dirs +or makemake --builddir builddir --files --relpath directory search-dirs + +By default makemake will create a rule like foo.o: foo.c bar.h +and this will require a VPATH if the dependencies are another directory. +Alternatively, use the --relpath option to makemake to explicitly add the +relative path to the dependencies. + +Note, this will die if there are circular dependencies. FIXME! +The --modules option also needs fixing. FIXME! + +There are special strings that are replaced in the template file: + @PROJECT@ Project name + @VPATH@ List of source directories + @INCLUDES@ List of include directories each prefixed by -I + @SRC@ List of source files + @OBJ@ List of object files + @CCRULES@ Rules to build object files from C files + +""" + +# See http://www.amk.ca/python/howto/regex/ for regular expressions in python. +# See also sre.py. +# + one or more, ? 0 or 1, * 0 or more + +# http://www.cs.umd.edu/~nspring/software/style-check-readme.html + +import sys +import getopt +import re +import os +import subprocess +from os import pathsep +import os.path + + +def unique (list): + + dict = {} + for item in list: + dict[item] = True; + + return dict.keys () + + +def file_search (filename, search_path, debug): + """Given a search path, find file + """ + + file_found = False + paths = search_path.split (pathsep) + for path in paths: + if os.path.exists (os.path.join (path, filename)): + file_found = True + break + + if file_found: + return os.path.abspath (os.path.join (path, filename)) + + # FIXME, if have :: at end of search path then need to search subdirs. + + return None + + +def hfiles_get (cfile, filedeps, mopts): + + deps = filedeps[cfile] + + if cfile in deps: + print >> sys.stderr, 'Circular dependency for', cfile + + + hfilelist = [] + + for hfile in filedeps[cfile]: + if hfile[-2:] == '.h': + if mopts['relpath']: + hfile = os.path.relpath (hfile) + hfilelist.append (hfile) + + for hfile in filedeps[cfile]: + hfilelist.extend (hfiles_get (hfile, filedeps, mopts)) + + return unique (hfilelist) + + +def cfiles_get (filedeps): + + cfilelist = [] + for target in filedeps: + if target[-2:] == '.c': + cfilelist.append (target) + + return unique (cfilelist) + + +def file_parse (pathname, indent, debug): + + if debug: + print >> sys.stderr, indent, 'Parsing file', pathname + + file = open (pathname, 'r') + text = file.read () + file.close () + + prog = re.compile (r'^#include[ ].*["<]([a-zA-Z_.0-9].*)[">]', re.MULTILINE) + + hfilelist = prog.findall (text, 0) + + if debug: + print >> sys.stderr, indent, 'Found hfiles', hfilelist, 'in', pathname + return hfilelist + + +def makefile_print (mopts, template, maincfilename, filedeps, + search_list, debug): + + basecfilelist = [] + cfilelist = [] + for target in filedeps: + if target[-2:] == '.c': + cfilelist.append (target) + basecfilelist.append (os.path.basename (target)) + basecfilelist.sort () + cfilelist.sort () + + project = os.path.splitext (os.path.basename (maincfilename)) + project = project[0] + + file = open (template, 'r') + + text = file.read () + file.close () + + vpath = ' '.join (search_list) + includes = '-I' + ' -I'.join (search_list) + src = ' '.join (basecfilelist) + obj = src + + if mopts['builddir'] != '': + objfilelist = [os.path.join (mopts['builddir'], obj1) for obj1 in basecfilelist] + objfilelist.sort () + obj = ' '.join (objfilelist) + project = os.path.join (mopts['builddir'], project) + + obj = re.sub (r'([a-zA-Z0-9/.-_]*)[.]c', r'\1' + mopts['objext'], obj) + + text = re.sub (r'@PROJECT@', project, text) + text = re.sub (r'@VPATH@', vpath, text) + text = re.sub (r'@INCLUDES@', includes, text) + text = re.sub (r'@SRC@', src, text) + + text = re.sub (r'@OBJ@', obj, text) + + if re.search (r'@CCRULES@', text) != None: + + search_path = pathsep.join (search_list) + + rules = '' + for cfile in cfilelist: + cfilebase = os.path.basename (cfile) + + if mopts['relpath']: + cfile1 = os.path.relpath (cfile) + else: + cfile1 = cfilebase + + if mopts['builddir'] != '': + rules = rules + os.path.join (mopts['builddir'], '') + + rules = rules + re.sub ('([a-zA-Z0-9/.-_]*)[.]c', r'\1' + mopts['objext'], cfilebase) + ': ' + cfile1 + + + hfilelist = hfiles_get (cfile, filedeps, mopts) + hfilelist.sort () + + if debug: + print >> sys.stderr, 'Need hfiles', hfilelist, 'for', cfile + + for hfile in hfilelist: + rules = rules + ' ' + hfile + + rules = rules + '\n' + rules = rules + '\t$(CC) -c $(CFLAGS) $< -o $@\n\n' + + text = re.sub (r'@CCRULES@', rules, text) + + + print text + + +def maincfilename_find (dirname): + + p = subprocess.Popen (['grep -l "main[ ]*(" ' + dirname + '/*.c'], + shell = True, stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + close_fds = True) + + (child_stdout, child_stdin) = (p.stdout, p.stdin) + child_stdin.close () + files = child_stdout.read () + child_stdout.close () + + filelist = files.strip ().split (' ') + if not filelist: + return None + + # What if there are multiple files with main? For now, select the + # first one. + return filelist[0] + + +def functions_find (gcc, filepath, functiondeps = {}): + + command = gcc + ' -c ' + filepath + ' -fdump-tree-cfg-raw > /dev/null' + # print >> sys.stderr, command + os.system (command) + + rtlfilename = os.path.abspath (os.path.basename (filepath)) + '.012t.cfg' + # print >> sys.stderr, rtlfilename + + file = open (rtlfilename, 'r') + text = file.readlines () + file.close () + + func_def = None + for line in text: + #print >> sys.stderr, line + matches = re.findall (r'^(.*)\s[(][)]', line) + if matches: + function = matches[0] + functiondeps[function] = [] + # print >> sys.stderr, 'DEF', function + matches = re.findall (r'.*gimple_call [<]([\w]*)[,]', line) + if matches: + # print >> sys.stderr, 'USE', matches[0] + functiondeps[function].append (matches[0]) + + command = 'rm ' + rtlfilename + # print >> sys.stderr, command + os.system (command) + + +def files_find (gcc, filepath, search_path, filedeps, moduledeps, functiondeps, indent, debug): + + # filedeps is a cache of all known included files + + if filedeps.has_key (filepath): + return + + # Find included header files + includes = file_parse (filepath, indent + ' ', debug) + includes2 = [] + + for hfile in includes: + hpath = file_search (hfile, search_path, debug) + if not hpath: + continue + includes2.append (hpath) + + # Guess modules from header files + modules = [] + for hpath in includes2: + cpath = re.sub (r'([a-zA-Z._0-9/.-_].*)[.]h', r'\1.c', hpath); + if (not os.path.exists (cpath)) or (cpath == filepath): + continue + # Have found a module + modules.append (cpath) + + base, ext = os.path.splitext (os.path.basename (filepath)) + if ext == '.c': + + functions_find (gcc, filepath, functiondeps) + + moduledeps[base] = [] + for module in modules: + modbase, ext = os.path.splitext (os.path.basename (module)) + moduledeps[base].append (modbase) + + filedeps[filepath] = includes2 + + # Search recursively each new included file + for file in includes2: + files_find (gcc, file, search_path, filedeps, moduledeps, functiondeps, indent + ' ', debug) + + # Search the modules + for file in modules: + files_find (gcc, file, search_path, filedeps, moduledeps, functiondeps, indent + ' ', debug) + + +def alldeps_print (depsdir, mopts): + + for target in depsdir.keys (): + + targetbase = os.path.basename (target) + if targetbase in mopts['exclude']: + continue + + deps = depsdir[target] + deps = [dep for dep in deps if os.path.basename (dep) not in mopts['exclude']] + if mopts['relpath']: + deps = [os.path.relpath (dep) for dep in deps] + + print os.path.relpath (target) + ': ' + ' '.join (deps) + '\n' + + +def deps_print (target, depsdir, mopts, record = {}): + + if record.has_key (target): + return + + deps = depsdir[target] + deps = [dep for dep in deps if os.path.basename (dep) not in mopts['exclude']] + for dep in deps: + deps_print (dep, depsdir, mopts, record) + + if mopts['relpath']: + deps = [os.path.relpath (dep) for dep in deps] + + record[target] = True + + print os.path.relpath (target) + ': ' + ' '.join (deps) + '\n' + + + +class Usage (Exception): + def __init__(self, msg): + self.msg = msg + + +def main(argv = None): + if argv is None: + argv = sys.argv + try: + try: + opts, args = getopt.gnu_getopt (argv[1:], "?h", \ + ["help", "builddir=", "objext=", + "exeext=", + "relpath", "debug", "template=", + "files", "modules", "exclude=", + "calls"]) + except getopt.error, msg: + raise Usage (msg) + + if not opts and not args: + print __doc__ + sys.exit (0) + + if len (args) < 1: + print __doc__ + sys.exit (0) + + mopts = {} + mopts['builddir'] = '' + mopts['objext'] = '.o' + mopts['exeext'] = '.out' + mopts['relpath'] = False + mopts['template'] = None + mopts['files'] = False + mopts['modules'] = False + mopts['calls'] = False + mopts['exclude'] = [] + debug = False + + # Process options + for o, a in opts: + if o in ("-?", "-h", "--help"): + print __doc__ + sys.exit (0) + elif o == "--builddir": + mopts['builddir'] = a + elif o == "--objext": + mopts['objext'] = a + elif o == "--exeext": + mopts['exeext'] = a + elif o == "--relpath": + mopts['relpath'] = True + elif o == "--debug": + debug = True + elif o == "--template": + mopts['template'] = a + elif o == "--files": + mopts['files'] = True + elif o == "--modules": + mopts['modules'] = True + elif o == "--calls": + mopts['calls'] = True + elif o == "--exclude": + mopts['exclude'] = a.split (' ') + + maincfilename = args[0] + + search_list = [] + if len (args) > 1: + search_list.extend (args[1:len (args)]) + + if debug: + print >> sys.stderr, search_list + search_path = pathsep.join (search_list) + if debug: + print >> sys.stderr, 'template', mopts['template'] + print >> sys.stderr, 'cfile', maincfilename + print >> sys.stderr, 'search_path', search_path + print >> sys.stderr, 'CWD = ', os.getcwd() + + if os.path.isdir (maincfilename): + if debug: + print >> sys.stderr, 'Searching ' + maincfilename + maincfilename = maincfilename_find (maincfilename) + if not maincfilename: + sys.exit (1) + + if debug: + print >> sys.stderr, 'Found C file ' + maincfilename + + includes = '-I' + ' -I'.join (search_list) + cflags = '-mmcu=atmega32u2' + opts = '-Os' + gcc = 'avr-gcc' + ' ' + cflags + ' ' + opts + ' ' + includes + + # Search main c file looking for header files included with #include + # and any header files included by the header files + + filedeps = {} + moduledeps = {} + functiondeps = {} + files_find (gcc, maincfilename, search_path, filedeps, moduledeps, functiondeps, '', debug) + + cfilelist = cfiles_get (filedeps) + ofilelist = [cfile[:-2] + mopts['objext'] for cfile in cfilelist] + outfile = maincfilename[:-2] + mopts['exeext'] + filedeps[outfile] = ofilelist + for ofile in ofilelist: + deps = [] + deps.append (ofile[:-2] + '.c') + filedeps[ofile] = deps + + # print >> sys.stderr, moduledeps + # print >> sys.stderr, filedeps + + if mopts['calls']: + deps_print ('main', functiondeps, mopts) + + if mopts['files']: + deps_print (outfile, filedeps, mopts) + + if mopts['modules']: + target, ext = os.path.splitext (os.path.basename (maincfilename)) + deps_print (target, moduledeps, mopts) + + if mopts['template']: + makefile_print (mopts, mopts['template'], maincfilename, filedeps, + search_list, debug) + + return 0 + + + except Usage, err: + print >> sys.stderr, err.msg + print >> sys.stderr, "for help use --help" + return 2 + + +if __name__ == "__main__": + sys.exit (main()) + diff --git a/fonts/Makefile b/fonts/Makefile new file mode 100644 index 0000000..901cf11 --- /dev/null +++ b/fonts/Makefile @@ -0,0 +1,18 @@ +CC = gcc +CFLAGS = -O2 -Wall -W -g + +FONTDEFS = $(wildcard *.txt) +FONTS = $(FONTDEFS:.txt=.h) + + +all: fontgen $(FONTS) + + +%.h: %.txt fontgen + ./fontgen $(@:.h=) < $^ > $@ + +fontgen: fontgen.c + $(CC) $(CFLAGS) $< -o $@ + +clean: + -rm *.o fontgen diff --git a/fonts/README b/fonts/README new file mode 100644 index 0000000..61b3933 --- /dev/null +++ b/fonts/README @@ -0,0 +1,123 @@ +To create a new font, edit a font definition file with text editor. +Then run make. This will run fontgen to create a corresponding .h +file that can be included in a program. + +Here's an example format for a font definition file. The first line +is a comment, the second line defines the width of each font +character, and the third light defines the height of each font +character. The following lines describe the font characters. The +. characters indicate an off pixel and other characters (such as @ or +#) indicate an on pixel. The first character is the corresponding +ASCII symbol. + +The font does not need to be contiguous. Empty entries will be +displayed as blanks. However, they will take up memory. + +# This is a demo font with only 3 characters. +width=5 +height=7 + +..... +..... +..... +..... +..... +..... +..... +! +.@@.. +.@@.. +.@@.. +.@@.. +.@@.. +..... +.@@.. +" +.@.@. +.@.@. +.@.@. +..... +..... +..... +..... + + +The font entries with indices below 32 can be specified using \nnn +where nnn is the octal representation for the desired index. For +example, here are three faces assigned to indices 1, 2, 3. Note, +index 0 cannot be used since this marks the end of a string. + +# Here's a demo font of three faces. +width=5 +height=7 +\001 +.@.@. +.@.@. +.@.@. +..... +..... +@...@ +.@@@. +\002 +..... +@@.@@ +@@.@@ +..... +..@.. +@...@ +.@@@. +\003 +..... +@@.@@ +@@.@@ +..... +..@.. +.@@@. +@...@ + +The tricky bit is representing these codes in C. You have to do +something like tinygl_text ("\001\002\003"); An alternative, is to +assign these to printable characters. For example, + +# Here's a demo font of three faces. +width=5 +height=7 +A +.@.@. +.@.@. +.@.@. +..... +..... +@...@ +.@@@. +B +..... +@@.@@ +@@.@@ +..... +..@.. +@...@ +.@@@. +C +..... +@@.@@ +@@.@@ +..... +..@.. +.@@@. +@...@ + +Then you can display them with tinygl_text ("ABC"); Unfortunately, the +font cannot display ABC as well. One solution is to load multiple +fonts and switch between them. + +#include "faces5x7.h" +#include "font5x7_1.h" + +tinygl_font_set (&faces5x7); +tinygl_text ("ABC"); + +tinygl_font_set (&font5x7_1); +tinygl_text ("ABC"); + +However, only one font can be active at a time. diff --git a/fonts/font3x5_1.h b/fonts/font3x5_1.h new file mode 100644 index 0000000..f2bc59a --- /dev/null +++ b/fonts/font3x5_1.h @@ -0,0 +1,162 @@ +/** @file font3x5_1.h + @author fontgen + @date 28 Sep 2010 + + @defgroup font3x5_1 This is a tiny 3x5 font with uppercase, digits, and symbols only. + M.P. Hayes 2 Sep 2010 + +*/ + +#ifndef FONT3X5_1_H_ +#define FONT3X5_1_H_ + +#define FONT3X5_1_WIDTH 3 +#define FONT3X5_1_HEIGHT 5 +#define FONT3X5_1_OFFSET 32 +#define FONT3X5_1_SIZE 59 + +#ifndef FONT_WIDTH +#define FONT_WIDTH 3 +#endif +#ifndef FONT_HEIGHT +#define FONT_HEIGHT 5 +#endif +#ifndef FONT_OFFSET +#define FONT_OFFSET 32 +#endif +#ifndef FONT_SIZE_MAX +#define FONT_SIZE_MAX 59 +#endif +#include "font.h" + +static font_t font3x5_1 = +{ + .flags = 1, /* (packed) */ + .width = 3, + .height = 5, + .offset = 32, + .size = 59, + .bytes = 2, + .data = + { + /* */ + 0x00, 0x00, + /* ! */ + 0x92, 0x20, + /* " */ + 0xeb, 0x73, + /* # */ + 0x7d, 0x5f, + /* $ */ + 0xde, 0x3d, + /* % */ + 0xa5, 0x52, + /* & */ + 0xea, 0x7a, + /* ' */ + 0x14, 0x00, + /* ( */ + 0x4a, 0x22, + /* ) */ + 0x22, 0x29, + /* * */ + 0xba, 0x2e, + /* + */ + 0xd0, 0x05, + /* , */ + 0x00, 0x14, + /* - */ + 0xc0, 0x01, + /* . */ + 0x00, 0x20, + /* / */ + 0xa4, 0x12, + /* 0 */ + 0x6a, 0x2b, + /* 1 */ + 0x9a, 0x74, + /* 2 */ + 0xa3, 0x72, + /* 3 */ + 0xa3, 0x38, + /* 4 */ + 0xed, 0x49, + /* 5 */ + 0x8f, 0x38, + /* 6 */ + 0xce, 0x2a, + /* 7 */ + 0xa7, 0x12, + /* 8 */ + 0xaa, 0x2a, + /* 9 */ + 0xae, 0x49, + /* : */ + 0x10, 0x04, + /* ; */ + 0x10, 0x14, + /* < */ + 0x54, 0x44, + /* = */ + 0x38, 0x0e, + /* > */ + 0x11, 0x15, + /* ? */ + 0x2a, 0x25, + /* @ */ + 0x00, 0x00, + /* A */ + 0xea, 0x5b, + /* B */ + 0xeb, 0x3a, + /* C */ + 0x4f, 0x72, + /* D */ + 0x6b, 0x3b, + /* E */ + 0xcf, 0x73, + /* F */ + 0xcf, 0x13, + /* G */ + 0x4f, 0x7a, + /* H */ + 0xed, 0x5b, + /* I */ + 0x97, 0x74, + /* J */ + 0x24, 0x7b, + /* K */ + 0x5d, 0x56, + /* L */ + 0x49, 0x72, + /* M */ + 0xfd, 0x5b, + /* N */ + 0x6f, 0x5b, + /* O */ + 0x6f, 0x7b, + /* P */ + 0xef, 0x13, + /* Q */ + 0x6f, 0x7f, + /* R */ + 0xef, 0x57, + /* S */ + 0xce, 0x38, + /* T */ + 0x97, 0x24, + /* U */ + 0x6d, 0x7b, + /* V */ + 0x6d, 0x2b, + /* W */ + 0xed, 0x5f, + /* X */ + 0xad, 0x5a, + /* Y */ + 0xad, 0x24, + /* Z */ + 0xa7, 0x72, + } +}; +#endif /* FONT3X5_1_H_ */ diff --git a/fonts/font3x5_1.txt b/fonts/font3x5_1.txt new file mode 100644 index 0000000..b58aa06 --- /dev/null +++ b/fonts/font3x5_1.txt @@ -0,0 +1,358 @@ +# This is a tiny 3x5 font with uppercase, digits, and symbols only. +# M.P. Hayes 2 Sep 2010 +width=3 +height=5 + +... +... +... +... +... +! +.@. +.@. +.@. +... +.@. +" +@@. +@.@ +@@@ +@.. +@@@ +# +@.@ +@@@ +@.@ +@@@ +@.@ +$ +.@@ +@@. +@@@ +.@@ +@@. +% +@.@ +..@ +.@. +@.. +@.@ +& +.@. +@.@ +@@. +@.@ +@@@ +' +..@ +.@. +... +... +... +( +.@. +@.. +@.. +@.. +.@. +) +.@. +..@ +..@ +..@ +.@. +* +.@. +@@@ +.@. +@@@ +.@. ++ +... +.@. +@@@ +.@. +... +, +... +... +... +.@. +@.. +- +... +... +@@@ +... +... +. +... +... +... +... +.@. +/ +..@ +..@ +.@. +@.. +@.. +0 +.@. +@.@ +@.@ +@.@ +.@. +1 +.@. +@@. +.@. +.@. +@@@ +2 +@@. +..@ +.@. +@.. +@@@ +3 +@@. +..@ +.@. +..@ +@@. +4 +@.@ +@.@ +@@@ +..@ +..@ +5 +@@@ +@.. +.@. +..@ +@@. +6 +.@@ +@.. +@@. +@.@ +.@. +7 +@@@ +..@ +.@. +@.. +@.. +8 +.@. +@.@ +.@. +@.@ +.@. +9 +.@@ +@.@ +.@@ +..@ +..@ +: +... +.@. +... +.@. +... +; +... +.@. +... +.@. +@.. +< +..@ +.@. +@.. +.@. +..@ += +... +@@@ +... +@@@ +... +> +@.. +.@. +..@ +.@. +@.. +? +.@. +@.@ +..@ +.@. +.@. +. +... +... +... +... +.@. +A +.@. +@.@ +@@@ +@.@ +@.@ +B +@@. +@.@ +@@. +@.@ +@@. +C +@@@ +@.. +@.. +@.. +@@@ +D +@@. +@.@ +@.@ +@.@ +@@. +E +@@@ +@.. +@@@ +@.. +@@@ +F +@@@ +@.. +@@@ +@.. +@.. +G +@@@ +@.. +@.. +@.@ +@@@ +H +@.@ +@.@ +@@@ +@.@ +@.@ +I +@@@ +.@. +.@. +.@. +@@@ +J +..@ +..@ +..@ +@.@ +@@@ +K +@.@ +@@. +@.. +@@. +@.@ +L +@.. +@.. +@.. +@.. +@@@ +M +@.@ +@@@ +@@@ +@.@ +@.@ +N +@@@ +@.@ +@.@ +@.@ +@.@ +O +@@@ +@.@ +@.@ +@.@ +@@@ +P +@@@ +@.@ +@@@ +@.. +@.. +Q +@@@ +@.@ +@.@ +@@@ +@@@ +R +@@@ +@.@ +@@@ +@@. +@.@ +S +.@@ +@.. +@@. +..@ +@@. +T +@@@ +.@. +.@. +.@. +.@. +U +@.@ +@.@ +@.@ +@.@ +@@@ +V +@.@ +@.@ +@.@ +@.@ +.@. +W +@.@ +@.@ +@@@ +@@@ +@.@ +X +@.@ +@.@ +.@. +@.@ +@.@ +Y +@.@ +@.@ +.@. +.@. +.@. +Z +@@@ +..@ +.@. +@.. +@@@ diff --git a/fonts/font5x7_1.h b/fonts/font5x7_1.h new file mode 100644 index 0000000..5c5ef55 --- /dev/null +++ b/fonts/font5x7_1.h @@ -0,0 +1,234 @@ +/** @file font5x7_1.h + @author fontgen + @date 28 Sep 2010 + + @defgroup font5x7_1 This is a 5x7 font with uppercase, lowercase, digits, and symbols. + M.P. Hayes 2 Sep 2010 + +*/ + +#ifndef FONT5X7_1_H_ +#define FONT5X7_1_H_ + +#define FONT5X7_1_WIDTH 5 +#define FONT5X7_1_HEIGHT 7 +#define FONT5X7_1_OFFSET 32 +#define FONT5X7_1_SIZE 95 + +#ifndef FONT_WIDTH +#define FONT_WIDTH 5 +#endif +#ifndef FONT_HEIGHT +#define FONT_HEIGHT 7 +#endif +#ifndef FONT_OFFSET +#define FONT_OFFSET 32 +#endif +#ifndef FONT_SIZE_MAX +#define FONT_SIZE_MAX 95 +#endif +#include "font.h" + +static const font_t font5x7_1 = +{ + .flags = 1, /* (packed) */ + .width = 5, + .height = 7, + .offset = 32, + .size = 95, + .bytes = 5, + .data = + { + /* */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ! */ + 0xc6, 0x18, 0x63, 0x80, 0x01, + /* " */ + 0x4a, 0x29, 0x00, 0x00, 0x00, + /* # */ + 0x4a, 0x7d, 0xf5, 0x95, 0x02, + /* $ */ + 0xc4, 0x17, 0x47, 0x1f, 0x01, + /* % */ + 0x63, 0x22, 0x22, 0x32, 0x06, + /* & */ + 0x26, 0x15, 0x51, 0x93, 0x05, + /* ' */ + 0x86, 0x08, 0x00, 0x00, 0x00, + /* ( */ + 0x88, 0x08, 0x21, 0x08, 0x02, + /* ) */ + 0x82, 0x20, 0x84, 0x88, 0x00, + /* * */ + 0x80, 0x54, 0x57, 0x09, 0x00, + /* + */ + 0x80, 0x90, 0x4f, 0x08, 0x00, + /* , */ + 0x00, 0x00, 0x60, 0x88, 0x00, + /* - */ + 0x00, 0x80, 0x0f, 0x00, 0x00, + /* . */ + 0x00, 0x00, 0x00, 0x8c, 0x01, + /* / */ + 0x00, 0x22, 0x22, 0x02, 0x00, + /* 0 */ + 0x2e, 0xe6, 0x3a, 0xa3, 0x03, + /* 1 */ + 0xc4, 0x10, 0x42, 0x88, 0x03, + /* 2 */ + 0x2e, 0x42, 0x44, 0xc4, 0x07, + /* 3 */ + 0x2e, 0x42, 0x07, 0xa3, 0x03, + /* 4 */ + 0x88, 0xa9, 0xf4, 0x11, 0x02, + /* 5 */ + 0x3f, 0x84, 0x07, 0xa3, 0x03, + /* 6 */ + 0x2e, 0x86, 0x17, 0xa3, 0x03, + /* 7 */ + 0x3f, 0x42, 0x44, 0x08, 0x01, + /* 8 */ + 0x2e, 0x46, 0x17, 0xa3, 0x03, + /* 9 */ + 0x2e, 0x46, 0x0f, 0xa3, 0x03, + /* : */ + 0xc0, 0x18, 0x60, 0x0c, 0x00, + /* ; */ + 0xc0, 0x18, 0x60, 0x88, 0x00, + /* < */ + 0x88, 0x88, 0x20, 0x08, 0x02, + /* = */ + 0x00, 0x7c, 0xf0, 0x01, 0x00, + /* > */ + 0x82, 0x20, 0x88, 0x88, 0x00, + /* ? */ + 0x2e, 0x42, 0x44, 0x00, 0x01, + /* @ */ + 0x2e, 0x42, 0x5b, 0xab, 0x03, + /* A */ + 0x44, 0xc5, 0x1f, 0x63, 0x04, + /* B */ + 0x2f, 0xc6, 0x17, 0xe3, 0x03, + /* C */ + 0x2e, 0x86, 0x10, 0xa2, 0x03, + /* D */ + 0x2f, 0xc6, 0x18, 0xe3, 0x03, + /* E */ + 0x3f, 0x84, 0x17, 0xc2, 0x07, + /* F */ + 0x3f, 0x84, 0x17, 0x42, 0x00, + /* G */ + 0x2e, 0x86, 0x1e, 0xa3, 0x07, + /* H */ + 0x31, 0xc6, 0x1f, 0x63, 0x04, + /* I */ + 0x8e, 0x10, 0x42, 0x88, 0x03, + /* J */ + 0x10, 0x42, 0x18, 0xa3, 0x03, + /* K */ + 0x31, 0x95, 0x51, 0x52, 0x04, + /* L */ + 0x21, 0x84, 0x10, 0xc2, 0x07, + /* M */ + 0x71, 0xd7, 0x1a, 0x63, 0x04, + /* N */ + 0x71, 0xd6, 0x1c, 0x63, 0x04, + /* O */ + 0x2e, 0xc6, 0x18, 0xa3, 0x03, + /* P */ + 0x2f, 0xc6, 0x17, 0x42, 0x00, + /* Q */ + 0x2e, 0xc6, 0x58, 0x93, 0x05, + /* R */ + 0x2f, 0xc6, 0x17, 0x63, 0x04, + /* S */ + 0x2e, 0x06, 0x07, 0xa3, 0x03, + /* T */ + 0x9f, 0x10, 0x42, 0x08, 0x01, + /* U */ + 0x31, 0xc6, 0x18, 0xa3, 0x03, + /* V */ + 0x31, 0xc6, 0x18, 0x15, 0x01, + /* W */ + 0x31, 0xc6, 0x5a, 0xab, 0x02, + /* X */ + 0x31, 0x2a, 0xa2, 0x62, 0x04, + /* Y */ + 0x31, 0x2a, 0x42, 0x08, 0x01, + /* Z */ + 0x1f, 0x22, 0x22, 0xc2, 0x07, + /* [ */ + 0x27, 0x84, 0x10, 0xc2, 0x01, + /* \ */ + 0x20, 0x08, 0x82, 0x20, 0x00, + /* ] */ + 0x0e, 0x21, 0x84, 0x90, 0x03, + /* ^ */ + 0x44, 0x45, 0x00, 0x00, 0x00, + /* _ */ + 0x00, 0x00, 0x00, 0xc0, 0x07, + /* ` */ + 0x82, 0x20, 0x00, 0x00, 0x00, + /* a */ + 0x00, 0x38, 0xe8, 0xa3, 0x07, + /* b */ + 0x21, 0xb4, 0x19, 0xe3, 0x03, + /* c */ + 0x00, 0xb8, 0x10, 0xa2, 0x03, + /* d */ + 0x10, 0xda, 0x1c, 0xa3, 0x07, + /* e */ + 0x00, 0xb8, 0xf8, 0x83, 0x03, + /* f */ + 0x4c, 0x8a, 0x23, 0x84, 0x00, + /* g */ + 0xc0, 0xc7, 0xe8, 0xa1, 0x03, + /* h */ + 0x21, 0xb4, 0x19, 0x63, 0x04, + /* i */ + 0x04, 0x18, 0x42, 0x88, 0x03, + /* j */ + 0x08, 0x30, 0x84, 0x92, 0x01, + /* k */ + 0x21, 0xa4, 0x32, 0x4a, 0x02, + /* l */ + 0x86, 0x10, 0x42, 0x88, 0x03, + /* m */ + 0x00, 0xac, 0x5a, 0x63, 0x04, + /* n */ + 0x00, 0xb4, 0x19, 0x63, 0x04, + /* o */ + 0x00, 0xb8, 0x18, 0xa3, 0x03, + /* p */ + 0x00, 0xbc, 0xf8, 0x42, 0x00, + /* q */ + 0x00, 0xd8, 0xec, 0x21, 0x04, + /* r */ + 0x00, 0xb4, 0x19, 0x42, 0x00, + /* s */ + 0x00, 0xb8, 0xe0, 0xe0, 0x03, + /* t */ + 0x42, 0x1c, 0x21, 0x24, 0x03, + /* u */ + 0x00, 0xc4, 0x18, 0xb3, 0x05, + /* v */ + 0x00, 0xc4, 0x18, 0x15, 0x01, + /* w */ + 0x00, 0xc4, 0x5a, 0xab, 0x02, + /* x */ + 0x00, 0x44, 0x45, 0x54, 0x04, + /* y */ + 0x00, 0xc4, 0xe8, 0xa1, 0x03, + /* z */ + 0x00, 0x7c, 0x44, 0xc4, 0x07, + /* { */ + 0x88, 0x10, 0x41, 0x08, 0x02, + /* | */ + 0x84, 0x10, 0x42, 0x08, 0x01, + /* } */ + 0x82, 0x10, 0x44, 0x88, 0x00, + /* ~ */ + 0x00, 0x88, 0x8a, 0x00, 0x00, + } +}; +#endif /* FONT5X7_1_H_ */ diff --git a/fonts/font5x7_1.txt b/fonts/font5x7_1.txt new file mode 100644 index 0000000..6709f79 --- /dev/null +++ b/fonts/font5x7_1.txt @@ -0,0 +1,764 @@ +# This is a 5x7 font with uppercase, lowercase, digits, and symbols. +# M.P. Hayes 2 Sep 2010 +width=5 +height=7 + +..... +..... +..... +..... +..... +..... +..... +! +.@@.. +.@@.. +.@@.. +.@@.. +.@@.. +..... +.@@.. +" +.@.@. +.@.@. +.@.@. +..... +..... +..... +..... +# +.@.@. +.@.@. +@@@@@ +.@.@. +@@@@@ +.@.@. +.@.@. +$ +..@.. +.@@@@ +@.@.. +.@@@. +..@.@ +@@@@. +..@.. +% +@@... +@@..@ +...@. +..@.. +.@... +@..@@ +...@@ +& +.@@.. +@..@. +@.@.. +.@... +@.@.@ +@..@. +.@@.@ +' +.@@.. +..@.. +.@... +..... +..... +..... +..... +( +...@. +..@.. +.@... +.@... +.@... +..@.. +...@. +) +.@... +..@.. +...@. +...@. +...@. +..@.. +.@... +* +..... +..@.. +@.@.@ +.@@@. +@.@.@ +..@.. +..... ++ +..... +..@.. +..@.. +@@@@@ +..@.. +..@.. +..... +, +..... +..... +..... +..... +.@@.. +..@.. +.@... +- +..... +..... +..... +@@@@@ +..... +..... +..... +. +..... +..... +..... +..... +..... +.@@.. +.@@.. +/ +..... +....@ +...@. +..@.. +.@... +@.... +..... +0 +.@@@. +@...@ +@..@@ +@.@.@ +@@..@ +@...@ +.@@@. +1 +..@.. +.@@.. +..@.. +..@.. +..@.. +..@.. +.@@@. +2 +.@@@. +@...@ +....@ +...@. +..@.. +.@... +@@@@@ +3 +.@@@. +@...@ +....@ +.@@@. +....@ +@...@ +.@@@. +4 +...@. +..@@. +.@.@. +@..@. +@@@@@ +...@. +...@. +5 +@@@@@ +@.... +@.... +@@@@. +....@ +@...@ +.@@@. +6 +.@@@. +@...@ +@.... +@@@@. +@...@ +@...@ +.@@@. +7 +@@@@@ +@...@ +....@ +...@. +..@.. +..@.. +..@.. +8 +.@@@. +@...@ +@...@ +.@@@. +@...@ +@...@ +.@@@. +9 +.@@@. +@...@ +@...@ +.@@@@ +....@ +@...@ +.@@@. +: +..... +.@@.. +.@@.. +..... +.@@.. +.@@.. +..... +; +..... +.@@.. +.@@.. +..... +.@@.. +..@.. +.@... +< +...@. +..@.. +.@... +@.... +.@... +..@.. +...@. += +..... +..... +@@@@@ +..... +@@@@@ +..... +..... +> +.@... +..@.. +...@. +....@ +...@. +..@.. +.@... +? +.@@@. +@...@ +....@ +...@. +..@.. +..... +..@.. +@ +.@@@. +@...@ +....@ +.@@.@ +@.@.@ +@.@.@ +.@@@. +A +..@.. +.@.@. +@...@ +@@@@@ +@...@ +@...@ +@...@ +B +@@@@. +@...@ +@...@ +@@@@. +@...@ +@...@ +@@@@. +C +.@@@. +@...@ +@.... +@.... +@.... +@...@ +.@@@. +D +@@@@. +@...@ +@...@ +@...@ +@...@ +@...@ +@@@@. +E +@@@@@ +@.... +@.... +@@@@. +@.... +@.... +@@@@@ +F +@@@@@ +@.... +@.... +@@@@. +@.... +@.... +@.... +G +.@@@. +@...@ +@.... +@.@@@ +@...@ +@...@ +.@@@@ +H +@...@ +@...@ +@...@ +@@@@@ +@...@ +@...@ +@...@ +I +.@@@. +..@.. +..@.. +..@.. +..@.. +..@.. +.@@@. +J +....@ +....@ +....@ +....@ +@...@ +@...@ +.@@@. +K +@...@ +@..@. +@.@.. +@@... +@.@.. +@..@. +@...@ +L +@.... +@.... +@.... +@.... +@.... +@.... +@@@@@ +M +@...@ +@@.@@ +@.@.@ +@.@.@ +@...@ +@...@ +@...@ +N +@...@ +@@..@ +@.@.@ +@..@@ +@...@ +@...@ +@...@ +O +.@@@. +@...@ +@...@ +@...@ +@...@ +@...@ +.@@@. +P +@@@@. +@...@ +@...@ +@@@@. +@.... +@.... +@.... +Q +.@@@. +@...@ +@...@ +@...@ +@.@.@ +@..@. +.@@.@ +R +@@@@. +@...@ +@...@ +@@@@. +@...@ +@...@ +@...@ +S +.@@@. +@...@ +@.... +.@@@. +....@ +@...@ +.@@@. +T +@@@@@ +..@.. +..@.. +..@.. +..@.. +..@.. +..@.. +U +@...@ +@...@ +@...@ +@...@ +@...@ +@...@ +.@@@. +V +@...@ +@...@ +@...@ +@...@ +@...@ +.@.@. +..@.. +W +@...@ +@...@ +@...@ +@.@.@ +@.@.@ +@.@.@ +.@.@. +X +@...@ +@...@ +.@.@. +..@.. +.@.@. +@...@ +@...@ +Y +@...@ +@...@ +.@.@. +..@.. +..@.. +..@.. +..@.. +Z +@@@@@ +....@ +...@. +..@.. +.@... +@.... +@@@@@ +[ +@@@.. +@.... +@.... +@.... +@.... +@.... +@@@.. +\ +..... +@.... +.@... +..@.. +...@. +....@ +..... +] +.@@@. +...@. +...@. +...@. +...@. +...@. +.@@@. +^ +..@.. +.@.@. +@...@ +..... +..... +..... +..... +_ +..... +..... +..... +..... +..... +..... +@@@@@ +` +.@... +..@.. +...@. +..... +..... +..... +..... +a +..... +..... +.@@@. +....@ +.@@@@ +@...@ +.@@@@ +b +@.... +@.... +@.@@. +@@..@ +@...@ +@...@ +@@@@. +c +..... +..... +.@@@. +@.... +@.... +@...@ +.@@@. +d +....@ +....@ +.@@.@ +@..@@ +@...@ +@...@ +.@@@@ +e +..... +..... +.@@@. +@...@ +@@@@@ +@.... +.@@@. +f +..@@. +.@..@ +.@... +@@@.. +.@... +.@... +.@... +g +..... +.@@@@ +@...@ +@...@ +.@@@@ +....@ +.@@@. +h +@.... +@.... +@.@@. +@@..@ +@...@ +@...@ +@...@ +i +..@.. +..... +.@@.. +..@.. +..@.. +..@.. +.@@@. +j +...@. +..... +..@@. +...@. +...@. +@..@. +.@@.. +k +@.... +@.... +@..@. +@.@.. +@@... +@.@.. +@..@. +l +.@@.. +..@.. +..@.. +..@.. +..@.. +..@.. +.@@@. +m +..... +..... +@@.@. +@.@.@ +@.@.@ +@...@ +@...@ +n +..... +..... +@.@@. +@@..@ +@...@ +@...@ +@...@ +o +..... +..... +.@@@. +@...@ +@...@ +@...@ +.@@@. +p +..... +..... +@@@@. +@...@ +@@@@. +@.... +@.... +q +..... +..... +.@@.@ +@..@@ +.@@@@ +....@ +....@ +r +..... +..... +@.@@. +@@..@ +@.... +@.... +@.... +s +..... +..... +.@@@. +@.... +.@@@. +....@ +@@@@. +t +.@... +.@... +@@@.. +.@... +.@... +.@..@ +..@@. +u +..... +..... +@...@ +@...@ +@...@ +@..@@ +.@@.@ +v +..... +..... +@...@ +@...@ +@...@ +.@.@. +..@.. +w +..... +..... +@...@ +@.@.@ +@.@.@ +@.@.@ +.@.@. +x +..... +..... +@...@ +.@.@. +..@.. +.@.@. +@...@ +y +..... +..... +@...@ +@...@ +.@@@@ +....@ +.@@@. +z +..... +..... +@@@@@ +...@. +..@.. +.@... +@@@@@ +{ +...@. +..@.. +..@.. +.@... +..@.. +..@.. +...@. +| +..@.. +..@.. +..@.. +..@.. +..@.. +..@.. +..@.. +} +.@... +..@.. +..@.. +...@. +..@.. +..@.. +.@... +~ +..... +..... +.@... +@.@.@ +...@. +..... +..... diff --git a/fonts/font5x7_2.h b/fonts/font5x7_2.h new file mode 100644 index 0000000..7af0cdc --- /dev/null +++ b/fonts/font5x7_2.h @@ -0,0 +1,186 @@ +/** @file font5x7_2.h + @author fontgen + @date 28 Sep 2010 + + @defgroup font5x7_2 This is a 5x7 font with uppercase, digits, and some symbols. + M.P. Hayes 2 Sep 2010 + +*/ + +#ifndef FONT5X7_2_H_ +#define FONT5X7_2_H_ + +#define FONT5X7_2_WIDTH 5 +#define FONT5X7_2_HEIGHT 7 +#define FONT5X7_2_OFFSET 32 +#define FONT5X7_2_SIZE 71 + +#ifndef FONT_WIDTH +#define FONT_WIDTH 5 +#endif +#ifndef FONT_HEIGHT +#define FONT_HEIGHT 7 +#endif +#ifndef FONT_OFFSET +#define FONT_OFFSET 32 +#endif +#ifndef FONT_SIZE_MAX +#define FONT_SIZE_MAX 71 +#endif +#include "font.h" + +static font_t font5x7_2 = +{ + .flags = 1, /* (packed) */ + .width = 5, + .height = 7, + .offset = 32, + .size = 71, + .bytes = 5, + .data = + { + /* */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ! */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* " */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* # */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* $ */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* % */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* & */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ' */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ( */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ) */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* * */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* + */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* , */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* - */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* . */ + 0x00, 0x00, 0x02, 0x00, 0x00, + /* / */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0 */ + 0x2e, 0xe6, 0x3a, 0xa3, 0x03, + /* 1 */ + 0xc4, 0x10, 0x42, 0x88, 0x03, + /* 2 */ + 0x2e, 0x42, 0x44, 0xc4, 0x07, + /* 3 */ + 0x1f, 0x11, 0x04, 0xa3, 0x03, + /* 4 */ + 0x88, 0xa9, 0xf4, 0x11, 0x02, + /* 5 */ + 0x3f, 0x3c, 0x08, 0xa3, 0x03, + /* 6 */ + 0x4c, 0x84, 0x17, 0xa3, 0x03, + /* 7 */ + 0x1f, 0x22, 0x42, 0x08, 0x01, + /* 8 */ + 0x2f, 0x46, 0x17, 0xa3, 0x03, + /* 9 */ + 0x2e, 0x46, 0x0f, 0x91, 0x01, + /* : */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ; */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* < */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* = */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* > */ + 0x41, 0x10, 0x44, 0x44, 0x00, + /* ? */ + 0x2e, 0x42, 0x44, 0x00, 0x01, + /* @ */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* A */ + 0x2e, 0xc6, 0xf8, 0x63, 0x04, + /* B */ + 0x4f, 0x4a, 0x27, 0xe5, 0x03, + /* C */ + 0x2e, 0x86, 0x10, 0xa2, 0x03, + /* D */ + 0x4f, 0x4a, 0x29, 0xe5, 0x03, + /* E */ + 0x3f, 0x84, 0x1f, 0xc2, 0x07, + /* F */ + 0x3f, 0x84, 0x17, 0x42, 0x00, + /* G */ + 0x2e, 0x86, 0x1c, 0xa3, 0x07, + /* H */ + 0x31, 0xc6, 0x1f, 0x63, 0x04, + /* I */ + 0x8e, 0x10, 0x42, 0x88, 0x03, + /* J */ + 0x1c, 0x21, 0x84, 0x92, 0x01, + /* K */ + 0x31, 0x95, 0x51, 0x52, 0x04, + /* L */ + 0x21, 0x84, 0x10, 0xc2, 0x07, + /* M */ + 0x71, 0xd7, 0x1a, 0x63, 0x04, + /* N */ + 0x71, 0xce, 0x9a, 0x73, 0x04, + /* O */ + 0x2e, 0xc6, 0x18, 0xa3, 0x03, + /* P */ + 0x2f, 0xc6, 0x17, 0x42, 0x00, + /* Q */ + 0x2e, 0xc6, 0x58, 0xd3, 0x05, + /* R */ + 0x2f, 0xc6, 0x57, 0x52, 0x04, + /* S */ + 0x2e, 0x06, 0x07, 0xa3, 0x03, + /* T */ + 0x9f, 0x10, 0x42, 0x08, 0x01, + /* U */ + 0x31, 0xc6, 0x18, 0xa3, 0x03, + /* V */ + 0x31, 0xc6, 0x18, 0x15, 0x01, + /* W */ + 0x31, 0xc6, 0x5a, 0x77, 0x04, + /* X */ + 0x31, 0x2a, 0xa2, 0x62, 0x04, + /* Y */ + 0x31, 0x46, 0x45, 0x08, 0x01, + /* Z */ + 0x1f, 0x22, 0x22, 0xc2, 0x07, + /* [ */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* \ */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ] */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ^ */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* _ */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* ` */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* c */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* d */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* e */ + 0x00, 0x00, 0x00, 0x00, 0x00, + /* f */ + 0x2e, 0x86, 0xf0, 0x43, 0x00, + } +}; +#endif /* FONT5X7_2_H_ */ diff --git a/fonts/font5x7_2.txt b/fonts/font5x7_2.txt new file mode 100644 index 0000000..c797492 --- /dev/null +++ b/fonts/font5x7_2.txt @@ -0,0 +1,332 @@ +# This is a 5x7 font with uppercase, digits, and some symbols. +# M.P. Hayes 2 Sep 2010 +width=5 +height=7 + +..... +..... +..... +..... +..... +..... +..... +. +..... +..... +..... +..@.. +..... +..... +..... +> +@.... +.@... +..@.. +...@. +..@.. +.@... +@.... +? +.@@@. +@...@ +....@ +...@. +..@.. +..... +..@.. +0 +.@@@. +@...@ +@..@@ +@.@.@ +@@..@ +@...@ +.@@@. +1 +..@.. +.@@.. +..@.. +..@.. +..@.. +..@.. +.@@@. +2 +.@@@. +@...@ +....@ +...@. +..@.. +.@... +@@@@@ +3 +@@@@@ +...@. +..@.. +...@. +....@ +@...@ +.@@@. +4 +...@. +..@@. +.@.@. +@..@. +@@@@@ +...@. +...@. +5 +@@@@@ +@.... +@@@@. +....@ +....@ +@...@ +.@@@. +6 +..@@. +.@... +@.... +@@@@. +@...@ +@...@ +.@@@. +7 +@@@@@ +....@ +...@. +..@.. +..@.. +..@.. +..@.. +8 +@@@@. +@...@ +@...@ +.@@@. +@...@ +@...@ +.@@@. +9 +.@@@. +@...@ +@...@ +.@@@@ +....@ +...@. +.@@.. +A +.@@@. +@...@ +@...@ +@...@ +@@@@@ +@...@ +@...@ +B +@@@@. +.@..@ +.@..@ +.@@@. +.@..@ +.@..@ +@@@@. +C +.@@@. +@...@ +@.... +@.... +@.... +@...@ +.@@@. +D +@@@@. +.@..@ +.@..@ +.@..@ +.@..@ +.@..@ +@@@@. +E +@@@@@ +@.... +@.... +@@@@@ +@.... +@.... +@@@@@ +F +@@@@@ +@.... +@.... +@@@@. +@.... +@.... +@.... +f +.@@@. +@...@ +@.... +@.... +@@@@@ +@.... +@.... +G +.@@@. +@...@ +@.... +@..@@ +@...@ +@...@ +.@@@@ +H +@...@ +@...@ +@...@ +@@@@@ +@...@ +@...@ +@...@ +I +.@@@. +..@.. +..@.. +..@.. +..@.. +..@.. +.@@@. +J +..@@@ +...@. +...@. +...@. +...@. +@..@. +.@@.. +K +@...@ +@..@. +@.@.. +@@... +@.@.. +@..@. +@...@ +L +@.... +@.... +@.... +@.... +@.... +@.... +@@@@@ +M +@...@ +@@.@@ +@.@.@ +@.@.@ +@...@ +@...@ +@...@ +N +@...@ +@@..@ +@@..@ +@.@.@ +@..@@ +@..@@ +@...@ +O +.@@@. +@...@ +@...@ +@...@ +@...@ +@...@ +.@@@. +P +@@@@. +@...@ +@...@ +@@@@. +@.... +@.... +@.... +Q +.@@@. +@...@ +@...@ +@...@ +@.@.@ +@..@. +@@@.@ +R +@@@@. +@...@ +@...@ +@@@@. +@.@.. +@..@. +@...@ +S +.@@@. +@...@ +@.... +.@@@. +....@ +@...@ +.@@@. +T +@@@@@ +..@.. +..@.. +..@.. +..@.. +..@.. +..@.. +U +@...@ +@...@ +@...@ +@...@ +@...@ +@...@ +.@@@. +V +@...@ +@...@ +@...@ +@...@ +@...@ +.@.@. +..@.. +W +@...@ +@...@ +@...@ +@.@.@ +@.@.@ +@@.@@ +@...@ +X +@...@ +@...@ +.@.@. +..@.. +.@.@. +@...@ +@...@ +Y +@...@ +@...@ +@...@ +.@.@. +..@.. +..@.. +..@.. +Z +@@@@@ +....@ +...@. +..@.. +.@... +@.... +@@@@@ diff --git a/fonts/fontgen.c b/fonts/fontgen.c new file mode 100644 index 0000000..a604c5d --- /dev/null +++ b/fonts/fontgen.c @@ -0,0 +1,462 @@ +/** @file fontgen.c + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief +*/ +#include +#include +#include +#include +#include +#include +#include + +/* FIXME. This is not robust. */ + + +typedef struct +{ + char name[64]; + char *comment; + uint8_t width; + uint8_t height; + uint8_t offset; + uint8_t size; + uint8_t bytes; + uint8_t interlaced; + uint8_t *data; +} font_t; + + +#define FONT_SIZE_MAX 255 + +int font_zoom (font_t *font, font_t *zoom_font, int zoom_x, int zoom_y) +{ + int i; + uint8_t *image; + uint8_t *zoom_image; + int bits; + + *zoom_font = *font; + zoom_font->width = font->width * zoom_x; + zoom_font->height = font->height * zoom_y; + zoom_font->bytes = font->bytes * zoom_x * zoom_y; + zoom_font->data = calloc (FONT_SIZE_MAX, zoom_font->bytes); + + bits = zoom_font->width * zoom_font->height; + if (zoom_font->interlaced) + bits = (bits + 1) / 2; + zoom_font->bytes = (bits + CHAR_BIT - 1) / CHAR_BIT; + + image = malloc (font->width * font->height); + zoom_image = malloc (font->width * zoom_x * font->height * zoom_y); + + for (i = font->offset; i < font->size + font->offset; i++) + { + int k; + int x; + int y; + uint8_t font_byte; + uint8_t *font_elt; + + font_elt = &font->data[i * font->bytes]; + + k = 0; + font_byte = *font_elt++; + + for (y = 0; y < font->height; y++) + { + for (x = 0; x < font->width; x++) + { + image[y * font->width + x] = (font_byte & 1) * 255; + font_byte >>= 1; + k++; + if (k >= CHAR_BIT) + { + k = 0; + font_byte = *font_elt++; + } + } + } + + for (y = 0; y < zoom_font->height; y++) + { + for (x = 0; x < zoom_font->width; x++) + zoom_image[y * zoom_font->width + x] + = image[(y / zoom_y) * font->width + (x / zoom_x)]; + } + + + font_elt = &zoom_font->data[i * zoom_font->bytes]; + k = 0; + *font_elt = 0; + for (y = 0; y < zoom_font->height; y++) + { + for (x = 0; x < zoom_font->width; x++) + { + if (zoom_image[y * zoom_font->width + x]) + *font_elt |= (1 << k); + k++; + if (k >= CHAR_BIT) + { + k = 0; + font_elt++; + *font_elt = 0; + } + } + } + } + + free (image); + free (zoom_image); + return 1; +} + + +int font_scan (font_t *font) +{ + char buffer[132]; + int line; + int symcnt; + int symline; + uint8_t symbol; + uint8_t symbol_min; + uint8_t symbol_max; + int tmp; + int bits; + unsigned int i; + + font->comment = 0; + + /* FIXME, use more robust key-value pair parsing. */ + while (1) + { + int c; + + c = fgetc (stdin); + if (c == EOF) + return 0; + + ungetc (c, stdin); + + if (!strchr ("#whi", c)) + break; + + if (!fgets (buffer, sizeof (buffer), stdin)) + return 0; + + if (c == 'w') + { + if (sscanf (buffer, "width=%d", &tmp) != 1) + fprintf (stderr, "Width parse error: %s\n", buffer); + font->width = tmp; + } + else if (c == 'h') + { + if (sscanf (buffer, "height=%d", &tmp) != 1) + fprintf (stderr, "Height parse error: %s\n", buffer); + font->height = tmp; + } + else if (c == 'i') + { + if (sscanf (buffer, "interlaced=%d", &tmp) != 1) + fprintf (stderr, "Interlaced parse error: %s\n", buffer); + font->interlaced = tmp; + } + else if (c == '#') + { + if (!font->comment) + font->comment = calloc (1, strlen (buffer) + 1); + else + font->comment = realloc (font->comment, + strlen (font->comment) + + strlen (buffer) + 1); + + strcat (font->comment, buffer + 1); + } + + } + + if (!font->width) + { + fprintf (stderr, "Missing width specifier\n"); + return 1; + } + + if (!font->height) + { + fprintf (stderr, "Missing height specifier\n"); + return 1; + } + + bits = font->width * font->height; + if (font->interlaced) + bits = (bits + 1) / 2; + font->bytes = (bits + CHAR_BIT - 1) / CHAR_BIT; + + font->offset = 0; + font->size = ~0; + + symbol_min = ~0; + symbol_max = 0; + + font->data = calloc (FONT_SIZE_MAX, font->bytes); + + symbol = 0; + + line = 4; + for (symcnt = 1; ; symcnt++) + { + int bit = 0; + + for (symline = 1; symline <= font->height + 1; symline++) + { + unsigned int num; + + if (!fgets (buffer, sizeof (buffer), stdin)) + { + /* Have reached end of file. */ + font->offset = symbol_min; + font->size = symbol_max - symbol_min + 1; + + return 0; + } + + /* Remove newline. */ + buffer[strlen (buffer) - 1] = '\0'; + + if (symline != 1) + { + char *p; + + if (strlen (buffer) != font->width) + { + fprintf (stderr, "Parse error at line %d: %s\n", line, buffer); + return 1; + } + + p = buffer; + if (font->interlaced) + { + num = symline & 1 ? font->width / 2 : (font->width + 1) / 2; + if (symline & 1) + p++; + } + else + num = font->width; + + for (i = 0; i < num; i++) + { + if (*p != '.') + { + font->data[symbol * font->bytes + bit / CHAR_BIT] + |= (1 << (bit % CHAR_BIT)); + } + else if (*p != '.') + { + fprintf (stderr, "Parse error at line %d: %c\n", line, *p); + return 1; + } + bit++; + if (font->interlaced) + p += 2; + else + p++; + } + } + else + { + if (buffer[0] == '\\' && buffer[1] != '\0') + { + if (sscanf (buffer + 1, "%o", &tmp) != 1) + { + fprintf (stderr, "Parse error (octal num) at line %d: %s\n", line, buffer); + return 2; + } + symbol = tmp; + } + else + { + char sym; + + if (sscanf (buffer, "%c", &sym) != 1) + { + fprintf (stderr, "Parse error (char) at line %d: %s\n", line, buffer); + return 2; + } + symbol = sym; + } + if (symbol < symbol_min) + symbol_min = symbol; + if (symbol > symbol_max) + symbol_max = symbol; + } + + line++; + } + } +} + + +static void font_print_1 (font_t *font, uint8_t symbol) +{ + int i; + + for (i = 0; i < font->bytes; i++) + printf ("0x%02x, ", font->data[symbol * font->bytes + i]); + fputs ("\n", stdout); +} + + +static void font_print (font_t *font) +{ + int i; + uint8_t bytes_per_char; + time_t now; + char name_upper[128]; + char timestr[32]; + + bytes_per_char = (font->width * font->height + 8 - 1) >> 3; + + for (i= 0; font->name[i]; i++) + name_upper[i] = toupper (font->name[i]); + name_upper[i] = '\0'; + + time (&now); + strftime (timestr, sizeof (timestr), "%d %b %Y", localtime (&now)); + + printf ("/** @file %s.h\n", font->name); + printf (" @author fontgen\n"); + printf (" @date %s\n\n", timestr); + printf (" @defgroup %s %s\n", font->name, font->comment); + printf ("*/\n\n"); + printf ("#ifndef %s_H_\n", name_upper); + printf ("#define %s_H_\n\n", name_upper); + printf ("#define %s_WIDTH %d\n", name_upper, font->width); + printf ("#define %s_HEIGHT %d\n", name_upper, font->height); + printf ("#define %s_OFFSET %d\n", name_upper, font->offset); + printf ("#define %s_SIZE %d\n\n", name_upper, font->size); + + printf ("#ifndef FONT_WIDTH\n#define FONT_WIDTH %d\n#endif\n", + font->width); + printf ("#ifndef FONT_HEIGHT\n#define FONT_HEIGHT %d\n#endif\n", + font->height); + printf ("#ifndef FONT_OFFSET\n#define FONT_OFFSET %d\n#endif\n", + font->offset); + printf ("#ifndef FONT_SIZE_MAX\n#define FONT_SIZE_MAX %d\n#endif\n", + font->size); + + printf ("#include \"font.h\"\n\n"); + printf ("static font_t %s =\n{\n", font->name); + + printf (" .flags = 1, /* (packed) */\n"); + printf (" .width = %d,\n", font->width); + printf (" .height = %d,\n", font->height); + printf (" .offset = %d,\n", font->offset); + printf (" .size = %d,\n", font->size); + printf (" .bytes = %d,\n", bytes_per_char); + printf (" .data =\n {\n"); + + for (i = font->offset; i < font->size + font->offset; i++) + { + if (i < 32) + printf (" /* \\%o */\n ", i); + else + printf (" /* %c */\n ", i); + + font_print_1 (font, i); + } + printf (" }\n};\n#endif /* %s_H_ */\n", name_upper); +} + + +static void font_draw_1 (font_t *font, uint8_t symbol) +{ + int i; + int j; + int bit; + char ch; + uint8_t *data; + + data = &font->data[symbol * font->bytes]; + bit = 0; + ch = *data++; + for (i = 0; i < font->height; i++) + { + for (j = 0; j < font->width; j++) + { + if (font->interlaced && ((i & 1) ^ (j & 1))) + { + fputc (' ', stdout); + continue; + } + fputc (ch & 1 ? '@' : '.', stdout); + ch >>= 1; + bit++; + if ((bit % CHAR_BIT) == 0) + ch = *data++; + } + fputc ('\n', stdout); + } +} + + +static void font_draw (font_t *font) +{ + int i; + + printf ("width=%d\n", font->width); + printf ("height=%d\n", font->height); + printf ("interlaced=%d\n", font->interlaced); + + for (i = 0; i < 32; i++) + { + printf ("\\%o\n", i); + font_draw_1 (font, i); + } + + for (; i < FONT_SIZE_MAX; i++) + { + printf ("%c\n", i); + font_draw_1 (font, i); + } +} + + +int main (int argc, char **argv) +{ + int ret; + font_t font; + + ret = font_scan (&font); + if (ret) + return ret; + + if (argc < 2) + { + fprintf (stderr, "Usage: fontgen fontname\n"); + return 1; + } + strcpy (font.name, argv[1]); + argc--; + argv++; + + if (argc > 2 && !strcmp (argv[1], "-zoom")) + { + int zoom; + font_t zoom_font; + + zoom = atoi (argv[2]); + argc -= 2; + argv += 2; + + font_zoom (&font, &zoom_font, zoom, zoom); + font = zoom_font; + } + + if (argc > 1 && !strcmp (argv[1], "-ascii")) + font_draw (&font); + else + font_print (&font); + return 0; +} diff --git a/utils/README b/utils/README new file mode 100644 index 0000000..a01e8c4 --- /dev/null +++ b/utils/README @@ -0,0 +1,4 @@ +This is a collection of common modules, such as utility functions, +etc. Note, that these modules do not directly access the hardware but +instead use the device driver modules. + diff --git a/utils/boing.c b/utils/boing.c new file mode 100644 index 0000000..1ecd1fe --- /dev/null +++ b/utils/boing.c @@ -0,0 +1,72 @@ +/** @file boing.c + @author M. P. Hayes, UCECE + @date 24 August 2010 + @brief Bouncing ball module +*/ +#include "system.h" +#include "boing.h" + +/** Update the state of a ball bouncing off the edges of the display + @param state current state + @return new state. */ +boing_state_t boing_update (boing_state_t state) +{ + tinygl_point_t hops[] = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, + {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}; + + state.pos.x += hops[state.dir].x; + state.pos.y += hops[state.dir].y; + + if (state.pos.x > TINYGL_WIDTH - 1 || state.pos.x < 0) + { + boing_dir_t newdir[] = {DIR_N, DIR_NW, DIR_W, DIR_SW, + DIR_S, DIR_SE, DIR_E, DIR_NE}; + state.pos.x -= 2 * hops[state.dir].x; + state.dir = newdir[state.dir]; + } + + if (state.pos.y > TINYGL_HEIGHT - 1 || state.pos.y < 0) + { + boing_dir_t newdir[] = {DIR_S, DIR_SE, DIR_E, DIR_NE, + DIR_N, DIR_NW, DIR_W, DIR_SW}; + state.pos.y -= 2 * hops[state.dir].y; + state.dir = newdir[state.dir]; + } + + return state; +} + + +/** Reverse the direction of a ball + @param state current state + @return new state with direction reversed. */ +boing_state_t boing_reverse (boing_state_t state) +{ + boing_dir_t newdir[] = {DIR_S, DIR_SW, DIR_W, DIR_NW, + DIR_N, DIR_NE, DIR_W, DIR_SE}; + + state.dir = newdir[state.dir]; + return state; +} + + +/** Initialise the state of a ball + @param xstart x coordinate to start at + @param ystart y coordinate to start at + @param dir initial direction + @return state. */ +boing_state_t boing_init (uint8_t xstart, uint8_t ystart, boing_dir_t dir) +{ + boing_state_t state; + + if (xstart > TINYGL_WIDTH) + xstart = TINYGL_WIDTH - 1; + if (ystart > TINYGL_HEIGHT) + ystart = TINYGL_HEIGHT - 1; + + state.pos.x = xstart; + state.pos.y = ystart; + state.dir = dir; + + return state; +} diff --git a/utils/boing.h b/utils/boing.h new file mode 100644 index 0000000..a2e586a --- /dev/null +++ b/utils/boing.h @@ -0,0 +1,42 @@ +/** @file boing.h + @author M. P. Hayes, UCECE + @date 24 August 2010 + @brief Bouncing ball module + + @defgroup boing Bouncing ball module +*/ +#ifndef BOING_H +#define BOING_H + +#include "tinygl.h" + +/** Compass direction of ball. */ +typedef enum dir {DIR_N, DIR_NE, DIR_E, DIR_SE, + DIR_S, DIR_SW, DIR_W, DIR_NW} boing_dir_t; + + +/** Structure defining state of ball. */ +typedef struct state {tinygl_point_t pos; boing_dir_t dir;} boing_state_t; + + +/** Update the state of a ball bouncing off the edges of the display + @param state current state + @return new state. */ +boing_state_t boing_update (boing_state_t state); + + +/** Reverse the direction of a ball + @param state current state + @return new state with direction reversed. */ +boing_state_t boing_reverse (boing_state_t state); + + +/** Initialise the state of a ball + @param xstart x coordinate to start at + @param ystart y coordinate to start at + @param dir initial direction + @return state. */ +boing_state_t boing_init (uint8_t xstart, uint8_t ystart, boing_dir_t dir); + + +#endif diff --git a/utils/font.h b/utils/font.h new file mode 100644 index 0000000..4e2714e --- /dev/null +++ b/utils/font.h @@ -0,0 +1,41 @@ +/** @file font.h + @author M. P. Hayes, UCECE + @date 1 March 2007 + @brief Font definition. +*/ + +#ifndef FONT_H +#define FONT_H + +#include "system.h" + +typedef const uint8_t font_data_t; + +/** Font structure. */ +typedef const struct +{ + /** Flags for future options. */ + uint8_t flags; + /** Width of font element. */ + uint8_t width; + /** Height of font element. */ + uint8_t height; + /** Index of first entry in font. */ + uint8_t offset; + /** Number of font entries in table. */ + uint8_t size; + /** Number of bytes per font entry. */ + uint8_t bytes; + /** Font element data. */ + font_data_t data[]; +} font_t; + + +/** Return the first character in the font. */ +#define FONT_FIRST(font) ((font)->offset) + +/** Return the last character in the font. */ +#define FONT_LAST(font) ((font)->offset + (font)->size - 1) + + +#endif diff --git a/utils/pacer.c b/utils/pacer.c new file mode 100644 index 0000000..c0ca5bc --- /dev/null +++ b/utils/pacer.c @@ -0,0 +1,30 @@ +/** @file pacer.c + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Paced loop module +*/ +#include "system.h" +#include "timer.h" +#include "pacer.h" + +static timer_tick_t pacer_period; + + +/** Initialise pacer: + @param pacer_rate rate in Hz. */ +void pacer_init (pacer_rate_t pacer_rate) +{ + timer_init (); + + pacer_period = TIMER_RATE / pacer_rate; +} + + +/** Wait until next pacer tick. */ +void pacer_wait (void) +{ + static timer_tick_t when = 0; + + timer_wait_until (when); + when += pacer_period; +} diff --git a/utils/pacer.h b/utils/pacer.h new file mode 100644 index 0000000..42f9b58 --- /dev/null +++ b/utils/pacer.h @@ -0,0 +1,46 @@ +/** @file pacer.h + @author M. P. Hayes, UCECE + @date 23 August 2010 + @brief Paced loop support. + + @defgroup pacer Paced loop module + + This module provides support for paced loops by abstracting a + hardware timer. + + Here's a simple example for a paced loop that operates at 1 kHz. + + @code + #include "pacer.h" + + void main (void) + { + pacer_init (1000); + + while (1) + { + pacer_wait (); + + // Do something. + } + } + @endcode +*/ +#ifndef PACER_H +#define PACER_H + +#include "system.h" + +/** Define size of pacer rates. */ +typedef uint16_t pacer_rate_t; + + +/** Wait for the next pacer tick. */ +extern void pacer_wait (void); + + +/** Initialise pacer: + @param pacer_rate rate in Hz. */ +extern void pacer_init (pacer_rate_t pacer_rate); + +#endif /* PACER_H */ diff --git a/utils/task.c b/utils/task.c new file mode 100644 index 0000000..4e75354 --- /dev/null +++ b/utils/task.c @@ -0,0 +1,76 @@ +/** @file task.c + @author M. P. Hayes, UCECE + @date 17 August 2011 + @brief Simple task scheduler. +*/ +#include "system.h" +#include "task.h" +#include "timer.h" + + +/** With 16-bit times the maximum value is 32768. */ +#define TASK_OVERRUN_MAX 32767 + + +/** Schedule tasks + @param tasks pointer to array of tasks (the highest priority + task comes first) + @param num_tasks number of tasks to schedule + @return this never returns. +*/ +void task_schedule (task_t *tasks, uint8_t num_tasks) +{ + uint8_t i; + timer_tick_t now; + task_t *next_task; + + timer_init (); + now = timer_get (); + + /* Start by scheduling the first task. */ + next_task = tasks; + + while (1) + { + timer_tick_t sleep_min; + + /* Wait until the next task is ready to run. */ + timer_wait_until (next_task->reschedule); + + /* Schedule the task. */ + next_task->func (next_task->data); + + /* Update the reschedule time. */ + next_task->reschedule += next_task->period; + + sleep_min = ~0; + now = timer_get (); + + /* Search array of tasks. Schedule the first task (highest priority) + that needs to run otherwise wait until first task ready. */ + for (i = 0; i < num_tasks; i++) + { + task_t * task = tasks + i; + timer_tick_t overrun; + + overrun = now - task->reschedule; + if (overrun < TASK_OVERRUN_MAX) + { + /* Have found a task that can run immediately. */ + next_task = task; + break; + } + else + { + timer_tick_t sleep; + + sleep = -overrun; + if (sleep < sleep_min) + { + sleep_min = sleep; + next_task = task; + } + } + } + } +} diff --git a/utils/task.h b/utils/task.h new file mode 100644 index 0000000..187f866 --- /dev/null +++ b/utils/task.h @@ -0,0 +1,137 @@ +/** @file task.h + @author M. P. Hayes, UCECE + @date 17 August 2011 + @brief Simple task scheduler. + + @defgroup task Simple task scheduler + + This scheduler periodically calls functions specified in an array + of tasks to schedule. There is no pre-emption; a task can hog the CPU. + The tasks at the start of the array have a higher priority. + + Each task must maintain its own state; either using static local + variables, file variables, or dynamically using the generic pointer + passed when the task is called. + + Here's an example of two LED flashing tasks that run at 2 and 3 Hz. + + @code + #include "task.h" + #include "led.h" + #include "system.h" + + static void led1_task (void *data) + { + static uint8_t state = 0; + + led_set (LED1, state); + state = !state; + } + + + static void led2_task (void *data) + { + static uint8_t state = 0; + + led_set (LED2, state); + state = !state; + } + + + int main (void) + { + task_t tasks[] = + { + {.func = led1_task, .period = TASK_RATE / 2, .data = 0}, + {.func = led2_task, .period = TASK_RATE / 3, .data = 0}, + }; + + system_init (); + led_init (); + + task_schedule (tasks, 2); + return 0; + } +@endcode + + Here's another similar example. This time there are two instances + of the same task but with different state. + +@code + #include "task.h" + #include "led.h" + #include "system.h" + + typedef struct state_struct + { + uint8_t led; + uint8_t on; + } state_t; + + + static void led_task (void *data) + { + state_t *pstate = data; + + led_set (pstate->led, pstate->on); + pstate->on = !pstate->on; + } + + + int main (void) + { + state_t led1 = {.led = LED1, .on = 0}; + state_t led2 = {.led = LED2, .on = 0}; + task_t tasks[] = + { + {.func = led_task, .period = TASK_RATE / 2, .data = &led1}, + {.func = led_task, .period = TASK_RATE / 3, .data = &led2}, + }; + + system_init (); + led_init (); + + task_schedule (tasks, 2); + return 0; + } +@endcode +*/ + +#ifndef TASK_H +#define TASK_H + +#include "system.h" +#include "timer.h" + + +#define TASK_RATE TIMER_RATE + + +/** Task function prototype. */ +typedef void (* task_func_t)(void *data); + + +/** Task structure. */ +typedef struct task_struct +{ + /** Function to call. */ + task_func_t func; + /** Generic pointer to pass to function. */ + void *data; + /** How many ticks between scheduling events. */ + timer_tick_t period; + /** When to reschedule. */ + timer_tick_t reschedule; +} task_t; + + +/** Schedule tasks + @param tasks pointer to array of tasks (the highest priority + task comes first) + @param num_tasks number of tasks to schedule + @return this never returns. +*/ +void task_schedule (task_t *tasks, uint8_t num_tasks); + +#endif + diff --git a/utils/tinygl.c b/utils/tinygl.c new file mode 100644 index 0000000..1a59108 --- /dev/null +++ b/utils/tinygl.c @@ -0,0 +1,278 @@ +/** @file tinygl.c + @author M. P. Hayes, UCECE + @date 24 August 2010 + @brief Tiny graphics library. +*/ +#include +#include "system.h" +#include "tinygl.h" +#include "display.h" + +enum {TINYGL_SPEED_DEFAULT = 20}; + +static uint16_t update_rate; +static uint16_t text_advance_period; +static font_t *font; +static tinygl_text_mode_t text_mode = TINYGL_TEXT_MODE_STEP; +static uint8_t message_index; +static uint8_t scroll_pos = 0; +static char message1[32] = ""; + + +/** Draw point. + @param point coordinates of point + @param pixel_value pixel value for line. */ +void tinygl_draw_point (tinygl_point_t point, tinygl_pixel_value_t pixel_value) +{ + display_pixel_set (point.x, point.y, pixel_value); +} + + +/** Draw line. + @param point1 coordinates of start of line + @param point2 coordinates of end of line + @param pixel_value pixel value for line. */ +void tinygl_draw_line (tinygl_point_t point1, tinygl_point_t point2, + tinygl_pixel_value_t pixel_value) +{ + int dx; + int dy; + int x_inc; + int y_inc; + + /* Draw a line using Bresenham's algorithm. */ + + dx = point2.x - point1.x; + dy = point2.y - point1.y; + + x_inc = dx >= 0 ? 1 : -1; + y_inc = dy >= 0 ? 1 : -1; + if (dx < 0) + dx = -dx; + if (dy < 0) + dy = -dy; + + if (dx >= dy) + { + int error; + + error = dx / 2; + + for (; point1.x != point2.x; point1.x += x_inc) + { + tinygl_draw_point (point1, pixel_value); + + error -= dy; + if (error < 0) + { + error += dx; + point1.y += y_inc; + } + } + } + else + { + int error; + + error = dy / 2; + for (; point1.y != point2.y; point1.y += y_inc) + { + tinygl_draw_point (point1, pixel_value); + + error -= dx; + if (error < 0) + { + error += dy; + point1.x += x_inc; + } + } + } + tinygl_draw_point (point1, pixel_value); +} + + +/** Draw box. + @param tl coordinates of top left corner of box + @param br coordinates of bottom right of box + @param pixel_value pixel value for box. */ +void tinygl_draw_box (tinygl_point_t tl, tinygl_point_t br, + tinygl_pixel_value_t pixel_value) +{ + tinygl_draw_line (tl, tinygl_point (br.x, tl.y), pixel_value); + tinygl_draw_line (tl, tinygl_point (tl.x, br.y), pixel_value); + tinygl_draw_line (tinygl_point (br.x, tl.y), br, pixel_value); + tinygl_draw_line (tinygl_point (tl.x, br.y), br, pixel_value); +} + + +/** Clear display. */ +void tinygl_clear (void) +{ + display_clear (); + + /* Stop message display. */ + message1[0] = 0; + message_index = 0; +} + + +/** Determine if pixel on or off. + @param ch character to display + @param col column of font element + @param row row of font element + @return 1 if pixel on; if pixel out of bounds return 0. */ +static bool tinygl_font_pixel_get (char ch, uint8_t col, uint8_t row) +{ + int8_t index; + font_data_t *char_data; + uint8_t offset; + + if (!font || col >= font->width || row >= font->height) + return 0; + + /* Find index of font entry. */ + index = ch - font->offset; + if (index < 0 || index >= font->size) + return 0; + + /* Get start of font entry data for ch. */ + char_data = &font->data[index * font->bytes]; + + /* Extract whether pixel should be on or off. */ + offset = row * font->width + col; + return (char_data[offset / 8] & BIT (offset % 8)) != 0; +} + + +/** Display a character. + @param ch character to display + @return 1 if character fully displayed. */ +static bool tinygl_display_char (char ch) +{ + uint8_t x; + uint8_t y; + + if (!font) + return 0; + + switch (text_mode) + { + case TINYGL_TEXT_MODE_SCROLL_LEFT: + display_scroll_left (); + + for (y = 0; y < font->height; y++) + { + tinygl_draw_point (tinygl_point (TINYGL_WIDTH - 1, y), + tinygl_font_pixel_get (ch, scroll_pos, y)); + } + break; + + case TINYGL_TEXT_MODE_STEP: + if (scroll_pos != 0) + break; + + for (x = 0; x < font->width; x++) + { + for (y = 0; y < font->height; y++) + { + tinygl_draw_point (tinygl_point (x, y), + tinygl_font_pixel_get (ch, x, y)); + } + } + break; + + case TINYGL_TEXT_MODE_ROTATE_SCROLL_DOWN: + display_scroll_down (); + + for (x = 0; x < font->height; x++) + { + tinygl_draw_point (tinygl_point (x, 0), + tinygl_font_pixel_get (ch, scroll_pos, x)); + } + break; + } + + scroll_pos++; + if (scroll_pos > font->width) + scroll_pos = 0; + return scroll_pos == 0; +} + + +/** Advance message. */ +static void tinygl_text_advance (void) +{ + if (!message1[message_index]) + message_index = 0; + + if (message1[message_index]) + { + if (tinygl_display_char (message1[message_index])) + message_index++; + } +} + + +/** Display a message repeatedly. + @param string null terminated message to display. */ +void tinygl_text (const char *string) +{ + message_index = 0; + scroll_pos = 0; + strncpy (message1, string, sizeof (message1)); +} + + +/** Set the message update speed. + @param speed text advance speed (characters per 10 s). */ +void tinygl_text_speed_set (uint8_t speed) +{ + text_advance_period = update_rate / (speed * TINYGL_WIDTH) * 10; +} + + +/** Set the message display mode. + @param mode display mode. */ +void tinygl_text_mode_set (tinygl_text_mode_t mode) +{ + text_mode = mode; +} + + +/** Set the font to use for text. + @param pfont pointer to font description. */ +void tinygl_font_set (font_t *pfont) +{ + font = pfont; +} + + +/** Update display (refresh display and update message). */ +void tinygl_update (void) +{ + static uint16_t tick = 0; + + tick++; + if (tick >= text_advance_period) + { + tick = 0; + + tinygl_text_advance (); + } + + display_update (); +} + + +/** Initialise things. + @param rate rate in Hz that tinygl_update called. */ +void tinygl_init (uint16_t rate) +{ + update_rate = rate; + + display_init (); + + tinygl_text_speed_set (TINYGL_SPEED_DEFAULT); + + tinygl_clear (); +} diff --git a/utils/tinygl.h b/utils/tinygl.h new file mode 100644 index 0000000..e6cd64a --- /dev/null +++ b/utils/tinygl.h @@ -0,0 +1,182 @@ +/** @file tinygl.h + @author M. P. Hayes, UCECE + @date 24 August 2010 + @brief Tiny graphics library. + + @defgroup tinygl Tiny graphics library + +

Introduction to Tinygl

+ + Tinygl is a tiny graphics library for a simple dot matrix + display. This file declares the data types and graphics + primitives provided by tinygl. The basic graphics primitive is + a point. This specifies a pair of (x, y) coordinates on the + display. Each point has an associated pixel value. Currently, + this can be 0 for off and 1 for on. + + +

A simple Tinygl application

+ + Here's a simple application that draws a line from (1, 2) to + (3, 5). The paced loop runs at 1 kHz and this sets the display + refresh period to 200 Hz since there are 5 columns. + + @code + #include "pacer.h" + #include "tinygl.h" + + void main (void) + { + pacer_init (1000); + tinygl_init (1000); + + tinygl_draw_line (tinygl_point (1, 2), tinygl_point (3, 5)); + + while (1) + { + pacer_wait (); + tinygl_update (); + } + } + @endcode + +

A Tinygl text application

+ + Here's another simple application that displays a message. + + @code + #include "pacer.h" + #include "tinygl.h" + #include "../fonts/font5x7_1.h" + + void main (void) + { + pacer_init (1000); + tinygl_init (1000); + + tinygl_font_set (&font5x7_1); + tinygl_text_speed_set (10); + tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL_LEFT); + tinygl_text ("HELLO WORLD "); + + while (1) + { + pacer_wait (); + tinygl_update (); + } + } + @endcode + +*/ + +#ifndef TINYGL_H +#define TINYGL_H + +#include "system.h" +#include "display.h" +#include "font.h" + +/** Define size of display. */ +#define TINYGL_WIDTH DISPLAY_WIDTH +#define TINYGL_HEIGHT DISPLAY_HEIGHT + + +/** Define a pixel value. Currently the only supported values are 0 + for off and 1 for on. */ +typedef uint8_t tinygl_pixel_value_t; + + +/** Define a display coordinate. Note these are signed to allow + relative coordinates. */ +typedef int8_t tinygl_coord_t; + + +/** Define a point as a pair of coordinates. The display origin is the + top left corner. */ +typedef struct tinygl_point +{ + tinygl_coord_t x; + tinygl_coord_t y; +} tinygl_point_t; + + +/** Define text display modes. */ +typedef enum +{ + /* Stepping text. */ + TINYGL_TEXT_MODE_STEP, + /** Scrolling text. */ + TINYGL_TEXT_MODE_SCROLL_LEFT, + /** Rotated scrolling text. */ + TINYGL_TEXT_MODE_ROTATE_SCROLL_DOWN +} tinygl_text_mode_t; + + +/** Construct a point from a pair of coordinates. + @param x x coordinate + @param y y coordinate + @return point. */ +static inline tinygl_point_t tinygl_point (tinygl_coord_t x, tinygl_coord_t y) +{ + tinygl_point_t point = {x, y}; + + return point; +} + + +/** Display a message repeatedly. + @param string null terminated message to display. */ +void tinygl_text (const char *string); + + +/** Set the message update speed. + @param speed text advance speed (characters per 10 s). */ +void tinygl_text_speed_set (uint8_t speed); + + +/** Set the message display mode. + @param mode display mode. */ +void tinygl_text_mode_set (tinygl_text_mode_t mode); + + +/** Set the font to use for text. + @param pfont pointer to font description. */ +void tinygl_font_set (font_t *pfont); + + +/** Draw point. + @param point coordinates of point + @param pixel_value pixel value to draw point. */ +void tinygl_draw_point (tinygl_point_t point, tinygl_pixel_value_t pixel_value); + + +/** Draw line. + @param point1 coordinates of start of line + @param point2 coordinates of end of line + @param pixel_value pixel value to draw line. */ +void tinygl_draw_line (tinygl_point_t point1, tinygl_point_t point2, + tinygl_pixel_value_t pixel_value); + + +/** Draw box. + @param tl coordinates of top left corner of box + @param br coordinates of bottom right of box + @param pixel_value pixel value to draw box. */ +void tinygl_draw_box (tinygl_point_t tl, tinygl_point_t br, + tinygl_pixel_value_t pixel_value); + + +/** Clear display. */ +void tinygl_clear (void); + + +/** Update display and advance message. */ +void tinygl_update (void); + + +/** Initialise things. + @param rate rate in Hz that tinygl_update called. */ +void tinygl_init (uint16_t rate); + + +#endif /* TINYGL_H */ diff --git a/utils/uint8toa.c b/utils/uint8toa.c new file mode 100644 index 0000000..2faaca2 --- /dev/null +++ b/utils/uint8toa.c @@ -0,0 +1,34 @@ +/** @file uint8toa.c + @author M. P. Hayes, UCECE + @date 15 May 2007 + @brief +*/ +#include "system.h" + + +/** Convert 8 bit unsigned number to decimal ASCII string. This uses + much less memory than sprintf. + @param num number to convert + @param str pointer to array of at least 4 chars to hold string + @param leading_zeroes non-zero to pad with leading zeroes. */ +void +uint8toa (uint8_t num, char *str, bool leading_zeroes) +{ + uint8_t d; + uint8_t i; + uint8_t const powers[] = {100, 10, 1, 0}; + + for (i = 0; (d = powers[i]); i++) + { + uint8_t q; + + q = num / d; + if (leading_zeroes || q || d == 1) + { + *str++ = '0' + q; + num -= q * d; + leading_zeroes = 1; + } + } + *str = '\0'; +} diff --git a/utils/uint8toa.h b/utils/uint8toa.h new file mode 100644 index 0000000..67af57d --- /dev/null +++ b/utils/uint8toa.h @@ -0,0 +1,22 @@ +/** @file uint8toa.h + @author M. P. Hayes, UCECE + @date 21 Nov 2006 + @brief 8 bit unsigned int to ASCII conversion. + + @defgroup uint8toa 8 bit unsigned int to ASCII conversion +*/ + +#ifndef UINT8TOA_H +#define UINT8TOA_H + +#include "system.h" + + +/** Convert 8 bit unsigned number to decimal ASCII string. This uses + much less memory than sprintf. + @param num number to convert + @param str pointer to array of at least 4 chars to hold string + @param leading_zeroes non-zero to pad with leading zeroes. */ +void uint8toa (uint8_t num, char *str, bool leading_zeroes); + +#endif