Ken Van Hoeylandt 7ea8c346b0
Various improvements (#673)
Graphics & rendering

- Implement `binfont-module` to generate bitmap fonts on the device itself
- Remove lodepng support from LVGL library and create `Modules/lodepng-module` to make the feature re-usable in non-LVGL apps too. Add binding functions for LVGL support.
- Implement large icons for boot screen (Tactility and USB logos)
- Remove unused asset files in `Data/`

Boot

- Split up `Tactility.cpp` and its `run()` function into various `Init*.cpp` files.
- Re-implement `Boot.cpp` app as non-LVGL app
- Boot app now has a `BootSequence.cpp` for the init code.
- LVGL is now started when the Boot app finishes
- Move more init logic into Boot app

BLE

- Don't allocate scan result buffers unless BLE is on
- Allocate scan results in external memory if possible

UX & UI

- USB Settings app: remove border from the button container
2026-10-04 18:09:21 +02:00

89 lines
2.3 KiB
C

// SPDX-License-Identifier: Apache-2.0
#ifdef ESP_PLATFORM
#include <esp_lvgl_port.h>
#include <lvgl/lvgl.h>
#include <lvgl/module.h>
#include <lvgl/devices/keyboard_private.h>
#include <png_decoder.h>
#include <tactility/error.h>
#include <tactility/log.h>
#include <tactility/time.h>
#define TAG "lvgl_esp32"
extern struct LvglModuleConfig lvgl_module_config;
extern void lvgl_devices_attach();
extern void lvgl_devices_detach();
static bool initialized = false;
void lvgl_lock(void) {
if (!initialized) { return; }
lvgl_port_lock(portMAX_DELAY);
}
bool lvgl_try_lock(uint32_t timeoutTicks) {
if (!initialized) { return false; }
// lvgl_port_lock expects milliseconds
return lvgl_port_lock(timeoutTicks * portTICK_PERIOD_MS);
}
void lvgl_unlock(void) {
if (!initialized) { return; }
lvgl_port_unlock();
}
error_t lvgl_arch_start() {
const lvgl_port_cfg_t lvgl_cfg = {
.task_priority = lvgl_module_config.task_priority,
.task_stack = lvgl_module_config.task_stack_size,
.task_affinity = lvgl_module_config.task_affinity,
.task_max_sleep_ms = 500,
.timer_period_ms = 5
};
if (lvgl_port_init(&lvgl_cfg) != ESP_OK) {
return ERROR_RESOURCE;
}
// We must have the state set to "initialized" so that the lvgl lock works
// when we call listener functions. These functions could create new
// devices and services. The latter might start adding widgets immediately.
initialized = true;
lvgl_lock();
lvgl_png_decoder_init();
lvgl_unlock();
// Must exist before devices/services are attached below, since those can
// immediately try to assign an indev to this group (e.g. USB HID input).
lvgl_keyboard_on_start_lvgl();
lvgl_devices_attach();
if (lvgl_module_config.on_start) lvgl_module_config.on_start();
return ERROR_NONE;
}
error_t lvgl_arch_stop() {
if (lvgl_module_config.on_stop) lvgl_module_config.on_stop();
lvgl_devices_detach();
lvgl_keyboard_on_stop_lvgl();
if (lvgl_port_deinit() != ESP_OK) {
// Recreate what stop() above tore down, then call on_start again to recover
lvgl_keyboard_on_start_lvgl();
if (lvgl_module_config.on_start) lvgl_module_config.on_start();
return ERROR_RESOURCE;
}
initialized = false;
return ERROR_NONE;
}
#endif