diff --git a/components/esp_lvgl_port/idf_component.yml b/components/esp_lvgl_port/idf_component.yml index fb7e7619..aed2f92d 100644 --- a/components/esp_lvgl_port/idf_component.yml +++ b/components/esp_lvgl_port/idf_component.yml @@ -1,4 +1,4 @@ -version: "2.4.3" +version: "2.4.4" description: ESP LVGL port url: https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port dependencies: diff --git a/components/esp_lvgl_port/src/lvgl8/esp_lvgl_port_knob.c b/components/esp_lvgl_port/src/lvgl8/esp_lvgl_port_knob.c index 328e405a..dfbc9ecf 100644 --- a/components/esp_lvgl_port/src/lvgl8/esp_lvgl_port_knob.c +++ b/components/esp_lvgl_port/src/lvgl8/esp_lvgl_port_knob.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,8 @@ typedef struct { knob_handle_t knob_handle; /* Encoder knob handlers */ button_handle_t btn_handle; /* Encoder button handlers */ lv_indev_drv_t indev_drv; /* LVGL input device driver */ - bool btn_enter; /* Encoder button enter state */ + bool btn_enter; /* Encoder button enter state */ + int32_t diff; /* Encoder diff */ } lvgl_port_encoder_ctx_t; /******************************************************************************* @@ -29,6 +30,9 @@ typedef struct { static void lvgl_port_encoder_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data); static void lvgl_port_encoder_btn_down_handler(void *arg, void *arg2); static void lvgl_port_encoder_btn_up_handler(void *arg, void *arg2); +static void lvgl_port_encoder_left_handler(void *arg, void *arg2); +static void lvgl_port_encoder_right_handler(void *arg, void *arg2); +static int32_t lvgl_port_calculate_diff(knob_handle_t knob, knob_event_t event); /******************************************************************************* * Public API functions @@ -54,6 +58,9 @@ lv_indev_t *lvgl_port_add_encoder(const lvgl_port_encoder_cfg_t *encoder_cfg) ESP_GOTO_ON_FALSE(encoder_ctx->knob_handle, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for knob create!"); } + ESP_ERROR_CHECK(iot_knob_register_cb(encoder_ctx->knob_handle, KNOB_LEFT, lvgl_port_encoder_left_handler, encoder_ctx)); + ESP_ERROR_CHECK(iot_knob_register_cb(encoder_ctx->knob_handle, KNOB_RIGHT, lvgl_port_encoder_right_handler, encoder_ctx)); + /* Encoder Enter */ if (encoder_cfg->encoder_enter != NULL) { encoder_ctx->btn_handle = iot_button_create(encoder_cfg->encoder_enter); @@ -64,6 +71,7 @@ lv_indev_t *lvgl_port_add_encoder(const lvgl_port_encoder_cfg_t *encoder_cfg) ESP_ERROR_CHECK(iot_button_register_cb(encoder_ctx->btn_handle, BUTTON_PRESS_UP, lvgl_port_encoder_btn_up_handler, encoder_ctx)); encoder_ctx->btn_enter = false; + encoder_ctx->diff = 0; /* Register a encoder input device */ lv_indev_drv_init(&encoder_ctx->indev_drv); @@ -118,22 +126,13 @@ esp_err_t lvgl_port_remove_encoder(lv_indev_t *encoder) static void lvgl_port_encoder_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { - static int32_t last_v = 0; - assert(indev_drv); lvgl_port_encoder_ctx_t *ctx = (lvgl_port_encoder_ctx_t *)indev_drv->user_data; assert(ctx); - int32_t invd = iot_knob_get_count_value(ctx->knob_handle); - knob_event_t event = iot_knob_get_event(ctx->knob_handle); - - if (last_v ^ invd) { - last_v = invd; - data->enc_diff = (KNOB_LEFT == event) ? (-1) : ((KNOB_RIGHT == event) ? (1) : (0)); - } else { - data->enc_diff = 0; - } + data->enc_diff = ctx->diff; data->state = (true == ctx->btn_enter) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + ctx->diff = 0; } static void lvgl_port_encoder_btn_down_handler(void *arg, void *arg2) @@ -159,3 +158,47 @@ static void lvgl_port_encoder_btn_up_handler(void *arg, void *arg2) } } } + +static void lvgl_port_encoder_left_handler(void *arg, void *arg2) +{ + lvgl_port_encoder_ctx_t *ctx = (lvgl_port_encoder_ctx_t *) arg2; + knob_handle_t knob = (knob_handle_t)arg; + if (ctx && knob) { + /* LEFT */ + if (knob == ctx->knob_handle) { + int32_t diff = lvgl_port_calculate_diff(knob, KNOB_LEFT); + ctx->diff = (ctx->diff > 0) ? diff : ctx->diff + diff; + } + } +} + +static void lvgl_port_encoder_right_handler(void *arg, void *arg2) +{ + lvgl_port_encoder_ctx_t *ctx = (lvgl_port_encoder_ctx_t *) arg2; + knob_handle_t knob = (knob_handle_t)arg; + if (ctx && knob) { + /* RIGHT */ + if (knob == ctx->knob_handle) { + int32_t diff = lvgl_port_calculate_diff(knob, KNOB_RIGHT); + ctx->diff = (ctx->diff < 0) ? diff : ctx->diff + diff; + } + } +} + +static int32_t lvgl_port_calculate_diff(knob_handle_t knob, knob_event_t event) +{ + static int32_t last_v = 0; + + int32_t diff = 0; + int32_t invd = iot_knob_get_count_value(knob); + + if (last_v ^ invd) { + + diff = (int32_t)((uint32_t)invd - (uint32_t)last_v); + diff += (event == KNOB_RIGHT && invd < last_v) ? CONFIG_KNOB_HIGH_LIMIT : + (event == KNOB_LEFT && invd > last_v) ? CONFIG_KNOB_LOW_LIMIT : 0; + last_v = invd; + } + + return diff; +} diff --git a/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_knob.c b/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_knob.c index 81157182..cf461eed 100644 --- a/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_knob.c +++ b/components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_knob.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ typedef struct { button_handle_t btn_handle; /* Encoder button handlers */ lv_indev_t *indev; /* LVGL input device driver */ bool btn_enter; /* Encoder button enter state */ + int32_t diff; /* Encoder diff */ } lvgl_port_encoder_ctx_t; /******************************************************************************* @@ -29,7 +30,9 @@ typedef struct { static void lvgl_port_encoder_read(lv_indev_t *indev_drv, lv_indev_data_t *data); static void lvgl_port_encoder_btn_down_handler(void *arg, void *arg2); static void lvgl_port_encoder_btn_up_handler(void *arg, void *arg2); -static void lvgl_port_encoder_knob_handler(void *arg, void *arg2); +static void lvgl_port_encoder_left_handler(void *arg, void *arg2); +static void lvgl_port_encoder_right_handler(void *arg, void *arg2); +static int32_t lvgl_port_calculate_diff(knob_handle_t knob, knob_event_t event); /******************************************************************************* * Public API functions @@ -54,8 +57,8 @@ lv_indev_t *lvgl_port_add_encoder(const lvgl_port_encoder_cfg_t *encoder_cfg) encoder_ctx->knob_handle = iot_knob_create(encoder_cfg->encoder_a_b); ESP_GOTO_ON_FALSE(encoder_ctx->knob_handle, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for knob create!"); - ESP_ERROR_CHECK(iot_knob_register_cb(encoder_ctx->knob_handle, KNOB_LEFT, lvgl_port_encoder_knob_handler, encoder_ctx)); - ESP_ERROR_CHECK(iot_knob_register_cb(encoder_ctx->knob_handle, KNOB_RIGHT, lvgl_port_encoder_knob_handler, encoder_ctx)); + ESP_ERROR_CHECK(iot_knob_register_cb(encoder_ctx->knob_handle, KNOB_LEFT, lvgl_port_encoder_left_handler, encoder_ctx)); + ESP_ERROR_CHECK(iot_knob_register_cb(encoder_ctx->knob_handle, KNOB_RIGHT, lvgl_port_encoder_right_handler, encoder_ctx)); } /* Encoder Enter */ @@ -68,6 +71,7 @@ lv_indev_t *lvgl_port_add_encoder(const lvgl_port_encoder_cfg_t *encoder_cfg) ESP_ERROR_CHECK(iot_button_register_cb(encoder_ctx->btn_handle, BUTTON_PRESS_UP, lvgl_port_encoder_btn_up_handler, encoder_ctx)); encoder_ctx->btn_enter = false; + encoder_ctx->diff = 0; lvgl_port_lock(0); /* Register a encoder input device */ @@ -130,21 +134,13 @@ esp_err_t lvgl_port_remove_encoder(lv_indev_t *encoder) static void lvgl_port_encoder_read(lv_indev_t *indev_drv, lv_indev_data_t *data) { - static int32_t last_v = 0; assert(indev_drv); lvgl_port_encoder_ctx_t *ctx = (lvgl_port_encoder_ctx_t *)lv_indev_get_user_data(indev_drv); assert(ctx); - int32_t invd = iot_knob_get_count_value(ctx->knob_handle); - knob_event_t event = iot_knob_get_event(ctx->knob_handle); - - if (last_v ^ invd) { - last_v = invd; - data->enc_diff = (KNOB_LEFT == event) ? (-1) : ((KNOB_RIGHT == event) ? (1) : (0)); - } else { - data->enc_diff = 0; - } + data->enc_diff = ctx->diff; data->state = (true == ctx->btn_enter) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + ctx->diff = 0; } static void lvgl_port_encoder_btn_down_handler(void *arg, void *arg2) @@ -177,9 +173,51 @@ static void lvgl_port_encoder_btn_up_handler(void *arg, void *arg2) lvgl_port_task_wake(LVGL_PORT_EVENT_TOUCH, ctx->indev); } -static void lvgl_port_encoder_knob_handler(void *arg, void *arg2) +static void lvgl_port_encoder_left_handler(void *arg, void *arg2) { lvgl_port_encoder_ctx_t *ctx = (lvgl_port_encoder_ctx_t *) arg2; - /* Wake LVGL task, if needed */ - lvgl_port_task_wake(LVGL_PORT_EVENT_TOUCH, ctx->indev); + knob_handle_t knob = (knob_handle_t)arg; + if (ctx && knob) { + /* LEFT */ + if (knob == ctx->knob_handle) { + int32_t diff = lvgl_port_calculate_diff(knob, KNOB_LEFT); + ctx->diff = (ctx->diff > 0) ? diff : ctx->diff + diff; + } + /* Wake LVGL task, if needed */ + lvgl_port_task_wake(LVGL_PORT_EVENT_TOUCH, ctx->indev); + } +} + +static void lvgl_port_encoder_right_handler(void *arg, void *arg2) +{ + lvgl_port_encoder_ctx_t *ctx = (lvgl_port_encoder_ctx_t *) arg2; + knob_handle_t knob = (knob_handle_t)arg; + if (ctx && knob) { + /* RIGHT */ + if (knob == ctx->knob_handle) { + int32_t diff = lvgl_port_calculate_diff(knob, KNOB_RIGHT); + ctx->diff = (ctx->diff < 0) ? diff : ctx->diff + diff; + } + /* Wake LVGL task, if needed */ + lvgl_port_task_wake(LVGL_PORT_EVENT_TOUCH, ctx->indev); + } +} + + +static int32_t lvgl_port_calculate_diff(knob_handle_t knob, knob_event_t event) +{ + static int32_t last_v = 0; + + int32_t diff = 0; + int32_t invd = iot_knob_get_count_value(knob); + + if (last_v ^ invd) { + + diff = (int32_t)((uint32_t)invd - (uint32_t)last_v); + diff += (event == KNOB_RIGHT && invd < last_v) ? CONFIG_KNOB_HIGH_LIMIT : + (event == KNOB_LEFT && invd > last_v) ? CONFIG_KNOB_LOW_LIMIT : 0; + last_v = invd; + } + + return diff; }