diff options
| author | Tobias Wiese <tobias@tobiaswiese.com> | 2021-05-03 23:58:30 +0200 |
|---|---|---|
| committer | Tobias Wiese <tobias@tobiaswiese.com> | 2021-07-22 02:26:29 +0200 |
| commit | 68b5f182af145fdd9e62c9dde3eedcb9108f5ba4 (patch) | |
| tree | 67c0011276b30f8f785b934be44044935f78bd73 | |
Signed-off-by: Tobias Wiese <tobias@tobiaswiese.com>
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | Makefile | 91 | ||||
| -rw-r--r-- | base.c | 20 | ||||
| -rw-r--r-- | blink.c | 23 | ||||
| -rw-r--r-- | chars/0.xbm | 4 | ||||
| -rw-r--r-- | chars/0.xcf | bin | 0 -> 873 bytes | |||
| -rw-r--r-- | chars/1.xbm | 4 | ||||
| -rw-r--r-- | chars/1.xcf | bin | 0 -> 867 bytes | |||
| -rw-r--r-- | chars/2.xbm | 4 | ||||
| -rw-r--r-- | chars/2.xcf | bin | 0 -> 831 bytes | |||
| -rw-r--r-- | chars/3.xbm | 4 | ||||
| -rw-r--r-- | chars/3.xcf | bin | 0 -> 831 bytes | |||
| -rw-r--r-- | chars/4.xbm | 4 | ||||
| -rw-r--r-- | chars/4.xcf | bin | 0 -> 855 bytes | |||
| -rw-r--r-- | chars/5.xbm | 4 | ||||
| -rw-r--r-- | chars/5.xcf | bin | 0 -> 831 bytes | |||
| -rw-r--r-- | chars/6.xbm | 4 | ||||
| -rw-r--r-- | chars/6.xcf | bin | 0 -> 831 bytes | |||
| -rw-r--r-- | chars/7.xbm | 4 | ||||
| -rw-r--r-- | chars/7.xcf | bin | 0 -> 855 bytes | |||
| -rw-r--r-- | chars/8.xbm | 4 | ||||
| -rw-r--r-- | chars/8.xcf | bin | 0 -> 831 bytes | |||
| -rw-r--r-- | chars/9.xbm | 4 | ||||
| -rw-r--r-- | chars/9.xcf | bin | 0 -> 831 bytes | |||
| -rw-r--r-- | chars/chars.c | 118 | ||||
| -rw-r--r-- | chars/chars.h | 10 | ||||
| -rw-r--r-- | chars/space.xbm | 4 | ||||
| -rw-r--r-- | chars/space.xcf | bin | 0 -> 771 bytes | |||
| -rw-r--r-- | color.c | 13 | ||||
| -rw-r--r-- | fade.c | 41 | ||||
| -rw-r--r-- | img_mono.c | 58 | ||||
| -rw-r--r-- | img_mono.xbm | 6 | ||||
| -rw-r--r-- | libleds.c | 14 | ||||
| -rw-r--r-- | libleds.h | 55 | ||||
| -rw-r--r-- | libleds_asm.S | 92 | ||||
| -rw-r--r-- | m16def.inc | 862 | ||||
| -rw-r--r-- | numtest.c | 30 | ||||
| -rw-r--r-- | pulse.c | 24 | ||||
| -rw-r--r-- | test.c | 22 |
39 files changed, 1528 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a78512b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/* +!/*/ +!/Makefile +!/*.* +*.[ao] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cc18b7e --- /dev/null +++ b/Makefile @@ -0,0 +1,91 @@ +SHELL = /bin/sh +MCU = atmega16 +F_CPU=16000000 + +CC = avr-gcc +CFLAGS = -g -Os -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Wall +AS = avr-as +ASFLAGS = $(CFLAGS) +LD = avr-ld +LDFLAGS = + +TARGETS := test img_mono blink fade pulse numtest +MAINS := $(addsuffix .o, $(TARGETS)) +C_OBJS := base.o libleds.o chars/chars.o +S_OBJS := libleds_asm.o +OBJS := $(C_OBJS) $(S_OBJS) +DEPS := Makefile libleds.h + +COLOR_TARGETS := c_black c_white c_red c_green c_blue +COLOR_MAINS := $(addsuffix .o, $(COLOR_TARGETS)) + +NUMBERS = $(shell seq 0 9) +UPPERCASE = 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 +LOWERCASE = $(call lc, $(UPPERCASE)) +SPECIAL_CHARS = space +CHARS = $(NUMBERS) $(UPPERCASE) $(LOWERCASE) $(SPECIAL_CHARS) + +NUMBERS_DEP = chars/chars.o $(addprefix chars/, $(addsuffix .xbm, $(NUMBERS))) +UPPERCASE_DEP = chars/chars.o $(addprefix chars/, $(addsuffix .xbm, $(UPPERCASE))) +LOWERCASE_DEP = chars/chars.o $(addprefix chars/, $(addsuffix .xbm, $(LOWERCASE))) +SPECIAL_CHARS_DEP = chars/chars.o $(addprefix chars/, $(addsuffix .xbm, $(SPECIAL_CHARS))) +CHARS_DEP = chars/chars.o $(addprefix chars/, $(addsuffix .xbm, $(CHARS))) + + +.PHONY: all all-normal all-colors +all: all-core all-colors + +all-core: $(TARGETS) +.PHONY: color +all-colors color: $(COLOR_TARGETS) + +.PHONY: clean +clean: + rm -f $(TARGETS) $(MAINS) $(OBJS) $(COLOR_TARGETS) $(COLOR_MAINS) + rm -f chars/chars.o + +.PHONY: list-targets _list-targets-core _list-targets-color +list-targets: _list-targets-core _list-targets-color + @printf "\n" + +list-targets-core list-targets-color: % : _% + @printf "\n" + +_list-targets-core: + @printf "%s " "$(TARGETS)" + +_list-targets-color: + @printf "%s " "$(COLOR_TARGETS)" + + +# Build targets + + +chars/chars.c: %.c: %.h + @touch $@ + +$(MAINS) $(C_OBJS): %.o : %.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< + +$(TARGETS) $(COLOR_TARGETS): % : $(OBJS) %.o + $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ + +numtest.o: $(NUMBERS_DEP) +img_mono.o: %.o : %.xbm + +# Color Targets +c_black.o: color.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< \ + -DCOLOR_RED=0x00 -DCOLOR_GREEN=0x00 -DCOLOR_BLUE=0x00 +c_white.o: color.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< \ + -DCOLOR_RED=0x00 -DCOLOR_GREEN=0xFF -DCOLOR_BLUE=0xFF +c_red.o: color.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< \ + -DCOLOR_RED=0xFF -DCOLOR_GREEN=0x00 -DCOLOR_BLUE=0x00 +c_green.o: color.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< \ + -DCOLOR_RED=0x00 -DCOLOR_GREEN=0xFF -DCOLOR_BLUE=0x00 +c_blue.o: color.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< \ + -DCOLOR_RED=0x00 -DCOLOR_GREEN=0x00 -DCOLOR_BLUE=0xFF @@ -0,0 +1,20 @@ +#include <avr/io.h> +#include "libleds.h" + +static uint16_t const STRIP_LENGTH = 8*32; +static char const PORT = 0; +static char const PINS = 1<<7; + +void led_main(); + +void init() +{ + DDRD = 255; +} + +int main() +{ + init(); + led_main(); + return 0; +} @@ -0,0 +1,23 @@ +#include <util/delay.h> +#include "libleds.h" + +static struct led_obj const PANEL = {0, 1<<7, 32, 8}; +static unsigned char const INTENSITY = 0x15; +static unsigned int const DELAY_MS = 150; + +void led_main() +{ + struct led_color const colors[] = { + {INTENSITY, 0x00, 0x00}, + {0x00, INTENSITY, 0x00}, + {0x00, 0x00, INTENSITY}, + }; + + unsigned char i = 0; + + while (1) { + led_write_rgb_all(PANEL, colors[i]); + _delay_ms(DELAY_MS); + i = (i + 1) % (sizeof(colors) / sizeof(colors[0])); + } +} diff --git a/chars/0.xbm b/chars/0.xbm new file mode 100644 index 0000000..420af7e --- /dev/null +++ b/chars/0.xbm @@ -0,0 +1,4 @@ +#define c0_width 5 +#define c0_height 8 +static unsigned char c0_bits[] = { + 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e }; diff --git a/chars/0.xcf b/chars/0.xcf Binary files differnew file mode 100644 index 0000000..a3ab875 --- /dev/null +++ b/chars/0.xcf diff --git a/chars/1.xbm b/chars/1.xbm new file mode 100644 index 0000000..0e3b28c --- /dev/null +++ b/chars/1.xbm @@ -0,0 +1,4 @@ +#define c1_width 5 +#define c1_height 8 +static unsigned char c1_bits[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; diff --git a/chars/1.xcf b/chars/1.xcf Binary files differnew file mode 100644 index 0000000..9ca02a3 --- /dev/null +++ b/chars/1.xcf diff --git a/chars/2.xbm b/chars/2.xbm new file mode 100644 index 0000000..b88cc50 --- /dev/null +++ b/chars/2.xbm @@ -0,0 +1,4 @@ +#define c2_width 5 +#define c2_height 8 +static unsigned char c2_bits[] = { + 0x1f, 0x10, 0x10, 0x1f, 0x01, 0x01, 0x01, 0x1f }; diff --git a/chars/2.xcf b/chars/2.xcf Binary files differnew file mode 100644 index 0000000..05d2415 --- /dev/null +++ b/chars/2.xcf diff --git a/chars/3.xbm b/chars/3.xbm new file mode 100644 index 0000000..5723c18 --- /dev/null +++ b/chars/3.xbm @@ -0,0 +1,4 @@ +#define c3_width 5 +#define c3_height 8 +static unsigned char c3_bits[] = { + 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x10, 0x1f }; diff --git a/chars/3.xcf b/chars/3.xcf Binary files differnew file mode 100644 index 0000000..f1796d3 --- /dev/null +++ b/chars/3.xcf diff --git a/chars/4.xbm b/chars/4.xbm new file mode 100644 index 0000000..419d375 --- /dev/null +++ b/chars/4.xbm @@ -0,0 +1,4 @@ +#define c4_width 5 +#define c4_height 8 +static unsigned char c4_bits[] = { + 0x11, 0x11, 0x11, 0x1f, 0x10, 0x10, 0x10, 0x10 }; diff --git a/chars/4.xcf b/chars/4.xcf Binary files differnew file mode 100644 index 0000000..6eb8a27 --- /dev/null +++ b/chars/4.xcf diff --git a/chars/5.xbm b/chars/5.xbm new file mode 100644 index 0000000..00eb4bc --- /dev/null +++ b/chars/5.xbm @@ -0,0 +1,4 @@ +#define c5_width 5 +#define c5_height 8 +static unsigned char c5_bits[] = { + 0x1f, 0x01, 0x01, 0x1f, 0x10, 0x10, 0x10, 0x1f }; diff --git a/chars/5.xcf b/chars/5.xcf Binary files differnew file mode 100644 index 0000000..48b178e --- /dev/null +++ b/chars/5.xcf diff --git a/chars/6.xbm b/chars/6.xbm new file mode 100644 index 0000000..4b307c3 --- /dev/null +++ b/chars/6.xbm @@ -0,0 +1,4 @@ +#define c6_width 5 +#define c6_height 8 +static unsigned char c6_bits[] = { + 0x1f, 0x01, 0x01, 0x1f, 0x11, 0x11, 0x11, 0x1f }; diff --git a/chars/6.xcf b/chars/6.xcf Binary files differnew file mode 100644 index 0000000..402e31c --- /dev/null +++ b/chars/6.xcf diff --git a/chars/7.xbm b/chars/7.xbm new file mode 100644 index 0000000..345352e --- /dev/null +++ b/chars/7.xbm @@ -0,0 +1,4 @@ +#define c7_width 5 +#define c7_height 8 +static unsigned char c7_bits[] = { + 0x1f, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }; diff --git a/chars/7.xcf b/chars/7.xcf Binary files differnew file mode 100644 index 0000000..49ad0eb --- /dev/null +++ b/chars/7.xcf diff --git a/chars/8.xbm b/chars/8.xbm new file mode 100644 index 0000000..0b1b1ca --- /dev/null +++ b/chars/8.xbm @@ -0,0 +1,4 @@ +#define c8_width 5 +#define c8_height 8 +static unsigned char c8_bits[] = { + 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x1f }; diff --git a/chars/8.xcf b/chars/8.xcf Binary files differnew file mode 100644 index 0000000..879b641 --- /dev/null +++ b/chars/8.xcf diff --git a/chars/9.xbm b/chars/9.xbm new file mode 100644 index 0000000..2e6c2cd --- /dev/null +++ b/chars/9.xbm @@ -0,0 +1,4 @@ +#define c9_width 5 +#define c9_height 8 +static unsigned char c9_bits[] = { + 0x1f, 0x11, 0x11, 0x1f, 0x10, 0x10, 0x10, 0x1f }; diff --git a/chars/9.xcf b/chars/9.xcf Binary files differnew file mode 100644 index 0000000..8c7c6fd --- /dev/null +++ b/chars/9.xcf diff --git a/chars/chars.c b/chars/chars.c new file mode 100644 index 0000000..de72a10 --- /dev/null +++ b/chars/chars.c @@ -0,0 +1,118 @@ +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "../libleds.h" +#include "chars.h" + +#include "space.xbm" +#include "0.xbm" +#include "1.xbm" +#include "2.xbm" +#include "3.xbm" +#include "4.xbm" +#include "5.xbm" +#include "6.xbm" +#include "7.xbm" +#include "8.xbm" +#include "9.xbm" + +static unsigned char *get_char_bits(char c) { + switch (c) { + case ' ': + return cspace_bits; + case '0': + return c0_bits; + case '1': + return c1_bits; + case '2': + return c2_bits; + case '3': + return c3_bits; + case '4': + return c4_bits; + case '5': + return c5_bits; + case '6': + return c6_bits; + case '7': + return c7_bits; + case '8': + return c8_bits; + case '9': + return c9_bits; + default: + return NULL; + } +} + +static char is_active(unsigned char const *bits, unsigned int const i) +{ + /* + * The first led is in the top left corner. + * After that it goes down the column, then up the next and so on. + * + * This means all columns with an even index count down. + * Those with an odd index count up. + * + * + * With a height of 8 the led numbers would look like this: + * + * 00 0F 10 1F 20 ... + * 01 0E 11 1E 21 ... + * 02 0D 12 1D ... + * 03 0C 13 1C ... + * 04 0B 14 1B ... + * 05 0A 15 1A ... + * 06 09 16 19 ... + * 07 08 17 18 ... + */ + + unsigned int const bytes_per_row = ceil(char_width / 8.0); + unsigned int col = i / char_height; + unsigned int row = i % char_height; + if (col % 2) + row = char_height - 1 - row; + + // calculate byte to access + unsigned int byte = row * bytes_per_row; + byte += col / 8; + + unsigned char data = bits[byte]; + unsigned char mask = 1<<(col % 8); + return data & mask; +} + +static char leds_write_char(const struct led_color color, char c, struct led_color *buf) +{ + unsigned char *bits = get_char_bits(c); + if (bits == NULL) + return 0; + + for (unsigned int i = 0; i < char_length; i++) { + if (is_active(bits, i)) + buf[i] = color; + else + buf[i] = (struct led_color){0, 0, 0}; + } + + return 1; +} + +struct led_color *leds_text(struct led_color const color, const char *text) +{ + unsigned int const len = strlen(text); + struct led_color *buf = calloc( + sizeof(struct led_color), len * char_length + ); + + for (unsigned int i = 0; i < len; i++) { + if (!leds_write_char(color, text[i], buf + i*char_length)) { + // Invalid char + free(buf); + return NULL; + } + } + + return buf; +} diff --git a/chars/chars.h b/chars/chars.h new file mode 100644 index 0000000..91c7ea7 --- /dev/null +++ b/chars/chars.h @@ -0,0 +1,10 @@ +#ifndef CHARS_CHARS_H +#define CHARS_CHARS_H + +#define char_width (5+1) +#define char_height 8 +#define char_length (char_width * char_height) + +struct led_color *leds_text(struct led_color const color, const char *text); + +#endif /* !CHARS_CHARS_H */ diff --git a/chars/space.xbm b/chars/space.xbm new file mode 100644 index 0000000..7b4791b --- /dev/null +++ b/chars/space.xbm @@ -0,0 +1,4 @@ +#define cspace_width 5 +#define cspace_height 8 +static unsigned char cspace_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/chars/space.xcf b/chars/space.xcf Binary files differnew file mode 100644 index 0000000..c32a481 --- /dev/null +++ b/chars/space.xcf @@ -0,0 +1,13 @@ +#include "libleds.h" + +#if !defined(COLOR_RED) || !defined(COLOR_GREEN) || !defined(COLOR_BLUE) +# error Requires COLOR_* symbols to be set. +#endif + +static struct led_obj const PANEL = {0, 1<<7, 32, 8}; + +void led_main() +{ + struct led_color const color = { COLOR_RED, COLOR_GREEN, COLOR_BLUE}; + led_write_rgb_all(PANEL, color); +} @@ -0,0 +1,41 @@ +#include "libleds.h" + +static struct led_obj const PANEL = {0, 1<<7, 32, 8}; + +void write_all(struct led_color const color) +{ + led_write_rgb_all(PANEL, color); + led_latch(); +} + +void led_main() +{ + static int const STEP = 0x04; + static int const MIN = 0x10; + static int const MAX = 0xF0; + + struct led_color color = {MAX, MIN, MIN}; + while (1) { + for (int i = MIN; i < MAX; i += STEP) { + color.red -= STEP; + color.green += STEP; + write_all(color); + } + color.red = MIN; + color.green = MAX; + for (int i = MIN; i < MAX; i += STEP) { + color.green -= STEP; + color.blue += STEP; + write_all(color); + } + color.green = MIN; + color.blue = MAX; + for (int i = MIN; i < MAX; i += STEP) { + color.blue -= STEP; + color.red += STEP; + write_all(color); + } + color.blue = MIN; + color.red = MAX; + } +} diff --git a/img_mono.c b/img_mono.c new file mode 100644 index 0000000..b711a6b --- /dev/null +++ b/img_mono.c @@ -0,0 +1,58 @@ +#include <math.h> +#include "libleds.h" +#include "img_mono.xbm" + +static char const PORT = 0; +static char const PINS = 1<<7; + +char const is_active(unsigned int const n) +{ + /* + * The first led is in the top left corner. + * After that it goes down the column, then up the next and so on. + * + * This means all columns with an even index count down. + * Those with an odd index count up. + * + * + * With a height of 8 the led numbers would look like this: + * + * 00 0F 10 1F 20 ... + * 01 0E 11 1E 21 ... + * 02 0D 12 1D ... + * 03 0C 13 1C ... + * 04 0B 14 1B ... + * 05 0A 15 1A ... + * 06 09 16 19 ... + * 07 08 17 18 ... + */ + + unsigned int const bytes_per_row = ceil(img_width / 8.0); + unsigned int col = n / img_height; + unsigned int row = n % img_height; + if (col % 2) + row = img_height - 1 - row; + + // calculate byte to access + unsigned int byte = row * bytes_per_row; + byte += col / 8; + + unsigned char data = img_bits[byte]; + unsigned char mask = 1<<(col % 8); + return data & mask; +} + +void led_main() +{ + const int length = img_width * img_height; + + struct led_color pixel[length]; + + for (unsigned int i = 0; i < length; i++) { + unsigned char out = is_active(i) ? 0xFF : 0x00; + pixel[i] = (struct led_color){out, out, out}; + } + + for (unsigned int i = 0; i < length; i++) + led_write_rgb(PORT, PINS, pixel[i]); +} diff --git a/img_mono.xbm b/img_mono.xbm new file mode 100644 index 0000000..81f61b4 --- /dev/null +++ b/img_mono.xbm @@ -0,0 +1,6 @@ +#define img_width 32 +#define img_height 8 +static unsigned char img_bits[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, + 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55 }; diff --git a/libleds.c b/libleds.c new file mode 100644 index 0000000..1e32d90 --- /dev/null +++ b/libleds.c @@ -0,0 +1,14 @@ +#include <util/delay.h> +#include "libleds.h" + +void led_write_rgb_all(struct led_obj const obj, struct led_color const color) +{ + for (int i = 0; i < obj.width * obj.height; i++) { + led_write_rgb(obj.port, obj.pins, color); + } +} + +void led_latch(void) +{ + _delay_us(280); +} diff --git a/libleds.h b/libleds.h new file mode 100644 index 0000000..2af1325 --- /dev/null +++ b/libleds.h @@ -0,0 +1,55 @@ +#ifndef LIBLEDS_H +#define LIBLEDS_H +#include <stdio.h> + +struct led_color { + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +struct led_obj { + /* + * port to use as output. + * + * The port must already be configured for output. + * + * currently this is not used and PORTD is used instead. + */ + uint16_t port; + + /* + * bitmask specifing with ports to use. + * + * currently this is not used and 0xFF is used instead. + */ + unsigned char pins; + + /* + * the width of the object. + * + * Might be 0 if the width is unknown. Some function that depend on + * knowing the number of elements will not work. + */ + unsigned int width; + + /* + * the height of the object. + * + * Might be 0 if the height is unknown. Some function that depend on + * knowing the number of elements will not work. + * + * If the object is not a rectangle this should be set to 1. + * width is then the number of leds in the strip / star / ... + */ + unsigned int height; +}; + +void led_write_rgb(uint16_t const port, unsigned char const pins, + struct led_color color); + +void led_write_rgb_all(struct led_obj const obj, struct led_color const color); + +void led_latch(); + +#endif /* !LIBLEDS_H */ diff --git a/libleds_asm.S b/libleds_asm.S new file mode 100644 index 0000000..fd7e67c --- /dev/null +++ b/libleds_asm.S @@ -0,0 +1,92 @@ +.include "m16def.inc" + +#ifndef F_CPU +# error The LEDs are timing sensitive. F_CPU required. +#elif F_CPU < 4000000 +# error The LEDs are timing sensitive. CPU Frequency must be at least 4MHz +#elif F_CPU == 4000000 + +// 4MHz +#define nop_short +#define nop_long nop $ nop + +#elif F_CPU == 8000000 + +// 8MHz +#define nop_short nop +#define nop_long nop $ nop $ nop $ nop $ nop + +#elif F_CPU == 16000000 + +// 16MHz +#define nop_short nop $ nop $ nop +#define nop_long nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop + +#else +# error Missing nop definitions for your CPU frequency. +#endif + + +.global led_write_rgb + .type led_write_rgb, @function +; void (uint16_t port, char pins, char r, char g, char b); +; +; Args: +; port: r25, r24 +; pins: r22 +; b: r20 +; g: r19 +; r: r18 +; +; destroys: r19 +; +; The leds expect the data in G-R-B order +led_write_rgb: + clr r0 + dec r0 + + call L_led_write_byte + mov r19, r18 + call L_led_write_byte + mov r19, r20 + call L_led_write_byte + ret + +; Args: +; port: X -- curently ignored, hadcoded to PORTD +; pins: r22 -- currently ignored, hardcoded to 0xFF +; byte: r19 (!) +; +; Prerequisites: +; r0 must be 0xFF +; +; destroys: r21 -- will be 0 afterwards +; destroys: r19 -- call rol on it once to restore +L_led_write_byte: + + ldi r21, 8 + +L_led_write_byte__loop_head: + rol r19 + brcc L_led_write_byte__zero + +L_led_write_byte__one: + out PORTD, r0 + nop_long + out PORTD, r1 + nop_short + rjmp L_led_write_byte__loop_ctrl + +L_led_write_byte__zero: + out PORTD, r0 + nop_short + out PORTD, r1 + nop_long + +L_led_write_byte__loop_ctrl: + ; loop ctrl + dec r21 + brne L_led_write_byte__loop_head + +L_led_write_byte__out: + ret diff --git a/m16def.inc b/m16def.inc new file mode 100644 index 0000000..27cc811 --- /dev/null +++ b/m16def.inc @@ -0,0 +1,862 @@ +;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y +;* +;* Number : AVR000 +;* File Name : "m16def.inc" +;* Title : Register/Bit Definitions for the ATmega16 +;* Date : 2011-02-09 +;* Version : 2.35 +;* Support E-mail : avr@atmel.com +;* Target MCU : ATmega16 +;* +;* DESCRIPTION +;* When including this file in the assembly program file, all I/O register +;* names and I/O register bit names appearing in the data book can be used. +;* In addition, the six registers forming the three data pointers X, Y and +;* Z have been assigned names XL - ZH. Highest RAM address for Internal +;* SRAM is also defined +;* +;* The Register names are represented by their hexadecimal address. +;* +;* The Register Bit names are represented by their bit number (0-7). +;* +;* Please observe the difference in using the bit names with instructions +;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" +;* (skip if bit in register set/cleared). The following example illustrates +;* this: +;* +;* in r16,PORTB ;read PORTB latch +;* sbr r16,(1<<PB6)+(1<<PB5) ;set PB6 and PB5 (use masks, not bit#) +;* out PORTB,r16 ;output to PORTB +;* +;* in r16,TIFR ;read the Timer Interrupt Flag Register +;* sbrc r16,TOV0 ;test the overflow flag (use bit#) +;* rjmp TOV0_is_set ;jump if set +;* ... ;otherwise do something else +;************************************************************************* + +#ifndef _M16DEF_INC_ +#define _M16DEF_INC_ + + +#pragma partinc 0 + +; ***** SPECIFY DEVICE *************************************************** +;.device ATmega16 +#pragma AVRPART ADMIN PART_NAME ATmega16 +.equ SIGNATURE_000, 0x1e +.equ SIGNATURE_001, 0x94 +.equ SIGNATURE_002, 0x03 + +#pragma AVRPART CORE CORE_VERSION V2E + + +; ***** I/O REGISTER DEFINITIONS ***************************************** +; NOTE: +; Definitions marked "MEMORY MAPPED"are extended I/O ports +; and cannot be used with IN/OUT instructions +.equ SREG, 0x3f +.equ SPL, 0x3d +.equ SPH, 0x3e +.equ OCR0, 0x3c +.equ GICR, 0x3b +.equ GIFR, 0x3a +.equ TIMSK, 0x39 +.equ TIFR, 0x38 +.equ SPMCSR, 0x37 +.equ TWCR, 0x36 +.equ MCUCR, 0x35 +.equ MCUCSR, 0x34 +.equ TCCR0, 0x33 +.equ TCNT0, 0x32 +.equ OSCCAL, 0x31 +.equ OCDR, 0x31 +.equ SFIOR, 0x30 +.equ TCCR1A, 0x2f +.equ TCCR1B, 0x2e +.equ TCNT1L, 0x2c +.equ TCNT1H, 0x2d +.equ OCR1AL, 0x2a +.equ OCR1AH, 0x2b +.equ OCR1BL, 0x28 +.equ OCR1BH, 0x29 +.equ ICR1L, 0x26 +.equ ICR1H, 0x27 +.equ TCCR2, 0x25 +.equ TCNT2, 0x24 +.equ OCR2, 0x23 +.equ ASSR, 0x22 +.equ WDTCR, 0x21 +.equ UBRRH, 0x20 +.equ UCSRC, 0x20 +.equ EEARL, 0x1e +.equ EEARH, 0x1f +.equ EEDR, 0x1d +.equ EECR, 0x1c +.equ PORTA, 0x1b +.equ DDRA, 0x1a +.equ PINA, 0x19 +.equ PORTB, 0x18 +.equ DDRB, 0x17 +.equ PINB, 0x16 +.equ PORTC, 0x15 +.equ DDRC, 0x14 +.equ PINC, 0x13 +.equ PORTD, 0x12 +.equ DDRD, 0x11 +.equ PIND, 0x10 +.equ SPDR, 0x0f +.equ SPSR, 0x0e +.equ SPCR, 0x0d +.equ UDR, 0x0c +.equ UCSRA, 0x0b +.equ UCSRB, 0x0a +.equ UBRRL, 0x09 +.equ ACSR, 0x08 +.equ ADMUX, 0x07 +.equ ADCSRA, 0x06 +.equ ADCH, 0x05 +.equ ADCL, 0x04 +.equ TWDR, 0x03 +.equ TWAR, 0x02 +.equ TWSR, 0x01 +.equ TWBR, 0x00 + + +; ***** BIT DEFINITIONS ************************************************** + +; ***** TIMER_COUNTER_0 ************** +; TCCR0 - Timer/Counter Control Register +.equ CS00, 0 ; Clock Select 1 +.equ CS01, 1 ; Clock Select 1 +.equ CS02, 2 ; Clock Select 2 +.equ WGM01, 3 ; Waveform Generation Mode 1 +.equ CTC0, WGM01 ; For compatibility +.equ COM00, 4 ; Compare match Output Mode 0 +.equ COM01, 5 ; Compare Match Output Mode 1 +.equ WGM00, 6 ; Waveform Generation Mode 0 +.equ PWM0, WGM00 ; For compatibility +.equ FOC0, 7 ; Force Output Compare + +; TCNT0 - Timer/Counter Register +.equ TCNT0_0, 0 ; +.equ TCNT0_1, 1 ; +.equ TCNT0_2, 2 ; +.equ TCNT0_3, 3 ; +.equ TCNT0_4, 4 ; +.equ TCNT0_5, 5 ; +.equ TCNT0_6, 6 ; +.equ TCNT0_7, 7 ; + +; OCR0 - Output Compare Register +.equ OCR0_0, 0 ; +.equ OCR0_1, 1 ; +.equ OCR0_2, 2 ; +.equ OCR0_3, 3 ; +.equ OCR0_4, 4 ; +.equ OCR0_5, 5 ; +.equ OCR0_6, 6 ; +.equ OCR0_7, 7 ; + +; TIMSK - Timer/Counter Interrupt Mask Register +.equ TOIE0, 0 ; Timer/Counter0 Overflow Interrupt Enable +.equ OCIE0, 1 ; Timer/Counter0 Output Compare Match Interrupt register + +; TIFR - Timer/Counter Interrupt Flag register +.equ TOV0, 0 ; Timer/Counter0 Overflow Flag +.equ OCF0, 1 ; Output Compare Flag 0 + +; SFIOR - Special Function IO Register +.equ PSR10, 0 ; Prescaler Reset Timer/Counter1 and Timer/Counter0 + + +; ***** TIMER_COUNTER_1 ************** +; TIMSK - Timer/Counter Interrupt Mask Register +.equ TOIE1, 2 ; Timer/Counter1 Overflow Interrupt Enable +.equ OCIE1B, 3 ; Timer/Counter1 Output CompareB Match Interrupt Enable +.equ OCIE1A, 4 ; Timer/Counter1 Output CompareA Match Interrupt Enable +.equ TICIE1, 5 ; Timer/Counter1 Input Capture Interrupt Enable + +; TIFR - Timer/Counter Interrupt Flag register +.equ TOV1, 2 ; Timer/Counter1 Overflow Flag +.equ OCF1B, 3 ; Output Compare Flag 1B +.equ OCF1A, 4 ; Output Compare Flag 1A +.equ ICF1, 5 ; Input Capture Flag 1 + +; TCCR1A - Timer/Counter1 Control Register A +.equ WGM10, 0 ; Waveform Generation Mode +.equ PWM10, WGM10 ; For compatibility +.equ WGM11, 1 ; Waveform Generation Mode +.equ PWM11, WGM11 ; For compatibility +.equ FOC1B, 2 ; Force Output Compare 1B +.equ FOC1A, 3 ; Force Output Compare 1A +.equ COM1B0, 4 ; Compare Output Mode 1B, bit 0 +.equ COM1B1, 5 ; Compare Output Mode 1B, bit 1 +.equ COM1A0, 6 ; Compare Ouput Mode 1A, bit 0 +.equ COM1A1, 7 ; Compare Output Mode 1A, bit 1 + +; TCCR1B - Timer/Counter1 Control Register B +.equ CS10, 0 ; Prescaler source of Timer/Counter 1 +.equ CS11, 1 ; Prescaler source of Timer/Counter 1 +.equ CS12, 2 ; Prescaler source of Timer/Counter 1 +.equ WGM12, 3 ; Waveform Generation Mode +.equ CTC10, WGM12 ; For compatibility +.equ CTC1, WGM12 ; For compatibility +.equ WGM13, 4 ; Waveform Generation Mode +.equ CTC11, WGM13 ; For compatibility +.equ ICES1, 6 ; Input Capture 1 Edge Select +.equ ICNC1, 7 ; Input Capture 1 Noise Canceler + + +; ***** EXTERNAL_INTERRUPT *********** +; GICR - General Interrupt Control Register +.equ GIMSK, GICR ; For compatibility +.equ IVCE, 0 ; Interrupt Vector Change Enable +.equ IVSEL, 1 ; Interrupt Vector Select +.equ INT2, 5 ; External Interrupt Request 2 Enable +.equ INT0, 6 ; External Interrupt Request 0 Enable +.equ INT1, 7 ; External Interrupt Request 1 Enable + +; GIFR - General Interrupt Flag Register +.equ INTF2, 5 ; External Interrupt Flag 2 +.equ INTF0, 6 ; External Interrupt Flag 0 +.equ INTF1, 7 ; External Interrupt Flag 1 + +; MCUCR - General Interrupt Control Register +.equ ISC00, 0 ; Interrupt Sense Control 0 Bit 0 +.equ ISC01, 1 ; Interrupt Sense Control 0 Bit 1 +.equ ISC10, 2 ; Interrupt Sense Control 1 Bit 0 +.equ ISC11, 3 ; Interrupt Sense Control 1 Bit 1 + +; MCUCSR - MCU Control And Status Register +.equ ISC2, 6 ; Interrupt Sense Control 2 + + +; ***** EEPROM *********************** +; EEDR - EEPROM Data Register +.equ EEDR0, 0 ; EEPROM Data Register bit 0 +.equ EEDR1, 1 ; EEPROM Data Register bit 1 +.equ EEDR2, 2 ; EEPROM Data Register bit 2 +.equ EEDR3, 3 ; EEPROM Data Register bit 3 +.equ EEDR4, 4 ; EEPROM Data Register bit 4 +.equ EEDR5, 5 ; EEPROM Data Register bit 5 +.equ EEDR6, 6 ; EEPROM Data Register bit 6 +.equ EEDR7, 7 ; EEPROM Data Register bit 7 + +; EECR - EEPROM Control Register +.equ EERE, 0 ; EEPROM Read Enable +.equ EEWE, 1 ; EEPROM Write Enable +.equ EEMWE, 2 ; EEPROM Master Write Enable +.equ EEWEE, EEMWE ; For compatibility +.equ EERIE, 3 ; EEPROM Ready Interrupt Enable + + +; ***** CPU ************************** +; SREG - Status Register +.equ SREG_C, 0 ; Carry Flag +.equ SREG_Z, 1 ; Zero Flag +.equ SREG_N, 2 ; Negative Flag +.equ SREG_V, 3 ; Two's Complement Overflow Flag +.equ SREG_S, 4 ; Sign Bit +.equ SREG_H, 5 ; Half Carry Flag +.equ SREG_T, 6 ; Bit Copy Storage +.equ SREG_I, 7 ; Global Interrupt Enable + +; MCUCR - MCU Control Register +;.equ ISC00, 0 ; Interrupt Sense Control 0 Bit 0 +;.equ ISC01, 1 ; Interrupt Sense Control 0 Bit 1 +;.equ ISC10, 2 ; Interrupt Sense Control 1 Bit 0 +;.equ ISC11, 3 ; Interrupt Sense Control 1 Bit 1 +.equ SM0, 4 ; Sleep Mode Select +.equ SM1, 5 ; Sleep Mode Select +.equ SE, 6 ; Sleep Enable +.equ SM2, 7 ; Sleep Mode Select + +; MCUCSR - MCU Control And Status Register +.equ MCUSR, MCUCSR ; For compatibility +.equ PORF, 0 ; Power-on reset flag +.equ EXTRF, 1 ; External Reset Flag +.equ EXTREF, EXTRF ; For compatibility +.equ BORF, 2 ; Brown-out Reset Flag +.equ WDRF, 3 ; Watchdog Reset Flag +.equ JTRF, 4 ; JTAG Reset Flag +.equ JTD, 7 ; JTAG Interface Disable + +; OSCCAL - Oscillator Calibration Value +.equ CAL0, 0 ; Oscillator Calibration Value Bit0 +.equ CAL1, 1 ; Oscillator Calibration Value Bit1 +.equ CAL2, 2 ; Oscillator Calibration Value Bit2 +.equ CAL3, 3 ; Oscillator Calibration Value Bit3 +.equ CAL4, 4 ; Oscillator Calibration Value Bit4 +.equ CAL5, 5 ; Oscillator Calibration Value Bit5 +.equ CAL6, 6 ; Oscillator Calibration Value Bit6 +.equ CAL7, 7 ; Oscillator Calibration Value Bit7 + +; SFIOR - Special function I/O register +;.equ PSR10, 0 ; Prescaler reset +.equ PSR2, 1 ; Prescaler reset +.equ PUD, 2 ; Pull-up Disable + + +; ***** TIMER_COUNTER_2 ************** +; TIMSK - Timer/Counter Interrupt Mask register +.equ TOIE2, 6 ; Timer/Counter2 Overflow Interrupt Enable +.equ OCIE2, 7 ; Timer/Counter2 Output Compare Match Interrupt Enable + +; TIFR - Timer/Counter Interrupt Flag Register +.equ TOV2, 6 ; Timer/Counter2 Overflow Flag +.equ OCF2, 7 ; Output Compare Flag 2 + +; TCCR2 - Timer/Counter2 Control Register +.equ CS20, 0 ; Clock Select bit 0 +.equ CS21, 1 ; Clock Select bit 1 +.equ CS22, 2 ; Clock Select bit 2 +.equ WGM21, 3 ; Waveform Generation Mode +.equ CTC2, WGM21 ; For compatibility +.equ COM20, 4 ; Compare Output Mode bit 0 +.equ COM21, 5 ; Compare Output Mode bit 1 +.equ WGM20, 6 ; Waveform Genration Mode +.equ PWM2, WGM20 ; For compatibility +.equ FOC2, 7 ; Force Output Compare + +; TCNT2 - Timer/Counter2 +.equ TCNT2_0, 0 ; Timer/Counter 2 bit 0 +.equ TCNT2_1, 1 ; Timer/Counter 2 bit 1 +.equ TCNT2_2, 2 ; Timer/Counter 2 bit 2 +.equ TCNT2_3, 3 ; Timer/Counter 2 bit 3 +.equ TCNT2_4, 4 ; Timer/Counter 2 bit 4 +.equ TCNT2_5, 5 ; Timer/Counter 2 bit 5 +.equ TCNT2_6, 6 ; Timer/Counter 2 bit 6 +.equ TCNT2_7, 7 ; Timer/Counter 2 bit 7 + +; OCR2 - Timer/Counter2 Output Compare Register +.equ OCR2_0, 0 ; Timer/Counter2 Output Compare Register Bit 0 +.equ OCR2_1, 1 ; Timer/Counter2 Output Compare Register Bit 1 +.equ OCR2_2, 2 ; Timer/Counter2 Output Compare Register Bit 2 +.equ OCR2_3, 3 ; Timer/Counter2 Output Compare Register Bit 3 +.equ OCR2_4, 4 ; Timer/Counter2 Output Compare Register Bit 4 +.equ OCR2_5, 5 ; Timer/Counter2 Output Compare Register Bit 5 +.equ OCR2_6, 6 ; Timer/Counter2 Output Compare Register Bit 6 +.equ OCR2_7, 7 ; Timer/Counter2 Output Compare Register Bit 7 + +; ASSR - Asynchronous Status Register +.equ TCR2UB, 0 ; Timer/counter Control Register2 Update Busy +.equ OCR2UB, 1 ; Output Compare Register2 Update Busy +.equ TCN2UB, 2 ; Timer/Counter2 Update Busy +.equ AS2, 3 ; Asynchronous Timer/counter2 + +; SFIOR - Special Function IO Register +;.equ PSR2, 1 ; Prescaler Reset Timer/Counter2 + + +; ***** SPI ************************** +; SPDR - SPI Data Register +.equ SPDR0, 0 ; SPI Data Register bit 0 +.equ SPDR1, 1 ; SPI Data Register bit 1 +.equ SPDR2, 2 ; SPI Data Register bit 2 +.equ SPDR3, 3 ; SPI Data Register bit 3 +.equ SPDR4, 4 ; SPI Data Register bit 4 +.equ SPDR5, 5 ; SPI Data Register bit 5 +.equ SPDR6, 6 ; SPI Data Register bit 6 +.equ SPDR7, 7 ; SPI Data Register bit 7 + +; SPSR - SPI Status Register +.equ SPI2X, 0 ; Double SPI Speed Bit +.equ WCOL, 6 ; Write Collision Flag +.equ SPIF, 7 ; SPI Interrupt Flag + +; SPCR - SPI Control Register +.equ SPR0, 0 ; SPI Clock Rate Select 0 +.equ SPR1, 1 ; SPI Clock Rate Select 1 +.equ CPHA, 2 ; Clock Phase +.equ CPOL, 3 ; Clock polarity +.equ MSTR, 4 ; Master/Slave Select +.equ DORD, 5 ; Data Order +.equ SPE, 6 ; SPI Enable +.equ SPIE, 7 ; SPI Interrupt Enable + + +; ***** USART ************************ +; UDR - USART I/O Data Register +.equ UDR0, 0 ; USART I/O Data Register bit 0 +.equ UDR1, 1 ; USART I/O Data Register bit 1 +.equ UDR2, 2 ; USART I/O Data Register bit 2 +.equ UDR3, 3 ; USART I/O Data Register bit 3 +.equ UDR4, 4 ; USART I/O Data Register bit 4 +.equ UDR5, 5 ; USART I/O Data Register bit 5 +.equ UDR6, 6 ; USART I/O Data Register bit 6 +.equ UDR7, 7 ; USART I/O Data Register bit 7 + +; UCSRA - USART Control and Status Register A +.equ USR, UCSRA ; For compatibility +.equ MPCM, 0 ; Multi-processor Communication Mode +.equ U2X, 1 ; Double the USART transmission speed +.equ UPE, 2 ; Parity Error +.equ PE, UPE ; For compatibility +.equ DOR, 3 ; Data overRun +.equ FE, 4 ; Framing Error +.equ UDRE, 5 ; USART Data Register Empty +.equ TXC, 6 ; USART Transmitt Complete +.equ RXC, 7 ; USART Receive Complete + +; UCSRB - USART Control and Status Register B +.equ UCR, UCSRB ; For compatibility +.equ TXB8, 0 ; Transmit Data Bit 8 +.equ RXB8, 1 ; Receive Data Bit 8 +.equ UCSZ2, 2 ; Character Size +.equ CHR9, UCSZ2 ; For compatibility +.equ TXEN, 3 ; Transmitter Enable +.equ RXEN, 4 ; Receiver Enable +.equ UDRIE, 5 ; USART Data register Empty Interrupt Enable +.equ TXCIE, 6 ; TX Complete Interrupt Enable +.equ RXCIE, 7 ; RX Complete Interrupt Enable + +; UCSRC - USART Control and Status Register C +.equ UCPOL, 0 ; Clock Polarity +.equ UCSZ0, 1 ; Character Size +.equ UCSZ1, 2 ; Character Size +.equ USBS, 3 ; Stop Bit Select +.equ UPM0, 4 ; Parity Mode Bit 0 +.equ UPM1, 5 ; Parity Mode Bit 1 +.equ UMSEL, 6 ; USART Mode Select +.equ URSEL, 7 ; Register Select + +.equ UBRRHI, UBRRH ; For compatibility + +; ***** TWI ************************** +; TWBR - TWI Bit Rate register +.equ I2BR, TWBR ; For compatibility +.equ TWBR0, 0 ; +.equ TWBR1, 1 ; +.equ TWBR2, 2 ; +.equ TWBR3, 3 ; +.equ TWBR4, 4 ; +.equ TWBR5, 5 ; +.equ TWBR6, 6 ; +.equ TWBR7, 7 ; + +; TWCR - TWI Control Register +.equ I2CR, TWCR ; For compatibility +.equ TWIE, 0 ; TWI Interrupt Enable +.equ I2IE, TWIE ; For compatibility +.equ TWEN, 2 ; TWI Enable Bit +.equ I2EN, TWEN ; For compatibility +.equ ENI2C, TWEN ; For compatibility +.equ TWWC, 3 ; TWI Write Collition Flag +.equ I2WC, TWWC ; For compatibility +.equ TWSTO, 4 ; TWI Stop Condition Bit +.equ I2STO, TWSTO ; For compatibility +.equ TWSTA, 5 ; TWI Start Condition Bit +.equ I2STA, TWSTA ; For compatibility +.equ TWEA, 6 ; TWI Enable Acknowledge Bit +.equ I2EA, TWEA ; For compatibility +.equ TWINT, 7 ; TWI Interrupt Flag +.equ I2INT, TWINT ; For compatibility + +; TWSR - TWI Status Register +.equ I2SR, TWSR ; For compatibility +.equ TWPS0, 0 ; TWI Prescaler +.equ TWS0, TWPS0 ; For compatibility +.equ I2GCE, TWPS0 ; For compatibility +.equ TWPS1, 1 ; TWI Prescaler +.equ TWS1, TWPS1 ; For compatibility +.equ TWS3, 3 ; TWI Status +.equ I2S3, TWS3 ; For compatibility +.equ TWS4, 4 ; TWI Status +.equ I2S4, TWS4 ; For compatibility +.equ TWS5, 5 ; TWI Status +.equ I2S5, TWS5 ; For compatibility +.equ TWS6, 6 ; TWI Status +.equ I2S6, TWS6 ; For compatibility +.equ TWS7, 7 ; TWI Status +.equ I2S7, TWS7 ; For compatibility + +; TWDR - TWI Data register +.equ I2DR, TWDR ; For compatibility +.equ TWD0, 0 ; TWI Data Register Bit 0 +.equ TWD1, 1 ; TWI Data Register Bit 1 +.equ TWD2, 2 ; TWI Data Register Bit 2 +.equ TWD3, 3 ; TWI Data Register Bit 3 +.equ TWD4, 4 ; TWI Data Register Bit 4 +.equ TWD5, 5 ; TWI Data Register Bit 5 +.equ TWD6, 6 ; TWI Data Register Bit 6 +.equ TWD7, 7 ; TWI Data Register Bit 7 + +; TWAR - TWI (Slave) Address register +.equ I2AR, TWAR ; For compatibility +.equ TWGCE, 0 ; TWI General Call Recognition Enable Bit +.equ TWA0, 1 ; TWI (Slave) Address register Bit 0 +.equ TWA1, 2 ; TWI (Slave) Address register Bit 1 +.equ TWA2, 3 ; TWI (Slave) Address register Bit 2 +.equ TWA3, 4 ; TWI (Slave) Address register Bit 3 +.equ TWA4, 5 ; TWI (Slave) Address register Bit 4 +.equ TWA5, 6 ; TWI (Slave) Address register Bit 5 +.equ TWA6, 7 ; TWI (Slave) Address register Bit 6 + + +; ***** ANALOG_COMPARATOR ************ +; SFIOR - Special Function IO Register +.equ ACME, 3 ; Analog Comparator Multiplexer Enable + +; ACSR - Analog Comparator Control And Status Register +.equ ACIS0, 0 ; Analog Comparator Interrupt Mode Select bit 0 +.equ ACIS1, 1 ; Analog Comparator Interrupt Mode Select bit 1 +.equ ACIC, 2 ; Analog Comparator Input Capture Enable +.equ ACIE, 3 ; Analog Comparator Interrupt Enable +.equ ACI, 4 ; Analog Comparator Interrupt Flag +.equ ACO, 5 ; Analog Compare Output +.equ ACBG, 6 ; Analog Comparator Bandgap Select +.equ ACD, 7 ; Analog Comparator Disable + + +; ***** AD_CONVERTER ***************** +; ADMUX - The ADC multiplexer Selection Register +.equ MUX0, 0 ; Analog Channel and Gain Selection Bits +.equ MUX1, 1 ; Analog Channel and Gain Selection Bits +.equ MUX2, 2 ; Analog Channel and Gain Selection Bits +.equ MUX3, 3 ; Analog Channel and Gain Selection Bits +.equ MUX4, 4 ; Analog Channel and Gain Selection Bits +.equ ADLAR, 5 ; Left Adjust Result +.equ REFS0, 6 ; Reference Selection Bit 0 +.equ REFS1, 7 ; Reference Selection Bit 1 + +; ADCSRA - The ADC Control and Status register +.equ ADCSR, ADCSRA ; For compatibility +.equ ADPS0, 0 ; ADC Prescaler Select Bits +.equ ADPS1, 1 ; ADC Prescaler Select Bits +.equ ADPS2, 2 ; ADC Prescaler Select Bits +.equ ADIE, 3 ; ADC Interrupt Enable +.equ ADIF, 4 ; ADC Interrupt Flag +.equ ADATE, 5 ; When this bit is written to one,the Timer/Counter2 prescaler will be reset.The bit will be cleared by hardware after the operation is performed.Writing a zero to this bit will have no effect.This bit will always be read as zero if Timer/Counter2 is clocked by the internal CPU clock.If this bit is written when Timer/Counter2 is operating in asynchronous mode,the bit will remain one until the prescaler has been reset. +.equ ADFR, ADATE ; For compatibility +.equ ADSC, 6 ; ADC Start Conversion +.equ ADEN, 7 ; ADC Enable + +; ADCH - ADC Data Register High Byte +.equ ADCH0, 0 ; ADC Data Register High Byte Bit 0 +.equ ADCH1, 1 ; ADC Data Register High Byte Bit 1 +.equ ADCH2, 2 ; ADC Data Register High Byte Bit 2 +.equ ADCH3, 3 ; ADC Data Register High Byte Bit 3 +.equ ADCH4, 4 ; ADC Data Register High Byte Bit 4 +.equ ADCH5, 5 ; ADC Data Register High Byte Bit 5 +.equ ADCH6, 6 ; ADC Data Register High Byte Bit 6 +.equ ADCH7, 7 ; ADC Data Register High Byte Bit 7 + +; ADCL - ADC Data Register Low Byte +.equ ADCL0, 0 ; ADC Data Register Low Byte Bit 0 +.equ ADCL1, 1 ; ADC Data Register Low Byte Bit 1 +.equ ADCL2, 2 ; ADC Data Register Low Byte Bit 2 +.equ ADCL3, 3 ; ADC Data Register Low Byte Bit 3 +.equ ADCL4, 4 ; ADC Data Register Low Byte Bit 4 +.equ ADCL5, 5 ; ADC Data Register Low Byte Bit 5 +.equ ADCL6, 6 ; ADC Data Register Low Byte Bit 6 +.equ ADCL7, 7 ; ADC Data Register Low Byte Bit 7 + +; SFIOR - Special Function IO Register +.equ ADTS0, 5 ; ADC Auto Trigger Source 0 +.equ ADTS1, 6 ; ADC Auto Trigger Source 1 +.equ ADTS2, 7 ; ADC Auto Trigger Source 2 + + +; ***** JTAG ************************* +; OCDR - On-Chip Debug Related Register in I/O Memory +.equ OCDR0, 0 ; On-Chip Debug Register Bit 0 +.equ OCDR1, 1 ; On-Chip Debug Register Bit 1 +.equ OCDR2, 2 ; On-Chip Debug Register Bit 2 +.equ OCDR3, 3 ; On-Chip Debug Register Bit 3 +.equ OCDR4, 4 ; On-Chip Debug Register Bit 4 +.equ OCDR5, 5 ; On-Chip Debug Register Bit 5 +.equ OCDR6, 6 ; On-Chip Debug Register Bit 6 +.equ OCDR7, 7 ; On-Chip Debug Register Bit 7 +.equ IDRD, OCDR7 ; For compatibility + +; MCUCSR - MCU Control And Status Register +;.equ JTRF, 4 ; JTAG Reset Flag +;.equ JTD, 7 ; JTAG Interface Disable + + +; ***** BOOT_LOAD ******************** +; SPMCSR - Store Program Memory Control Register +.equ SPMCR, SPMCSR ; For compatibility +.equ SPMEN, 0 ; Store Program Memory Enable +.equ PGERS, 1 ; Page Erase +.equ PGWRT, 2 ; Page Write +.equ BLBSET, 3 ; Boot Lock Bit Set +.equ RWWSRE, 4 ; Read While Write section read enable +.equ ASRE, RWWSRE ; For compatibility +.equ RWWSB, 6 ; Read While Write Section Busy +.equ ASB, RWWSB ; For compatibility +.equ SPMIE, 7 ; SPM Interrupt Enable + + +; ***** PORTA ************************ +; PORTA - Port A Data Register +.equ PORTA0, 0 ; Port A Data Register bit 0 +.equ PA0, 0 ; For compatibility +.equ PORTA1, 1 ; Port A Data Register bit 1 +.equ PA1, 1 ; For compatibility +.equ PORTA2, 2 ; Port A Data Register bit 2 +.equ PA2, 2 ; For compatibility +.equ PORTA3, 3 ; Port A Data Register bit 3 +.equ PA3, 3 ; For compatibility +.equ PORTA4, 4 ; Port A Data Register bit 4 +.equ PA4, 4 ; For compatibility +.equ PORTA5, 5 ; Port A Data Register bit 5 +.equ PA5, 5 ; For compatibility +.equ PORTA6, 6 ; Port A Data Register bit 6 +.equ PA6, 6 ; For compatibility +.equ PORTA7, 7 ; Port A Data Register bit 7 +.equ PA7, 7 ; For compatibility + +; DDRA - Port A Data Direction Register +.equ DDA0, 0 ; Data Direction Register, Port A, bit 0 +.equ DDA1, 1 ; Data Direction Register, Port A, bit 1 +.equ DDA2, 2 ; Data Direction Register, Port A, bit 2 +.equ DDA3, 3 ; Data Direction Register, Port A, bit 3 +.equ DDA4, 4 ; Data Direction Register, Port A, bit 4 +.equ DDA5, 5 ; Data Direction Register, Port A, bit 5 +.equ DDA6, 6 ; Data Direction Register, Port A, bit 6 +.equ DDA7, 7 ; Data Direction Register, Port A, bit 7 + +; PINA - Port A Input Pins +.equ PINA0, 0 ; Input Pins, Port A bit 0 +.equ PINA1, 1 ; Input Pins, Port A bit 1 +.equ PINA2, 2 ; Input Pins, Port A bit 2 +.equ PINA3, 3 ; Input Pins, Port A bit 3 +.equ PINA4, 4 ; Input Pins, Port A bit 4 +.equ PINA5, 5 ; Input Pins, Port A bit 5 +.equ PINA6, 6 ; Input Pins, Port A bit 6 +.equ PINA7, 7 ; Input Pins, Port A bit 7 + + +; ***** PORTB ************************ +; PORTB - Port B Data Register +.equ PORTB0, 0 ; Port B Data Register bit 0 +.equ PB0, 0 ; For compatibility +.equ PORTB1, 1 ; Port B Data Register bit 1 +.equ PB1, 1 ; For compatibility +.equ PORTB2, 2 ; Port B Data Register bit 2 +.equ PB2, 2 ; For compatibility +.equ PORTB3, 3 ; Port B Data Register bit 3 +.equ PB3, 3 ; For compatibility +.equ PORTB4, 4 ; Port B Data Register bit 4 +.equ PB4, 4 ; For compatibility +.equ PORTB5, 5 ; Port B Data Register bit 5 +.equ PB5, 5 ; For compatibility +.equ PORTB6, 6 ; Port B Data Register bit 6 +.equ PB6, 6 ; For compatibility +.equ PORTB7, 7 ; Port B Data Register bit 7 +.equ PB7, 7 ; For compatibility + +; DDRB - Port B Data Direction Register +.equ DDB0, 0 ; Port B Data Direction Register bit 0 +.equ DDB1, 1 ; Port B Data Direction Register bit 1 +.equ DDB2, 2 ; Port B Data Direction Register bit 2 +.equ DDB3, 3 ; Port B Data Direction Register bit 3 +.equ DDB4, 4 ; Port B Data Direction Register bit 4 +.equ DDB5, 5 ; Port B Data Direction Register bit 5 +.equ DDB6, 6 ; Port B Data Direction Register bit 6 +.equ DDB7, 7 ; Port B Data Direction Register bit 7 + +; PINB - Port B Input Pins +.equ PINB0, 0 ; Port B Input Pins bit 0 +.equ PINB1, 1 ; Port B Input Pins bit 1 +.equ PINB2, 2 ; Port B Input Pins bit 2 +.equ PINB3, 3 ; Port B Input Pins bit 3 +.equ PINB4, 4 ; Port B Input Pins bit 4 +.equ PINB5, 5 ; Port B Input Pins bit 5 +.equ PINB6, 6 ; Port B Input Pins bit 6 +.equ PINB7, 7 ; Port B Input Pins bit 7 + + +; ***** PORTC ************************ +; PORTC - Port C Data Register +.equ PORTC0, 0 ; Port C Data Register bit 0 +.equ PC0, 0 ; For compatibility +.equ PORTC1, 1 ; Port C Data Register bit 1 +.equ PC1, 1 ; For compatibility +.equ PORTC2, 2 ; Port C Data Register bit 2 +.equ PC2, 2 ; For compatibility +.equ PORTC3, 3 ; Port C Data Register bit 3 +.equ PC3, 3 ; For compatibility +.equ PORTC4, 4 ; Port C Data Register bit 4 +.equ PC4, 4 ; For compatibility +.equ PORTC5, 5 ; Port C Data Register bit 5 +.equ PC5, 5 ; For compatibility +.equ PORTC6, 6 ; Port C Data Register bit 6 +.equ PC6, 6 ; For compatibility +.equ PORTC7, 7 ; Port C Data Register bit 7 +.equ PC7, 7 ; For compatibility + +; DDRC - Port C Data Direction Register +.equ DDC0, 0 ; Port C Data Direction Register bit 0 +.equ DDC1, 1 ; Port C Data Direction Register bit 1 +.equ DDC2, 2 ; Port C Data Direction Register bit 2 +.equ DDC3, 3 ; Port C Data Direction Register bit 3 +.equ DDC4, 4 ; Port C Data Direction Register bit 4 +.equ DDC5, 5 ; Port C Data Direction Register bit 5 +.equ DDC6, 6 ; Port C Data Direction Register bit 6 +.equ DDC7, 7 ; Port C Data Direction Register bit 7 + +; PINC - Port C Input Pins +.equ PINC0, 0 ; Port C Input Pins bit 0 +.equ PINC1, 1 ; Port C Input Pins bit 1 +.equ PINC2, 2 ; Port C Input Pins bit 2 +.equ PINC3, 3 ; Port C Input Pins bit 3 +.equ PINC4, 4 ; Port C Input Pins bit 4 +.equ PINC5, 5 ; Port C Input Pins bit 5 +.equ PINC6, 6 ; Port C Input Pins bit 6 +.equ PINC7, 7 ; Port C Input Pins bit 7 + + +; ***** PORTD ************************ +; PORTD - Port D Data Register +.equ PORTD0, 0 ; Port D Data Register bit 0 +.equ PD0, 0 ; For compatibility +.equ PORTD1, 1 ; Port D Data Register bit 1 +.equ PD1, 1 ; For compatibility +.equ PORTD2, 2 ; Port D Data Register bit 2 +.equ PD2, 2 ; For compatibility +.equ PORTD3, 3 ; Port D Data Register bit 3 +.equ PD3, 3 ; For compatibility +.equ PORTD4, 4 ; Port D Data Register bit 4 +.equ PD4, 4 ; For compatibility +.equ PORTD5, 5 ; Port D Data Register bit 5 +.equ PD5, 5 ; For compatibility +.equ PORTD6, 6 ; Port D Data Register bit 6 +.equ PD6, 6 ; For compatibility +.equ PORTD7, 7 ; Port D Data Register bit 7 +.equ PD7, 7 ; For compatibility + +; DDRD - Port D Data Direction Register +.equ DDD0, 0 ; Port D Data Direction Register bit 0 +.equ DDD1, 1 ; Port D Data Direction Register bit 1 +.equ DDD2, 2 ; Port D Data Direction Register bit 2 +.equ DDD3, 3 ; Port D Data Direction Register bit 3 +.equ DDD4, 4 ; Port D Data Direction Register bit 4 +.equ DDD5, 5 ; Port D Data Direction Register bit 5 +.equ DDD6, 6 ; Port D Data Direction Register bit 6 +.equ DDD7, 7 ; Port D Data Direction Register bit 7 + +; PIND - Port D Input Pins +.equ PIND0, 0 ; Port D Input Pins bit 0 +.equ PIND1, 1 ; Port D Input Pins bit 1 +.equ PIND2, 2 ; Port D Input Pins bit 2 +.equ PIND3, 3 ; Port D Input Pins bit 3 +.equ PIND4, 4 ; Port D Input Pins bit 4 +.equ PIND5, 5 ; Port D Input Pins bit 5 +.equ PIND6, 6 ; Port D Input Pins bit 6 +.equ PIND7, 7 ; Port D Input Pins bit 7 + + +; ***** WATCHDOG ********************* +; WDTCR - Watchdog Timer Control Register +.equ WDP0, 0 ; Watch Dog Timer Prescaler bit 0 +.equ WDP1, 1 ; Watch Dog Timer Prescaler bit 1 +.equ WDP2, 2 ; Watch Dog Timer Prescaler bit 2 +.equ WDE, 3 ; Watch Dog Enable +.equ WDTOE, 4 ; RW +.equ WDDE, WDTOE ; For compatibility + + + +; ***** LOCKSBITS ******************************************************** +.equ LB1, 0 ; Lock bit +.equ LB2, 1 ; Lock bit +.equ BLB01, 2 ; Boot Lock bit +.equ BLB02, 3 ; Boot Lock bit +.equ BLB11, 4 ; Boot lock bit +.equ BLB12, 5 ; Boot lock bit + + +; ***** FUSES ************************************************************ +; LOW fuse bits +.equ CKSEL0, 0 ; Select Clock Source +.equ CKSEL1, 1 ; Select Clock Source +.equ CKSEL2, 2 ; Select Clock Source +.equ CKSEL3, 3 ; Select Clock Source +.equ SUT0, 4 ; Select start-up time +.equ SUT1, 5 ; Select start-up time +.equ BODEN, 6 ; Brown out detector enable +.equ BODLEVEL, 7 ; Brown out detector trigger level + +; HIGH fuse bits +.equ BOOTRST, 0 ; Select Reset Vector +.equ BOOTSZ0, 1 ; Select Boot Size +.equ BOOTSZ1, 2 ; Select Boot Size +.equ EESAVE, 3 ; EEPROM memory is preserved through chip erase +.equ CKOPT, 4 ; Oscillator Options +.equ SPIEN, 5 ; Enable Serial programming and Data Downloading +.equ JTAGEN, 6 ; Enable JTAG +.equ OCDEN, 7 ; Enable OCD + + + +; ***** CPU REGISTER DEFINITIONS ***************************************** +#define XH r27 +#define XL r26 +#define YH r29 +#define YL r28 +#define ZH r31 +#define ZL r30 + + + +; ***** DATA MEMORY DECLARATIONS ***************************************** +.equ FLASHEND, 0x1fff ; Note: Word address +.equ IOEND, 0x003f +.equ SRAM_START, 0x0060 +.equ SRAM_SIZE, 1024 +.equ RAMEND, 0x045f +.equ XRAMEND, 0x0000 +.equ E2END, 0x01ff +.equ EEPROMEND, 0x01ff +.equ EEADRBITS, 9 +#pragma AVRPART MEMORY PROG_FLASH 16384 +#pragma AVRPART MEMORY EEPROM 512 +#pragma AVRPART MEMORY INT_SRAM SIZE 1024 +#pragma AVRPART MEMORY INT_SRAM START_ADDR 0x60 + + + +; ***** BOOTLOADER DECLARATIONS ****************************************** +.equ NRWW_START_ADDR, 0x1c00 +.equ NRWW_STOP_ADDR, 0x1fff +.equ RWW_START_ADDR, 0x0 +.equ RWW_STOP_ADDR, 0x1bff +.equ PAGESIZE, 64 +.equ FIRSTBOOTSTART, 0x1f80 +.equ SECONDBOOTSTART, 0x1f00 +.equ THIRDBOOTSTART, 0x1e00 +.equ FOURTHBOOTSTART, 0x1c00 +.equ SMALLBOOTSTART, FIRSTBOOTSTART +.equ LARGEBOOTSTART, FOURTHBOOTSTART + + + +; ***** INTERRUPT VECTORS ************************************************ +.equ INT0addr, 0x0002 ; External Interrupt Request 0 +.equ INT1addr, 0x0004 ; External Interrupt Request 1 +.equ OC2addr, 0x0006 ; Timer/Counter2 Compare Match +.equ OVF2addr, 0x0008 ; Timer/Counter2 Overflow +.equ ICP1addr, 0x000a ; Timer/Counter1 Capture Event +.equ OC1Aaddr, 0x000c ; Timer/Counter1 Compare Match A +.equ OC1Baddr, 0x000e ; Timer/Counter1 Compare Match B +.equ OVF1addr, 0x0010 ; Timer/Counter1 Overflow +.equ OVF0addr, 0x0012 ; Timer/Counter0 Overflow +.equ SPIaddr, 0x0014 ; Serial Transfer Complete +.equ URXCaddr, 0x0016 ; USART, Rx Complete +.equ UDREaddr, 0x0018 ; USART Data Register Empty +.equ UTXCaddr, 0x001a ; USART, Tx Complete +.equ ADCCaddr, 0x001c ; ADC Conversion Complete +.equ ERDYaddr, 0x001e ; EEPROM Ready +.equ ACIaddr, 0x0020 ; Analog Comparator +.equ TWIaddr, 0x0022 ; 2-wire Serial Interface +.equ INT2addr, 0x0024 ; External Interrupt Request 2 +.equ OC0addr, 0x0026 ; Timer/Counter0 Compare Match +.equ SPMRaddr, 0x0028 ; Store Program Memory Ready + +.equ INT_VECTORS_SIZE, 42 ; size in words + +#endif /* _M16DEF_INC_ */ + +; ***** END OF FILE ****************************************************** diff --git a/numtest.c b/numtest.c new file mode 100644 index 0000000..50aeca4 --- /dev/null +++ b/numtest.c @@ -0,0 +1,30 @@ +#include <util/delay.h> +#include <string.h> +#include <stdlib.h> +#include "libleds.h" +#include "chars/chars.h" + +static struct led_obj const PANEL = {0, 1<<7, 32, 8}; + +void led_main() +{ + // clear + struct led_color const clear_color = { 0, 0, 0 }; + led_write_rgb_all(PANEL, clear_color); + + const struct led_color active_color = {0x10, 0x10, 0x10}; + const char *text = "0123"; + struct led_color *buf = leds_text(active_color, text); + + if (buf == NULL) { + return; + } + + struct led_color const padding = { 0, 0, 0 }; + for (unsigned int i = 0; i < 4*char_height; i++) + led_write_rgb(PANEL.port, PANEL.pins, padding); + for (unsigned int i = 0; i < char_length * strlen(text); i++) + led_write_rgb(PANEL.port, PANEL.pins, buf[i]); + + free(buf); +} @@ -0,0 +1,24 @@ +#include "libleds.h" + +static struct led_obj const PANEL = {0, 1<<7, 32, 8}; + +void update(int i) +{ + struct led_color const color = {i, i, i}; + led_write_rgb_all(PANEL, color); + led_latch(); +} + +void led_main() +{ + static int const STEP = 0x01; + static int const MIN = 0x00; + static int const MAX = 0xFF; + + while (1) { + for (int i = MIN; i < MAX; i += STEP) + update(i); + for (int i = MAX; i > MIN; i += STEP) + update(i); + } +} @@ -0,0 +1,22 @@ +#include "libleds.h" + +static struct led_obj const PANEL = {0, 1<<7, 32, 8}; +static unsigned char const INTENSITY = 0x01; + +void led_main() +{ + struct led_color const colors[] = { + {0x0000000, 0x0000000, 0x0000000}, + {INTENSITY, 0x0000000, 0x0000000}, + {0x0000000, INTENSITY, 0x0000000}, + {INTENSITY, INTENSITY, 0x0000000}, + {0x0000000, 0x0000000, INTENSITY}, + {INTENSITY, 0x0000000, INTENSITY}, + {0x0000000, INTENSITY, INTENSITY}, + {INTENSITY, INTENSITY, INTENSITY}, + }; + + for(int x = 0; x < PANEL.width; x++) + for (int i = 0; i < (sizeof(colors) / sizeof(colors[0])); i++) + led_write_rgb(PANEL.port, PANEL.pins, colors[i]); +} |
