|
|
@ -3,6 +3,7 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
#include <stdbool.h> |
|
|
|
#include <stdbool.h> |
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
#include "app_gui.h" |
|
|
|
#include "app_gui.h" |
|
|
|
#include "app_heater.h" |
|
|
|
#include "app_heater.h" |
|
|
|
#include "app_buzzer.h" |
|
|
|
#include "app_buzzer.h" |
|
|
@ -35,15 +36,19 @@ typedef void (*menu_callback_t)(int choice); |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb); |
|
|
|
static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct State { |
|
|
|
static struct State { |
|
|
|
float oven_temp; |
|
|
|
float oven_temp; |
|
|
|
//float soc_temp;
|
|
|
|
//float soc_temp;
|
|
|
|
|
|
|
|
|
|
|
|
// manual mode controls
|
|
|
|
// manual mode controls
|
|
|
|
int set_temp; |
|
|
|
int set_temp; |
|
|
|
int set_temp_wheel; |
|
|
|
|
|
|
|
bool heater_enabled; |
|
|
|
bool heater_enabled; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool down_prescaller; |
|
|
|
|
|
|
|
bool up_prescaller; |
|
|
|
|
|
|
|
|
|
|
|
bool pushed; |
|
|
|
bool pushed; |
|
|
|
bool paint_needed; |
|
|
|
bool paint_needed; |
|
|
|
uint32_t last_tick_event; |
|
|
|
uint32_t last_tick_event; |
|
|
@ -53,8 +58,17 @@ static struct State { |
|
|
|
bool initial_pushed; |
|
|
|
bool initial_pushed; |
|
|
|
|
|
|
|
|
|
|
|
screen_t screen; |
|
|
|
screen_t screen; |
|
|
|
int menu_pos; |
|
|
|
|
|
|
|
int menu_len; |
|
|
|
union { |
|
|
|
|
|
|
|
struct menu_state { |
|
|
|
|
|
|
|
int pos; |
|
|
|
|
|
|
|
int len; |
|
|
|
|
|
|
|
uint32_t change_time; |
|
|
|
|
|
|
|
uint32_t slide_end_time; |
|
|
|
|
|
|
|
uint16_t text_slide; |
|
|
|
|
|
|
|
uint8_t tick_counter; |
|
|
|
|
|
|
|
} menu; |
|
|
|
|
|
|
|
} page; |
|
|
|
} s_app = {}; |
|
|
|
} s_app = {}; |
|
|
|
|
|
|
|
|
|
|
|
/** Get push time (while held) */ |
|
|
|
/** Get push time (while held) */ |
|
|
@ -111,11 +125,33 @@ void app_task_gui(void *argument) |
|
|
|
} |
|
|
|
} |
|
|
|
osMessageQueueGet(guiEventQueHandle, &message, NULL, ticks_remain); |
|
|
|
osMessageQueueGet(guiEventQueHandle, &message, NULL, ticks_remain); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (message == GUI_EVENT_KNOB_PLUS) { |
|
|
|
|
|
|
|
if (s_app.up_prescaller) { |
|
|
|
|
|
|
|
s_app.up_prescaller = 0; |
|
|
|
|
|
|
|
// let this through
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// consume this
|
|
|
|
|
|
|
|
s_app.down_prescaller = 0; |
|
|
|
|
|
|
|
s_app.up_prescaller = 1; |
|
|
|
|
|
|
|
message = GUI_EVENT_NONE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (message == GUI_EVENT_KNOB_MINUS) { |
|
|
|
|
|
|
|
if (s_app.down_prescaller) { |
|
|
|
|
|
|
|
s_app.down_prescaller = 0; |
|
|
|
|
|
|
|
// let this through
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// consume this
|
|
|
|
|
|
|
|
s_app.up_prescaller = 0; |
|
|
|
|
|
|
|
s_app.down_prescaller = 1; |
|
|
|
|
|
|
|
message = GUI_EVENT_NONE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint32_t tickNow = xTaskGetTickCount(); |
|
|
|
uint32_t tickNow = xTaskGetTickCount(); |
|
|
|
|
|
|
|
|
|
|
|
// 10ms tick event
|
|
|
|
// 10ms tick event
|
|
|
|
if (tickNow - s_app.last_tick_event > pdMS_TO_TICKS(10)) { |
|
|
|
if (tickNow - s_app.last_tick_event > pdMS_TO_TICKS(10)) { |
|
|
|
s_app.screen(GUI_EVENT_TICK); |
|
|
|
s_app.screen(GUI_EVENT_SCREEN_TICK); |
|
|
|
s_app.last_tick_event = tickNow; |
|
|
|
s_app.last_tick_event = tickNow; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -161,6 +197,8 @@ void app_task_gui(void *argument) |
|
|
|
static void switch_screen(screen_t pScreen, bool init) { |
|
|
|
static void switch_screen(screen_t pScreen, bool init) { |
|
|
|
s_app.initial_pushed = s_app.pushed; |
|
|
|
s_app.initial_pushed = s_app.pushed; |
|
|
|
s_app.screen = pScreen; |
|
|
|
s_app.screen = pScreen; |
|
|
|
|
|
|
|
// clear the union field
|
|
|
|
|
|
|
|
memset(&s_app.page, 0, sizeof(s_app.page)); |
|
|
|
request_paint(); |
|
|
|
request_paint(); |
|
|
|
|
|
|
|
|
|
|
|
if (init) { |
|
|
|
if (init) { |
|
|
@ -190,6 +228,8 @@ static void input_sound_effect() |
|
|
|
static const char* main_menu_opts[] = { |
|
|
|
static const char* main_menu_opts[] = { |
|
|
|
"Manual mode", |
|
|
|
"Manual mode", |
|
|
|
"Calibration", |
|
|
|
"Calibration", |
|
|
|
|
|
|
|
"Moderately long text", |
|
|
|
|
|
|
|
"Very very long text that slides", |
|
|
|
NULL |
|
|
|
NULL |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -215,23 +255,9 @@ static void screen_home(GuiEvent event) |
|
|
|
|
|
|
|
|
|
|
|
// --------- manual mode screen ---------------
|
|
|
|
// --------- manual mode screen ---------------
|
|
|
|
|
|
|
|
|
|
|
|
/** Calc set temperature from the current knob position */ |
|
|
|
|
|
|
|
static void manual_calc_set_temp() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int clamped = s_app.set_temp_wheel; |
|
|
|
|
|
|
|
if (clamped < 0) { |
|
|
|
|
|
|
|
clamped = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s_app.set_temp = (clamped / 2) * 5; |
|
|
|
|
|
|
|
if (s_app.set_temp > MAX_TEMP) { |
|
|
|
|
|
|
|
s_app.set_temp = MAX_TEMP; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_heater_set_target((float) s_app.set_temp); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void screen_manual(GuiEvent event) |
|
|
|
static void screen_manual(GuiEvent event) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
bool temp_changed = false; |
|
|
|
if (event == GUI_EVENT_SCREEN_INIT) { |
|
|
|
if (event == GUI_EVENT_SCREEN_INIT) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -258,23 +284,25 @@ static void screen_manual(GuiEvent event) |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case GUI_EVENT_KNOB_PLUS: |
|
|
|
case GUI_EVENT_KNOB_PLUS: |
|
|
|
if (s_app.set_temp < MAX_TEMP) { |
|
|
|
if (s_app.set_temp <= MAX_TEMP - 5) { |
|
|
|
input_sound_effect(); |
|
|
|
s_app.set_temp += 5; |
|
|
|
s_app.set_temp_wheel++; |
|
|
|
temp_changed = true; |
|
|
|
manual_calc_set_temp(); |
|
|
|
|
|
|
|
request_paint(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case GUI_EVENT_KNOB_MINUS: |
|
|
|
case GUI_EVENT_KNOB_MINUS: |
|
|
|
if (s_app.set_temp > 0) { |
|
|
|
if (s_app.set_temp >= 5) { |
|
|
|
input_sound_effect(); |
|
|
|
s_app.set_temp -= 5; |
|
|
|
s_app.set_temp_wheel--; |
|
|
|
temp_changed = true; |
|
|
|
manual_calc_set_temp(); |
|
|
|
|
|
|
|
request_paint(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (temp_changed) { |
|
|
|
|
|
|
|
input_sound_effect(); |
|
|
|
|
|
|
|
app_heater_set_target((float) s_app.set_temp); |
|
|
|
|
|
|
|
request_paint(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------
|
|
|
|
// ---------------------------
|
|
|
@ -308,48 +336,83 @@ static void screen_manual_menu(GuiEvent event) |
|
|
|
// ------------------------
|
|
|
|
// ------------------------
|
|
|
|
|
|
|
|
|
|
|
|
static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { |
|
|
|
static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { |
|
|
|
|
|
|
|
bool menu_changed = false; |
|
|
|
|
|
|
|
uint32_t tickNow = xTaskGetTickCount(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct menu_state *menu = &s_app.page.menu; |
|
|
|
|
|
|
|
|
|
|
|
switch (event) { |
|
|
|
switch (event) { |
|
|
|
case GUI_EVENT_SCREEN_INIT: |
|
|
|
case GUI_EVENT_SCREEN_INIT: |
|
|
|
s_app.menu_pos = 0; |
|
|
|
menu->pos = 0; |
|
|
|
s_app.menu_len = 0; |
|
|
|
menu->len = 0; |
|
|
|
|
|
|
|
menu->change_time = tickNow; |
|
|
|
|
|
|
|
menu->text_slide = 0; |
|
|
|
const char **opt = options; |
|
|
|
const char **opt = options; |
|
|
|
while (*opt) { |
|
|
|
while (*opt) { |
|
|
|
s_app.menu_len++; |
|
|
|
menu->len++; |
|
|
|
opt++; |
|
|
|
opt++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
menu->pos = menu->len - 1; // FIXME temporary, for debug
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case GUI_EVENT_SCREEN_TICK: |
|
|
|
|
|
|
|
if (tickNow - menu->change_time >= pdMS_TO_TICKS(500)) { |
|
|
|
|
|
|
|
uint32_t textlen = strlen(options[menu->pos]) * 6; |
|
|
|
|
|
|
|
if (textlen >= FBW - 2) { |
|
|
|
|
|
|
|
if (textlen - menu->text_slide > FBW - 2) { |
|
|
|
|
|
|
|
menu->text_slide += 1; |
|
|
|
|
|
|
|
if (textlen - menu->text_slide > FBW - 2) { |
|
|
|
|
|
|
|
menu->slide_end_time = tickNow; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (tickNow - menu->slide_end_time >= pdMS_TO_TICKS(500)) { |
|
|
|
|
|
|
|
menu->change_time = tickNow; |
|
|
|
|
|
|
|
menu->slide_end_time = 0; |
|
|
|
|
|
|
|
menu->text_slide = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
request_paint(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case GUI_EVENT_PAINT: |
|
|
|
case GUI_EVENT_PAINT: |
|
|
|
for (int i = 0; i < s_app.menu_len; i++) { |
|
|
|
for (int i = 0; i < menu->len; i++) { |
|
|
|
fbcolor_t color = s_app.menu_pos != i; |
|
|
|
bool current = menu->pos == i; |
|
|
|
|
|
|
|
fbcolor_t color = !current; |
|
|
|
fbpos_t y = 27 + i * 10; |
|
|
|
fbpos_t y = 27 + i * 10; |
|
|
|
fb_rect(0, y, 64, 10, !color); |
|
|
|
fb_rect(0, y, FBW, 10, !color); |
|
|
|
fb_text(1, y + 1, options[i], FONT_5X7, color); |
|
|
|
fb_text(1 - (current ? menu->text_slide : 0), y + 1, options[i], FONT_5X7, color); |
|
|
|
// ensure the text doesnt escape the screen
|
|
|
|
// ensure the text doesnt escape the screen
|
|
|
|
fb_vline(63, y, 10, !color); |
|
|
|
fb_vline(FBW - 1, y, 10, !color); |
|
|
|
|
|
|
|
fb_vline(0, y, 10, !color); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
// the button is held! release is what activates the button
|
|
|
|
// the button is held! release is what activates the button
|
|
|
|
case GUI_EVENT_KNOB_RELEASE: |
|
|
|
case GUI_EVENT_KNOB_RELEASE: |
|
|
|
input_sound_effect(); |
|
|
|
input_sound_effect(); |
|
|
|
cb(s_app.menu_pos); |
|
|
|
cb(menu->pos); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case GUI_EVENT_KNOB_PLUS: |
|
|
|
case GUI_EVENT_KNOB_PLUS: |
|
|
|
if (s_app.menu_pos < s_app.menu_len - 1) { |
|
|
|
if (menu->pos < menu->len - 1) { |
|
|
|
s_app.menu_pos++; |
|
|
|
menu->pos++; |
|
|
|
input_sound_effect(); |
|
|
|
menu_changed = true; |
|
|
|
request_paint(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case GUI_EVENT_KNOB_MINUS: |
|
|
|
case GUI_EVENT_KNOB_MINUS: |
|
|
|
if (s_app.menu_pos > 0) { |
|
|
|
if (menu->pos > 0) { |
|
|
|
s_app.menu_pos--; |
|
|
|
menu->pos--; |
|
|
|
input_sound_effect(); |
|
|
|
menu_changed = true; |
|
|
|
request_paint(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (menu_changed) { |
|
|
|
|
|
|
|
menu->change_time = tickNow; |
|
|
|
|
|
|
|
menu->text_slide = 0; |
|
|
|
|
|
|
|
menu->slide_end_time = 0; |
|
|
|
|
|
|
|
input_sound_effect(); |
|
|
|
|
|
|
|
request_paint(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|