From 53f58a31339c3d4785e670b2e14e67223fd35dd3 Mon Sep 17 00:00:00 2001 From: Mitchell Marino Date: Fri, 22 Aug 2025 11:38:21 -0500 Subject: [PATCH] fix mutex issue --- main/drivers/char_lcd.cpp | 13 ++++++++++++- main/drivers/char_lcd.h | 6 ++++-- main/drivers/i2c_lcd_pcf8574.c | 6 ++---- main/steps/setup_wires.cpp | 3 ++- main/steps/step0.cpp | 3 ++- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/main/drivers/char_lcd.cpp b/main/drivers/char_lcd.cpp index 2d08276..32bb85b 100644 --- a/main/drivers/char_lcd.cpp +++ b/main/drivers/char_lcd.cpp @@ -92,11 +92,12 @@ void init_lcd() { ESP_LOGI(TAG, "Initializing LCD..."); lcd_mutex = xSemaphoreCreateMutex(); + assert(lcd_mutex != NULL); lcd_init(&lcd, LCD_ADDR, CHAR_LCD_I2C_NUM); lcd_begin(&lcd, LCD_COLS, LCD_ROWS); - lcd_set_backlight(&lcd, true); + lcd_set_backlight_to(&lcd, 1); register_replay_fn(replay_handler); @@ -229,6 +230,8 @@ void lcd_set_backlight(bool backlight, bool no_lock) { } void lcd_create_char(uint8_t location, const uint8_t charmap[], bool no_lock) { + if (location == 8) location = 0; + if (!no_lock) xSemaphoreTake(lcd_mutex, portMAX_DELAY); lcd_create_char(&lcd, location, charmap); if (!no_lock) xSemaphoreGive(lcd_mutex); @@ -300,4 +303,12 @@ void lcd_do_splash() { lcd_print(6, 1, "\x01\x02Marino", true); lcd_print(5, 2, "\x03\x04\x05\x06""DEV", true); xSemaphoreGive(lcd_mutex); +} + +bool lcd_lock(uint32_t ticks_to_wait) { + return xSemaphoreTake(lcd_mutex, ticks_to_wait); +} + +void lcd_unlock() { + xSemaphoreGive(lcd_mutex); } \ No newline at end of file diff --git a/main/drivers/char_lcd.h b/main/drivers/char_lcd.h index d881899..884f0e9 100644 --- a/main/drivers/char_lcd.h +++ b/main/drivers/char_lcd.h @@ -71,10 +71,12 @@ void lcd_do_splash(); /// @brief Locks the LCD to allow chaining multiple commands without interuptions. /// /// Commands you call while you lock the LCD, you must call with the `no_lock` flag set to true. -void lcd_lock(); +/// +/// Do not hold this lock for an extended period of time. +/// @return `true` iff the lock was aquired. +bool lcd_lock(uint32_t ticks_to_wait); /// @brief Unlocks the LCD to give away the mutex access to it. void lcd_unlock(); - #endif /* CHAR_LCD_H */ diff --git a/main/drivers/i2c_lcd_pcf8574.c b/main/drivers/i2c_lcd_pcf8574.c index 581ef31..0bcd51c 100644 --- a/main/drivers/i2c_lcd_pcf8574.c +++ b/main/drivers/i2c_lcd_pcf8574.c @@ -260,7 +260,7 @@ void lcd_print(i2c_lcd_pcf8574_handle_t* lcd, const char* str) { while (*str) { if (*str == '\x08') { lcd_write(lcd, '\x00'); - *str++; + str++; } else { lcd_write(lcd, *str++); } @@ -305,10 +305,10 @@ static void lcd_send(i2c_lcd_pcf8574_handle_t* lcd, uint8_t value, bool is_data) i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (lcd->i2c_addr << 1) | I2C_MASTER_WRITE, true); + xSemaphoreTake(main_i2c_mutex, portMAX_DELAY); lcd_write_nibble(lcd, (value >> 4 & 0x0F), is_data, cmd); lcd_write_nibble(lcd, (value & 0x0F), is_data, cmd); i2c_master_stop(cmd); - xSemaphoreTake(main_i2c_mutex, portMAX_DELAY); esp_err_t ret = i2c_master_cmd_begin(lcd->i2c_port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); xSemaphoreGive(main_i2c_mutex); i2c_cmd_link_delete(cmd); @@ -334,10 +334,8 @@ static void lcd_write_nibble(i2c_lcd_pcf8574_handle_t* lcd, uint8_t half_byte, b if (half_byte & 0x04) data |= lcd->data_mask[2]; if (half_byte & 0x08) data |= lcd->data_mask[3]; - xSemaphoreTake(main_i2c_mutex, portMAX_DELAY); i2c_master_write_byte(cmd, data | lcd->enable_mask, true); i2c_master_write_byte(cmd, data, true); - xSemaphoreGive(main_i2c_mutex); } // lcd_write_nibble() // Private function to change the PCF8574 pins to the given value. diff --git a/main/steps/setup_wires.cpp b/main/steps/setup_wires.cpp index 732a43f..99f9bcb 100644 --- a/main/steps/setup_wires.cpp +++ b/main/steps/setup_wires.cpp @@ -23,7 +23,8 @@ void print_wires(WireColor* wires, int editing_idx) { } lcd_print(1, 3, string_buf); - lcd_set_cursor_pos(editing_idx+1, 1); + // TODO: find a way to indicate without a cursor. + // lcd_set_cursor_pos(editing_idx+1, 1); } void setup_wires(void) { diff --git a/main/steps/step0.cpp b/main/steps/step0.cpp index 44d4bb9..7205db1 100644 --- a/main/steps/step0.cpp +++ b/main/steps/step0.cpp @@ -214,7 +214,8 @@ static void _update_display(uint8_t* digits, uint8_t cursor_pos) { lcd_print(1, 1, str_buf); cursor_pos = MAX(0, MIN(4, cursor_pos)); int mapped_cursor_pos = CURSOR_POS_MAP[cursor_pos]; - lcd_set_cursor_pos(mapped_cursor_pos, 1); + // TODO: find some way to indicate without a cursor. + // lcd_set_cursor_pos(mapped_cursor_pos, 1); } static void set_game_time() {