2024-11-06 07:33 PM - edited 2024-11-06 07:34 PM
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
Solved! Go to Solution.
2024-11-09 01:28 PM - edited 2024-11-10 09:27 PM
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 */
}
}
2024-11-07 04:58 AM - edited 2024-11-07 05:03 AM
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.
2024-11-07 05:02 AM
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 ?
2024-11-07 06:22 AM - edited 2024-11-07 07:09 AM
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.
2024-11-07 06:43 AM
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.
2024-11-07 07:34 AM - edited 2024-11-07 07:47 AM
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 ?
2024-11-07 07:22 PM
The same goes for SPI. I set the CLK to 2Mhz, this is what I get if LTDC is NOT init. Exactly 2Mhz.
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.
2024-11-09 01:28 PM - edited 2024-11-10 09:27 PM
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 */
}
}