From 8603f84142d835f9d602c6bc0812e9698743f016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 16 Nov 2020 20:01:15 +0100 Subject: [PATCH] Issue #6: Improve LCD menu and implement function to see safety flags --- .../include/reflow-controller/ui/menu.h | 3 + stm-firmware/reflow-menu.c | 87 +++++++++++++++++-- stm-firmware/ui/menu.c | 18 ++++ 3 files changed, 100 insertions(+), 8 deletions(-) diff --git a/stm-firmware/include/reflow-controller/ui/menu.h b/stm-firmware/include/reflow-controller/ui/menu.h index 4ba3093..2842af7 100644 --- a/stm-firmware/include/reflow-controller/ui/menu.h +++ b/stm-firmware/include/reflow-controller/ui/menu.h @@ -35,6 +35,7 @@ typedef void (*menu_func_t)(struct lcd_menu *menu, enum menu_entry_func_entry en struct menu_inputs { int16_t rotary_encoder_delta; enum button_state push_button; + bool button_ready; }; struct lcd_menu { @@ -76,6 +77,8 @@ int16_t menu_get_rotary_delta(const struct lcd_menu *menu); enum button_state menu_get_button_state(const struct lcd_menu *menu); +bool menu_get_button_ready_state(const struct lcd_menu *menu); + void menu_list_compute_count(struct menu_list *list); void menu_list_scroll_down(struct menu_list *list); diff --git a/stm-firmware/reflow-menu.c b/stm-firmware/reflow-menu.c index 3b07dca..637af11 100644 --- a/stm-firmware/reflow-menu.c +++ b/stm-firmware/reflow-menu.c @@ -107,7 +107,6 @@ static void reflow_menu_monitor(struct lcd_menu *menu, enum menu_entry_func_entr static void reflow_menu_about(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent) { static void *my_parent; - static bool button_ready; static int page = 0; static int last_page = -1; static uint32_t uptime_secs; @@ -118,13 +117,13 @@ static void reflow_menu_about(struct lcd_menu *menu, enum menu_entry_func_entry int16_t rot_delta; uint32_t ser1, ser2, ser3; enum button_state push_button; + bool button_ready; if (entry_type == MENU_ENTRY_FIRST_ENTER) { uptime_secs = 0ULL; page = 0; last_page = -1; my_parent = parent; - button_ready = false; menu_display_clear(menu); menu_ack_rotary_delta(menu); } @@ -190,6 +189,7 @@ static void reflow_menu_about(struct lcd_menu *menu, enum menu_entry_func_entry menu_lcd_output(menu, 3, "Page 4/5"); break; case 4: + last_page = 4; systick_get_uptime_from_tick(&uptime_days, &uptime_hours, &uptime_mins, &new_uptime_secs); if (new_uptime_secs != uptime_secs) { uptime_secs = new_uptime_secs; @@ -206,6 +206,7 @@ static void reflow_menu_about(struct lcd_menu *menu, enum menu_entry_func_entry } push_button = menu_get_button_state(menu); + button_ready = menu_get_button_ready_state(menu); if (push_button == BUTTON_IDLE) button_ready = true; @@ -216,20 +217,93 @@ static void reflow_menu_about(struct lcd_menu *menu, enum menu_entry_func_entry } } +static void reflow_menu_err_flags(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent) +{ + static void *my_parent = NULL; + static uint8_t offset; + static uint64_t timestamp; + bool state; + enum button_state push_button; + int16_t rot; + uint32_t i; + char name[64]; + int32_t line_counter; + bool skip_err_flag_prefix; + bool try_ack = false; + enum safety_flag flag; + bool button_ready; + + push_button = menu_get_button_state(menu); + rot = menu_get_rotary_delta(menu); + + if (entry_type != MENU_ENTRY_CONTINUE) { + if (entry_type == MENU_ENTRY_FIRST_ENTER) { + my_parent = parent; + offset = 0; + } + } else { + if (push_button == BUTTON_IDLE && rot == 0) { + if (!systick_ticks_have_passed(timestamp, 150)) + return; + } + + } + + button_ready = menu_get_button_ready_state(menu); + if (push_button == BUTTON_SHORT_RELEASED && button_ready) { + menu_entry_dropback(menu, my_parent); + } if (push_button == BUTTON_LONG && button_ready) { + try_ack = true; + } + + if (rot >= 4 || rot <= -4) { + menu_ack_rotary_delta(menu); + if (rot > 0) { + offset++; + } else { + if (offset > 0) + offset--; + } + } + + menu_display_clear(menu); + + line_counter = -offset; + for (i = 0; i < safety_controller_get_flag_count(); i++) { + (void)safety_controller_get_flag_by_index(i, &state, &flag); + if (try_ack) + safety_controller_ack_flag(flag); + if (state) { + if (line_counter >= 0 && line_counter < 4) { + safety_controller_get_flag_name_by_index(i, name, sizeof(name)); + if (!strncmp(name, "ERR_FLAG_", 9)) { + skip_err_flag_prefix = true; + } else { + skip_err_flag_prefix = false; + } + menu_lcd_outputf(menu, line_counter, "%s", (skip_err_flag_prefix ? &name[9] : name)); + } + line_counter++; + } + } + timestamp = systick_get_global_tick(); +} + static void reflow_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent) { (void)parent; static struct menu_list list; - static bool button_valid; bool menu_changed = false; static const char * const root_entry_names[] = { "About", "Monitoring", + "Error Flags", NULL }; static const menu_func_t root_entry_funcs[] = { reflow_menu_about, - reflow_menu_monitor + reflow_menu_monitor, + reflow_menu_err_flags, }; enum button_state push_button; int16_t rot_delta; @@ -240,7 +314,6 @@ static void reflow_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_e update_display_buffer(0, "Main Menu"); menu_ack_rotary_delta(menu); if (entry_type == MENU_ENTRY_FIRST_ENTER) { - button_valid = false; list.entry_names = root_entry_names; list.submenu_list = root_entry_funcs; list.update_display = menu->update_display; @@ -252,9 +325,7 @@ static void reflow_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_e push_button = menu_get_button_state(menu); rot_delta = menu_get_rotary_delta(menu); - if (push_button == BUTTON_IDLE) { - button_valid = true; - } else if (button_valid && push_button == BUTTON_SHORT_RELEASED) { + if (menu_get_button_ready_state(menu) && push_button == BUTTON_SHORT_RELEASED) { /* Enter currently selected menu_entry */ menu_list_enter_selected_entry(&list, menu); } diff --git a/stm-firmware/ui/menu.c b/stm-firmware/ui/menu.c index fdc92ac..2ee69e9 100644 --- a/stm-firmware/ui/menu.c +++ b/stm-firmware/ui/menu.c @@ -27,6 +27,7 @@ void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum butto { menu_func_t tmp; + if (!menu) return; @@ -38,6 +39,9 @@ void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum butto tmp = menu->active_entry; + if (menu->active_entry_type == MENU_ENTRY_FIRST_ENTER && push_button != BUTTON_IDLE) { + menu->inputs.button_ready = false; + } if (menu->active_entry_type == MENU_ENTRY_FIRST_ENTER) { menu->active_entry(menu, menu->active_entry_type, menu->init_parent); @@ -48,6 +52,9 @@ void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum butto if (menu->active_entry_type != MENU_ENTRY_CONTINUE && tmp == menu->active_entry) { menu->active_entry_type = MENU_ENTRY_CONTINUE; } + + if (push_button == BUTTON_IDLE) + menu->inputs.button_ready = true; } void menu_init(struct lcd_menu *menu, menu_func_t root_node, void (*display_update)(uint8_t row, const char *data)) @@ -59,6 +66,7 @@ void menu_init(struct lcd_menu *menu, menu_func_t root_node, void (*display_upda menu->active_entry = root_node; menu->init_parent = NULL; menu->inputs.push_button = BUTTON_IDLE; + menu->inputs.button_ready = false; menu->inputs.rotary_encoder_delta = 0; menu->active_entry_type = MENU_ENTRY_FIRST_ENTER; menu->update_display = display_update; @@ -243,6 +251,16 @@ enum button_state menu_get_button_state(const struct lcd_menu *menu) return ret; } +bool menu_get_button_ready_state(const struct lcd_menu *menu) +{ + bool ret = false; + + if (menu) + ret = menu->inputs.button_ready; + + return ret; +} + void menu_display_clear(struct lcd_menu *menu) { uint8_t i;