split gui file

calib-gui
Ondřej Hruška 2 years ago
parent 415a6cb06c
commit ccce0ff72f
  1. 146
      Core/Src/Gui/app_gui.c
  2. 94
      Core/Src/Gui/app_gui.h
  3. 38
      Core/Src/Gui/gui_event.h
  4. 38
      Core/Src/Gui/screen_home.c
  5. 91
      Core/Src/Gui/screen_manual.c
  6. 97
      Core/Src/Gui/screen_menu.c
  7. 27
      Core/Src/Gui/screen_menu.h
  8. 422
      Core/Src/app_gui.c
  9. 39
      Core/Src/app_gui.h
  10. 2
      Core/Src/app_heater.c
  11. 2
      Core/Src/app_heater.h
  12. 3
      Core/Src/app_knob.c
  13. 8
      Makefile

@ -0,0 +1,146 @@
/**
* TODO file description
*/
#include <stdbool.h>
#include <string.h>
#include "app_gui.h"
#include "app_buzzer.h"
#include "app_temp.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "ufb/framebuffer.h"
#include "ufb/fb_text.h"
#include "app_safety.h"
/** Get push time (while held) */
uint32_t push_time() {
return s_app.pushed ? (xTaskGetTickCount() - s_app.push_time) : 0;
}
/** Schedule paint (the screen func will be called with the PAINT event argument */
void request_paint() {
s_app.paint_needed = true;
}
/** Draw the common overlay / HUD (with temperatures and heater status) */
static void draw_common_overlay();
static char tmp[100];
/** Main loop */
void app_task_gui(void *argument) {
// Wait until inited
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
PUTS("GUI task starts\r\n");
s_app.last_tick_time = xTaskGetTickCount();
switch_screen(screen_home, true);
while (1) {
uint32_t message = GUI_EVENT_NONE;
int32_t ticks_remain = (int32_t) pdMS_TO_TICKS(10) - (int32_t) (xTaskGetTickCount() - s_app.last_tick_time);
if (ticks_remain < 0) {
ticks_remain = 0;
}
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();
// 10ms tick event
if (tickNow - s_app.last_tick_time > pdMS_TO_TICKS(10)) {
s_app.screen(GUI_EVENT_SCREEN_TICK);
s_app.last_tick_time = tickNow;
}
if (tickNow - s_app.last_read_temp_time > pdMS_TO_TICKS(250)) {
s_app.oven_temp = app_temp_read_oven();
//s_app.soc_temp = app_temp_read_soc();
request_paint();
s_app.last_read_temp_time = tickNow;
}
switch (message) {
case GUI_EVENT_KNOB_PRESS:
s_app.pushed = true;
s_app.push_time = tickNow;
break;
case GUI_EVENT_KNOB_RELEASE:
s_app.pushed = false;
if (s_app.initial_pushed) {
s_app.initial_pushed = false;
message = GUI_EVENT_NONE;
}
break;
}
if (message != GUI_EVENT_NONE) {
s_app.screen(message);
}
app_safety_pass_display_updating();
if (s_app.paint_needed) {
s_app.paint_needed = false;
fb_clear();
draw_common_overlay();
s_app.screen(GUI_EVENT_PAINT);
fb_blit();
}
}
}
/** Switch to a different screen handler.
* If "init" is true, immediately call it with the init event. */
void switch_screen(screen_t pScreen, bool init) {
s_app.initial_pushed = s_app.pushed;
s_app.screen = pScreen;
// clear the union field
memset(&s_app.page, 0, sizeof(s_app.page));
request_paint();
if (init) {
pScreen(GUI_EVENT_SCREEN_INIT);
}
}
/** Draw GUI common to all screens */
static void draw_common_overlay() {
SPRINTF(tmp, "%3.1f°C →%3d°C", s_app.oven_temp, s_app.set_temp);
fb_text(3, 3, tmp, FONT_3X5, 1);
if (s_app.heater_enabled) {
fb_frame(0, 0, FBW, 11, 2, 1);
}
}
/** Play input sound effect if this is an input event */
void input_sound_effect() {
app_buzzer_beep();
}

@ -0,0 +1,94 @@
/**
* TODO file description
*/
#ifndef BLUEPILLTROUBA_APP_GUI_H
#define BLUEPILLTROUBA_APP_GUI_H
#include "cmsis_os2.h"
#include <stdbool.h>
#include "gui_event.h"
void app_task_gui(void *argument);
/**
* Screen callback type. The event is either INIT, PAINT, or one of the input events.
*/
typedef void (*screen_t)(GuiEvent event);
/** Input beep (push or knob turn) */
void input_sound_effect();
/** Switch to a different screen. Handles initial push state handling (so release
* does not cause a "click" event).
*
* @param pScreen - screen to switch to
* @param init - call the INIT event immediately after
*/
void switch_screen(screen_t pScreen, bool init);
void request_paint();
uint32_t push_time();
// prototypes for screen handlers
void screen_home(GuiEvent event);
void screen_manual(GuiEvent event);
void screen_manual_menu(GuiEvent event);
static struct State {
/// Latest oven temp readout
float oven_temp;
//float soc_temp;
// manual mode controls
/// Currently set target temp
int set_temp;
/// Heater enabled status (only visual)
bool heater_enabled;
/// Prescaller for the knob, CCW direction.
/// Event increments this counter and resets the other. Knob turn event is generated on overflow.
bool down_prescaller;
/// Prescaller for the knob, CW direction
/// See `down_prescaller`
bool up_prescaller;
/// Curent status of the push button
bool pushed;
/// Repaint was requested from the screen code
bool paint_needed;
/// Timestamp of the last GUI tick
uint32_t last_tick_time;
/// Timestamp when the button was pushed
uint32_t push_time;
/// Timestamp when we last read oven temperature for display
uint32_t last_read_temp_time;
/// true if the button is still held since init (i.e. the push action should not work as "enter")
bool initial_pushed;
/// Pointer to the currently active screen func
screen_t screen;
/// data specific for each of the screens (not persistent across screen switching)
union {
/// Generic menu
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 = {};
#endif //BLUEPILLTROUBA_APP_GUI_H

@ -0,0 +1,38 @@
//
// Created by MightyPork on 2023/04/09.
//
#ifndef TOASTER_OVEN_BLUEPILL_GUI_EVENT_H
#define TOASTER_OVEN_BLUEPILL_GUI_EVENT_H
#include "cmsis_os2.h"
extern osThreadId_t guiTskHandle;
extern osMessageQueueId_t guiEventQueHandle;
// sent through the notify queue
typedef enum GuiEvent {
/// No event, zero; This is a default value.
GUI_EVENT_NONE = 0,
/// Cause redraw
GUI_EVENT_PAINT = 0,
/// Used as the argument when initing a screen
GUI_EVENT_SCREEN_INIT = 1,
/// Time tick, used to carry timing to the screen functions.
/// This tick has 10ms interval
GUI_EVENT_SCREEN_TICK = 2,
/// Knob rotate CW
GUI_EVENT_KNOB_PLUS,
/// Knob rotate CCW
GUI_EVENT_KNOB_MINUS,
/// Knob pressed
GUI_EVENT_KNOB_PRESS,
/// Knob released
GUI_EVENT_KNOB_RELEASE,
/// Temperature readings changed.
/// Not really an input event, but it should trigger a redraw
GUI_EVENT_TEMP_CHANGE,
} GuiEvent;
#endif //TOASTER_OVEN_BLUEPILL_GUI_EVENT_H

@ -0,0 +1,38 @@
//
// Created by MightyPork on 2023/04/09.
//
#include <stddef.h>
#include <stdbool.h>
#include "app_gui.h"
#include "app_heater.h"
#include "screen_menu.h"
static const char* main_menu_opts[] = {
"Ruční režim",
"Kalibrace",
"Programy",
"Diagnostika",
NULL
};
static void main_menu_cb(int opt) {
switch (opt) {
case 0:
switch_screen(screen_manual, true);
break;
case 1:
// TODO
break;
}
}
void screen_home(GuiEvent event)
{
if (event == GUI_EVENT_SCREEN_INIT) {
app_heater_enable(false);
}
screen_menu(event, main_menu_opts, main_menu_cb);
}

@ -0,0 +1,91 @@
//
// Created by MightyPork on 2023/04/09.
//
#include <stddef.h>
#include <stdbool.h>
#include "app_gui.h"
#include "gui_event.h"
#include "screen_menu.h"
#include "app_heater.h"
#include "ufb/fb_7seg.h"
#include "FreeRTOS.h"
void screen_manual(GuiEvent event)
{
bool temp_changed = false;
if (event == GUI_EVENT_SCREEN_INIT) {
return;
}
// menu is activated by long push
if (push_time() >= pdMS_TO_TICKS(500)) {
switch_screen(screen_manual_menu, true);
return;
}
switch (event) {
case GUI_EVENT_PAINT:
fb_7seg_number(4, 40, 12, 20, 2, 2,
1,
s_app.set_temp, 3, 0
);
break;
case GUI_EVENT_KNOB_RELEASE:
input_sound_effect();
s_app.heater_enabled ^= 1;
app_heater_enable(s_app.heater_enabled);
request_paint();
break;
case GUI_EVENT_KNOB_PLUS:
if (s_app.set_temp <= MAX_TEMP - 5) {
s_app.set_temp += 5;
temp_changed = true;
}
break;
case GUI_EVENT_KNOB_MINUS:
if (s_app.set_temp >= 5) {
s_app.set_temp -= 5;
temp_changed = true;
}
break;
}
if (temp_changed) {
input_sound_effect();
app_heater_set_target((float) s_app.set_temp);
request_paint();
}
}
// ---------------------------
static const char* manual_menu_opts[] = {
"Zrušit",
"Hlavní menu",
NULL
};
static void manual_menu_cb(int opt) {
switch (opt) {
case 0:
// Close menu
switch_screen(screen_manual, false);
break;
case 1:
s_app.heater_enabled = false;
app_heater_enable(false);
switch_screen(screen_home, true);
break;
}
}
void screen_manual_menu(GuiEvent event)
{
screen_menu(event, manual_menu_opts, manual_menu_cb);
}

@ -0,0 +1,97 @@
//
// Created by MightyPork on 2023/04/09.
//
#include <stdbool.h>
#include "screen_menu.h"
#include "app_gui.h"
#include "FreeRTOS.h"
#include "task.h"
#include "ufb/utf8.h"
#include "ufb/framebuffer_config.h"
#include "ufb/framebuffer.h"
#include "ufb/fb_text.h"
void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) {
bool menu_changed = false;
const uint32_t tickNow = xTaskGetTickCount();
struct menu_state *menu = &s_app.page.menu;
switch (event) {
case GUI_EVENT_SCREEN_INIT:
menu->pos = 0;
menu->len = 0;
menu->change_time = tickNow;
menu->text_slide = 0;
const char **opt = options;
while (*opt) {
menu->len++;
opt++;
}
break;
case GUI_EVENT_SCREEN_TICK:
// long text sliding animation
if (tickNow - menu->change_time >= pdMS_TO_TICKS(500)) {
const uint32_t textlen = utf8_strlen(options[menu->pos]) * 6;
if (textlen >= FBW - 2) {
if (textlen - menu->text_slide > FBW - 1) {
menu->text_slide += 1;
if (textlen - menu->text_slide >= FBW - 1) {
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;
case GUI_EVENT_PAINT:
for (int i = 0; i < menu->len; i++) {
// is the row currently rendered the selected row?
const bool is_selected = menu->pos == i;
const fbcolor_t color = !is_selected; // text color - black if selected, because it's inverted
const fbpos_t y = 27 + i * 10;
fb_rect(0, y, FBW, 10, !color);
fb_text(1 - (is_selected ? menu->text_slide : 0), y + 1, options[i], FONT_5X7, color);
// ensure the text doesn't touch the edge (looks ugly)
fb_vline(FBW - 1, y, 10, !color);
fb_vline(0, y, 10, !color);
}
break;
// the button is held! release is what activates the button
case GUI_EVENT_KNOB_RELEASE:
input_sound_effect();
cb(menu->pos);
break;
case GUI_EVENT_KNOB_PLUS:
if (menu->pos < menu->len - 1) {
menu->pos++;
menu_changed = true;
}
break;
case GUI_EVENT_KNOB_MINUS:
if (menu->pos > 0) {
menu->pos--;
menu_changed = true;
}
break;
}
if (menu_changed) {
menu->change_time = tickNow;
menu->text_slide = 0;
menu->slide_end_time = 0;
input_sound_effect();
request_paint();
}
}

@ -0,0 +1,27 @@
//
// Created by MightyPork on 2023/04/09.
//
// Generic menu screen
//
#ifndef TOASTER_OVEN_BLUEPILL_SCREEN_MENU_H
#define TOASTER_OVEN_BLUEPILL_SCREEN_MENU_H
#include "gui_event.h"
/**
* Choice callback for the generic menu screen. Options are indexed from zero
*/
typedef void (*menu_callback_t)(int choice);
/**
* Generic menu screen (must be called from a screen function with the standard signature)
*
* @param event - currently handled event
* @param options - options for the menu (items to show, NULL terminated array of const strings)
* @param cb - choice callback
*/
void screen_menu(GuiEvent event, const char **options, menu_callback_t cb);
#endif //TOASTER_OVEN_BLUEPILL_SCREEN_MENU_H

@ -1,422 +0,0 @@
/**
* TODO file description
*/
#include <stdbool.h>
#include <string.h>
#include "app_gui.h"
#include "app_heater.h"
#include "app_buzzer.h"
#include "app_temp.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "ufb/framebuffer.h"
#include "ufb/fb_text.h"
#include "ufb/fb_7seg.h"
#include "app_safety.h"
#include "ufb/utf8.h"
#define MAX_TEMP 400
/**
* Screen callback type. The event is either INIT, PAINT, or one of the input events.
*/
typedef void (*screen_t)(GuiEvent event);
/**
* Choice callback for the generic menu screen
*/
typedef void (*menu_callback_t)(int choice);
/**
* Generic menu screen (must be called from a screen function with the standard signature)
*
* @param event - currently handled event
* @param options - options for the menu (items to show)
* @param cb - choice callback
*/
static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb);
static struct State {
float oven_temp;
//float soc_temp;
// manual mode controls
int set_temp;
bool heater_enabled;
bool down_prescaller;
bool up_prescaller;
bool pushed;
bool paint_needed;
uint32_t last_tick_event;
uint32_t push_tick;
uint32_t last_read_temp_tick;
// true if the button is still held since init (i.e. the push action should not work as "enter")
bool initial_pushed;
screen_t screen;
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 = {};
/** Get push time (while held) */
static uint32_t push_time() {
return s_app.pushed ? (xTaskGetTickCount() - s_app.push_tick) : 0;
}
/** Schedule paint (the screen func will be called with the PAINT event argument */
static void request_paint() {
s_app.paint_needed = true;
}
/** Home screen */
static void screen_home(GuiEvent event);
/** Manual temperature setting screen */
static void screen_manual(GuiEvent event);
/** Menu in the manual temperature setting screen */
static void screen_manual_menu(GuiEvent event);
/** Draw the common overlay / HUD (with temperatures and heater status) */
static void draw_common_overlay();
/** Input beep (push or knob turn) */
static void input_sound_effect();
/** Switch to a different screen. Handles initial push state handling (so release
* does not cause a "click" event).
*
* @param pScreen - screen to switch to
* @param init - call the INIT event immediately after
*/
static void switch_screen(screen_t pScreen, bool init);
static char tmp[100];
/** Main loop */
void app_task_gui(void *argument)
{
// Wait until inited
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
PUTS("GUI task starts\r\n");
s_app.last_tick_event = xTaskGetTickCount();
switch_screen(screen_home, true);
while (1) {
uint32_t message = GUI_EVENT_NONE;
int32_t ticks_remain = (int32_t) pdMS_TO_TICKS(10) - (int32_t)(xTaskGetTickCount() - s_app.last_tick_event);
if (ticks_remain < 0) {
ticks_remain = 0;
}
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();
// 10ms tick event
if (tickNow - s_app.last_tick_event > pdMS_TO_TICKS(10)) {
s_app.screen(GUI_EVENT_SCREEN_TICK);
s_app.last_tick_event = tickNow;
}
if (tickNow - s_app.last_read_temp_tick > pdMS_TO_TICKS(250)) {
s_app.oven_temp = app_temp_read_oven();
//s_app.soc_temp = app_temp_read_soc();
request_paint();
s_app.last_read_temp_tick = tickNow;
}
switch (message) {
case GUI_EVENT_KNOB_PRESS:
s_app.pushed = true;
s_app.push_tick = tickNow;
break;
case GUI_EVENT_KNOB_RELEASE:
s_app.pushed = false;
if (s_app.initial_pushed) {
s_app.initial_pushed = false;
message = GUI_EVENT_NONE;
}
break;
}
if (message != GUI_EVENT_NONE) {
s_app.screen(message);
}
app_safety_pass_display_updating();
if (s_app.paint_needed) {
s_app.paint_needed = false;
fb_clear();
draw_common_overlay();
s_app.screen(GUI_EVENT_PAINT);
fb_blit();
}
}
}
/** Switch to a different screen handler.
* If "init" is true, immediately call it with the init event. */
static void switch_screen(screen_t pScreen, bool init) {
s_app.initial_pushed = s_app.pushed;
s_app.screen = pScreen;
// clear the union field
memset(&s_app.page, 0, sizeof(s_app.page));
request_paint();
if (init) {
pScreen(GUI_EVENT_SCREEN_INIT);
}
}
/** Draw GUI common to all screens */
static void draw_common_overlay()
{
SPRINTF(tmp, "%3.1f°C →%3d°C", s_app.oven_temp, s_app.set_temp);
fb_text(3, 3, tmp, FONT_3X5, 1);
if (s_app.heater_enabled) {
fb_frame(0, 0, FBW, 11, 2, 1);
}
}
/** Play input sound effect if this is an input event */
static void input_sound_effect()
{
app_buzzer_beep();
}
// ------------- home screen ----------------
static const char* main_menu_opts[] = {
"Ruční režim",
"Kalibrace",
"Programy",
"Diagnostika",
NULL
};
static void main_menu_cb(int opt) {
switch (opt) {
case 0:
switch_screen(screen_manual, true);
break;
case 1:
// TODO
break;
}
}
static void screen_home(GuiEvent event)
{
if (event == GUI_EVENT_SCREEN_INIT) {
app_heater_enable(false);
}
screen_menu(event, main_menu_opts, main_menu_cb);
}
// --------- manual mode screen ---------------
static void screen_manual(GuiEvent event)
{
bool temp_changed = false;
if (event == GUI_EVENT_SCREEN_INIT) {
return;
}
// menu is activated by long push
if (push_time() >= pdMS_TO_TICKS(500)) {
switch_screen(screen_manual_menu, true);
return;
}
switch (event) {
case GUI_EVENT_PAINT:
fb_7seg_number(4, 40, 12, 20, 2, 2,
1,
s_app.set_temp, 3, 0
);
break;
case GUI_EVENT_KNOB_RELEASE:
input_sound_effect();
s_app.heater_enabled ^= 1;
app_heater_enable(s_app.heater_enabled);
request_paint();
break;
case GUI_EVENT_KNOB_PLUS:
if (s_app.set_temp <= MAX_TEMP - 5) {
s_app.set_temp += 5;
temp_changed = true;
}
break;
case GUI_EVENT_KNOB_MINUS:
if (s_app.set_temp >= 5) {
s_app.set_temp -= 5;
temp_changed = true;
}
break;
}
if (temp_changed) {
input_sound_effect();
app_heater_set_target((float) s_app.set_temp);
request_paint();
}
}
// ---------------------------
static const char* manual_menu_opts[] = {
"Zrušit",
"Hlavní menu",
NULL
};
static void manual_menu_cb(int opt) {
switch (opt) {
case 0:
// Close menu
switch_screen(screen_manual, false);
break;
case 1:
s_app.heater_enabled = false;
app_heater_enable(false);
switch_screen(screen_home, true);
break;
}
}
static void screen_manual_menu(GuiEvent event)
{
screen_menu(event, manual_menu_opts, manual_menu_cb);
}
// ------------------------
static void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) {
bool menu_changed = false;
const uint32_t tickNow = xTaskGetTickCount();
struct menu_state *menu = &s_app.page.menu;
switch (event) {
case GUI_EVENT_SCREEN_INIT:
menu->pos = 0;
menu->len = 0;
menu->change_time = tickNow;
menu->text_slide = 0;
const char **opt = options;
while (*opt) {
menu->len++;
opt++;
}
break;
case GUI_EVENT_SCREEN_TICK:
// long text sliding animation
if (tickNow - menu->change_time >= pdMS_TO_TICKS(500)) {
const uint32_t textlen = utf8_strlen(options[menu->pos]) * 6;
if (textlen >= FBW - 2) {
if (textlen - menu->text_slide > FBW - 1) {
menu->text_slide += 1;
if (textlen - menu->text_slide >= FBW - 1) {
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;
case GUI_EVENT_PAINT:
for (int i = 0; i < menu->len; i++) {
// is the row currently rendered the selected row?
const bool is_selected = menu->pos == i;
const fbcolor_t color = !is_selected; // text color - black if selected, because it's inverted
const fbpos_t y = 27 + i * 10;
fb_rect(0, y, FBW, 10, !color);
fb_text(1 - (is_selected ? menu->text_slide : 0), y + 1, options[i], FONT_5X7, color);
// ensure the text doesn't touch the edge (looks ugly)
fb_vline(FBW - 1, y, 10, !color);
fb_vline(0, y, 10, !color);
}
break;
// the button is held! release is what activates the button
case GUI_EVENT_KNOB_RELEASE:
input_sound_effect();
cb(menu->pos);
break;
case GUI_EVENT_KNOB_PLUS:
if (menu->pos < menu->len - 1) {
menu->pos++;
menu_changed = true;
}
break;
case GUI_EVENT_KNOB_MINUS:
if (menu->pos > 0) {
menu->pos--;
menu_changed = true;
}
break;
}
if (menu_changed) {
menu->change_time = tickNow;
menu->text_slide = 0;
menu->slide_end_time = 0;
input_sound_effect();
request_paint();
}
}

@ -1,39 +0,0 @@
/**
* TODO file description
*/
#ifndef BLUEPILLTROUBA_APP_GUI_H
#define BLUEPILLTROUBA_APP_GUI_H
#include "cmsis_os2.h"
extern osThreadId_t guiTskHandle;
extern osMessageQueueId_t guiEventQueHandle;
void app_task_gui(void *argument);
// sent through the notify queue
typedef enum GuiEvent {
/// No event, zero; This is a default value.
GUI_EVENT_NONE = 0,
/// Cause redraw
GUI_EVENT_PAINT = 0,
/// Used as the argument when initing a screen
GUI_EVENT_SCREEN_INIT = 1,
/// Time tick, used to carry timing to the screen functions.
/// This tick has 10ms interval
GUI_EVENT_SCREEN_TICK = 2,
/// Knob rotate CW
GUI_EVENT_KNOB_PLUS,
/// Knob rotate CCW
GUI_EVENT_KNOB_MINUS,
/// Knob pressed
GUI_EVENT_KNOB_PRESS,
/// Knob released
GUI_EVENT_KNOB_RELEASE,
/// Temperature readings changed.
/// Not really an input event, but it should trigger a redraw
GUI_EVENT_TEMP_CHANGE,
} GuiEvent;
#endif //BLUEPILLTROUBA_APP_GUI_H

@ -8,8 +8,8 @@
#include "cmsis_os2.h" #include "cmsis_os2.h"
#include "tim.h" #include "tim.h"
#include "queue.h" #include "queue.h"
#include "app_gui.h"
#include "app_safety.h" #include "app_safety.h"
#include "Gui/gui_event.h"
extern osMutexId_t heaterMutexHandle; extern osMutexId_t heaterMutexHandle;

@ -8,6 +8,8 @@
#include <stdbool.h> #include <stdbool.h>
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define MAX_TEMP 400
extern osThreadId_t heaterTskHandle; extern osThreadId_t heaterTskHandle;
void app_task_heater(void *argument); void app_task_heater(void *argument);

@ -6,10 +6,11 @@
#include "main.h" #include "main.h"
#include "app_knob.h" #include "app_knob.h"
#include "tim.h" #include "tim.h"
#include "app_gui.h"
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "queue.h" #include "queue.h"
#include "timers.h" #include "timers.h"
#include "cmsis_os2.h"
#include "Gui/gui_event.h"
extern osTimerId_t buttonPushTimerHandle; extern osTimerId_t buttonPushTimerHandle;
extern osTimerId_t buttonReleaseTimerHandle; extern osTimerId_t buttonReleaseTimerHandle;

@ -47,7 +47,10 @@ Core/Src/usart.c \
Core/Src/app_oled.c \ Core/Src/app_oled.c \
Core/Src/app_main.c \ Core/Src/app_main.c \
Core/Src/app_pid.c \ Core/Src/app_pid.c \
Core/Src/app_gui.c \ Core/Src/Gui/app_gui.c \
Core/Src/Gui/screen_menu.c \
Core/Src/Gui/screen_home.c \
Core/Src/Gui/screen_manual.c \
Core/Src/app_temp.c \ Core/Src/app_temp.c \
Core/Src/app_knob.c \ Core/Src/app_knob.c \
Core/Src/app_buzzer.c \ Core/Src/app_buzzer.c \
@ -154,6 +157,7 @@ AS_INCLUDES = \
# C includes # C includes
C_INCLUDES = \ C_INCLUDES = \
-ICore/Inc \ -ICore/Inc \
-ICore/Src \
-IDrivers/STM32F1xx_HAL_Driver/Inc \ -IDrivers/STM32F1xx_HAL_Driver/Inc \
-IMiddlewares/Third_Party/FreeRTOS/Source/include \ -IMiddlewares/Third_Party/FreeRTOS/Source/include \
-IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \ -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \
@ -225,7 +229,7 @@ $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
.PHONY: all flash clean flash-stlink analyze size .PHONY: all flash clean flash-stlink analyze size fonts
####################################### #######################################
# clean up # clean up

Loading…
Cancel
Save