From 68b5f182af145fdd9e62c9dde3eedcb9108f5ba4 Mon Sep 17 00:00:00 2001 From: Tobias Wiese Date: Mon, 3 May 2021 23:58:30 +0200 Subject: Initial commit Signed-off-by: Tobias Wiese --- .gitignore | 5 + Makefile | 91 ++++++ base.c | 20 ++ blink.c | 23 ++ chars/0.xbm | 4 + chars/0.xcf | Bin 0 -> 873 bytes chars/1.xbm | 4 + chars/1.xcf | Bin 0 -> 867 bytes chars/2.xbm | 4 + chars/2.xcf | Bin 0 -> 831 bytes chars/3.xbm | 4 + chars/3.xcf | Bin 0 -> 831 bytes chars/4.xbm | 4 + chars/4.xcf | Bin 0 -> 855 bytes chars/5.xbm | 4 + chars/5.xcf | Bin 0 -> 831 bytes chars/6.xbm | 4 + chars/6.xcf | Bin 0 -> 831 bytes chars/7.xbm | 4 + chars/7.xcf | Bin 0 -> 855 bytes chars/8.xbm | 4 + chars/8.xcf | Bin 0 -> 831 bytes chars/9.xbm | 4 + chars/9.xcf | Bin 0 -> 831 bytes chars/chars.c | 118 ++++++++ chars/chars.h | 10 + chars/space.xbm | 4 + chars/space.xcf | Bin 0 -> 771 bytes color.c | 13 + fade.c | 41 +++ img_mono.c | 58 ++++ img_mono.xbm | 6 + libleds.c | 14 + libleds.h | 55 ++++ libleds_asm.S | 92 ++++++ m16def.inc | 862 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ numtest.c | 30 ++ pulse.c | 24 ++ test.c | 22 ++ 39 files changed, 1528 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 base.c create mode 100644 blink.c create mode 100644 chars/0.xbm create mode 100644 chars/0.xcf create mode 100644 chars/1.xbm create mode 100644 chars/1.xcf create mode 100644 chars/2.xbm create mode 100644 chars/2.xcf create mode 100644 chars/3.xbm create mode 100644 chars/3.xcf create mode 100644 chars/4.xbm create mode 100644 chars/4.xcf create mode 100644 chars/5.xbm create mode 100644 chars/5.xcf create mode 100644 chars/6.xbm create mode 100644 chars/6.xcf create mode 100644 chars/7.xbm create mode 100644 chars/7.xcf create mode 100644 chars/8.xbm create mode 100644 chars/8.xcf create mode 100644 chars/9.xbm create mode 100644 chars/9.xcf create mode 100644 chars/chars.c create mode 100644 chars/chars.h create mode 100644 chars/space.xbm create mode 100644 chars/space.xcf create mode 100644 color.c create mode 100644 fade.c create mode 100644 img_mono.c create mode 100644 img_mono.xbm create mode 100644 libleds.c create mode 100644 libleds.h create mode 100644 libleds_asm.S create mode 100644 m16def.inc create mode 100644 numtest.c create mode 100644 pulse.c create mode 100644 test.c 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 diff --git a/base.c b/base.c new file mode 100644 index 0000000..5ebe2a7 --- /dev/null +++ b/base.c @@ -0,0 +1,20 @@ +#include +#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; +} diff --git a/blink.c b/blink.c new file mode 100644 index 0000000..7bf248f --- /dev/null +++ b/blink.c @@ -0,0 +1,23 @@ +#include +#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 new file mode 100644 index 0000000..a3ab875 Binary files /dev/null and b/chars/0.xcf differ 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 new file mode 100644 index 0000000..9ca02a3 Binary files /dev/null and b/chars/1.xcf differ 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 new file mode 100644 index 0000000..05d2415 Binary files /dev/null and b/chars/2.xcf differ 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 new file mode 100644 index 0000000..f1796d3 Binary files /dev/null and b/chars/3.xcf differ 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 new file mode 100644 index 0000000..6eb8a27 Binary files /dev/null and b/chars/4.xcf differ 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 new file mode 100644 index 0000000..48b178e Binary files /dev/null and b/chars/5.xcf differ 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 new file mode 100644 index 0000000..402e31c Binary files /dev/null and b/chars/6.xcf differ 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 new file mode 100644 index 0000000..49ad0eb Binary files /dev/null and b/chars/7.xcf differ 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 new file mode 100644 index 0000000..879b641 Binary files /dev/null and b/chars/8.xcf differ 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 new file mode 100644 index 0000000..8c7c6fd Binary files /dev/null and b/chars/9.xcf differ 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 +#include +#include + +#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 new file mode 100644 index 0000000..c32a481 Binary files /dev/null and b/chars/space.xcf differ diff --git a/color.c b/color.c new file mode 100644 index 0000000..f7c1261 --- /dev/null +++ b/color.c @@ -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); +} diff --git a/fade.c b/fade.c new file mode 100644 index 0000000..09d6233 --- /dev/null +++ b/fade.c @@ -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 +#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 +#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 + +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< +#include +#include +#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); +} diff --git a/pulse.c b/pulse.c new file mode 100644 index 0000000..d5d186e --- /dev/null +++ b/pulse.c @@ -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); + } +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..176223f --- /dev/null +++ b/test.c @@ -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]); +} -- cgit v1.2.3