2024-11-02 04:19 AM - last edited on 2024-11-08 01:56 AM by SofLit
I am trying to reinitialize the LTDC-TFT LCD controller in a task when I press a button.
I am using the STM32H735G-DK kit, which has a TFT LCD. I have created a project using TouchGFX, and it seems the display gets initialized and loaded with images from the TouchGFX init and TouchGFX task.
Firstly, I want to achieve the re-initialization of the LTDC-TFT LCD on the STM32H735G-DK.
when i try re initializing the LTDC, it got freeze, not sure how to unfreeze it, display goes blank unable to restore back all the images which has been loaded after a reset
I am working on the low-power modes of the STM32H735G-DK and want to make sure the display goes off when I put the controller in sleep/stop mode and wakes up along with other peripherals after an external wake-up signal.
Above image which states LTDC has the 4 power modes, one of it is STOP mode
if LTDC Got freeze in STOP mode, how to unfreeze it?
can we make it work in stop mode? if yes how can we reconfigure the LTDC?
Here is what I have tried:
void test_task(void)
{
for(;;)
{
if (Button_Pressed ==1)
{
Button_Pressed=0;
printf("Entering sleep mode...\n");
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config();
vDisplay_Reinit();
printf("\n\r Exiting sleep mode\n\r");
}
}
}
void vDisplay_Reinit(void)
{
HAL_LTDC_MspDeInit(&hltdc);
HAL_DMA2D_MspDeInit(&hdma2d);
osDelay(10);
HAL_Init();
MX_GPIO_Init();
MX_DMA2D_Init();
MX_LTDC_Init();
MX_OCTOSPI1_Init();
MX_OCTOSPI2_Init();
MX_LIBJPEG_Init();
MX_TouchGFX_Init();
TouchGFX_Task(NULL);
}
I am able to turn the LTDC display ON & OFF using the following code:
void DisplayONOFF(void)
{
__HAL_LTDC_DISABLE(&hltdc);
/* Assert display enable LCD_DISP pin */
HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_RESET);
/* Assert backlight LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_Port, LCD_BL_CTRL_Pin, GPIO_PIN_RESET);
osDelay(10);
__HAL_LTDC_ENABLE(&hltdc);
// Reset Control Pins
/* Assert display enable LCD_DISP pin */
HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_SET);
/* Assert backlight LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_Port, LCD_BL_CTRL_Pin, GPIO_PIN_SET);
osDelay(10);
}
Reference Links:
STM32H7-LTDC: STM32H7-Peripheral-LCD_TFT_Controller (LTDC)
STM32H7-LTDC_AppNote: app_note
2024-11-08 12:56 AM
Hello Rakesh.
According to the datasheet and the table you have attached, the content of the registers are retained when using stop mode. Therefore, you shouldn't have to reinitialize the LTDC peripheral when exiting stop mode. To exit stop mode, the following is stated in the HAL_PWR driver:
(+) Exit: Any EXTI Line (Internal or External) configured in Interrupt/Event mode.
So any interrupt will exit stop mode.
Regarding your other question on how to reconfigure the LTDC, could you share the content of your HAL_LTDC_MspDeInit() function? Are you sure you couldn't just use the HAL_LTDC_DeInit() function? The same goes for DMA2D.
2024-11-11 10:40 AM - edited 2024-11-11 10:42 AM
Hello Johan,
Thanks for your reply,
I have tried to reinitialize the Display Using
HAL_LTDC_DeInit(&hltdc) & HAL_DMA2D_DeInit(&hdma2d) functions, but these couldn't help me to bring back the display after wakeup from the stop mode...so that's why I have tried using HAL_LTDC_MspDeInit functions
I'll make a brief about my goal, I wanted to bring up the display after wakeup from the stop mode, in the freeRTOS (CMISI V2.0) environment, the Touch gfx task wasn't running correctly as expected after wakeup, and the display was not loading with the images after wakeup which as earlier(before entering into stop mode)
I have attached the Project which I'm working on, it has been created using touch gfx, and PC13 (EXTI) was used to wake up the source ( USER BUTTON on STM32H735GDK)
now I have implemented a system that goes to stop mode, and when I press the user button wakes the system, the process repeats,
continue the other tasks where all stopped after wakeup, and reload the all images and fonts, UI content in Display using touch gfx( which is not happening in my case)
Could you please check out the same!!, ignore me if any mistakes are made!
Please let me know what sequence/steps are missed, Is there any specific sequence after wakeup and before going to stop mode, to continue from where does it stop?
I have tried to check the RTC wakeup example: Example:https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Projects/STM32H735G-DK/Examples/PWR/PWR_STOP_RTC
FYI, HAL_LTDC_MspDeInit,HAL_DMA2D_MspInit functions
/**
* @brief LTDC MSP De-Initialization
* This function freeze the hardware resources used in this example
* hltdc: LTDC handle pointer
* @retval None
*/
void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef* hltdc)
{
if(hltdc->Instance==LTDC)
{
/* USER CODE BEGIN LTDC_MspDeInit 0 */
/* USER CODE END LTDC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_LTDC_CLK_DISABLE();
/**LTDC GPIO Configuration
PB8 ------> LTDC_B6
PD3 ------> LTDC_G7
PB9 ------> LTDC_B7
PE0 ------> LTDC_R0
PA8 ------> LTDC_B3
PE1 ------> LTDC_R6
PG14 ------> LTDC_B0
PD0 ------> LTDC_B1
PD6 ------> LTDC_B2
PH15 ------> LTDC_G4
PC7 ------> LTDC_G6
PC6 ------> LTDC_HSYNC
PG7 ------> LTDC_CLK
PB1 ------> LTDC_G0
PH11 ------> LTDC_R5
PH9 ------> LTDC_R3
PA3 ------> LTDC_B5
PH8 ------> LTDC_R2
PH10 ------> LTDC_R4
PH4 ------> LTDC_G5
PA4 ------> LTDC_VSYNC
PE12 ------> LTDC_B4
PE13 ------> LTDC_DE
PE15 ------> LTDC_R7
PH3 ------> LTDC_R1
PA6 ------> LTDC_G2
PB0 ------> LTDC_G1
PE11 ------> LTDC_G3
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_1|GPIO_PIN_0);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_12|GPIO_PIN_13
|GPIO_PIN_15|GPIO_PIN_11);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_14|GPIO_PIN_7);
HAL_GPIO_DeInit(GPIOH, GPIO_PIN_15|GPIO_PIN_11|GPIO_PIN_9|GPIO_PIN_8
|GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_3);
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_7|GPIO_PIN_6);
/* LTDC interrupt DeInit */
HAL_NVIC_DisableIRQ(LTDC_IRQn);
/* USER CODE BEGIN LTDC_MspDeInit 1 */
/* USER CODE END LTDC_MspDeInit 1 */
}
}
/**
* @brief DMA2D MSP Initialization
* This function configures the hardware resources used in this example
* hdma2d: DMA2D handle pointer
* @retval None
*/
void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d)
{
if(hdma2d->Instance==DMA2D)
{
/* USER CODE BEGIN DMA2D_MspInit 0 */
/* USER CODE END DMA2D_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_DMA2D_CLK_ENABLE();
/* DMA2D interrupt Init */
HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2D_IRQn);
/* USER CODE BEGIN DMA2D_MspInit 1 */
/* USER CODE END DMA2D_MspInit 1 */
}
}
2024-11-11 11:14 AM
Locate issue and dont do reinit . LTDC too use PLL , that require restart , check if
SystemClock_Config();
doit, when no write your code.
2024-11-11 09:59 PM - edited 2024-11-12 09:04 AM
Hello MM,
Correct me if I'm not clear..!
I have tried removing the Display Re-initialization part after wakeup from stop mode But shows only a Blank screen, UI is not getting loaded, TouchGFX_Task() itself is not running and Other tasks are running normally(checked using prints)!
If I don't put the following line, I'm unable to see any prints and I can't visualize that other tasks are running, due to a blank screen in the display
SystemClock_Config();
FYI, the sequence I have also checked Deinit LTDC, DMA2D, goto stop mode, and wakeup then Initialize the LTDC, DMA2D, OSPI, TouchGFX_Init
Also Tried deleting resources used by TouchGFX_Task(like Semaphores & Queues), Do I need to Delete the task and recreate the TouchGFX task to load the images/UI content?
Is there any specific sequence to be followed? If yes, please let me know the sequence to bring up the display ( loaded with UI Content/images).
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if I'm not wrong you might want me to check the clock configuration, I have also tried the following clock configuration after wakeup from the stop mode, Still UI not loading correctly, but all other tasks are running except Touchgfx_Task
Are there any examples available to have an idea of how UI gets loaded after wakeup from the stop mode in STM32H735GDK?
/**
* @brief Configures system clock after wake-up from STOP: enable HSE, PLL
* and select PLL as system clock source.
* @PAram None
* @retval None
*/
static void SYSCLKConfig_STOP(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
uint32_t pFLatency = 0;
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/* Get the Oscillators configuration according to the internal RCC registers */
HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
/* After wake-up from STOP reconfigure the system clock: Enable HSE and PLL */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Get the Clocks configuration according to the internal RCC registers */
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
{
Error_Handler();
}
}
2024-11-12 09:55 AM
I dont say remove system clock , i say about LTDC clock , that isnt init in this function. For inspire read STM32CubeH7/Projects/STM32H735G-DK/Examples/LTDC/LTDC_ColorKeying_FromOSPI/Src/stm32h7xx_hal_msp.c at master · STMicroelectronics/STM32CubeH7 · GitHub and your msp init specialy this part
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLL3.PLL3M = 5;
PeriphClkInitStruct.PLL3.PLL3N = 160;
PeriphClkInitStruct.PLL3.PLL3P = 2;
PeriphClkInitStruct.PLL3.PLL3Q = 2;
PeriphClkInitStruct.PLL3.PLL3R = 83;
PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL1VCOWIDE;
PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL1VCIRANGE_0;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) ;
too RTOS require suspend task before stop etc.
2024-11-12 10:12 PM - edited 2024-11-13 05:11 AM
Hello MM,
Thanks for the information you shared,
I have tried the following changes in my code!
please let me know if any changes required
I have updated the Clock Configuration for LTDC After Wakeup from Stop mode, touchgfx_task is now up and running, and UI loaded images as expected
I haven't found any sequence like this, I came across this sequence after many trials & errors,
please mention a sequence of steps in documentation/app note / example-based
or attach any links if already exist!
Working Sequence:
Display OFF(BL CTRL PIN RESET, DISP EN PIN RESET)
Enter Into STOP MODE
(Exit from stop mode with EXTI input or RTC Wakeup Trigger-- Action)
System Clock Configuration(Oscillator , Clock& peripherals)
Display ON (BL CTRL PIN SET, DISP EN PIN SET)
/* These steps to be followed while before entering and after exiting stop mode to bring up or load the display back*/
/* Assert display enable LCD_DISP_CTRL pin */
HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_RESET);
/* Assert back light LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_Port, LCD_BL_CTRL_Pin, GPIO_PIN_RESET);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SYSCLKConfig_STOP();
/* Assert display enable LCD_DISP_CTRL pin */
HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_SET);
/* Assert back light LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_Port, LCD_BL_CTRL_Pin, GPIO_PIN_SET);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Reset all RSR(Reset) flags */
SET_BIT(RCC->RSR, RCC_RSR_RMVF);
}
static void SYSCLKConfig_STOP(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
uint32_t pFLatency = 0;
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/* Get the Oscillators configuration according to the internal RCC registers */
HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
/* After wake-up from STOP reconfigure the system clock: Enable HSE and PLL */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Get the Clocks configuration according to the internal RCC registers */
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
{
Error_Handler();
}
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
PeriphClkInitStruct.PLL2.PLL2M = 5;
PeriphClkInitStruct.PLL2.PLL2N = 80;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 2;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.OspiClockSelection = RCC_OSPICLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLL3.PLL3M = 25; //5;
PeriphClkInitStruct.PLL3.PLL3N = 288; //160;
PeriphClkInitStruct.PLL3.PLL3P = 2; //2;
PeriphClkInitStruct.PLL3.PLL3Q = 2; //2;
PeriphClkInitStruct.PLL3.PLL3R = 30; //83;
PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_0; //RCC_PLL1VCIRANGE_0;
PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOMEDIUM; //RCC_PLL1VCOWIDE;
PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
Note:
if we suspend the task before entering into stop mode, triggers a hard fault error
vTaskSuspend(TouchGFX_Task);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SYSCLKConfig_STOP();
vTaskResume(TouchGFX_Task);
2024-11-13 07:52 AM
TouchGFX in LTDC mode is hw based , not only RTOS, then simple Suspend not work, search here and see some about interrupts disable etc. Next important is where is stored framebuffer? Internal or external RAM.
Restore for example SDRAM isnt possible, data is lost after stop . G-DK isnt simple hw , when your design dont require specialdo , use method RUN core - STOP before wait wake - continue with RTOS init and all app.
Or Run all app and before stop reboot with for example WWDG , detect it on main and STOP here , exist many variants. Use STOP in the middle work too , but other hw condition must meet ...