reflow-oven-control-sw/stm-firmware/lcd-menu.c

183 lines
4.6 KiB
C
Raw Normal View History

/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/lcd-menu.h>
#include <reflow-controller/ui/menu.h>
#include <reflow-controller/ui/lcd.h>
#include <reflow-controller/rotary-encoder.h>
#include <reflow-controller/systick.h>
#include <reflow-controller/adc-meas.h>
#include <reflow-controller/safety-adc.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include <reflow-controller/ui/lcd.h>
#include <reflow-controller/temp-converter.h>
2020-06-09 22:53:13 +02:00
static char __attribute__((section(".ccmram"))) display_buffer[4][21] = {0};
static struct lcd_menu reflow_menu;
static struct lcd_menu *reflow_menu_ptr = &reflow_menu;
static void update_display_buffer(uint8_t row, const char *data)
{
int i;
if (row > 4)
return;
if (!data)
return;
for (i = 0; data[i] && i < LCD_CHAR_WIDTH; i++) {
display_buffer[row][i] = data[i];
}
display_buffer[row][i] = 0;
}
static void reflow_menu_monitor(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent)
{
static void *my_parent;
static uint64_t my_timestamp = 0;
char line[17];
float tmp;
int res;
const char *prefix;
if (entry_type == MENU_ENTRY_FIRST_ENTER) {
my_parent = parent;
menu_display_clear(menu);
}
if (systick_ticks_have_passed(my_timestamp, 250)) {
adc_pt1000_get_current_resistance(&tmp);
snprintf(line, sizeof(line), "Res: %.1f", tmp);
menu->update_display(0, line);
res = temp_converter_convert_resistance_to_temp(tmp, &tmp);
switch (res) {
case -1:
prefix = "<";
break;
case 1:
prefix = ">";
break;
default:
prefix = "";
break;
}
snprintf(line, sizeof(line), "Temp: %s%.1f " LCD_DEGREE_SYMBOL_STRING "C", prefix, tmp);
menu->update_display(1, line);
tmp = safety_adc_get_temp();
snprintf(line, sizeof(line), "Tj: %.1f " LCD_DEGREE_SYMBOL_STRING "C", tmp);
menu->update_display(2, line);
tmp = safety_adc_get_vref();
snprintf(line, sizeof(line), "Vref: %.1f mV", tmp);
menu->update_display(3, line);
}
if (menu->inputs.push_button == BUTTON_SHORT_RELEASED || menu->inputs.push_button == BUTTON_LONG) {
menu_entry_dropback(menu, my_parent);
}
}
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;
static const char * const root_entries[] = {
"Device Info",
"Safety Monitor",
"Foo",
"bar",
"foobar",
NULL
};
if (entry_type != MENU_ENTRY_CONTINUE) {
menu_display_clear(menu);
button_valid = false;
list.entry_names = root_entries;
list.submenu_list = NULL;
list.update_display = menu->update_display;
list.currently_selected = 0;
menu_list_compute_count(&list);
update_display_buffer(0, "Main Menu");
}
if (menu->inputs.push_button == BUTTON_IDLE) {
button_valid = true;
} else if (button_valid && menu->inputs.push_button == BUTTON_SHORT_RELEASED) {
switch (list.currently_selected) {
case 1:
menu_entry_enter(menu, reflow_menu_monitor, false);
break;
default:
break;
}
}
if (menu->inputs.rotary_encoder_delta >= 4) {
menu_list_scroll_down(&list);
menu_ack_rotary_delta(menu);
} else if (menu->inputs.rotary_encoder_delta <= -4) {
menu_list_scroll_up(&list);
menu_ack_rotary_delta(menu);
}
menu_list_display(&list, 1, 3);
}
int reflow_menu_handle()
{
int32_t rot_delta;
enum button_state button;
static enum lcd_fsm_ret lcd_ret = LCD_FSM_NOP;
static uint64_t lcd_timestamp = 0ULL;
rot_delta = rotary_encoder_get_change_val();
button = button_read_event();
menu_handle(reflow_menu_ptr, (int16_t)rot_delta, button);
if (lcd_ret != LCD_FSM_WAIT_CALL || systick_ticks_have_passed(lcd_timestamp, 2))
lcd_ret = lcd_fsm_write_buffer(display_buffer);
if (lcd_ret == LCD_FSM_CALL_AGAIN)
return 1;
else
return 0;
}
void reflow_menu_init()
{
rotary_encoder_setup();
button_init();
lcd_init();
menu_init(reflow_menu_ptr, reflow_menu_root_entry, update_display_buffer);
}