diff --git a/flake.nix b/flake.nix index 10be19d..257aafe 100644 --- a/flake.nix +++ b/flake.nix @@ -327,7 +327,7 @@ lib = pkgs.lib; avr = pkgs.pkgsCross.avr.buildPackages; in pkgs.stdenv.mkDerivation rec { - name = "prime-tx"; + name = "radio-rx"; src = ./.; buildInputs = [ @@ -353,6 +353,39 @@ ''; }; + packages."x86_64-linux"."interrupts-standalone" = (packages."x86_64-linux"."interrupts" atmega32u4); + + packages."x86_64-linux"."interrupts" = + { mcu, chip_select, f_cpu }: + let + pkgs = import nixpkgs { system = "x86_64-linux"; }; + lib = pkgs.lib; + avr = pkgs.pkgsCross.avr.buildPackages; + in pkgs.stdenv.mkDerivation rec { + name = "interrupts"; + src = ./.; + + buildInputs = [ + (packages."x86_64-linux"."base" { inherit mcu chip_select f_cpu; }) + (packages."x86_64-linux"."shift-register" { inherit mcu chip_select f_cpu; }) + (packages."x86_64-linux"."display" { inherit mcu chip_select f_cpu; }) + ]; + + CFLAGS = cflags { inherit mcu chip_select f_cpu; }; + INCLUDE_DIRS = pkgs.lib.concatStringsSep " " (map (dir: "-I${dir}") buildInputs); + OBJECT_FILES = pkgs.lib.concatStringsSep " " (map (dir: "${dir}/*.o") buildInputs); + + buildPhase = '' + ${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o main.o -c ${src}/interrupts/main.c + ${avr.gcc}/bin/avr-gcc ${CFLAGS} -o interrupts.elf main.o ${OBJECT_FILES} + $OBJCOPY -O ihex interrupts.elf interrupts.hex + ''; + installPhase = '' + mkdir $out + cp interrupts.elf interrupts.hex $out + ''; + }; + devShell."x86_64-linux" = let pkgs = import nixpkgs { system = "x86_64-linux"; }; diff --git a/interrupts/main.c b/interrupts/main.c new file mode 100644 index 0000000..ea384e8 --- /dev/null +++ b/interrupts/main.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include + +dio_t light = { .ddr = &DDRC, .port = &PORTC, .pin = &PINC, .addr = 7 }; +dio_t interrupt_line = { .ddr = &DDRD, .port = &PORTD, .pin = &PIND, .addr = 2 }; + +bool button_values[4] = { false, false, false, false }; +dio_t buttons[4] = { + { .ddr = &DDRD, .port = &PORTD, .pin = &PIND, .addr = 6 }, + { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 7 }, + { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 6 }, + { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 5 }, +}; + + +ISR(INT2_vect) { + dio_set(&light, 1); + for (int i = 0; i < 4; i++) { + button_values[i] = dio_read(&buttons[i]); + } +} + +void display_buttons(display_t *display) { + char msg[16]; + + snprintf(msg, 16, ": %d %d %d %d", button_values[0], button_values[1], button_values[2], button_values[3]); + display_clear(display); + display_write_message(display, msg); +} + +int main(void) { + EIMSK = 1 << INT2; + EICRA |= 1 << ISC21 | 1 << ISC20; + + display_t display = { + .reg = { + .output = { .ddr = &DDRF, .port = &PORTF, .pin = &PINF, .addr = 7 }, + .shift_clock = { .ddr = &DDRF, .port = &PORTF, .pin = &PINF, .addr = 6 }, + .latch_clock = { .ddr = &DDRF, .port = &PORTF, .pin = &PINF, .addr = 5 }, + } + }; + display_init(&display); + + dio_set_direction(&light, LINE_OUT); + dio_set_direction(&interrupt_line, LINE_IN); + for (int i = 0; i < 4; i++) { + dio_set_direction(&buttons[i], LINE_IN); + } + + set_sleep_mode(SLEEP_MODE_IDLE); + while (1) { + display_buttons(&display); + dio_set(&light, 0); + + sei(); + sleep_mode(); + cli(); + } + + return 0; +}