Issue #6: Improve LCD menu and implement function to see safety flags

This commit is contained in:
Mario Hüttel 2020-11-16 20:01:15 +01:00
parent d51c73d694
commit 8603f84142
3 changed files with 100 additions and 8 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;