lil startup animation

This commit is contained in:
2026-05-10 20:16:05 -06:00
parent 9dad0f9390
commit d8150a9bdd
4 changed files with 78 additions and 30 deletions
+6
View File
@@ -5,3 +5,9 @@ int as1115_send_command(uint8_t cmd, uint8_t data) {
uint8_t packet[] = {cmd, data}; uint8_t packet[] = {cmd, data};
return i2c_write(0x00, packet, sizeof packet); return i2c_write(0x00, packet, sizeof packet);
} }
void as1115_blank_display() {
for (int i = 1; i <= 8; i++) {
as1115_send_command(i, 0xFF);
}
}
+1
View File
@@ -21,3 +21,4 @@
#define DIG_6_7_INTENSITY_REG 0x13 #define DIG_6_7_INTENSITY_REG 0x13
int as1115_send_command(uint8_t cmd, uint8_t data); int as1115_send_command(uint8_t cmd, uint8_t data);
void as1115_blank_display();
+4 -2
View File
@@ -5,7 +5,9 @@
#define OSCILLATOR_CALIBRATION 0x76 #define OSCILLATOR_CALIBRATION 0x76
#define MAIN_TIME 30 * 1000L #define MAIN_TIME 60 * 1000L
// #define TIME_INCREMENT 30*1000L // #define TIME_INCREMENT 10*1000L
#define INCREMENT_MODE MODE_FISCHER #define INCREMENT_MODE MODE_FISCHER
#define RESET_DELAY 3000 #define RESET_DELAY 3000
#define STARTUP_ANIMATION
#define DISPLAY_BRIGHTNESS 0x06
+67 -28
View File
@@ -1,5 +1,6 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -15,11 +16,28 @@
#define PLAYER_A_BUTTON 0 #define PLAYER_A_BUTTON 0
#define PLAYER_B_BUTTON 1 #define PLAYER_B_BUTTON 1
PROGMEM const uint8_t startup_animation[][8] = {
{0xFF, 0xFF, 0xFF, 0x0A, 0x0A, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF},
{0xFF, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0xFF},
{0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A},
{0xFF, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0xFF},
{0xFF, 0xFF, 0x0A, 0xFF, 0xFF, 0x0A, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0x0A, 0x0A, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
};
volatile uint32_t ms_since_boot = 0; volatile uint32_t ms_since_boot = 0;
typedef enum { STOPPED, PLAYER_A, PLAYER_B } state_type; typedef enum { STARTUP, STOPPED, PLAYER_A, PLAYER_B } state_type;
volatile state_type state = STOPPED; #ifdef STARTUP_ANIMATION
#define INITIAL_STATE STARTUP
#else
#define INITIAL_STATE STOPPED
#endif
volatile state_type state = INITIAL_STATE;
volatile uint32_t player_a_timer = MAIN_TIME; volatile uint32_t player_a_timer = MAIN_TIME;
volatile uint32_t player_b_timer = MAIN_TIME; volatile uint32_t player_b_timer = MAIN_TIME;
@@ -151,6 +169,24 @@ void reset() {
render_timer(player_b_timer, DISPLAY_RIGHT); render_timer(player_b_timer, DISPLAY_RIGHT);
} }
void handle_buttons() {
cli();
if (button_pressed(PLAYER_A_BUTTON) && state != PLAYER_B &&
player_b_timer != 0 && player_a_timer != 0) {
player_a_timer += get_increment(player_a_timer);
state = PLAYER_B;
move_started_at = player_b_timer;
}
if (button_pressed(PLAYER_B_BUTTON) && state != PLAYER_A &&
player_b_timer != 0 && player_a_timer != 0) {
player_b_timer += get_increment(player_b_timer);
state = PLAYER_A;
move_started_at = player_a_timer;
}
sei();
}
int main() { int main() {
cli(); cli();
setupio(); setupio();
@@ -158,37 +194,40 @@ int main() {
setup_clock(); setup_clock();
sei(); sei();
render_timer(MAIN_TIME, DISPLAY_LEFT); as1115_blank_display();
render_timer(MAIN_TIME, DISPLAY_RIGHT);
as1115_send_command(DECODE_MODE_REG, 0xFF); // decode as1115_send_command(DECODE_MODE_REG, 0xFF); // decode
as1115_send_command(SCAN_LIMIT_REG, 0x07); // enable all digits as1115_send_command(SCAN_LIMIT_REG, 0x07); // enable all digits
as1115_send_command(GLOBAL_INTENSITY_REG, 0x06); // set brightness as1115_send_command(GLOBAL_INTENSITY_REG,
as1115_send_command(SHUTDOWN_REG, 0x01); // turn on DISPLAY_BRIGHTNESS); // set brightness
as1115_send_command(SHUTDOWN_REG, 0x01); // turn on
while (true) { while (true) {
render_timer(player_a_timer, DISPLAY_LEFT); switch (state) {
render_timer(player_b_timer, DISPLAY_RIGHT); case STARTUP: {
size_t frame = ms_since_boot / 100;
if (frame >= sizeof startup_animation / 8) {
state = STOPPED;
break;
}
cli(); for (int i = 0; i < 8; i++) {
if (button_pressed(PLAYER_A_BUTTON) && state != PLAYER_B && uint8_t byte = pgm_read_byte(&startup_animation[frame][i]);
player_b_timer != 0 && player_a_timer != 0) { as1115_send_command(i + 1, byte);
player_a_timer += get_increment(player_a_timer); }
state = PLAYER_B; break;
move_started_at = player_b_timer;
} }
case PLAYER_A:
if (button_pressed(PLAYER_B_BUTTON) && state != PLAYER_A && case PLAYER_B:
player_b_timer != 0 && player_a_timer != 0) { case STOPPED:
player_b_timer += get_increment(player_b_timer); render_timer(player_a_timer, DISPLAY_LEFT);
state = PLAYER_A; render_timer(player_b_timer, DISPLAY_RIGHT);
move_started_at = player_a_timer; handle_buttons();
} if (state == STOPPED && (player_a_timer == 0 || player_b_timer == 0) &&
sei(); (ms_since_boot > finished_at + RESET_DELAY)) {
reset();
if (state == STOPPED && (player_a_timer == 0 || player_b_timer == 0) && }
(ms_since_boot > finished_at + RESET_DELAY)) { break;
reset();
} }
} }
} }