From bff0bb30dd0846a96571f054a4cec75c0c260559 Mon Sep 17 00:00:00 2001 From: Mitchell Marino Date: Fri, 28 Mar 2025 16:46:52 -0500 Subject: [PATCH] led playback --- main/drivers/bottom_half.cpp | 1 + main/drivers/leds.cpp | 17 ++++++++++++ main/drivers/speaker.cpp | 17 ++++++++++++ main/drivers/sseg.cpp | 46 +++++++++++++++++++++++++++++++-- main/drivers/state_tracking.cpp | 29 +++++++++++++-------- main/steps/step2.cpp | 2 +- 6 files changed, 98 insertions(+), 14 deletions(-) diff --git a/main/drivers/bottom_half.cpp b/main/drivers/bottom_half.cpp index defd928..7644bf1 100644 --- a/main/drivers/bottom_half.cpp +++ b/main/drivers/bottom_half.cpp @@ -31,6 +31,7 @@ static void receive_button_switch(); static void receive_touch(); static bool replay_handler(const char* event, char* arg) { + // no reply neccesary return false; } diff --git a/main/drivers/leds.cpp b/main/drivers/leds.cpp index c792ae9..a30317e 100644 --- a/main/drivers/leds.cpp +++ b/main/drivers/leds.cpp @@ -2,12 +2,29 @@ #include "led_strip.h" #include #include "state_tracking.h" +#include static const char* TAG = "leds"; static led_strip_handle_t leds; static bool replay_handler(const char* event, char* arg) { + if (strcmp(event, "LED_SET") == 0) { + uint32_t led = atoi(strtok(arg, ",")); + uint32_t color = atoi(strtok(NULL, ",")); + ESP_LOGI("leds", "color: %ld", color); + led_set(led, color); + return true; + } + if (strcmp(event, "LED_FLUSH") == 0) { + leds_flush(); + return true; + } + if (strcmp(event, "LED_CLR") == 0) { + leds_clear(); + return true; + } + return false; } diff --git a/main/drivers/speaker.cpp b/main/drivers/speaker.cpp index b54a213..e63f85d 100644 --- a/main/drivers/speaker.cpp +++ b/main/drivers/speaker.cpp @@ -31,6 +31,23 @@ QueueHandle_t play_clip_queue; std::vector playing_clips; static bool replay_handler(const char* event, char* arg) { + if (strcmp(event, "PLAY_WAV") == 0) { + char* file_name = strtok(arg, ":"); + char* play_immediately_str = strtok(NULL, ":"); + char* repeat_str = strtok(NULL, ":"); + char* prescaler_str = strtok(NULL, ":"); + + bool play_immediately = strcmp(play_immediately_str, "true") == 0; + bool repeat = strcmp(repeat_str, "true") == 0; + uint8_t prescaler = atoi(prescaler_str); + play_clip_wav(file_name, play_immediately, repeat, prescaler, 0); + return true; + } + if (strcmp(event, "STOP_WAV") == 0) { + stop_clip(arg, 0); + return true; + } + return false; } diff --git a/main/drivers/sseg.cpp b/main/drivers/sseg.cpp index 3e023ca..0401c81 100644 --- a/main/drivers/sseg.cpp +++ b/main/drivers/sseg.cpp @@ -1,12 +1,52 @@ #include "sseg.h" #include #include "state_tracking.h" +#include TM1640* sseg = nullptr; static const char *TAG = "sseg"; static bool replay_handler(const char* event, char* arg) { + if (strcmp(event, "SSEG_G_RAW") == 0) { + uint8_t segments[4]; + segments[0] = atoi(strtok(arg, ",")); + for (int i = 1; i < 4; i++) { + segments[i] = atoi(strtok(NULL, ",")); + } + set_game_sseg_raw(segments); + return true; + } + if (strcmp(event, "SSEG_G_CLR") == 0) { + clear_game_sseg(); + return true; + } + if (strcmp(event, "SSEG_M_RAW") == 0) { + uint8_t segments[4]; + segments[0] = atoi(strtok(arg, ",")); + for (int i = 1; i < 4; i++) { + segments[i] = atoi(strtok(NULL, ",")); + } + set_module_sseg_raw(segments); + return true; + } + if (strcmp(event, "SSEG_M_CLR") == 0) { + clear_module_sseg(); + return true; + } + if (strcmp(event, "SSEG_G") == 0) { + uint32_t value = atoi(strtok(arg, ",")); + uint8_t dot_pos = atoi(strtok(NULL, ",")); + set_game_sseg_num(value, dot_pos); + return true; + } + if (strcmp(event, "SSEG_M") == 0) { + uint32_t value = atoi(strtok(arg, ",")); + uint8_t dot_pos = atoi(strtok(NULL, ",")); + set_module_sseg_num(value, dot_pos); + return true; + } + return false; } @@ -68,6 +108,7 @@ void clear_module_sseg() { } void set_game_sseg_num(uint32_t value, uint8_t dot_pos) { + uint32_t initial_value = value; for (int i = 0; i < 4; i++) { auto idx = value % 10; sseg->sendChar(3-i, TM16XX_NUMBER_FONT[idx], i == dot_pos); @@ -76,12 +117,13 @@ void set_game_sseg_num(uint32_t value, uint8_t dot_pos) { if (is_state_tracking()) { char buf[16]; - sprintf(buf, "%ld,%d", value, dot_pos); + sprintf(buf, "%ld,%d", initial_value, dot_pos); event_occured("SSEG_G", buf); } } void set_module_sseg_num(uint32_t value, uint8_t dot_pos) { + uint32_t initial_value = value; for (int i = 0; i < 4; i++) { auto idx = value % 10; sseg->sendChar(7-i, TM16XX_NUMBER_FONT[idx], i == dot_pos); @@ -90,7 +132,7 @@ void set_module_sseg_num(uint32_t value, uint8_t dot_pos) { if (is_state_tracking()) { char buf[16]; - sprintf(buf, "%ld,%d", value, dot_pos); + sprintf(buf, "%ld,%d", initial_value, dot_pos); event_occured("SSEG_M", buf); } } diff --git a/main/drivers/state_tracking.cpp b/main/drivers/state_tracking.cpp index f191d55..93521cb 100644 --- a/main/drivers/state_tracking.cpp +++ b/main/drivers/state_tracking.cpp @@ -2,6 +2,8 @@ #include #include +static const char* PLAYBACK_TAG = "playback"; + enum state_t { STATE_IDLE = 0, STATE_RECORDING = 1, @@ -44,15 +46,17 @@ static void playback_task(void* arg) { const size_t size = 16*1024; char* buf = (char*) malloc(size*sizeof(char)); if (buf == nullptr) { - ESP_LOGE("playback", "buf alloc failure"); + ESP_LOGE(PLAYBACK_TAG, "buf alloc failure"); vTaskDelete(NULL); } while (state == STATE_PLAYBACK && playback_stream != nullptr) { - fgets(buf, size, playback_stream); - ESP_LOGI("playback", "handling: %s", buf); + char* ret = fgets(buf, size, playback_stream); + if (ret == nullptr) { + break; + } if (buf[0] == '\0') { - ESP_LOGI("playback", "playback done"); + ESP_LOGI(PLAYBACK_TAG, "playback done"); break; } // get rid of the '\n' and possibly '\r' in the string @@ -63,6 +67,7 @@ static void playback_task(void* arg) { break; } } + ESP_LOGI(PLAYBACK_TAG, "handling: %s", buf); // look for a comma, indicating the end of the "ticks" part // TODO: replace with strtok @@ -74,7 +79,7 @@ static void playback_task(void* arg) { } } if (comma_pos == 0) { - ESP_LOGE("playback", "Failed to find comma in playback line"); + ESP_LOGE(PLAYBACK_TAG, "Failed to find comma in playback line"); continue; } @@ -92,7 +97,7 @@ static void playback_task(void* arg) { i++; } if (colon_pos == 0) { - ESP_LOGE("playback", "Failed to find colon in playback line"); + ESP_LOGE(PLAYBACK_TAG, "Failed to find colon in playback line"); continue; } @@ -100,27 +105,29 @@ static void playback_task(void* arg) { char* event_name = buf + (comma_pos + 1); char* arg = buf + (colon_pos + 1); - ESP_LOGI("playback", "going to wait until %ld", tick); int32_t ticks_to_wait = ((int32_t) tick) - (int32_t)(xTaskGetTickCount() - playback_start_time); if (ticks_to_wait < 0) { - ESP_LOGW("playback", "Playback is behind by %ld ticks!", ticks_to_wait); + ESP_LOGW(PLAYBACK_TAG, "Playback is behind by %ld ticks!", ticks_to_wait); } if (ticks_to_wait > 0) { vTaskDelay(ticks_to_wait); } - - ESP_LOGI("playback", "matching..."); bool matched = false; for (const auto& fn : replay_fns) { matched = (fn)(event_name, arg); if (matched) break; } - ESP_LOGI("playback", "matched? %d", matched); + if (!matched) { + ESP_LOGW(PLAYBACK_TAG, "Failed to match event: %s!", event_name); + } } free(buf); + playback_task_handle = NULL; + + stop_playback(); vTaskDelete(NULL); } diff --git a/main/steps/step2.cpp b/main/steps/step2.cpp index e88b0f5..18a6bf0 100644 --- a/main/steps/step2.cpp +++ b/main/steps/step2.cpp @@ -88,6 +88,7 @@ static void new_puzzle(void) { // ESP_LOGI(TAG, "Flipping bit %i on display %i", i, display); } } + set_module_sseg_raw(display_map); } void step2(void) { @@ -98,7 +99,6 @@ void step2(void) { int strike_time = 0; while(solved_times < NUM_SOLVES) { // for every bit in the answer- - set_module_sseg_raw(display_map); if (get_keypad_pressed(&key)) { lcd_clear(); char c = char_of_keypad_key(key);