Create the lantern controller

uart
Savanni D'Gerinel 2022-08-06 14:45:45 -04:00
parent 78cd1908a7
commit 7b4429db35
5 changed files with 106 additions and 27 deletions

View File

@ -89,6 +89,7 @@
(packages."x86_64-linux"."prime-tx" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; })
(packages."x86_64-linux"."radio-rx" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; })
(packages."x86_64-linux"."lantern" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; avr = true; })
(packages."x86_64-linux"."lantern-controller" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; avr = true; })
];
};
@ -257,6 +258,30 @@
];
};
packages."x86_64-linux"."lantern-controller_" =
let
pkgs = import nixpkgs { system = "x86_64-linux"; };
avr = pkgs.pkgsCross.avr.buildPackages;
in packages."x86_64-linux"."lantern-controller" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; avr = true; };
packages."x86_64-linux"."lantern-controller" =
{ gcc, cflags, avr }:
let
pkgs = import nixpkgs { system = "x86_64-linux"; };
in mkProgram {
pkgs = pkgs;
gcc = gcc;
cflags = cflags;
pname = "lantern-controller";
psrc = ./lantern-controller;
inherit avr;
pbuildInputs = [
(packages."x86_64-linux"."dio" { inherit gcc cflags; })
(packages."x86_64-linux"."spi" { inherit gcc cflags; })
(packages."x86_64-linux"."rfm" { inherit gcc cflags; })
];
};
devShell."x86_64-linux" =
let
pkgs = import nixpkgs { system = "x86_64-linux"; };

77
lantern-controller/main.c Normal file
View File

@ -0,0 +1,77 @@
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <dio.h>
#include <rfm.h>
#include <stdbool.h>
#include <string.h>
dio_t buttons[4] = {
{ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 5 },
{ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 6 },
{ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 7 },
{ .ddr = &DDRD, .port = &PORTD, .pin = &PIND, .addr = 6 },
};
typedef struct {
bool button_press[4];
} status_flags_t;
status_flags_t status_flags = {
.button_press = { false, false, false, false }
};
ISR(INT2_vect) {
for (int i = 0; i < 4; i++) {
status_flags.button_press[i] = dio_read(&buttons[i]);
}
}
int main(void) {
EIMSK = 1 << INT2;
EICRA |= 1 << ISC21 | 1 << ISC20;
rfm_t radio = (rfm_t){
.spi = {
.clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 1 },
.data_out = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 2 },
.data_in = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 3 },
.chip_select = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 4 },
},
.irq = { .ddr = &DDRE, .port = &PORTE, .pin = &PINE, .addr = 6 },
.reset = { .ddr = &DDRD, .port = &PORTD, .pin = &PIND, .addr = 4 },
};
rfm_error_e error;
rfm_init(&radio, (uint8_t [4]){ 0xde, 0xca, 0xfb, 0xad }, 4, &error);
set_sleep_mode(SLEEP_MODE_IDLE);
while(1) {
sei();
sleep_mode();
cli();
char msg[60];
if (status_flags.button_press[0]) {
status_flags.button_press[0] = false;
strcpy(msg, "normal");
} else if (status_flags.button_press[1]) {
status_flags.button_press[1] = false;
strcpy(msg, "spooky");
} else if (status_flags.button_press[2]) {
status_flags.button_press[2] = false;
strcpy(msg, "eerie");
} else if (status_flags.button_press[3]) {
status_flags.button_press[3] = false;
strcpy(msg, "flash");
}
rfm_transmit(&radio, (uint8_t *)msg, strlen(msg) + 1);
interrupt_flags_t flags = rfm_interrupts(&radio);
while(!flags.packet_sent) {
_delay_ms(1);
flags = rfm_interrupts(&radio);
}
rfm_standby(&radio);
}
}

View File

@ -26,20 +26,7 @@ You should have received a copy of the GNU General Public License along with thi
#define PULSE_OFF_COUNT FPS * 5
#define PULSE_ON_COUNT 5
uint8_t status_light_value = 0;
dio_t status_light = { .ddr = &DDRC, .port = &PORTC, .pin = &PINC, .addr = 7 };
/*
dio_t buttons[4] = {
{ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 5 },
{ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 6 },
{ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 7 },
{ .ddr = &DDRD, .port = &PORTD, .pin = &PIND, .addr = 6 },
};
*/
typedef struct {
// int button_press[4];
bool frame_timeout;
} status_flags_t;
@ -49,14 +36,6 @@ ISR(TIMER1_COMPA_vect) {
status_flags.frame_timeout = true;
}
/*
ISR(INT2_vect) {
for (int i = 0; i < 4; i++) {
status_flags.button_press[i] = dio_read(&buttons[i]);
}
}
*/
void setup_fps_timer(void) {
// WGM = 0100: CTC with OCR1nA top
// CS = 101: clock / 1024
@ -82,8 +61,6 @@ int main(void) {
*/
status_flags.frame_timeout = false;
dio_set_direction(&status_light, LINE_OUT);
// Disable unneeded modules
PRR0 = _BV(7) | _BV(5) | _BV(2);
PRR1 = _BV(7) | _BV(4) | _BV(3) | _BV(0);

View File

@ -196,7 +196,7 @@ void rfm_transmit(rfm_t *rfm, uint8_t *data, uint8_t length) {
rfm_set_mode(rfm, (op_mode_t){ .listen_on = false, .mode = standby });
_rfm_set_low_power(rfm);
_rfm_write(rfm, REG_FIFO, &length, 1);
_rfm_write(rfm, REG_FIFO, data, length);
_rfm_write(rfm, REG_FIFO, (uint8_t *)data, length);
_rfm_write(rfm, REG_DIO_MAPPING1, (uint8_t [1]){ 0x00 }, 1);
rfm_set_mode(rfm, (op_mode_t){ .listen_on = false, .mode = tx });
}
@ -206,13 +206,13 @@ void rfm_receive_mode(rfm_t *rfm) {
rfm_set_mode(rfm, (op_mode_t){ .listen_on = false, .mode = rx });
}
void rfm_receive(rfm_t *rfm, uint8_t data[66], uint8_t *length) {
void rfm_receive(rfm_t *rfm, uint8_t *data, uint8_t *length) {
_rfm_write(rfm, REG_DIO_MAPPING1, (uint8_t [1]){ _BV(6) }, 1);
rfm_set_mode(rfm, (op_mode_t){ .listen_on = false, .mode = rx });
_rfm_read(rfm, REG_FIFO, length, 1);
if (*length > 0) {
_rfm_read(rfm, 0x00, data, *length);
_rfm_read(rfm, 0x00, (uint8_t *)data, *length);
}
}

View File

@ -76,7 +76,7 @@ void rfm_sleep(rfm_t *);
void rfm_standby(rfm_t *);
void rfm_receive_mode(rfm_t *);
void rfm_transmit(rfm_t *rfm, uint8_t *data, uint8_t length);
void rfm_receive(rfm_t *rfm, uint8_t data[66], uint8_t *length);
void rfm_receive(rfm_t *rfm, uint8_t *data, uint8_t *length);
op_mode_t rfm_mode(rfm_t *rfm);
void rfm_set_mode(rfm_t *rfm, op_mode_t mode);