state tracking on char_lcd

This commit is contained in:
Mitchell Marino 2025-03-27 02:04:19 -05:00 committed by Mitchell M
parent 54ff226694
commit 758b16aa0d
5 changed files with 112 additions and 17 deletions

View File

@ -2,11 +2,14 @@
#include "./i2c_lcd_pcf8574.h" #include "./i2c_lcd_pcf8574.h"
#include <esp_log.h> #include <esp_log.h>
#include "state_tracking.h"
i2c_lcd_pcf8574_handle_t lcd; i2c_lcd_pcf8574_handle_t lcd;
static const char *TAG = "char_lcd"; static const char *TAG = "char_lcd";
static char buf[65];
void init_lcd() { void init_lcd() {
ESP_LOGI(TAG, "Initializing LCD..."); ESP_LOGI(TAG, "Initializing LCD...");
@ -18,17 +21,29 @@ void init_lcd() {
ESP_LOGI(TAG, "LCD initialized!"); ESP_LOGI(TAG, "LCD initialized!");
} }
void lcd_clear() { void lcd_clear() {
lcd_clear(&lcd); lcd_clear(&lcd);
if (is_state_tracking()) {
event_occured("LCD_CLEAR", NULL);
}
} }
void lcd_cursor_home() { void lcd_cursor_home() {
lcd_home(&lcd); lcd_home(&lcd);
if (is_state_tracking()) {
event_occured("LCD_CURSOR", "0,0");
}
} }
void lcd_set_cursor_pos(uint8_t col, uint8_t row) { void lcd_set_cursor_pos(uint8_t col, uint8_t row) {
lcd_set_cursor(&lcd, col, row); lcd_set_cursor(&lcd, col, row);
if (is_state_tracking()) {
sprintf(buf, "%d,%d", col, row);
event_occured("LCD_CURSOR", buf);
}
} }
void lcd_set_display(bool display) { void lcd_set_display(bool display) {
@ -37,6 +52,10 @@ void lcd_set_display(bool display) {
} else { } else {
lcd_no_display(&lcd); lcd_no_display(&lcd);
} }
if (is_state_tracking()) {
event_occured("LCD_SET_DISPLAY", display ? "true" : "false");
}
} }
void lcd_set_cursor_vis(bool cursor) { void lcd_set_cursor_vis(bool cursor) {
@ -45,6 +64,10 @@ void lcd_set_cursor_vis(bool cursor) {
} else { } else {
lcd_no_cursor(&lcd); lcd_no_cursor(&lcd);
} }
if (is_state_tracking()) {
event_occured("LCD_CURSOR_VIS", cursor ? "true" : "false");
}
} }
void lcd_set_cursor_blink(bool blink) { void lcd_set_cursor_blink(bool blink) {
@ -53,20 +76,40 @@ void lcd_set_cursor_blink(bool blink) {
} else { } else {
lcd_no_blink(&lcd); lcd_no_blink(&lcd);
} }
if (is_state_tracking()) {
event_occured("LCD_CURSOR_BLINK", blink ? "true" : "false");
}
} }
void lcd_scroll_display_left() { void lcd_scroll_display_left() {
lcd_scroll_display_left(&lcd); lcd_scroll_display_left(&lcd);
if (is_state_tracking()) {
event_occured("LCD_SCROLL_DISPLAY_LEFT", NULL);
}
} }
void lcd_scroll_display_right() { void lcd_scroll_display_right() {
lcd_scroll_display_right(&lcd); lcd_scroll_display_right(&lcd);
if (is_state_tracking()) {
event_occured("LCD_SCROLL_DISPLAY_RIGHT", NULL);
}
} }
void lcd_left_to_right() { void lcd_left_to_right() {
lcd_left_to_right(&lcd); lcd_left_to_right(&lcd);
if (is_state_tracking()) {
event_occured("LCD_SCROLL_LEFT_TO_RIGHT", NULL);
}
} }
void lcd_right_to_left() { void lcd_right_to_left() {
lcd_right_to_left(&lcd); lcd_right_to_left(&lcd);
if (is_state_tracking()) {
event_occured("LCD_SCROLL_RIGHT_TO_LEFT", NULL);
}
} }
void lcd_set_autoscroll(bool autoscroll) { void lcd_set_autoscroll(bool autoscroll) {
@ -75,25 +118,51 @@ void lcd_set_autoscroll(bool autoscroll) {
} else { } else {
lcd_no_autoscroll(&lcd); lcd_no_autoscroll(&lcd);
} }
if (is_state_tracking()) {
event_occured("LCD_AUTOSCROLL", autoscroll ? "true" : "false");
}
} }
void lcd_set_backlight(uint8_t brightness) { void lcd_set_backlight(uint8_t brightness) {
lcd_set_backlight(&lcd, brightness); lcd_set_backlight(&lcd, brightness);
if (is_state_tracking()) {
sprintf(buf, "%d", brightness);
event_occured("LCD_BACKLIGHT", buf);
}
} }
void lcd_create_char(uint8_t location, uint8_t charmap[]) { void lcd_create_char(uint8_t location, uint8_t* charmap) {
lcd_create_char(&lcd, location, charmap); lcd_create_char(&lcd, location, charmap);
if (is_state_tracking()) {
snprintf(buf, 65,
"%d,%d,%d,%d,%d,%d,%d,%d,%d", location,
charmap[0], charmap[1], charmap[2], charmap[3], charmap[4], charmap[5], charmap[6], charmap[7]
);
event_occured("LCD_CREATE_CHAR", buf);
}
} }
void lcd_write(uint8_t value) { void lcd_write(uint8_t value) {
lcd_write(&lcd, value); lcd_write(&lcd, value);
if (is_state_tracking()) {
sprintf(buf, "%d", value);
event_occured("LCD_WRITE", buf);
}
} }
void lcd_print(const char* str) { void lcd_print(const char* str) {
lcd_print(&lcd, str); lcd_print(&lcd, str);
if (is_state_tracking()) {
event_occured("LCD_PRINT", str);
}
} }
void lcd_print(uint8_t col, uint8_t row, const char* str) { void lcd_print(uint8_t col, uint8_t row, const char* str) {
lcd_set_cursor_pos(col, row); lcd_set_cursor_pos(col, row);
lcd_print(&lcd, str); lcd_print(str);
} }

View File

@ -1,4 +1,5 @@
#include "state_tracking.h" #include "state_tracking.h"
#include <unistd.h>
#include <vector> #include <vector>
enum state_t { enum state_t {
@ -7,7 +8,7 @@ enum state_t {
STATE_PLAYBACK = 2, STATE_PLAYBACK = 2,
}; };
static std::vector<Event> registered_events; static std::vector<EventCB> event_cbs;
static bool should_close_recording_stream; static bool should_close_recording_stream;
static FILE* recording_stream; static FILE* recording_stream;
@ -17,12 +18,12 @@ static bool should_close_playback_stream;
static FILE* playback_stream; static FILE* playback_stream;
static state_t state = STATE_IDLE; static state_t state = STATE_IDLE;
void register_event(const char* name, void (*replay_callback)(uint32_t, const char*)) { void register_event_cb(const char* name, void (*replay_callback)(uint32_t, const char*)) {
Event event = { EventCB event = {
.name = name, .name = name,
.replay_callback = replay_callback, .replay_callback = replay_callback,
}; };
registered_events.push_back(event); event_cbs.push_back(event);
} }
void event_occured(const char* name, const char* arg) { void event_occured(const char* name, const char* arg) {
@ -36,7 +37,13 @@ void event_occured(const char* name, const char* arg) {
arg = (arg == nullptr) ? "" : arg; arg = (arg == nullptr) ? "" : arg;
uint32_t ticks = xTaskGetTickCount() - recording_start_time; uint32_t ticks = xTaskGetTickCount() - recording_start_time;
fprintf(recording_stream, "%ld,%s:%s\n", ticks, name, (arg == nullptr) ? "" : arg); fprintf(recording_stream, "%ld,%s:%s\n", ticks, name, (arg == nullptr) ? "" : arg);
fflush(recording_stream); fflush(recording_stream);
int fd = fileno(recording_stream);
if (fd != -1) {
fsync(fd);
}
} }
bool set_recording_source(FILE* stream, bool should_close) { bool set_recording_source(FILE* stream, bool should_close) {
@ -85,3 +92,7 @@ bool stop_playback() {
// TODO: impl // TODO: impl
return false; return false;
} }
bool is_state_tracking() {
return state == STATE_RECORDING;
}

View File

@ -5,7 +5,7 @@
#include "esp_vfs_fat.h" #include "esp_vfs_fat.h"
/// @brief An event that represents the physical bomb state moving. /// @brief An event that represents the physical bomb state moving.
struct Event { struct EventCB {
// The name of the event. // The name of the event.
// This should not contain whitespace or the characters ':', ',' // This should not contain whitespace or the characters ':', ','
const char* name; const char* name;
@ -14,10 +14,12 @@ struct Event {
void (*replay_callback)(uint32_t, const char*); void (*replay_callback)(uint32_t, const char*);
}; };
/// @brief Registers an event to be tracked. /// @brief Registers a callback for a certain event to be called on replay.
/// @param name The name of the event that has occured. /// @param name The name of the event to respond to.
/// @param replay_callback A function to call to recreate this state transition. /// @param replay_callback A function to call to playback this state transition.
void register_event(const char* name, void (*replay_callback)(uint32_t, const char*)); void register_event_cb(const char* name, void (*replay_callback)(uint32_t, const char*));
// TODO: add one for generically responding to all events.
/// @brief Call this to indicate that the bomb state has transitioned. /// @brief Call this to indicate that the bomb state has transitioned.
/// @param name The name of the event that has occured. /// @param name The name of the event that has occured.
@ -53,4 +55,10 @@ bool start_playback();
/// @return true if stopping the playback is successful. /// @return true if stopping the playback is successful.
bool stop_playback(); bool stop_playback();
/// @brief Gets weather or not we are tracking the state
/// This can be helpful to conditionally do extra computation only
/// when we are tracking the state.
/// @return
bool is_state_tracking();
#endif /* STATE_TRACKING_H */ #endif /* STATE_TRACKING_H */

View File

@ -35,11 +35,19 @@ extern "C" void app_main(void) {
init_wires(); init_wires();
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
set_recording_source(fopen(MOUNT_POINT "record.txt", "w"), true); // set_recording_source(stdout, false);
FILE* record_file = fopen(MOUNT_POINT "/record.txt", "w");
if (record_file == nullptr) {
ESP_LOGE("main", "failed to open record.txt");
}
set_recording_source(record_file, true);
start_recording(); start_recording();
clean_bomb(); clean_bomb();
step0(); step0();
stop_recording();
set_game_time(initial_game_time); set_game_time(initial_game_time);
start_game_timer(); start_game_timer();
total_strikes = 0; total_strikes = 0;
@ -76,5 +84,4 @@ extern "C" void app_main(void) {
display_game_results(); display_game_results();
stop_recording();
} }

View File

@ -42,7 +42,7 @@ void step0() {
StarCodeHandler star_codes[] = { StarCodeHandler star_codes[] = {
{ {
.code = "*9819", .code = "*9819",
.display_text = "Diffusal Initiated", .display_text = "Defusal Initiated",
.should_exit = true, .should_exit = true,
.callback = nullptr, .callback = nullptr,
}, },