11/*
2- * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
@@ -20,6 +20,7 @@ typedef struct {
2020 button_handle_t btn_handle ; /* Encoder button handlers */
2121 lv_indev_t * indev ; /* LVGL input device driver */
2222 bool btn_enter ; /* Encoder button enter state */
23+ int32_t diff ; /* Encoder diff */
2324} lvgl_port_encoder_ctx_t ;
2425
2526/*******************************************************************************
@@ -29,7 +30,9 @@ typedef struct {
2930static void lvgl_port_encoder_read (lv_indev_t * indev_drv , lv_indev_data_t * data );
3031static void lvgl_port_encoder_btn_down_handler (void * arg , void * arg2 );
3132static void lvgl_port_encoder_btn_up_handler (void * arg , void * arg2 );
32- static void lvgl_port_encoder_knob_handler (void * arg , void * arg2 );
33+ static void lvgl_port_encoder_left_handler (void * arg , void * arg2 );
34+ static void lvgl_port_encoder_right_handler (void * arg , void * arg2 );
35+ static int32_t lvgl_port_calculate_diff (knob_handle_t knob , knob_event_t event );
3336
3437/*******************************************************************************
3538* Public API functions
@@ -54,8 +57,8 @@ lv_indev_t *lvgl_port_add_encoder(const lvgl_port_encoder_cfg_t *encoder_cfg)
5457 encoder_ctx -> knob_handle = iot_knob_create (encoder_cfg -> encoder_a_b );
5558 ESP_GOTO_ON_FALSE (encoder_ctx -> knob_handle , ESP_ERR_NO_MEM , err , TAG , "Not enough memory for knob create!" );
5659
57- ESP_ERROR_CHECK (iot_knob_register_cb (encoder_ctx -> knob_handle , KNOB_LEFT , lvgl_port_encoder_knob_handler , encoder_ctx ));
58- ESP_ERROR_CHECK (iot_knob_register_cb (encoder_ctx -> knob_handle , KNOB_RIGHT , lvgl_port_encoder_knob_handler , encoder_ctx ));
60+ ESP_ERROR_CHECK (iot_knob_register_cb (encoder_ctx -> knob_handle , KNOB_LEFT , lvgl_port_encoder_left_handler , encoder_ctx ));
61+ ESP_ERROR_CHECK (iot_knob_register_cb (encoder_ctx -> knob_handle , KNOB_RIGHT , lvgl_port_encoder_right_handler , encoder_ctx ));
5962 }
6063
6164 /* Encoder Enter */
@@ -68,6 +71,7 @@ lv_indev_t *lvgl_port_add_encoder(const lvgl_port_encoder_cfg_t *encoder_cfg)
6871 ESP_ERROR_CHECK (iot_button_register_cb (encoder_ctx -> btn_handle , BUTTON_PRESS_UP , lvgl_port_encoder_btn_up_handler , encoder_ctx ));
6972
7073 encoder_ctx -> btn_enter = false;
74+ encoder_ctx -> diff = 0 ;
7175
7276 lvgl_port_lock (0 );
7377 /* Register a encoder input device */
@@ -130,21 +134,13 @@ esp_err_t lvgl_port_remove_encoder(lv_indev_t *encoder)
130134
131135static void lvgl_port_encoder_read (lv_indev_t * indev_drv , lv_indev_data_t * data )
132136{
133- static int32_t last_v = 0 ;
134137 assert (indev_drv );
135138 lvgl_port_encoder_ctx_t * ctx = (lvgl_port_encoder_ctx_t * )lv_indev_get_driver_data (indev_drv );
136139 assert (ctx );
137140
138- int32_t invd = iot_knob_get_count_value (ctx -> knob_handle );
139- knob_event_t event = iot_knob_get_event (ctx -> knob_handle );
140-
141- if (last_v ^ invd ) {
142- last_v = invd ;
143- data -> enc_diff = (KNOB_LEFT == event ) ? (-1 ) : ((KNOB_RIGHT == event ) ? (1 ) : (0 ));
144- } else {
145- data -> enc_diff = 0 ;
146- }
141+ data -> enc_diff = ctx -> diff ;
147142 data -> state = (true == ctx -> btn_enter ) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED ;
143+ ctx -> diff = 0 ;
148144}
149145
150146static 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)
177173 lvgl_port_task_wake (LVGL_PORT_EVENT_TOUCH , ctx -> indev );
178174}
179175
180- static void lvgl_port_encoder_knob_handler (void * arg , void * arg2 )
176+ static void lvgl_port_encoder_left_handler (void * arg , void * arg2 )
181177{
182178 lvgl_port_encoder_ctx_t * ctx = (lvgl_port_encoder_ctx_t * ) arg2 ;
183- /* Wake LVGL task, if needed */
184- lvgl_port_task_wake (LVGL_PORT_EVENT_TOUCH , ctx -> indev );
179+ knob_handle_t knob = (knob_handle_t )arg ;
180+ if (ctx && knob ) {
181+ /* LEFT */
182+ if (knob == ctx -> knob_handle ) {
183+ int32_t diff = lvgl_port_calculate_diff (knob , KNOB_LEFT );
184+ ctx -> diff = (ctx -> diff > 0 ) ? diff : ctx -> diff + diff ;
185+ }
186+ /* Wake LVGL task, if needed */
187+ lvgl_port_task_wake (LVGL_PORT_EVENT_TOUCH , ctx -> indev );
188+ }
189+ }
190+
191+ static void lvgl_port_encoder_right_handler (void * arg , void * arg2 )
192+ {
193+ lvgl_port_encoder_ctx_t * ctx = (lvgl_port_encoder_ctx_t * ) arg2 ;
194+ knob_handle_t knob = (knob_handle_t )arg ;
195+ if (ctx && knob ) {
196+ /* RIGHT */
197+ if (knob == ctx -> knob_handle ) {
198+ int32_t diff = lvgl_port_calculate_diff (knob , KNOB_RIGHT );
199+ ctx -> diff = (ctx -> diff < 0 ) ? diff : ctx -> diff + diff ;
200+ }
201+ /* Wake LVGL task, if needed */
202+ lvgl_port_task_wake (LVGL_PORT_EVENT_TOUCH , ctx -> indev );
203+ }
204+ }
205+
206+
207+ static int32_t lvgl_port_calculate_diff (knob_handle_t knob , knob_event_t event )
208+ {
209+ static int32_t last_v = 0 ;
210+
211+ int32_t diff = 0 ;
212+ int32_t invd = iot_knob_get_count_value (knob );
213+
214+ if (last_v ^ invd ) {
215+
216+ diff = (int32_t )((uint32_t )invd - (uint32_t )last_v );
217+ diff += (event == KNOB_RIGHT && invd < last_v ) ? CONFIG_KNOB_HIGH_LIMIT :
218+ (event == KNOB_LEFT && invd > last_v ) ? CONFIG_KNOB_LOW_LIMIT : 0 ;
219+ last_v = invd ;
220+ }
221+
222+ return diff ;
185223}
0 commit comments