diff --git a/base/include/base.h b/base/include/base.h index 0dbaf7e..7ec9502 100644 --- a/base/include/base.h +++ b/base/include/base.h @@ -15,5 +15,15 @@ inline void clear_pin(io_pin_t *pin) { *(pin->port) &= 0xff ^ (1 << pin->pin); } +typedef struct RNG { + uint8_t mod; + int8_t a; + int8_t c; + uint8_t seed; +} rng_t; + +rng_t rng_new(uint8_t seed); + +uint8_t rng_sample(rng_t *state); #endif diff --git a/base/src/base.c b/base/src/base.c new file mode 100644 index 0000000..fc30f2e --- /dev/null +++ b/base/src/base.c @@ -0,0 +1,12 @@ +#include "../base.h" + + + +rng_t rng_new(uint8_t seed) { + return { .mod = 255, .a = 253, .c = 41, .seed = seed }; +} + +uint8_t rng_sample(rng_t *state) { + state->seed = (state->a * state->seed + state->c) % state->mod; + return state->seed; +} diff --git a/flake.nix b/flake.nix index 62a860e..b9ba0c2 100644 --- a/flake.nix +++ b/flake.nix @@ -25,6 +25,7 @@ }; */ + /* defaultPackage."x86_64-linux" = let pkgs = import nixpkgs { system = "x86_64-linux"; }; @@ -48,6 +49,7 @@ cp main.elf main.hex $out ''; }; + */ devShell."x86_64-linux" = let @@ -55,12 +57,18 @@ avr = with pkgs.pkgsCross.avr.buildPackages; [ binutils gcc + gdb avrdude + simavr + gtkwave ]; in pkgs.mkShell { name = "Wearables-shell"; buildInputs = avr; + + GCC="${pkgs.pkgsCross.avr.buildPackages.gcc}"; + AVR="${pkgs.avrlibc}"; }; }; } diff --git a/sk9822/Makefile b/sk9822/Makefile new file mode 100644 index 0000000..12252bf --- /dev/null +++ b/sk9822/Makefile @@ -0,0 +1,23 @@ +MCU=attiny85 +CHIP_SELECT=AVR_ATtiny85 +F_CPU=8000000 +CFLAGS=-O -finline-functions -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=${F_CPU} -std=gnu99 -D__${CHIP_SELECT}__=1 +LINKFLAGS=-mmcu=${MCU} + +OBJECTS= main.o \ + sk9822.o + +.SUFFIXES: .c .o .h + +%.o: %.c %.h + ${GCC}/bin/avr-gcc ${CFLAGS} ${AVR}/avr/include -I../base/include/ -o $@ -c $< + +main: main.o sk9822.o + # ${GCC}/bin/avr-gcc ${CFLAGS} -I../base/include/ -E -o main.E src/main.c + # ${GCC}/bin/avr-gcc ${CFLAGS} -I../base/include/ -S -o main.S src/main.c + ${GCC}/bin/avr-gcc ${CFLAGS} ${LINKFLAGS} -I../base/include/ -o main.elf main.o sk9822.o + ${OBJCOPY} -O ihex main.elf main.hex + +clean: + rm *.o make.elf main.hex main.S main.E + diff --git a/sk9822/main.c b/sk9822/main.c new file mode 100644 index 0000000..fff6fe0 --- /dev/null +++ b/sk9822/main.c @@ -0,0 +1,51 @@ +#include +#include + +#include +#include "sk9822.h" + +uint8_t random_step(uint8_t value, uint8_t min, uint8_t max, rng_t *rng) { + int8_t step = (rng_sample(rng) % 32) - 16; + uint16_t new_value = value + step; + if (new_value > max) { + return max; + } else if (new_value < min) { + return min; + } else { + return new_value; + } +} + +void flicker(rgb_t *pixel, rng_t *rng) { + pixel->r = random_step(pixel->r, 180, 255, rng); + pixel->g = random_step(pixel->g, 10, 40, rng); +} + +int main (void) { + DDRB = _BV(2) | _BV(1) | _BV(0); + PORTB = 0; + _delay_ms(50); + + io_pin_t data_pin = { .port = &PORTB, .pin = 0 }; + io_pin_t clock_pin = { .port = &PORTB, .pin = 2 }; + + rgb_t lamps[2] = { { .brightness = 9, .r = 212, .g = 50, .b = 0 }, + { .brightness = 1, .r = 0, .g = 0, .b = 0 } }; + + int8_t step_1 = 1; + rng_t rng = rng_new(0); + while (1) { + send_pixels(data_pin, clock_pin, lamps, 2); + + flicker(&lamps[0], &rng); + + lamps[1].r += step_1; + + if (lamps[1].r == 255) { + step_1 = -1; + } else if (lamps[1].r == 0) { + step_1 = 1; + } + _delay_ms(16); + } +} diff --git a/sk9822/sk9822.c b/sk9822/sk9822.c new file mode 100644 index 0000000..4d5d6b8 --- /dev/null +++ b/sk9822/sk9822.c @@ -0,0 +1,36 @@ +void send_byte(io_pin_t data_pin, io_pin_t clock_pin, uint8_t byte) { + for (int i = 7; i >= 0; i--) { + if (byte & _BV(i)) { + (*data_pin.port) |= _BV(data_pin.pin); + } else { + (*data_pin.port) &= ~(_BV(data_pin.pin)); + } + (*clock_pin.port) |= _BV(clock_pin.pin); + (*clock_pin.port) &= ~(_BV(clock_pin.pin)); + } +} + +void send_start(io_pin_t data_pin, io_pin_t clock_pin) { + send_byte(data_pin, clock_pin, 0); + send_byte(data_pin, clock_pin, 0); + send_byte(data_pin, clock_pin, 0); + send_byte(data_pin, clock_pin, 0); +} + +void send_term(io_pin_t data_pin, io_pin_t clock_pin) { + send_byte(data_pin, clock_pin, 0xff); + send_byte(data_pin, clock_pin, 0xff); + send_byte(data_pin, clock_pin, 0xff); + send_byte(data_pin, clock_pin, 0xff); +} + +void send_pixels(io_pin_t data_pin, io_pin_t clock_pin, rgb_t * pixels, uint8_t count) { + send_start(data_pin, clock_pin); + for (uint8_t i = 0; i < count; i++) { + send_byte(data_pin, clock_pin, 0xe0 + pixels[i].brightness); + send_byte(data_pin, clock_pin, pixels[i].r); + send_byte(data_pin, clock_pin, pixels[i].b); + send_byte(data_pin, clock_pin, pixels[i].g); + } + send_term(data_pin, clock_pin); +} diff --git a/sk9822/sk9822.h b/sk9822/sk9822.h new file mode 100644 index 0000000..8357537 --- /dev/null +++ b/sk9822/sk9822.h @@ -0,0 +1,10 @@ +#include + +typedef struct RGB_s { + uint8_t brightness; + uint8_t r; + uint8_t g; + uint8_t b; +} rgb_t; + +void send_pixels(io_pin_t data_pin, io_pin_t clock_pin, rgb_t *pixels, uint8_t count);