@@ -18,8 +18,6 @@ typedef struct
1818 portMUX_TYPE lock;
1919} lcd_tear_t ;
2020
21- lcd_tear_t *tear_ctx = nullptr ;
22-
2321static const axs15231b_lcd_init_cmd_t lcd_init_cmds[] = {
2422 {0xBB , (uint8_t []){0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x5A , 0xA5 }, 8 , 0 },
2523 {0xA0 , (uint8_t []){0xC0 , 0x10 , 0x00 , 0x02 , 0x00 , 0x00 , 0x04 , 0x3F , 0x20 , 0x05 , 0x3F , 0x3F , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, 17 , 0 },
@@ -55,53 +53,62 @@ static const axs15231b_lcd_init_cmd_t lcd_init_cmds[] = {
5553 {0x2C , (uint8_t []){0x00 , 0x00 , 0x00 , 0x00 }, 4 , 0 }
5654};
5755
58- static void display_sync_cb (lv_event_t *e)
56+ static void displaySyncCallback (lv_event_t *e)
5957{
6058 lcd_tear_t *tear_handle = (lcd_tear_t *)lv_event_get_user_data (e);
6159
62- if (tear_handle == nullptr || tear_handle->te_v_sync_sem == nullptr )
63- {
60+ if (tear_handle == nullptr ) {
6461 return ;
6562 }
6663
67- if (tear_handle->te_catch_sem )
68- {
64+ if (tear_handle->te_catch_sem ) {
6965 xSemaphoreGive (tear_handle->te_catch_sem );
7066 }
7167
72- xSemaphoreTake (tear_handle->te_v_sync_sem , pdMS_TO_TICKS (100 ));
68+ xSemaphoreTake (tear_handle->te_v_sync_sem , portMAX_DELAY);
69+ }
70+
71+ static void teSyncRegistrationTask (void * param)
72+ {
73+ Axs15231bDisplay* display = (Axs15231bDisplay*)param;
74+
75+ vTaskDelay (pdMS_TO_TICKS (200 ));
76+
77+ if (display != nullptr && display->getLvglDisplay () != nullptr ) {
78+ display->registerTeSyncCallback ();
79+ } else {
80+ TT_LOG_E (TAG, " Failed to register TE sync callback - LVGL display not ready after 200ms" );
81+ }
82+
83+ vTaskDelete (nullptr );
7384}
7485
75- static void display_sync_task (void *arg)
86+ static void displaySyncTask (void *arg)
7687{
7788 assert (arg);
7889 lcd_tear_t *tear_handle = (lcd_tear_t *)arg;
7990
80- while (true )
81- {
82- if (pdPASS != xSemaphoreTake (tear_handle->te_catch_sem , pdMS_TO_TICKS (tear_handle->time_Tvdl )))
83- {
91+ while (true ) {
92+ if (pdPASS != xSemaphoreTake (tear_handle->te_catch_sem , pdMS_TO_TICKS (tear_handle->time_Tvdl ))) {
8493 xSemaphoreTake (tear_handle->te_v_sync_sem , 0 );
8594 }
8695 }
8796 vTaskDelete (nullptr );
8897}
8998
90- static void IRAM_ATTR display_tear_interrupt (void *arg)
99+ static void displayTearInterrupt (void *arg)
91100{
92101 assert (arg);
93102 lcd_tear_t *tear_handle = (lcd_tear_t *)arg;
94103 BaseType_t xHigherPriorityTaskAwoken = pdFALSE;
95-
96- if (tear_handle->te_v_sync_sem )
97- {
104+
105+ if (tear_handle->te_v_sync_sem ) {
98106 portENTER_CRITICAL_ISR (&tear_handle->lock );
99107 tear_handle->te_timestamp = esp_log_timestamp ();
100108 portEXIT_CRITICAL_ISR (&tear_handle->lock );
101109 xSemaphoreGiveFromISR (tear_handle->te_v_sync_sem , &xHigherPriorityTaskAwoken);
102110
103- if (xHigherPriorityTaskAwoken)
104- {
111+ if (xHigherPriorityTaskAwoken) {
105112 portYIELD_FROM_ISR ();
106113 }
107114 }
@@ -200,30 +207,30 @@ bool Axs15231bDisplay::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp
200207
201208 if (configuration->tePin > 0 )
202209 {
203- tear_ctx = (lcd_tear_t *)malloc (sizeof (lcd_tear_t ));
204- if (tear_ctx == nullptr ) {
210+ lcd_tear_t * tear_handle = (lcd_tear_t *)malloc (sizeof (lcd_tear_t ));
211+ if (tear_handle == nullptr ) {
205212 TT_LOG_E (TAG, " Not enough memory for tear_ctx allocation!" );
206213 goto err;
207214 }
208215
209216 te_v_sync_sem = xSemaphoreCreateCounting (1 , 0 );
210217 if (!te_v_sync_sem) {
211- TT_LOG_E (TAG, " Not enough memory for te_v_sync_sem Semaphore. " );
218+ TT_LOG_E (TAG, " Failed to create TE vsync semaphore " );
212219 goto err;
213220 }
214- tear_ctx ->te_v_sync_sem = te_v_sync_sem;
221+ tear_handle ->te_v_sync_sem = te_v_sync_sem;
215222
216223 te_catch_sem = xSemaphoreCreateCounting (1 , 0 );
217224 if (!te_catch_sem) {
218- TT_LOG_E (TAG, " Not enough memory for te_catch_sem Semaphore. " );
225+ TT_LOG_E (TAG, " Failed to create TE catch semaphore " );
219226 goto err;
220227 }
221- tear_ctx ->te_catch_sem = te_catch_sem;
228+ tear_handle ->te_catch_sem = te_catch_sem;
222229
223- tear_ctx ->time_Tvdl = time_Tvdl;
224- tear_ctx ->time_Tvdh = time_Tvdh;
225- tear_ctx ->lock .owner = portMUX_FREE_VAL;
226- tear_ctx ->lock .count = 0 ;
230+ tear_handle ->time_Tvdl = time_Tvdl;
231+ tear_handle ->time_Tvdh = time_Tvdh;
232+ tear_handle ->lock .owner = portMUX_FREE_VAL;
233+ tear_handle ->lock .count = 0 ;
227234
228235 const gpio_config_t te_detect_cfg = {
229236 .pin_bit_mask = BIT64 (configuration->tePin ),
@@ -235,41 +242,39 @@ bool Axs15231bDisplay::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp
235242
236243 ESP_ERROR_CHECK (gpio_config (&te_detect_cfg));
237244 gpio_install_isr_service (0 );
238- ESP_ERROR_CHECK (gpio_isr_handler_add (configuration->tePin , display_tear_interrupt, tear_ctx ));
245+ ESP_ERROR_CHECK (gpio_isr_handler_add (configuration->tePin , displayTearInterrupt, tear_handle ));
239246
240- BaseType_t res = xTaskCreate (display_sync_task , " Tear Task " , 2048 , tear_ctx , 4 , nullptr );
247+ BaseType_t res = xTaskCreate (displaySyncTask , " TE Sync " , 2048 , tear_handle , 4 , nullptr );
241248 if (res != pdPASS) {
242- TT_LOG_E (TAG, " Create Sync Task Fail! " );
249+ TT_LOG_E (TAG, " Failed to create TE sync task " );
243250 goto err;
244251 }
252+
253+ tear_ctx = tear_handle;
254+
255+ // Schedule TE sync callback registration after LVGL display is created
256+ xTaskCreate (teSyncRegistrationTask, " TE Reg" , 2048 , this , 3 , nullptr );
245257 }
246258
247- lv_display_add_event_cb (getLvglDisplay (), display_sync_cb, LV_EVENT_FLUSH_START, tear_ctx);
248-
249259 return true ;
250260
251261err:
252- if (te_v_sync_sem)
253- {
262+ if (te_v_sync_sem) {
254263 vSemaphoreDelete (te_v_sync_sem);
255264 }
256- if (te_catch_sem)
257- {
265+ if (te_catch_sem) {
258266 vSemaphoreDelete (te_catch_sem);
259267 }
260- if (tear_ctx)
261- {
268+ if (tear_ctx) {
262269 free (tear_ctx);
270+ tear_ctx = nullptr ;
263271 }
264- if (panelHandle)
265- {
272+ if (panelHandle) {
266273 esp_lcd_panel_del (panelHandle);
267274 }
268- if (ioHandle)
269- {
275+ if (ioHandle) {
270276 esp_lcd_panel_io_del (ioHandle);
271277 }
272- spi_bus_free (SPI2_HOST);
273278 return false ;
274279}
275280
@@ -300,3 +305,12 @@ lvgl_port_display_cfg_t Axs15231bDisplay::getLvglPortDisplayConfig(esp_lcd_panel
300305 }
301306 };
302307}
308+
309+ void Axs15231bDisplay::registerTeSyncCallback () {
310+ if (tear_ctx != nullptr && getLvglDisplay () != nullptr ) {
311+ lv_display_add_event_cb (getLvglDisplay (), displaySyncCallback, LV_EVENT_FLUSH_START, tear_ctx);
312+ TT_LOG_I (TAG, " TE sync callback registered successfully" );
313+ } else {
314+ TT_LOG_W (TAG, " Cannot register TE sync callback - tear_ctx=%p display=%p" , tear_ctx, getLvglDisplay ());
315+ }
316+ }
0 commit comments