diff --git a/CHANGELOG.md b/CHANGELOG.md index 73aaabdfd..b1af0eaf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file. - Berry driver for PN532 NFC/Mifare reader (#22899) - Berry `tasmota.add_rule_once` and auto-remove rules with same pattern and id (#22900) - Berry example for HeatFan WiFi Controller +- LVGL add `lv.set_paint_cb()` to register a callback when screen is refreshed ### Breaking Changed diff --git a/lib/libesp32/berry_tasmota/src/be_lv_tasmota_lib.c b/lib/libesp32/berry_tasmota/src/be_lv_tasmota_lib.c index 951a6eb24..0a1710dd0 100644 --- a/lib/libesp32/berry_tasmota/src/be_lv_tasmota_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_lv_tasmota_lib.c @@ -16,6 +16,7 @@ extern int lv0_load_robotocondensed_latin1_font(bvm *vm); extern int lv0_load_font_embedded(bvm *vm); extern int lv0_screenshot(bvm *vm); +extern int lv0_set_paint_cb(bvm *vm); extern int lv0_load_freetype_font(bvm *vm); #include "solidify/solidified_lv_tasmota.h" @@ -37,6 +38,7 @@ module lv_tasmota (scope: global, strings: weak) { font_embedded, func(lv0_load_font_embedded) register_button_encoder, func(lv0_register_button_encoder) screenshot, func(lv0_screenshot) + set_paint_cb, func(lv0_set_paint_cb) load_freetype_font, func(lv0_load_freetype_font) } diff --git a/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota.be b/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota.be index f98dea1dc..f24f26a78 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota.be +++ b/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota.be @@ -25,6 +25,7 @@ def init(lv_tasmota) lv.register_button_encoder = lv_tasmota.register_button_encoder lv.screenshot = lv_tasmota.screenshot + lv.set_paint_cb = lv_tasmota.set_paint_cb # add version information lv.version = lv.version_major() diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota.h index 5d4d0254b..addf5c8cc 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota.h @@ -17,7 +17,7 @@ be_local_closure(module_lv_tasmota_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[36]) { /* constants */ + ( &(const bvalue[37]) { /* constants */ /* K0 */ be_nested_str_weak(lv), /* K1 */ be_nested_str_weak(start), /* K2 */ be_nested_str_weak(_constants), @@ -33,31 +33,32 @@ be_local_closure(module_lv_tasmota_init, /* name */ /* K12 */ be_nested_str_weak(load_freetype_font), /* K13 */ be_nested_str_weak(register_button_encoder), /* K14 */ be_nested_str_weak(screenshot), - /* K15 */ be_nested_str_weak(version), - /* K16 */ be_nested_str_weak(version_major), - /* K17 */ be_nested_str_weak(clock), - /* K18 */ be_nested_str_weak(lv_clock), - /* K19 */ be_nested_str_weak(clock_icon), - /* K20 */ be_nested_str_weak(lv_clock_icon), - /* K21 */ be_nested_str_weak(signal_arcs), - /* K22 */ be_nested_str_weak(lv_signal_arcs), - /* K23 */ be_nested_str_weak(signal_bars), - /* K24 */ be_nested_str_weak(lv_signal_bars), - /* K25 */ be_nested_str_weak(wifi_arcs_icon), - /* K26 */ be_nested_str_weak(lv_wifi_arcs_icon), - /* K27 */ be_nested_str_weak(wifi_arcs), - /* K28 */ be_nested_str_weak(lv_wifi_arcs), - /* K29 */ be_nested_str_weak(wifi_bars_icon), - /* K30 */ be_nested_str_weak(lv_wifi_bars_icon), - /* K31 */ be_nested_str_weak(wifi_bars), - /* K32 */ be_nested_str_weak(lv_wifi_bars), - /* K33 */ be_nested_str_weak(tasmota), - /* K34 */ be_nested_str_weak(get_option), - /* K35 */ be_const_int(0), + /* K15 */ be_nested_str_weak(set_paint_cb), + /* K16 */ be_nested_str_weak(version), + /* K17 */ be_nested_str_weak(version_major), + /* K18 */ be_nested_str_weak(clock), + /* K19 */ be_nested_str_weak(lv_clock), + /* K20 */ be_nested_str_weak(clock_icon), + /* K21 */ be_nested_str_weak(lv_clock_icon), + /* K22 */ be_nested_str_weak(signal_arcs), + /* K23 */ be_nested_str_weak(lv_signal_arcs), + /* K24 */ be_nested_str_weak(signal_bars), + /* K25 */ be_nested_str_weak(lv_signal_bars), + /* K26 */ be_nested_str_weak(wifi_arcs_icon), + /* K27 */ be_nested_str_weak(lv_wifi_arcs_icon), + /* K28 */ be_nested_str_weak(wifi_arcs), + /* K29 */ be_nested_str_weak(lv_wifi_arcs), + /* K30 */ be_nested_str_weak(wifi_bars_icon), + /* K31 */ be_nested_str_weak(lv_wifi_bars_icon), + /* K32 */ be_nested_str_weak(wifi_bars), + /* K33 */ be_nested_str_weak(lv_wifi_bars), + /* K34 */ be_nested_str_weak(tasmota), + /* K35 */ be_nested_str_weak(get_option), + /* K36 */ be_const_int(0), }), be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[58]) { /* code */ + ( &(const binstruction[60]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x88080101, // 0001 GETMBR R2 R0 K1 0x90060202, // 0002 SETMBR R1 K1 R2 @@ -87,35 +88,37 @@ be_local_closure(module_lv_tasmota_init, /* name */ 0x90061A02, // 001A SETMBR R1 K13 R2 0x8808010E, // 001B GETMBR R2 R0 K14 0x90061C02, // 001C SETMBR R1 K14 R2 - 0x8C080310, // 001D GETMET R2 R1 K16 - 0x7C080200, // 001E CALL R2 1 - 0x90061E02, // 001F SETMBR R1 K15 R2 - 0xB80A2400, // 0020 GETNGBL R2 K18 - 0x90062202, // 0021 SETMBR R1 K17 R2 - 0xB80A2800, // 0022 GETNGBL R2 K20 - 0x90062602, // 0023 SETMBR R1 K19 R2 - 0xB80A2C00, // 0024 GETNGBL R2 K22 - 0x90062A02, // 0025 SETMBR R1 K21 R2 - 0xB80A3000, // 0026 GETNGBL R2 K24 - 0x90062E02, // 0027 SETMBR R1 K23 R2 - 0xB80A3400, // 0028 GETNGBL R2 K26 - 0x90063202, // 0029 SETMBR R1 K25 R2 - 0xB80A3800, // 002A GETNGBL R2 K28 - 0x90063602, // 002B SETMBR R1 K27 R2 - 0xB80A3C00, // 002C GETNGBL R2 K30 - 0x90063A02, // 002D SETMBR R1 K29 R2 - 0xB80A4000, // 002E GETNGBL R2 K32 - 0x90063E02, // 002F SETMBR R1 K31 R2 + 0x8808010F, // 001D GETMBR R2 R0 K15 + 0x90061E02, // 001E SETMBR R1 K15 R2 + 0x8C080311, // 001F GETMET R2 R1 K17 + 0x7C080200, // 0020 CALL R2 1 + 0x90062002, // 0021 SETMBR R1 K16 R2 + 0xB80A2600, // 0022 GETNGBL R2 K19 + 0x90062402, // 0023 SETMBR R1 K18 R2 + 0xB80A2A00, // 0024 GETNGBL R2 K21 + 0x90062802, // 0025 SETMBR R1 K20 R2 + 0xB80A2E00, // 0026 GETNGBL R2 K23 + 0x90062C02, // 0027 SETMBR R1 K22 R2 + 0xB80A3200, // 0028 GETNGBL R2 K25 + 0x90063002, // 0029 SETMBR R1 K24 R2 + 0xB80A3600, // 002A GETNGBL R2 K27 + 0x90063402, // 002B SETMBR R1 K26 R2 + 0xB80A3A00, // 002C GETNGBL R2 K29 + 0x90063802, // 002D SETMBR R1 K28 R2 + 0xB80A3E00, // 002E GETNGBL R2 K31 + 0x90063C02, // 002F SETMBR R1 K30 R2 0xB80A4200, // 0030 GETNGBL R2 K33 - 0x8C080522, // 0031 GETMET R2 R2 K34 - 0x54120086, // 0032 LDINT R4 135 - 0x7C080400, // 0033 CALL R2 2 - 0x1C080523, // 0034 EQ R2 R2 K35 - 0x780A0001, // 0035 JMPF R2 #0038 - 0x8C080303, // 0036 GETMET R2 R1 K3 - 0x7C080200, // 0037 CALL R2 1 - 0x4C080000, // 0038 LDNIL R2 - 0x80040400, // 0039 RET 1 R2 + 0x90064002, // 0031 SETMBR R1 K32 R2 + 0xB80A4400, // 0032 GETNGBL R2 K34 + 0x8C080523, // 0033 GETMET R2 R2 K35 + 0x54120086, // 0034 LDINT R4 135 + 0x7C080400, // 0035 CALL R2 2 + 0x1C080524, // 0036 EQ R2 R2 K36 + 0x780A0001, // 0037 JMPF R2 #003A + 0x8C080303, // 0038 GETMET R2 R1 K3 + 0x7C080200, // 0039 CALL R2 1 + 0x4C080000, // 003A LDNIL R2 + 0x80040400, // 003B RET 1 R2 }) ) ); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino index e6838a48e..200004e1b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino @@ -50,6 +50,8 @@ extern bool lvgl_started(void); extern void lvgl_set_screenshot_file(File * file); extern void lvgl_reset_screenshot_file(void); File * lvgl_get_screenshot_file(void); +extern void lv_set_paint_cb(void* cb); +extern void* lv_get_paint_cb(void); /******************************************************************** * Structures used by LVGL_Berry @@ -658,6 +660,19 @@ extern "C" { be_pushstring(vm, fname); be_return(vm); } + + /*********************************************************************************************\ + * Screenshot in raw format + \********************************************************************************************/ + int lv0_set_paint_cb(bvm *vm); + int lv0_set_paint_cb(bvm *vm) { + int32_t argc = be_top(vm); // Get the number of arguments + if (argc >= 1 && be_iscomptr(vm, 1)) { + lv_set_paint_cb(be_tocomptr(vm, 1)); + } + be_pushcomptr(vm, lv_get_paint_cb()); + be_return(vm); + } } #else // USE_LVGL diff --git a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino index ad7029310..bd2aa1295 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino @@ -31,6 +31,9 @@ #include "freertos/task.h" #include "freertos/semphr.h" +// callback type when a screen paint is done +typedef void (*lv_paint_cb_t)(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t *pixels); + struct LVGL_Glue { lv_display_t *lv_display = nullptr; lv_indev_t *lv_indev = nullptr; @@ -38,6 +41,7 @@ struct LVGL_Glue { void *lv_pixel_buf2 = nullptr; Ticker tick; File * screenshot = nullptr; + lv_paint_cb_t paint_cb = nullptr; }; LVGL_Glue * lvgl_glue; @@ -100,6 +104,20 @@ void lv_flush_callback(lv_display_t *disp, const lv_area_t *area, uint8_t *color chrono_time > 0 ? pixels_len / chrono_time : -1); } } + // if there is a display callback, call it + if (lvgl_glue->paint_cb != nullptr) { + lvgl_glue->paint_cb(area->x1, area->y1, area->x2, area->y2, color_p); + } +} + +void lv_set_paint_cb(void* cb); +void lv_set_paint_cb(void* cb) { + lvgl_glue->paint_cb = (lv_paint_cb_t) cb; +} + +void * lv_get_paint_cb(void); +void * lv_get_paint_cb(void) { + return (void*) lvgl_glue->paint_cb; }