cancel
Showing results for 
Search instead for 
Did you mean: 

LTDC Interrupt Handling and TouchGFXGeneratedHAL::enableLCDControllerInterrupt() Issue

Anassoumi
Associate II
 

Hello Community,

I'm currently facing a challenging issue in my project that involves the TouchGFX framework on an STM32u59dk board, specifically related to the LTDC interrupt mechanism and its integration with the TouchGFX HAL.

Despite having the LTDC interrupt enabled and confirmed to be triggering correctly, I've noticed that the void TouchGFXGeneratedHAL::enableLCDControllerInterrupt() method is not being called in my application's execution flow. This method is crucial for configuring the interrupt handling in sync with the TouchGFX framework, particularly for managing the display's active and porch lines for smooth frame rendering.

The core of the issue seems to lie in the initialization of lcd_int_active_line and lcd_int_porch_line variables, which remain at 0. This is a direct consequence of TouchGFXGeneratedHAL::enableLCDControllerInterrupt() not being executed:

void TouchGFXGeneratedHAL::enableLCDControllerInterrupt()
{
lcd_int_active_line = (LTDC->BPCR & 0x7FF) - 1;
lcd_int_porch_line = (LTDC->AWCR & 0x7FF) - 1;

/* Sets the Line Interrupt position */
LTDC->LIPCR = lcd_int_active_line;
/* Line Interrupt Enable */
LTDC->IER |= LTDC_IER_LIE;
}

Without these critical values being set, the system fails to correctly manage the timing for frame buffer swapping and signaling the end of frame rendering in the HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef* hltdc) function. This effectively hampers the smooth operation and synchronization of frame updates, leading to potential rendering issues.

Here's how the issue manifests in the HAL_LTDC_LineEventCallback:

  • The condition if (LTDC->LIPCR == lcd_int_active_line) is intended to trigger actions at the start of the active display area. However, due to lcd_int_active_line and lcd_int_porch_line not being set, the intended synchronization and frame buffer management do not occur as designed

here is the lineEvent function :

 

extern "C"

{

void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef* hltdc)

{

if (!HAL::getInstance())

{

return;

}

 

if (LTDC->LIPCR == lcd_int_active_line)

{

//entering active area

HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_porch_line);

HAL::getInstance()->vSync();

OSWrappers::signalVSync();

 

// Swap frame buffers immediately instead of waiting for the task to be scheduled in.

// Note: task will also swap when it wakes up, but that operation is guarded and will not have

// any effect if already swapped.

HAL::getInstance()->swapFrameBuffers();

GPIO::set(GPIO::VSYNC_FREQ);

}

else

{

//exiting active area

HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_active_line);

 

// Signal to the framework that display update has finished.

HAL::getInstance()->frontPorchEntered();

GPIO::clear(GPIO::VSYNC_FREQ);

}

}

}

This situation has led me to reach out for assistance. Has anyone encountered a similar scenario where TouchGFXGeneratedHAL::enableLCDControllerInterrupt() does not get called, resulting in uninitialized line interrupt configurations? Any insights into potential misconfigurations or suggestions would be greatly appreciated.

5 REPLIES 5

Hello @Anassoumi ,

The code you have shared looks correct. Is it possible for you to share a screenshot of the NVIC settings from your STM32CubeMX project?

 

Thank you

Mohammad MORADI
ST Software Developer | TouchGFX

Thannks for your reply @Mohammad MORADI ESFAHANIASL , please see attached :

 

Anassoumi_0-1707932729659.png

Anassoumi_1-1707932781133.png

 

Thank you for the attachments.
I can see that you have set the TIM6 interrupt priority pretty low which might be the cause of the problem. Please set the priority of it to something lower than the rest (like 4), and set the priority of EXTI Line8 to something higher (like 10).

Try that and give us the results.
Good luck

Mohammad MORADI
ST Software Developer | TouchGFX
Anassoumi
Associate II

Still now working , when you mentionned Tim6 , i went to look for the initialization code but i can't see it initialized anywhere ,here is the main entry :

 

int main(void)

{

/* USER CODE BEGIN 1 */

 

/* USER CODE END 1 */

 

/* MCU Configuration--------------------------------------------------------*/

 

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

 

/* USER CODE BEGIN Init */

 

/* USER CODE END Init */

 

/* Configure the system clock */

SystemClock_Config();

 

/* Configure the peripherals common clocks */

PeriphCommonClock_Config();

 

/* Configure the System Power */

SystemPower_Config();

 

/* USER CODE BEGIN SysInit */

 

/* USER CODE END SysInit */

 

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_ADC4_Init();

MX_HSPI1_Init();

MX_I2C3_Init();

MX_I2C5_Init();

MX_ICACHE_Init();

MX_OCTOSPI1_Init();

MX_USART1_UART_Init();

MX_CRC_Init();

MX_DCACHE1_Init();

MX_DCACHE2_Init();

MX_DSIHOST_DSI_Init();

MX_LTDC_Init();

MX_TIM8_Init();

MX_DMA2D_Init();

/* USER CODE BEGIN 2 */

/* Enable the LCD, Send Display on DCS command to display */

InitializeDisplay();

/* USER CODE END 2 */

 

/* Init scheduler */

osKernelInitialize();

 

/* Call init function for freertos objects (in freertos.c) */

MX_FREERTOS_Init();

 

/* Start scheduler */

osKernelStart();

 

/* We should never get here as control is now taken by the scheduler */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

Anassoumi
Associate II

Hi @Mohammad MORADI ESFAHANIASL Could you provide guidance on the verification process to ensure optimal functionality? Despite creating a new project and adhering to the steps outlined in the TouchGFX example, the LCD is correctly displaying all colors, indicating a successfull setup with the LTDC configuration. I'm at a loss as to why it's malfunctioning with touchgfx; notably, the enableLCDControllerInterrupt, which should be triggered automatically by VSync, is not activating. This has led to considerable confusion...