mirror of https://github.com/arendst/Tasmota.git
Merge pull request #12074 from s-hadinger/lvgl_fix_events
LVGL fixed events and callbacks
This commit is contained in:
commit
5453aff793
|
@ -6,7 +6,7 @@
|
||||||
extern void lv_flush_callback(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
|
extern void lv_flush_callback(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
|
||||||
|
|
||||||
// Tick interval for LittlevGL internal timekeeping; 1 to 10 ms recommended
|
// Tick interval for LittlevGL internal timekeeping; 1 to 10 ms recommended
|
||||||
static const int lv_tick_interval_ms = 10;
|
static const int lv_tick_interval_ms = 5;
|
||||||
|
|
||||||
static void lv_tick_handler(void) { lv_tick_inc(lv_tick_interval_ms); }
|
static void lv_tick_handler(void) { lv_tick_inc(lv_tick_interval_ms); }
|
||||||
|
|
||||||
|
|
|
@ -923,6 +923,7 @@
|
||||||
// -- LVGL Graphics Library ---------------------------------
|
// -- LVGL Graphics Library ---------------------------------
|
||||||
//#define USE_LVGL // LVGL Engine, requires Berry, takes 440k of Flash
|
//#define USE_LVGL // LVGL Engine, requires Berry, takes 440k of Flash
|
||||||
#define USE_LVGL_PSRAM // Allocate LVGL memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
|
#define USE_LVGL_PSRAM // Allocate LVGL memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
|
||||||
|
#define USE_LVGL_MAX_SLEEP 10 // max sleep in ms when LVGL is enabled, more than 10ms will make display less responsive
|
||||||
#define USE_LVGL_BG_DEFAULT 0x000000 // Default color for the uninitialized background screen (black)
|
#define USE_LVGL_BG_DEFAULT 0x000000 // Default color for the uninitialized background screen (black)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8365,11 +8365,6 @@ bool Xdrv10(uint8_t function)
|
||||||
case FUNC_EVERY_100_MSECOND:
|
case FUNC_EVERY_100_MSECOND:
|
||||||
ScripterEvery100ms();
|
ScripterEvery100ms();
|
||||||
break;
|
break;
|
||||||
#ifdef USE_LVGL
|
|
||||||
case FUNC_EVERY_50_MSECOND:
|
|
||||||
lv_task_handler();
|
|
||||||
break;
|
|
||||||
#endif // USE_LVGL
|
|
||||||
|
|
||||||
case FUNC_EVERY_SECOND:
|
case FUNC_EVERY_SECOND:
|
||||||
ScriptEverySecond();
|
ScriptEverySecond();
|
||||||
|
|
|
@ -227,7 +227,8 @@ const lvbe_callback lvbe_callbacks[LVBE_MAX_CALLBACK] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t lvbe_callback_x(uint32_t n, struct _lv_obj_t * obj, int32_t v1, int32_t v2, int32_t v3, int32_t v4) {
|
int32_t lvbe_callback_x(uint32_t n, struct _lv_obj_t * obj, int32_t v1, int32_t v2, int32_t v3, int32_t v4) {
|
||||||
be_getglobal(berry.vm, LVBE_LVGL_CB_OBJ);
|
// berry_log_P(">>>: Callback called n=%i obj=0x%08X v1=%i v2=%i", n, obj, v1, v2);
|
||||||
|
be_getglobal(berry.vm, LVBE_LVGL_CB_DISPATCH); // stack: List
|
||||||
be_pushint(berry.vm, n);
|
be_pushint(berry.vm, n);
|
||||||
be_pushint(berry.vm, (int32_t) obj);
|
be_pushint(berry.vm, (int32_t) obj);
|
||||||
be_pushint(berry.vm, v1);
|
be_pushint(berry.vm, v1);
|
||||||
|
@ -237,7 +238,7 @@ int32_t lvbe_callback_x(uint32_t n, struct _lv_obj_t * obj, int32_t v1, int32_t
|
||||||
be_pcall(berry.vm, 6);
|
be_pcall(berry.vm, 6);
|
||||||
int32_t ret = be_toint(berry.vm, -7);
|
int32_t ret = be_toint(berry.vm, -7);
|
||||||
be_pop(berry.vm, 7);
|
be_pop(berry.vm, 7);
|
||||||
berry_log_P(">>>: Callback called%d", n);
|
// berry_log_P(">>>: Callback called out %d ret=%i", n, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,7 @@ const char berry_prog[] =
|
||||||
"_lvgl_cb = [ {}, {}, {}, {}, {}, {} ] "
|
"_lvgl_cb = [ {}, {}, {}, {}, {}, {} ] "
|
||||||
"_lvgl_cb_obj = [ {}, {}, {}, {}, {}, {} ] "
|
"_lvgl_cb_obj = [ {}, {}, {}, {}, {}, {} ] "
|
||||||
"def _lvgl_cb_dispatch(idx, obj, v1, v2, v3, v4) "
|
"def _lvgl_cb_dispatch(idx, obj, v1, v2, v3, v4) "
|
||||||
|
// "import string print(string.format('>>> idx=%i obj=0x%08X v1=%i', idx, obj, v1)) "
|
||||||
"var func = _lvgl_cb[idx].find(obj) "
|
"var func = _lvgl_cb[idx].find(obj) "
|
||||||
"var inst = _lvgl_cb_obj[idx].find(obj) "
|
"var inst = _lvgl_cb_obj[idx].find(obj) "
|
||||||
"if func != nil "
|
"if func != nil "
|
||||||
|
|
|
@ -32,53 +32,8 @@
|
||||||
|
|
||||||
#include "Adafruit_LvGL_Glue.h"
|
#include "Adafruit_LvGL_Glue.h"
|
||||||
|
|
||||||
|
|
||||||
/* Creates a semaphore to handle concurrent call to lvgl stuff
|
|
||||||
* If you wish to call *any* lvgl function from other threads/tasks
|
|
||||||
* you should lock on the very same semaphore! */
|
|
||||||
|
|
||||||
SemaphoreHandle_t xGuiSemaphore;
|
|
||||||
//uDisplay * udisp = nullptr;
|
|
||||||
|
|
||||||
// necessary for compilation
|
|
||||||
uint8_t color_type_lvgl = 0;
|
|
||||||
uint8_t * buffer_lvgl = nullptr;
|
|
||||||
void udisp_dimm_lvgl(uint8_t dim) {}
|
|
||||||
void udisp_bpwr_lvgl(uint8_t on) {}
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
const char task_name[] = "periodic_gui";
|
|
||||||
/* Create and start a periodic timer interrupt to call lv_tick_inc */
|
|
||||||
const esp_timer_create_args_t periodic_timer_args = {
|
|
||||||
&lv_tick_task,
|
|
||||||
nullptr,
|
|
||||||
ESP_TIMER_TASK,
|
|
||||||
task_name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Adafruit_LvGL_Glue * glue;
|
Adafruit_LvGL_Glue * glue;
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void guiTask(void *pvParameter);
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
* Provide a regular tick to lvgl, every ms
|
|
||||||
************************************************************/
|
|
||||||
|
|
||||||
#ifndef LV_TICK_PERIOD_MS
|
|
||||||
#define LV_TICK_PERIOD_MS 1 // default to tick every 1 ms
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void lv_tick_task(void *arg) {
|
|
||||||
(void) arg;
|
|
||||||
lv_tick_inc(LV_TICK_PERIOD_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// **************************************************
|
// **************************************************
|
||||||
// Logging
|
// Logging
|
||||||
// **************************************************
|
// **************************************************
|
||||||
|
@ -93,34 +48,6 @@ static void lvbe_debug(lv_log_level_t level, const char *file, uint32_t line, co
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
* Maint FreeRTOS task used in a separate thread
|
|
||||||
************************************************************/
|
|
||||||
static void guiTask(void *pvParameter) {
|
|
||||||
(void) pvParameter;
|
|
||||||
xGuiSemaphore = xSemaphoreCreateMutex();
|
|
||||||
|
|
||||||
/* Create and start a periodic timer interrupt to call lv_tick_inc */
|
|
||||||
esp_timer_handle_t periodic_timer;
|
|
||||||
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
|
|
||||||
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
|
||||||
|
|
||||||
/* Try to take the semaphore, call lvgl related function on success */
|
|
||||||
if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
|
|
||||||
lv_task_handler();
|
|
||||||
xSemaphoreGive(xGuiSemaphore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A task should NEVER return */
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Main screen refresh function
|
* Main screen refresh function
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
@ -421,11 +348,6 @@ void start_lvgl(const char * uconfig) {
|
||||||
|
|
||||||
#endif // USE_UFILESYS
|
#endif // USE_UFILESYS
|
||||||
|
|
||||||
/* If you want to use a task to create the graphic, you NEED to create a Pinned task
|
|
||||||
* Otherwise there can be problem such as memory corruption and so on.
|
|
||||||
* NOTE: When not using Wi-Fi nor Bluetooth you can pin the guiTask to core 0 */
|
|
||||||
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1);
|
|
||||||
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_LVGL "LVGL initialized"));
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_LVGL "LVGL initialized"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,6 +362,12 @@ bool Xdrv54(uint8_t function)
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
break;
|
break;
|
||||||
case FUNC_LOOP:
|
case FUNC_LOOP:
|
||||||
|
if (glue) {
|
||||||
|
if (TasmotaGlobal.sleep > USE_LVGL_MAX_SLEEP) {
|
||||||
|
TasmotaGlobal.sleep = USE_LVGL_MAX_SLEEP; // sleep is max 10ms
|
||||||
|
}
|
||||||
|
lv_task_handler();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FUNC_EVERY_50_MSECOND:
|
case FUNC_EVERY_50_MSECOND:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue