#include #include #include #include "gui.h" #include "nokia.h" #include "liquid.h" #include "drawing.h" static void gui_thread(void *arg); static void gui_tick(TimerHandle_t xTimer); TaskHandle_t hGuiThread = NULL; static TimerHandle_t hTicker = NULL; void gui_init() { printf("GUI init\n"); LCD_setup(); LCD_setContrast(48); int rv = xTaskCreate(gui_thread, "gui", 4096, NULL, 6, &hGuiThread); assert (rv == pdPASS); hTicker = xTimerCreate( "gui_tick", /* name */ pdMS_TO_TICKS(10), /* period/time */ pdTRUE, /* auto reload */ (void*)0, /* timer ID */ gui_tick); /* callback */ assert(hTicker != NULL); xTimerStart(hTicker, portMAX_DELAY); } static void gui_tick(TimerHandle_t xTimer) { xTaskNotify(hGuiThread, 0b10000, eSetBits); } /** * Notification API: * * 0b1 - knob CW * 0b10 - knowb CCW * 0b100 - button released * 0b1000 - button pressed * 0b10000 - ticker event * * @param arg */ static void __attribute__((noreturn)) gui_thread(void *arg) { struct Liquid *liquid = Liquid_start(); uint32_t last_wheel_time = 0; uint32_t last_time = xTaskGetTickCount(); while (1) { bool want_repaint = false; uint32_t value = 0; xTaskNotifyWait(0, ULONG_MAX, &value, pdMS_TO_TICKS(10)); uint32_t time = xTaskGetTickCount(); if (value & 0b10000) { // TICK want_repaint |= Liquid_handleTick(liquid, time - last_time); last_time = time; } if (value & 0b1000) { want_repaint |= Liquid_handleInput(liquid, InputEvent_Button(1)); } else if (value & 0b100) { want_repaint |= Liquid_handleInput(liquid, InputEvent_Button(0)); } if (value & 0b11) { uint32_t increment = 1; // wheel delta changes with speed if (last_wheel_time != 0) { uint32_t ela = time - last_wheel_time; if (ela < pdMS_TO_TICKS(20)) { increment = 25; } else if (ela < pdMS_TO_TICKS(35)) { increment = 10; } else if (ela < pdMS_TO_TICKS(75)) { increment = 5; } } last_wheel_time = time; if (value & 0b01) { want_repaint |= Liquid_handleInput(liquid, InputEvent_Wheel(increment)); } if (value & 0b10) { want_repaint |= Liquid_handleInput(liquid, InputEvent_Wheel(-increment)); } } if (want_repaint) { Liquid_paint(liquid); } } }