Demonstrate sleep mode and interrupts
This commit is contained in:
parent
a81d8cec6b
commit
221dcd1541
35
flake.nix
35
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"; };
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
#include <base.h>
|
||||
#include <display.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue