diff --git a/src/as1115.c b/src/as1115.c index b391e20..b155550 100644 --- a/src/as1115.c +++ b/src/as1115.c @@ -5,3 +5,9 @@ int as1115_send_command(uint8_t cmd, uint8_t data) { uint8_t packet[] = {cmd, data}; return i2c_write(0x00, packet, sizeof packet); } + +void as1115_blank_display() { + for (int i = 1; i <= 8; i++) { + as1115_send_command(i, 0xFF); + } +} diff --git a/src/as1115.h b/src/as1115.h index 77f97a3..1c202d1 100644 --- a/src/as1115.h +++ b/src/as1115.h @@ -21,3 +21,4 @@ #define DIG_6_7_INTENSITY_REG 0x13 int as1115_send_command(uint8_t cmd, uint8_t data); +void as1115_blank_display(); diff --git a/src/config.h b/src/config.h index 0f5a435..2831253 100644 --- a/src/config.h +++ b/src/config.h @@ -5,7 +5,9 @@ #define OSCILLATOR_CALIBRATION 0x76 -#define MAIN_TIME 30 * 1000L -// #define TIME_INCREMENT 30*1000L +#define MAIN_TIME 60 * 1000L +// #define TIME_INCREMENT 10*1000L #define INCREMENT_MODE MODE_FISCHER #define RESET_DELAY 3000 +#define STARTUP_ANIMATION +#define DISPLAY_BRIGHTNESS 0x06 diff --git a/src/main.c b/src/main.c index ee8b179..8d36295 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -15,11 +16,28 @@ #define PLAYER_A_BUTTON 0 #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; -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_b_timer = MAIN_TIME; @@ -151,6 +169,24 @@ void reset() { 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() { cli(); setupio(); @@ -158,37 +194,40 @@ int main() { setup_clock(); sei(); - render_timer(MAIN_TIME, DISPLAY_LEFT); - render_timer(MAIN_TIME, DISPLAY_RIGHT); + as1115_blank_display(); - as1115_send_command(DECODE_MODE_REG, 0xFF); // decode - as1115_send_command(SCAN_LIMIT_REG, 0x07); // enable all digits - as1115_send_command(GLOBAL_INTENSITY_REG, 0x06); // set brightness - as1115_send_command(SHUTDOWN_REG, 0x01); // turn on + as1115_send_command(DECODE_MODE_REG, 0xFF); // decode + as1115_send_command(SCAN_LIMIT_REG, 0x07); // enable all digits + as1115_send_command(GLOBAL_INTENSITY_REG, + DISPLAY_BRIGHTNESS); // set brightness + as1115_send_command(SHUTDOWN_REG, 0x01); // turn on while (true) { - render_timer(player_a_timer, DISPLAY_LEFT); - render_timer(player_b_timer, DISPLAY_RIGHT); + switch (state) { + case STARTUP: { + size_t frame = ms_since_boot / 100; + if (frame >= sizeof startup_animation / 8) { + state = STOPPED; + break; + } - 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; + for (int i = 0; i < 8; i++) { + uint8_t byte = pgm_read_byte(&startup_animation[frame][i]); + as1115_send_command(i + 1, byte); + } + break; } - - 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(); - - if (state == STOPPED && (player_a_timer == 0 || player_b_timer == 0) && - (ms_since_boot > finished_at + RESET_DELAY)) { - reset(); + case PLAYER_A: + case PLAYER_B: + case STOPPED: + render_timer(player_a_timer, DISPLAY_LEFT); + render_timer(player_b_timer, DISPLAY_RIGHT); + handle_buttons(); + if (state == STOPPED && (player_a_timer == 0 || player_b_timer == 0) && + (ms_since_boot > finished_at + RESET_DELAY)) { + reset(); + } + break; } } }