cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7S, LTCD and uart won't work together

AlexCaron
Associate II

Hi, 

I'm using a STM32H7S78-DK board along with stm32cudeide 1.16.0. I'm loading the example LTDC_ColorKeyring which work fine, here is the issue... I'm trying to implement uart4 connected to the onboard ST-link. If I init MX_UART4_Init() and use HAL_UART_Transmit(), BEFORE MX_LTDC_Init(), it work fine. As soon as the LTDC is init, I cannot use the Uart at all. I don't see any pin conflict here... the uart4_tx is PD1 and is only connect to the VCP of the st-link.

I'm evaluating the STM32H7S for business, but if I cannot get those two simple peripheral working together...thats a big flaw

1 ACCEPTED SOLUTION

Accepted Solutions

In the code below from HAL_LTDC_MspInit we can see that in the USER CODE BEGIN section we make a new RCC_OscInitTypeDef with a vlaue of zero , this clears out any values from our original RCC settings , in this case

HSI calibration value. In the code below it is never initialized  again, when the struct is passed to HAL_RCC_OscConfig(&RCC_OscInitStruct) (line 153)  sets HSI calibration value to 0 since it was never initialized in this struct. 

 

The solution is to add RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT before the call to HAL_RCC_OscConfig (line 152 below)

 

Admittedly the example has a few issues, for example the .ioc file sets LTDC to 200MHZ, but fixing it and regenerating does not generate a SystemClockConfig function, hence why the clock is configured in user space. 

 

For now the solution provided fixes the original post's issue. The bugs have been reported internally.

 

 

 

 

void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc) { GPIO_InitTypeDef GPIO_InitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; if(hltdc->Instance==LTDC) { /* USER CODE BEGIN LTDC_MspInit 0 */ RCC_OscInitTypeDef RCC_OscInitStruct={0}; /* USER CODE END LTDC_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC; PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } /* Peripheral clock enable */ __HAL_RCC_LTDC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); /**LTDC GPIO Configuration PD3 ------> LTDC_B1 PB5 ------> LTDC_R2 PG0 ------> LTDC_R7 PB3(JTDO/TRACESWO) ------> LTDC_R4 PG2 ------> LTDC_HSYNC PE11 ------> LTDC_VSYNC PA12 ------> LTDC_B2 PA11 ------> LTDC_B3 PB4(NJTRST) ------> LTDC_R3 PA9 ------> LTDC_B5 PG1 ------> LTDC_R6 PA10 ------> LTDC_B4 PG12 ------> LTDC_G1 PA8 ------> LTDC_B6 PG13 ------> LTDC_CLK PA15(JTDI) ------> LTDC_R5 PF7 ------> LTDC_G0 PF9 ------> LTDC_R0 PF10 ------> LTDC_R1 PB12 ------> LTDC_G5 PA0 ------> LTDC_G3 PA1 ------> LTDC_G2 PF11 ------> LTDC_B0 PB14 ------> LTDC_DE PB15 ------> LTDC_G7 PB11 ------> LTDC_G6 PB13 ------> LTDC_G4 PA6 ------> LTDC_B7 */ GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_15|GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF10_LTDC; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_12 |GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14 |GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF11_LTDC; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_8|GPIO_PIN_15 |GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF12_LTDC; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN LTDC_MspInit 1 */ /* LCD clock configuration */ /* Typical PCLK is 25 MHz so the PLL3R is configured to provide this clock */ /* LCD clock configuration */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL3.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL3.PLLM = 4; RCC_OscInitStruct.PLL3.PLLN = 25; RCC_OscInitStruct.PLL3.PLLP = 2; RCC_OscInitStruct.PLL3.PLLQ = 20; RCC_OscInitStruct.PLL3.PLLR = 16; RCC_OscInitStruct.PLL3.PLLS = 2; RCC_OscInitStruct.PLL3.PLLT = 2; RCC_OscInitStruct.PLL3.PLLFractional = 0; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { /* Initialization error */ while(1); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC; PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R; if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { while(1); } /* USER CODE END LTDC_MspInit 1 */ } }
View more

 

 

 

 

If you feel a post has answered your question, please click "Accept as Solution"

View solution in original post

7 REPLIES 7
Imen.D
ST Employee

Hello @AlexCaron ,

Let me first welcome you to the ST Community.

Please check the clock configuration is initialized/enabled properly for both peripherals. 

Did you follow exactly the readme? Also, check the hardware connections.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Hi Imen,

Thank you for your reply, as I said, they both work unless the ltdc is started so I assume both clock/configuration are fine. Starting the ltdc completely stop the uart4 to work. Anyway the project is comming from one of your example, maybe you should check ?

As a first check, we noticed that there are differences between the pinout for the display connector of the LTDC_ColorKeying example and the pinout of the schematic:

The issue is on LTDC_R2 which was connected to pin PB5 in the SW-example, but it was connected to PF0 on the schematic.

Please, check your LTDC pin configuration, as it can be the same issue for you and in this case the board doesn't work.

This issue is escalated internally for fix in the coming release of software.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

LTDC is working, there is images on the LCD, and the UART is also working when LTDC is not initializated yet. UART_4_tx is on PD1, I don't see this pin is the LTDC configuration, except if there is an error in the schematic and this pin is shared with something else. I can try to probe PD1 with a scope.

So I probed PD1 pin, the fisrt capture show the uart BEFORE LTDC, the second one is after LTDC, it look the same, but the timings are off. Every HIGH-LOW transition are little bit slower. So the baudrate after LTDC is 12% slower. The original baudrate is 115200, if I set my analyser to 101375, the second became readible. So why the UART become 12% after LTDC was init ?

AlexCaron_0-1730993663938.png

 

The same goes for SPI. I set the CLK to 2Mhz, this is what I get if LTDC is NOT init. Exactly 2Mhz.

AlexCaron_0-1731036023891.png

Now when LTDC is init. 1.778Mhz, which is also a loss of about 12% like the Uart. It seems the LTDC slow down the whole clock domain...The same happen when I choose HSI or HSE.

AlexCaron_1-1731036070392.png

 

In the code below from HAL_LTDC_MspInit we can see that in the USER CODE BEGIN section we make a new RCC_OscInitTypeDef with a vlaue of zero , this clears out any values from our original RCC settings , in this case

HSI calibration value. In the code below it is never initialized  again, when the struct is passed to HAL_RCC_OscConfig(&RCC_OscInitStruct) (line 153)  sets HSI calibration value to 0 since it was never initialized in this struct. 

 

The solution is to add RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT before the call to HAL_RCC_OscConfig (line 152 below)

 

Admittedly the example has a few issues, for example the .ioc file sets LTDC to 200MHZ, but fixing it and regenerating does not generate a SystemClockConfig function, hence why the clock is configured in user space. 

 

For now the solution provided fixes the original post's issue. The bugs have been reported internally.

 

 

 

 

void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc) { GPIO_InitTypeDef GPIO_InitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; if(hltdc->Instance==LTDC) { /* USER CODE BEGIN LTDC_MspInit 0 */ RCC_OscInitTypeDef RCC_OscInitStruct={0}; /* USER CODE END LTDC_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC; PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } /* Peripheral clock enable */ __HAL_RCC_LTDC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); /**LTDC GPIO Configuration PD3 ------> LTDC_B1 PB5 ------> LTDC_R2 PG0 ------> LTDC_R7 PB3(JTDO/TRACESWO) ------> LTDC_R4 PG2 ------> LTDC_HSYNC PE11 ------> LTDC_VSYNC PA12 ------> LTDC_B2 PA11 ------> LTDC_B3 PB4(NJTRST) ------> LTDC_R3 PA9 ------> LTDC_B5 PG1 ------> LTDC_R6 PA10 ------> LTDC_B4 PG12 ------> LTDC_G1 PA8 ------> LTDC_B6 PG13 ------> LTDC_CLK PA15(JTDI) ------> LTDC_R5 PF7 ------> LTDC_G0 PF9 ------> LTDC_R0 PF10 ------> LTDC_R1 PB12 ------> LTDC_G5 PA0 ------> LTDC_G3 PA1 ------> LTDC_G2 PF11 ------> LTDC_B0 PB14 ------> LTDC_DE PB15 ------> LTDC_G7 PB11 ------> LTDC_G6 PB13 ------> LTDC_G4 PA6 ------> LTDC_B7 */ GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_15|GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF10_LTDC; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_12 |GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14 |GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF11_LTDC; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_8|GPIO_PIN_15 |GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF12_LTDC; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN LTDC_MspInit 1 */ /* LCD clock configuration */ /* Typical PCLK is 25 MHz so the PLL3R is configured to provide this clock */ /* LCD clock configuration */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL3.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL3.PLLM = 4; RCC_OscInitStruct.PLL3.PLLN = 25; RCC_OscInitStruct.PLL3.PLLP = 2; RCC_OscInitStruct.PLL3.PLLQ = 20; RCC_OscInitStruct.PLL3.PLLR = 16; RCC_OscInitStruct.PLL3.PLLS = 2; RCC_OscInitStruct.PLL3.PLLT = 2; RCC_OscInitStruct.PLL3.PLLFractional = 0; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { /* Initialization error */ while(1); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC; PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R; if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { while(1); } /* USER CODE END LTDC_MspInit 1 */ } }
View more

 

 

 

 

If you feel a post has answered your question, please click "Accept as Solution"