New panel design
This commit is contained in:
1 parent
face2432e4
commit
b5d6b4a897
30 files changed
+4540
-171
No files matched your search
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Host implementation of the firmware's lvgl_port.h contract.
|
||||
*
|
||||
* The firmware version (main/ui/lvgl_port.c) is built on FreeRTOS tasks and
|
||||
* esp_timer. This file provides the same six entry points on pthreads so that
|
||||
* main/ui/ui_manager.c -- the file whose layout we actually iterate on --
|
||||
* compiles and runs unchanged on the desktop.
|
||||
*
|
||||
* The one deliberate behavioural difference is lvgl_port_start(): on the
|
||||
* device it spawns the task that calls lv_timer_handler(), whereas here the
|
||||
* simulator's own main loop drives LVGL. See the comment on that function.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
#include "lvgl_port.h"
|
||||
|
||||
static const char *TAG = "lvgl_port_sim";
|
||||
|
||||
static pthread_mutex_t lvgl_mutex;
|
||||
static bool mutex_ready = false;
|
||||
static volatile bool paused = false;
|
||||
|
||||
/* LVGL's millisecond time base. The firmware drives this from a 2ms esp_timer
|
||||
* calling lv_tick_inc(); on the host a monotonic clock read is both simpler
|
||||
* and more accurate. */
|
||||
static uint32_t tick_get_cb(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (uint32_t)(ts.tv_sec * 1000U + ts.tv_nsec / 1000000U);
|
||||
}
|
||||
|
||||
esp_err_t lvgl_port_init(void)
|
||||
{
|
||||
/*
|
||||
* Recursive, matching the device: lv_timer_handler() runs callbacks that
|
||||
* may re-enter code which also takes the lock. Keeping the same semantics
|
||||
* here means a deadlock introduced in shared UI code reproduces in the
|
||||
* simulator instead of only showing up on hardware.
|
||||
*/
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
if (pthread_mutex_init(&lvgl_mutex, &attr) != 0) {
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
mutex_ready = true;
|
||||
|
||||
lv_init();
|
||||
lv_tick_set_cb(tick_get_cb);
|
||||
|
||||
ESP_LOGI(TAG, "LVGL %d.%d.%d initialized (simulator)",
|
||||
lv_version_major(), lv_version_minor(), lv_version_patch());
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* No-op by design.
|
||||
*
|
||||
* On the device this starts the tick timer and the LVGL service task. Here the
|
||||
* tick is a clock callback installed in lvgl_port_init(), and lv_timer_handler()
|
||||
* is called from the simulator's main loop -- running it from a second thread
|
||||
* as well would mean two threads rendering into one framebuffer.
|
||||
*
|
||||
* It still exists so that shared start-up code can call it unconditionally.
|
||||
*/
|
||||
esp_err_t lvgl_port_start(void)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void lvgl_port_pause(void)
|
||||
{
|
||||
paused = true;
|
||||
}
|
||||
|
||||
void lvgl_port_resume(void)
|
||||
{
|
||||
paused = false;
|
||||
}
|
||||
|
||||
bool lvgl_port_is_paused(void)
|
||||
{
|
||||
return paused;
|
||||
}
|
||||
|
||||
bool lvgl_port_lock(int timeout_ms)
|
||||
{
|
||||
if (!mutex_ready) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timeout_ms < 0) {
|
||||
return pthread_mutex_lock(&lvgl_mutex) == 0;
|
||||
}
|
||||
|
||||
struct timespec deadline;
|
||||
clock_gettime(CLOCK_REALTIME, &deadline);
|
||||
deadline.tv_sec += timeout_ms / 1000;
|
||||
deadline.tv_nsec += (long)(timeout_ms % 1000) * 1000000L;
|
||||
if (deadline.tv_nsec >= 1000000000L) {
|
||||
deadline.tv_sec++;
|
||||
deadline.tv_nsec -= 1000000000L;
|
||||
}
|
||||
|
||||
return pthread_mutex_timedlock(&lvgl_mutex, &deadline) == 0;
|
||||
}
|
||||
|
||||
void lvgl_port_unlock(void)
|
||||
{
|
||||
if (mutex_ready) {
|
||||
pthread_mutex_unlock(&lvgl_mutex);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user