From eeb5f3d50ce3831e2a12262984657b1b9a4ae7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sat, 14 Jan 2023 14:58:04 +0000 Subject: [PATCH] optimisation: refactor menu_draw_P() Add a way to only change the LCD column Change in memory: Flash: -90 bytes SRAM: 0 bytes --- Firmware/lcd.cpp | 28 +++++++++++++++++++++++----- Firmware/lcd.h | 4 ++++ Firmware/menu.cpp | 22 +++++++++++++++------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index a726c6db2..8677ea0c4 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -329,13 +329,31 @@ void lcd_no_autoscroll(void) } #endif -void lcd_set_cursor(uint8_t col, uint8_t row) +/// @brief set the current LCD row +/// @param row LCD row number, ranges from 0 to LCD_HEIGHT - 1 +static void FORCE_INLINE lcd_set_current_row(uint8_t row) +{ + lcd_currline = min(row, LCD_HEIGHT - 1); +} + +/// @brief Calculate the LCD row offset +/// @param row LCD row number, ranges from 0 to LCD_HEIGHT - 1 +/// @return row offset which the LCD register understands +static uint8_t __attribute__((noinline)) lcd_get_row_offset(uint8_t row) { uint8_t row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; - if (row >= LCD_HEIGHT) - row = LCD_HEIGHT - 1; // we count rows starting w/0 - lcd_currline = row; - lcd_command(LCD_SETDDRAMADDR | (col + row_offsets[row])); + return row_offsets[min(row, LCD_HEIGHT - 1)]; +} + +void lcd_set_cursor(uint8_t col, uint8_t row) +{ + lcd_set_current_row(row); + lcd_command(LCD_SETDDRAMADDR | (col + lcd_get_row_offset(lcd_currline))); +} + +void lcd_set_cursor_column(uint8_t col) +{ + lcd_command(LCD_SETDDRAMADDR | (col + lcd_get_row_offset(lcd_currline))); } // Allows us to fill the first 8 CGRAM locations diff --git a/Firmware/lcd.h b/Firmware/lcd.h index 9949683cb..08c48a615 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -37,6 +37,10 @@ extern void lcd_no_autoscroll(void);*/ extern void lcd_set_cursor(uint8_t col, uint8_t row); +/// @brief Change the cursor column position while preserving the current row position +/// @param col column number, ranges from 0 to LCD_WIDTH - 1 +void lcd_set_cursor_column(uint8_t col); + extern void lcd_createChar_P(uint8_t, const uint8_t*); diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index e4e2259c1..56e729639 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -435,13 +435,21 @@ static void menu_draw_P(char chr, const char* str, int16_t val); template<> void menu_draw_P(char chr, const char* str, int16_t val) { - int text_len = strlen_P(str); - if (text_len > 15) text_len = 15; - char spaces[LCD_WIDTH + 1] = {0}; - memset(spaces,' ', LCD_WIDTH); - if (val <= -100) spaces[15 - text_len - 1] = 0; - else spaces[15 - text_len] = 0; - lcd_printf_P(menu_fmt_int3, chr, str, spaces, val); + // The LCD row position is controlled externally. We may only modify the column here + lcd_putc(chr); + uint8_t len = lcd_print_pad_P(str, LCD_WIDTH - 1); + lcd_set_cursor_column((LCD_WIDTH - 1) - len + 1); + lcd_putc(':'); + + // The value is right adjusted, set the cursor then render the value + if (val < 10) { // 1 digit + lcd_set_cursor_column(LCD_WIDTH - 1); + } else if (val < 100) { // 2 digits + lcd_set_cursor_column(LCD_WIDTH - 2); + } else { // 3 digits + lcd_set_cursor_column(LCD_WIDTH - 3); + } + lcd_print(val); } template<>