From 6a798e96e991c2faa3ae325e01ffc60d0ebd0c20 Mon Sep 17 00:00:00 2001 From: Mitchell Marino Date: Fri, 28 Mar 2025 01:58:48 -0500 Subject: [PATCH] preliminary tft state tracking --- main/drivers/tft.cpp | 62 +++++++++++++++++++++++++++++++++++--------- main/main.cpp | 12 ++++++++- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/main/drivers/tft.cpp b/main/drivers/tft.cpp index 1bbd6d6..e3b2f12 100644 --- a/main/drivers/tft.cpp +++ b/main/drivers/tft.cpp @@ -1,4 +1,5 @@ #include "tft.h" +#include "state_tracking.h" static const char* TAG = "tft"; @@ -26,6 +27,14 @@ static bool notify_lvgl_flush_ready( return false; } +const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +/// Base 64 encodes a u16... sort of. This doesn't do any of the fancy padding stuff. +static void encode_base64(char* buf, size_t start_idx, uint16_t value) { + buf[start_idx+0] = base64_chars[(value >> 10) & 0x3F]; + buf[start_idx+1] = base64_chars[(value >> 4) & 0x3F]; + buf[start_idx+2] = base64_chars[(value << 2) & 0x3F]; +} + static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) { esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data; @@ -33,7 +42,46 @@ static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t int offsetx2 = area->x2; int offsety1 = area->y1; int offsety2 = area->y2; + esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map); + + // TODO: change this to be a kconfig value + #if true + + if (is_state_tracking()) { + size_t size = (offsetx2 + 1 - offsetx1) * (offsety2 + 1 - offsety1) + 1; + // if (size > 1024) { + // ESP_LOGW("tft_track_state", "Write too big (%d)! truncating to 1024!", size); + // } + // size = MIN(1024, size); + + + // 24 bytes for the offsets + // 3 bytes per encoded color + // 1 byte for null terminator + size_t alloc_size = 24 + size * 3 + 1; + char* buf = (char*)malloc(alloc_size); + + if (buf != nullptr) { + size_t initial_offset = sprintf(buf, "%d,%d,%d,%d:", offsetx1, offsety1, offsetx2 + 1, offsety2 + 1); + + for (size_t i = 0; i < size; i++) { + size_t index = initial_offset + i * 3; + + // we assume that the size of the color data is 16b + static_assert(sizeof(lv_color_t) == sizeof(uint16_t), "lv_color_t must be 16b wide"); + encode_base64(buf, index, color_map[i].full); + } + buf[initial_offset + (size-1) * 3 + 1] = '\0'; + + event_occured("TFT_W", buf); + free(buf); + } else { + ESP_LOGE("tft_track_state", "buffer alloc failed!"); + } + } + + #endif } static void IRAM_ATTR lv_tick_task(void *param) { @@ -150,10 +198,10 @@ static void guiTask(void *pvParameter) { ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &periodic_timer)); ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LVGL_UPDATE_PERIOD_MS * 1000)); - screen = lv_disp_get_scr_act(NULL); + screen = lv_scr_act(); lv_style_init(&style_screen); lv_style_set_bg_color(&style_screen, lv_color_black()); - lv_obj_add_style(lv_scr_act(), &style_screen, LV_STATE_DEFAULT); + lv_obj_add_style(screen, &style_screen, LV_STATE_DEFAULT); while (1) { /* Delay 1 tick (assumes FreeRTOS tick is 10ms */ @@ -169,14 +217,6 @@ static void guiTask(void *pvParameter) { vTaskDelete(NULL); } -static void tick_timer_task(void* arg) { - while (1) - { - lv_task_handler(); - vTaskDelay(pdMS_TO_TICKS(10)); - } -} - void init_tft() { ESP_LOGI(TAG, "Initializing TFT..."); @@ -184,7 +224,5 @@ void init_tft() { initialize_display(); xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 5, NULL, 1); - // xTaskCreatePinnedToCore(tick_timer_task, "tick_lvgl", 4096, NULL, 5, NULL, 1); - ESP_LOGI(TAG, "TFT initialized!"); } diff --git a/main/main.cpp b/main/main.cpp index 498c617..1d3b626 100755 --- a/main/main.cpp +++ b/main/main.cpp @@ -5,6 +5,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_rom_gpio.h" +#include "esp_heap_caps.h" #include "drivers/all.h" #include "drivers/state_tracking.h" @@ -35,6 +36,15 @@ extern "C" void app_main(void) { init_wires(); vTaskDelay(pdMS_TO_TICKS(1000)); + char* str = (char*) heap_caps_malloc(10 * sizeof(char), MALLOC_CAP_SPIRAM); + if (str == nullptr) { + ESP_LOGI("main", "aww."); + } else { + sprintf(str, "mitchell"); + ESP_LOGI("main", "Hello %s", str); + heap_caps_free(str); + } + // set_recording_source(stdout, false); FILE* record_file = fopen(MOUNT_POINT "/record.txt", "w"); if (record_file == nullptr) { @@ -46,7 +56,6 @@ extern "C" void app_main(void) { clean_bomb(); step0(); - stop_recording(); set_game_time(initial_game_time); start_game_timer(); @@ -55,6 +64,7 @@ extern "C" void app_main(void) { current_step = 1; if (skip_to_step <= 1) step1(); step_finish_times[current_step-1] = get_game_time(); + stop_recording(); clean_bomb(); current_step = 2; if (skip_to_step <= 2) step2();