Merge branch 'master' of eng-git.canterbury.ac.nz:mph/ucfk4

main
Michael Hayes 12 years ago
commit 170c458a03

@ -0,0 +1,80 @@
# File: Makefile
# Author: M. P. Hayes, UCECE
# Date: 12 Sep 2010
# Descr: Makefile for gobble7
# Definitions.
CC = avr-gcc
CFLAGS = -mmcu=atmega32u2 -Os -Wall -Wstrict-prototypes -Wextra -g -I. -I../../drivers/avr -I../../fonts -I../../drivers -I../../utils
OBJCOPY = avr-objcopy
SIZE = avr-size
DEL = rm
# Default target.
all: gobble7.out
# Compile: create object files from C source files.
gobble7.o: gobble7.c ../../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 things.h
$(CC) -c $(CFLAGS) $< -o $@
things.o: things.c ../../drivers/avr/system.h ../../drivers/display.h ../../utils/font.h ../../utils/tinygl.h things.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 $@
font.o: ../../utils/font.c ../../drivers/avr/system.h ../../utils/font.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 output file (executable) from object files.
gobble7.out: gobble7.o things.o pio.o system.o timer.o display.o led.o ledmat.o navswitch.o font.o task.o tinygl.o
$(CC) $(CFLAGS) $^ -o $@ -lm
$(SIZE) $@
# Create hex file for programming from executable file.
gobble7.hex: gobble7.out
$(OBJCOPY) -O ihex gobble7.out gobble7.hex
# Target: clean project.
.PHONY: clean
clean:
-$(DEL) *.o *.out *.hex
# Target: program project.
.PHONY: program
program: gobble7.hex
dfu-programmer atmega32u2 erase; dfu-programmer atmega32u2 flash gobble7.hex; dfu-programmer atmega32u2 start

@ -0,0 +1,70 @@
# File: Makefile
# Author: M. P. Hayes, UCECE
# Date: 11 Sep 2010
# Descr: Makefile for gobble7
CC = gcc
CFLAGS = -Wall -Wstrict-prototypes -Wextra -g -I. -I../../drivers/test -I../../drivers -I../../fonts -I../../utils
DEL = rm
# Default target.
all: gobble7
# Compile: create object files from C source files.
gobble7-test.o: gobble7.c ../../drivers/display.h ../../drivers/led.h ../../drivers/navswitch.h ../../drivers/test/system.h ../../drivers/test/timer.h ../../fonts/font3x5_1.h ../../utils/font.h ../../utils/task.h ../../utils/tinygl.h things.h
$(CC) -c $(CFLAGS) $< -o $@
things-test.o: things.c ../../drivers/display.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h things.h
$(CC) -c $(CFLAGS) $< -o $@
display-test.o: ../../drivers/display.c ../../drivers/display.h ../../drivers/ledmat.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 $@
ledmat-test.o: ../../drivers/ledmat.c ../../drivers/ledmat.h ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/test/system.h
$(CC) -c $(CFLAGS) $< -o $@
navswitch-test.o: ../../drivers/navswitch.c ../../drivers/navswitch.h ../../drivers/test/avrtest.h ../../drivers/test/delay.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 ../../drivers/test/avrtest.h ../../drivers/test/pio.h ../../drivers/test/system.h
$(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 $@
timer-test.o: ../../drivers/test/timer.c ../../drivers/test/system.h ../../drivers/test/timer.h
$(CC) -c $(CFLAGS) $< -o $@
font-test.o: ../../utils/font.c ../../drivers/test/system.h ../../utils/font.h
$(CC) -c $(CFLAGS) $< -o $@
task-test.o: ../../utils/task.c ../../drivers/test/system.h ../../drivers/test/timer.h ../../utils/task.h
$(CC) -c $(CFLAGS) $< -o $@
tinygl-test.o: ../../utils/tinygl.c ../../drivers/display.h ../../drivers/test/system.h ../../utils/font.h ../../utils/tinygl.h
$(CC) -c $(CFLAGS) $< -o $@
# Link: create executable file from object files.
gobble7: gobble7-test.o things-test.o display-test.o led-test.o ledmat-test.o navswitch-test.o mgetkey-test.o pio-test.o system-test.o timer-test.o font-test.o task-test.o tinygl-test.o
$(CC) $(CFLAGS) $^ -o $@ -lrt
# Clean: delete derived files.
.PHONY: clean
clean:
-$(DEL) gobble7 gobble7-test.o things-test.o display-test.o led-test.o ledmat-test.o navswitch-test.o mgetkey-test.o pio-test.o system-test.o timer-test.o font-test.o task-test.o tinygl-test.o

@ -0,0 +1,45 @@
# File: Makefile
# Author: M. P. Hayes, UCECE
# Date: 11 Sep 2010
# Descr: Makefile for led5 docs
# The scripts used to make the graphs require the program dot; this
# is part of the graphviz package.
DEL = rm
all: file_dependencies.pdf module_dependencies.pdf makefile_dependencies.pdf build_dependencies.pdf callgraph.pdf
file_dependencies.pdf: files.d
../../../etc/graphdeps.py $< --out $@
module_dependencies.pdf: modules.d
../../../etc/graphdeps.py $< --modules --rotate --out $@
makefile_dependencies.pdf: ../Makefile
../../../etc/graphdeps.py $< --out $@
build_dependencies.pdf: ../Makefile
../../../etc/graphdeps.py $< --out $@ --showops
callgraph.pdf: callgraph.d
../../../etc/graphdeps.py --calls --modules $< --out $@ --showops
files.d: ../Makefile
(cd ..; ../../etc/makemake.py --relpath --files . . ../../drivers ../../drivers/avr ../../utils ../../extra --exclude system.h > doc/files.d)
modules.d: ../Makefile
(cd ..; ../../etc/makemake.py --relpath --modules . . ../../drivers ../../drivers/avr ../../utils ../../extra --exclude system > doc/modules.d)
callgraph.d: ../Makefile
(cd ..; ../../etc/makemake.py --cc="avr-gcc" --cflags="-Os -mmcu=atmega32u2" --relpath --calls . . ../../drivers ../../drivers/avr ../../utils ../../extra --exclude system.h > doc/callgraph.d)
# Clean: delete derived files.
.PHONY: clean
clean:
-$(DEL) *.d *.pdf

@ -0,0 +1,16 @@
Running make in this directory will generate a number of PDF graphs.
In the callgraph, the arrows means "calls". In the dependency graphs,
the arrows means "requires" (or "depends upon").
callgraph.pdf This shows the callgraph, i.e., what functions each
function in the program calls.
module_dependencies.pdf This shows the dependencies between the modules.
file_dependencies.pdf This shows the dependencies between the files.
makefile_dependencies.pdf This shows the dependencies required by make when
building the program.
build_dependencies.pdf This is like makefile_dependencies.pdf but shows
the operations performed to generate the new file.
callgraph.d This shows the callgraph in text format.
files.d This shows the file dependencies in text format.
modules.d This shows the module dependencies in text format.

@ -0,0 +1,127 @@
/** @file gobble7.c
@author M.P. Hayes
@date 1 Oct 2013
@brief
*/
#include <stdio.h>
#include <stdlib.h>
#include "system.h"
#include "task.h"
#include "navswitch.h"
#include "led.h"
#include "timer.h"
#include "tinygl.h"
#include "../fonts/font3x5_1.h"
#include "things.h"
#define DISPLAY_RATE 200
#define MOVE_RATE 10
#define NAVSWITCH_RATE 50
#define MONSTER_FLASH_RATE 5
static bool running = 0;
static bool game_over = 1;
static int duration = 0;
static void display (__unused__ void *data)
{
tinygl_update ();
}
static void monster_flash_task (__unused__ void *data)
{
/* Flash the monster. */
if (running)
monster_toggle ();
}
static void things_task (__unused__ void *data)
{
/* Move the things. */
if (running)
{
duration++;
things_move ();
}
}
static void navswitch_task (__unused__ void *data)
{
navswitch_update ();
if (navswitch_push_event_p (NAVSWITCH_NORTH))
monster_move (0, -1);
if (navswitch_push_event_p (NAVSWITCH_SOUTH))
monster_move (0, 1);
if (navswitch_push_event_p (NAVSWITCH_EAST))
monster_move (1, 0);
if (navswitch_push_event_p (NAVSWITCH_WEST))
monster_move (-1, 0);
/* Pause/resume things running around. */
if (navswitch_push_event_p (NAVSWITCH_PUSH))
{
if (! running && game_over)
{
srand (timer_get ());
tinygl_clear ();
things_create ();
duration = 0;
game_over = 0;
}
running = !running;
led_set (LED1, running);
}
if (running && things_killed_p ())
{
char buffer[6];
running = 0;
game_over = 1;
led_set (LED1, 0);
sprintf (buffer, "%d", duration);
tinygl_text (buffer);
}
}
int main (void)
{
task_t tasks[] =
{
{.func = display, .period = TASK_RATE / DISPLAY_RATE},
{.func = navswitch_task, .period = TASK_RATE / NAVSWITCH_RATE},
{.func = things_task, .period = TASK_RATE / MOVE_RATE},
{.func = monster_flash_task, .period = TASK_RATE / MONSTER_FLASH_RATE},
};
system_init ();
navswitch_init ();
led_init ();
led_set (LED1, 0);
tinygl_init (DISPLAY_RATE);
tinygl_font_set (&font3x5_1);
tinygl_text_mode_set (TINYGL_TEXT_MODE_SCROLL);
tinygl_text_dir_set (TINYGL_TEXT_DIR_ROTATE);
tinygl_text ("GOBBLE: PUSH TO START");
task_schedule (tasks, 4);
return 0;
}

@ -0,0 +1,193 @@
#include <stdlib.h>
#include "things.h"
#include "tinygl.h"
/* Number of initial objects. */
#define THINGS_NUM 6
#define SAFE_DISTANCE 3
#define ANXIETY_LEVEL 2
#define PANIC_LEVEL 50
#define MOVE_ATTEMPTS 12
typedef struct thing_struct
{
tinygl_point_t pos;
uint8_t anxiety;
bool alive;
} thing_t;
static thing_t things[THINGS_NUM];
bool things_killed_p (void)
{
uint8_t i;
for (i = 1; i < THINGS_NUM; i++)
{
if (things[i].alive)
return 0;
}
return 1;
}
static int8_t thing_find (tinygl_point_t pos)
{
uint8_t i;
for (i = 0; i < THINGS_NUM; i++)
{
if (things[i].pos.x == pos.x
&& things[i].pos.y == pos.y
&& things[i].alive)
return i;
}
return -1;
}
static uint8_t thing_distance_squared (thing_t *things, uint8_t this)
{
int8_t dx;
int8_t dy;
dx = things[this].pos.x - things[0].pos.x;
dy = things[this].pos.y - things[0].pos.y;
return dx * dx + dy * dy;
}
static bool thing_inbounds_p (tinygl_point_t pos)
{
return pos.x >= 0 && pos.x < TINYGL_WIDTH
&& pos.y >= 0 && pos.y < TINYGL_HEIGHT;
}
static bool thing_position_valid_p (tinygl_point_t pos)
{
return thing_inbounds_p (pos) && thing_find (pos) == -1;
}
void monster_move (int8_t dx, int8_t dy)
{
int8_t other;
tinygl_point_t newpos;
newpos = tinygl_point (things[0].pos.x + dx, things[0].pos.y + dy);
if (!thing_inbounds_p (newpos))
return;
other = thing_find (newpos);
if (other != -1)
things[other].alive = 0;
tinygl_draw_point (things[0].pos, 0);
things[0].pos = newpos;
tinygl_draw_point (newpos, 1);
}
void monster_toggle (void)
{
tinygl_pixel_set (things[0].pos, ! tinygl_pixel_get (things[0].pos));
}
static void thing_move (uint8_t this)
{
uint8_t i;
uint8_t distsq;
uint8_t panic;
tinygl_point_t pos;
tinygl_draw_point (things[this].pos, 0);
distsq = thing_distance_squared (things, this);
pos = things[this].pos;
if (thing_distance_squared (things, this) <= SAFE_DISTANCE * SAFE_DISTANCE)
things[this].anxiety++;
else
things[this].anxiety = 0;
panic = things[this].anxiety > ANXIETY_LEVEL
&& (rand () % 100 > (100 - PANIC_LEVEL));
for (i = 0; i < MOVE_ATTEMPTS; i++)
{
int8_t dx;
int8_t dy;
tinygl_point_t newpos;
dx = (rand () % 3) - 1;
dy = (rand () % 3) - 1;
newpos = tinygl_point (pos.x + dx, pos.y + dy);
if ((dx || dy) && ! thing_position_valid_p (newpos))
continue;
things[this].pos = newpos;
if (panic || thing_distance_squared (things, this) > distsq)
break;
}
/* Stay put if cannot find better position. */
if (i == MOVE_ATTEMPTS)
things[this].pos = pos;
tinygl_draw_point (things[this].pos, 1);
}
void things_move (void)
{
uint8_t i;
for (i = 1; i < THINGS_NUM; i++)
if (things[i].alive)
thing_move (i);
}
void things_create (void)
{
uint8_t i;
things[0].pos.x = 0;
things[0].pos.y = 0;
things[0].alive = 1;
tinygl_draw_point (things[0].pos, 1);
for (i = 1; i < THINGS_NUM; i++)
{
uint8_t x;
uint8_t y;
do
{
x = rand () % TINYGL_WIDTH;
y = rand () % TINYGL_HEIGHT;
} while (thing_find (tinygl_point (x, y)) != -1);
things[i].pos.x = x;
things[i].pos.y = y;
things[i].alive = 1;
tinygl_draw_point (things[i].pos, 1);
}
}

@ -0,0 +1,16 @@
#ifndef THINGS_H
#define THINGS_H
#include "system.h"
bool things_killed_p (void);
void things_create (void);
void things_move (void);
void monster_move (int8_t dx, int8_t dy);
void monster_toggle (void);
#endif

@ -19,23 +19,26 @@
#define PWM_RATE 40
/* This is the rate (Hz) of luminance changes. */
#define PULSATE_RATE 10
#define PULSATE_RATE 1
#define UPDATE_RATE (LUMINANCE_STEPS * PWM_RATE)
#define LOOP_RATE (TINYGL_WIDTH * UPDATE_RATE)
/* Brightness = Luminance ** 2.5. */
int main (void)
{
uint16_t pulsate_tick = 0;
uint8_t pwm_tick = 0;
uint8_t x;
uint8_t y;
uint8_t update_col = 0;
uint8_t col;
uint8_t luminance = 0;
/* This controls the luminance levels. The maximum value
of LUMINANCE_STEPS gives 100 percent duty cycle. */
const uint8_t levels[] = {1, 2, 4, 8, 15, 25, 15, 8, 4, 2, 1};
/* This controls the luminance levels. */
const uint8_t levels[] = {4, 8, 16, 32, 64, 100, 64, 32, 16, 4};
system_init ();
@ -54,36 +57,43 @@ int main (void)
pacer_wait ();
tinygl_update ();
}
pulsate_tick++;
if (pulsate_tick >= UPDATE_RATE / PULSATE_RATE)
{
pulsate_tick = 0;
if (luminance == 0)
luminance = ARRAY_SIZE (levels) - 1;
else
luminance--;
}
state = levels[luminance] > pwm_tick;
/* Pulse width modulate pixels to control luminance. */
for (x = 0; x < TINYGL_WIDTH; x++)
{
for (y = 0; y < TINYGL_HEIGHT; y++)
if (update_col != col)
continue;
if (update_col == 0)
update_col = TINYGL_WIDTH;
update_col--;
pulsate_tick++;
if (pulsate_tick >= UPDATE_RATE / PULSATE_RATE)
{
tinygl_draw_point (tinygl_point (x, y), state);
pulsate_tick = 0;
if (luminance == 0)
luminance = ARRAY_SIZE (levels) - 1;
else
luminance--;
}
state = levels[luminance] > pwm_tick * 100 / LUMINANCE_STEPS;
/* Pulse width modulate pixels to control luminance. */
for (x = 0; x < TINYGL_WIDTH; x++)
{
for (y = 0; y < TINYGL_HEIGHT; y++)
{
tinygl_draw_point (tinygl_point (x, y), state);
}
}
led_set (LED1, state);
pwm_tick++;
if (pwm_tick >= UPDATE_RATE / PWM_RATE)
{
pwm_tick = 0;
}
}
led_set (LED1, state);
pwm_tick++;
if (pwm_tick >= UPDATE_RATE / PWM_RATE)
{
pwm_tick = 0;
}
}
return 0;

Loading…
Cancel
Save