From df82f142063c81248c161925b890b948f3ceafdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sat, 2 May 2020 19:10:20 +0200 Subject: [PATCH] Make LCD code working. Add FSM for LCD in order to write it in mainloop --- .../include/reflow-controller/ui/lcd.h | 10 + stm-firmware/ui/lcd.c | 218 +++++++++++++++++- 2 files changed, 224 insertions(+), 4 deletions(-) diff --git a/stm-firmware/include/reflow-controller/ui/lcd.h b/stm-firmware/include/reflow-controller/ui/lcd.h index be13de4..28dad8b 100644 --- a/stm-firmware/include/reflow-controller/ui/lcd.h +++ b/stm-firmware/include/reflow-controller/ui/lcd.h @@ -31,4 +31,14 @@ #define LCD_RS_MASK (1U << LCD_RS) #define LCD_E_MASK (1U << LCD_E) +enum lcd_fsm_ret {LCD_FSM_NOP, LCD_FSM_CALL_AGAIN, LCD_FSM_WAIT_CALL}; + +void lcd_init(void); + +void lcd_string(const char *data); + +void lcd_home(void); + +enum lcd_fsm_ret lcd_fsm_write_buffer(const char (*display_buffer)[21]); + #endif /* __LCD_H__ */ diff --git a/stm-firmware/ui/lcd.c b/stm-firmware/ui/lcd.c index 398ea64..a696482 100644 --- a/stm-firmware/ui/lcd.c +++ b/stm-firmware/ui/lcd.c @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include static void lcd_port_clear(void) { @@ -42,9 +45,9 @@ static void lcd_enable(void) __ASM("nop"); __ASM("nop"); __ASM("nop"); - __ASM("nop"); + //systick_wait_ms(10); LCD_DPORT->ODR &= ~LCD_E_MASK; - __ASM("nop"); + //systick_wait_ms(10); __ASM("nop"); __ASM("nop"); __ASM("nop"); @@ -141,6 +144,8 @@ static void lcd_command(uint8_t data) // Set DD RAM Address --------- 0b1xxxxxxx (Display Data RAM) #define LCD_SET_DDADR 0x80 +static char shadow_display[4][21]; + void lcd_clear(void) { lcd_command(LCD_CLEAR_DISPLAY); @@ -153,7 +158,7 @@ void lcd_home(void) systick_wait_ms(3); } -void lcd_setcursor(uint8_t x, uint8_t y) +static uint8_t lcd_get_set_cursor_cmd(uint8_t x, uint8_t y) { uint8_t data; @@ -179,9 +184,19 @@ void lcd_setcursor(uint8_t x, uint8_t y) break; default: - return; // für den Fall einer falschen Zeile + /* In case of wrong line, assume first line */ + data = LCD_SET_DDADR + LCD_DDADR_LINE1; + break; } + return data; +} + +void lcd_setcursor(uint8_t x, uint8_t y) +{ + uint8_t data; + + data = lcd_get_set_cursor_cmd(x, y); lcd_command(data); } @@ -191,13 +206,38 @@ void lcd_string(const char *data) lcd_data((uint8_t)*data++); } +static void lcd_port_init() +{ + LCD_DPORT->MODER &= MODER_DELETE(LCD_E) & MODER_DELETE(LCD_RS) & MODER_DELETE(LCD_DATA_BIT_OFFSET) & + MODER_DELETE(LCD_DATA_BIT_OFFSET + 1) & MODER_DELETE(LCD_DATA_BIT_OFFSET + 2) & + MODER_DELETE(LCD_DATA_BIT_OFFSET + 3); + + LCD_DPORT->MODER |= OUTPUT(LCD_E) | OUTPUT(LCD_RS) | OUTPUT(LCD_DATA_BIT_OFFSET) | + OUTPUT(LCD_DATA_BIT_OFFSET + 1) | OUTPUT(LCD_DATA_BIT_OFFSET + 2) | + OUTPUT(LCD_DATA_BIT_OFFSET + 3); +} + +static void lcd_clear_shadow_buff() +{ + int i, j; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 21; j++) { + shadow_display[i][j] = 0x0; + } + } +} + void lcd_init(void) { int i; rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(LCD_RCC_MASK)); + lcd_port_init(); lcd_port_clear(); + lcd_clear_shadow_buff(); + systick_wait_ms(100); LCD_DPORT->ODR |= (0x3 << LCD_DATA_BIT_OFFSET); @@ -237,3 +277,173 @@ void lcd_deinit() lcd_port_clear(); rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(LCD_RCC_MASK)); } + +static uint8_t compare_input_to_shadow(const char (*display_buffer)[21]) +{ + uint8_t ret = 0; + int i, row; + + for (row = 0; row < 4; row++) { + for (i = 0; i < 20; i++) { + if (display_buffer[row][i] != shadow_display[row][i]) { + ret |= (1U<ODR |= LCD_E_MASK; + else + LCD_DPORT->ODR &= ~LCD_E_MASK; + + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); +} + +static void lcd_fsm_write_command(bool high, uint8_t cmd) +{ + lcd_port_clear(); + + if (high) + lcd_out((cmd >> 4) & 0x0F); + else + lcd_out((cmd) & 0x0F); +} + +static void lcd_fsm_write_data(bool high, uint8_t data) +{ + LCD_DPORT->ODR |= (1<> 4) & 0x0F); + else + lcd_out((data) & 0x0F); +} + +enum lcd_fsm_ret lcd_fsm_write_buffer(const char (*display_buffer)[21]) +{ + static bool idle = true; + static uint8_t rows_to_handle = 0; + static uint32_t state_cnt; + static uint8_t row_cnt = 0; + static uint32_t char_cnt; + static uint32_t line_len; + static uint64_t timestamp = 0ULL; + enum lcd_fsm_ret ret; + + ret = LCD_FSM_NOP; + + if (idle) { + rows_to_handle = compare_input_to_shadow(display_buffer); + memcpy(shadow_display, display_buffer, sizeof(shadow_display)); + shadow_display[0][20] = 0; + shadow_display[1][20] = 0; + shadow_display[2][20] = 0; + shadow_display[3][20] = 0; + state_cnt = 0; + row_cnt = 0; + idle = false; + } + + if (rows_to_handle == 0) { + idle = true; + return ret; + } + + if ((rows_to_handle & (1<= line_len) ? ' ' : shadow_display[row_cnt][char_cnt]); + lcd_fsm_enable(true); + ret = LCD_FSM_WAIT_CALL; + state_cnt++; + break; + case 6: + lcd_fsm_enable(false); + ret = LCD_FSM_WAIT_CALL; + state_cnt++; + break; + case 7: + lcd_fsm_write_data(false, (char_cnt >= line_len) ? ' ' : shadow_display[row_cnt][char_cnt]); + lcd_fsm_enable(true); + ret = LCD_FSM_WAIT_CALL; + state_cnt++; + break; + case 8: + lcd_fsm_enable(false); + ret = LCD_FSM_WAIT_CALL; + char_cnt++; + if (char_cnt < 20) { + state_cnt = 5; + } else { + state_cnt = 0; + rows_to_handle &= (uint8_t)~(1U<