Create the lantern controller
This commit is contained in:
parent
78cd1908a7
commit
7b4429db35
25
flake.nix
25
flake.nix
|
@ -89,6 +89,7 @@
|
||||||
(packages."x86_64-linux"."prime-tx" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; })
|
(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"."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" { 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" =
|
devShell."x86_64-linux" =
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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_OFF_COUNT FPS * 5
|
||||||
#define PULSE_ON_COUNT 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 {
|
typedef struct {
|
||||||
// int button_press[4];
|
|
||||||
bool frame_timeout;
|
bool frame_timeout;
|
||||||
} status_flags_t;
|
} status_flags_t;
|
||||||
|
|
||||||
|
@ -49,14 +36,6 @@ ISR(TIMER1_COMPA_vect) {
|
||||||
status_flags.frame_timeout = true;
|
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) {
|
void setup_fps_timer(void) {
|
||||||
// WGM = 0100: CTC with OCR1nA top
|
// WGM = 0100: CTC with OCR1nA top
|
||||||
// CS = 101: clock / 1024
|
// CS = 101: clock / 1024
|
||||||
|
@ -82,8 +61,6 @@ int main(void) {
|
||||||
*/
|
*/
|
||||||
status_flags.frame_timeout = false;
|
status_flags.frame_timeout = false;
|
||||||
|
|
||||||
dio_set_direction(&status_light, LINE_OUT);
|
|
||||||
|
|
||||||
// Disable unneeded modules
|
// Disable unneeded modules
|
||||||
PRR0 = _BV(7) | _BV(5) | _BV(2);
|
PRR0 = _BV(7) | _BV(5) | _BV(2);
|
||||||
PRR1 = _BV(7) | _BV(4) | _BV(3) | _BV(0);
|
PRR1 = _BV(7) | _BV(4) | _BV(3) | _BV(0);
|
||||||
|
|
|
@ -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_mode(rfm, (op_mode_t){ .listen_on = false, .mode = standby });
|
||||||
_rfm_set_low_power(rfm);
|
_rfm_set_low_power(rfm);
|
||||||
_rfm_write(rfm, REG_FIFO, &length, 1);
|
_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_write(rfm, REG_DIO_MAPPING1, (uint8_t [1]){ 0x00 }, 1);
|
||||||
rfm_set_mode(rfm, (op_mode_t){ .listen_on = false, .mode = tx });
|
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 });
|
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_write(rfm, REG_DIO_MAPPING1, (uint8_t [1]){ _BV(6) }, 1);
|
||||||
rfm_set_mode(rfm, (op_mode_t){ .listen_on = false, .mode = rx });
|
rfm_set_mode(rfm, (op_mode_t){ .listen_on = false, .mode = rx });
|
||||||
_rfm_read(rfm, REG_FIFO, length, 1);
|
_rfm_read(rfm, REG_FIFO, length, 1);
|
||||||
|
|
||||||
if (*length > 0) {
|
if (*length > 0) {
|
||||||
_rfm_read(rfm, 0x00, data, *length);
|
_rfm_read(rfm, 0x00, (uint8_t *)data, *length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ void rfm_sleep(rfm_t *);
|
||||||
void rfm_standby(rfm_t *);
|
void rfm_standby(rfm_t *);
|
||||||
void rfm_receive_mode(rfm_t *);
|
void rfm_receive_mode(rfm_t *);
|
||||||
void rfm_transmit(rfm_t *rfm, uint8_t *data, uint8_t length);
|
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);
|
op_mode_t rfm_mode(rfm_t *rfm);
|
||||||
void rfm_set_mode(rfm_t *rfm, op_mode_t mode);
|
void rfm_set_mode(rfm_t *rfm, op_mode_t mode);
|
||||||
|
|
Loading…
Reference in New Issue