Skip to main content
Visitor II
July 19, 2024
Question

STM32H747XI DSIHost - No output on HAL_DSI_ShortWrite

  • July 19, 2024
  • 1 reply
  • 867 views

Hello,

I have a custom pcb with STM32H747XI and a DSI LCD. Everything is on M7 with PWR_DIRECT_SMPS_SUPPLY.
The issue that I am facing is that I can't write any data on lanes. Both Positive and Negative are on 1.44v constantly.

I tried to be as close as possible to LCD_DSI_VideoMode_SingleBuffer example but with using .ioc generated code.
Attached you can find the .ioc and I can upload the whole project if required but probably I miss something in general.

Below are the MX_DSIHOST_DSI_Init & HAL_DSI_MspInit as generated.
(the clock for DSI is around 7Mhz for debug)

 

 

void MX_DSIHOST_DSI_Init(void)
{

 /* USER CODE BEGIN DSIHOST_Init 0 */
 /* USER CODE END DSIHOST_Init 0 */

 DSI_PLLInitTypeDef PLLInit = {0};
 DSI_HOST_TimeoutTypeDef HostTimeouts = {0};
 DSI_PHY_TimerTypeDef PhyTimings = {0};
 DSI_VidCfgTypeDef VidCfg = {0};

 /* USER CODE BEGIN DSIHOST_Init 1 */

 /* USER CODE END DSIHOST_Init 1 */
 hdsi.Instance = DSI;
 hdsi.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_ENABLE;
 hdsi.Init.TXEscapeCkdiv = 4;
 hdsi.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
 PLLInit.PLLNDIV = 40;
 PLLInit.PLLIDF = DSI_PLL_IN_DIV2;
 PLLInit.PLLODF = DSI_PLL_OUT_DIV8;
 if (HAL_DSI_Init(&hdsi, &PLLInit) != HAL_OK)
 {
 Error_Handler();
 }
 HostTimeouts.TimeoutCkdiv = 1;
 HostTimeouts.HighSpeedTransmissionTimeout = 0;
 HostTimeouts.LowPowerReceptionTimeout = 0;
 HostTimeouts.HighSpeedReadTimeout = 0;
 HostTimeouts.LowPowerReadTimeout = 0;
 HostTimeouts.HighSpeedWriteTimeout = 0;
 HostTimeouts.HighSpeedWritePrespMode = DSI_HS_PM_DISABLE;
 HostTimeouts.LowPowerWriteTimeout = 0;
 HostTimeouts.BTATimeout = 0;
 if (HAL_DSI_ConfigHostTimeouts(&hdsi, &HostTimeouts) != HAL_OK)
 {
 Error_Handler();
 }
 PhyTimings.ClockLaneHS2LPTime = 14;
 PhyTimings.ClockLaneLP2HSTime = 6;
 PhyTimings.DataLaneHS2LPTime = 6;
 PhyTimings.DataLaneLP2HSTime = 3;
 PhyTimings.DataLaneMaxReadTime = 0;
 PhyTimings.StopWaitTime = 0;
 if (HAL_DSI_ConfigPhyTimer(&hdsi, &PhyTimings) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_DSI_ConfigFlowControl(&hdsi, DSI_FLOW_CONTROL_BTA) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_DSI_SetLowPowerRXFilter(&hdsi, 10000) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_DSI_ConfigErrorMonitor(&hdsi, HAL_DSI_ERROR_NONE) != HAL_OK)
 {
 Error_Handler();
 }
 VidCfg.VirtualChannelID = 0;
 VidCfg.ColorCoding = DSI_RGB888;
 VidCfg.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
 VidCfg.Mode = DSI_VID_MODE_BURST;
 VidCfg.PacketSize = 480;
 VidCfg.NumberOfChunks = 0;
 VidCfg.NullPacketSize = 0;
 VidCfg.HSPolarity = DSI_HSYNC_ACTIVE_LOW;
 VidCfg.VSPolarity = DSI_VSYNC_ACTIVE_LOW;
 VidCfg.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
 VidCfg.HorizontalSyncActive = 2;
 VidCfg.HorizontalBackPorch = 6;
 VidCfg.HorizontalLine = 134;
 VidCfg.VerticalSyncActive = 4;
 VidCfg.VerticalBackPorch = 58;
 VidCfg.VerticalFrontPorch = 63;
 VidCfg.VerticalActive = 1120;
 VidCfg.LPCommandEnable = DSI_LP_COMMAND_DISABLE;
 VidCfg.LPLargestPacketSize = 0;
 VidCfg.LPVACTLargestPacketSize = 0;
 VidCfg.LPHorizontalFrontPorchEnable = DSI_LP_HFP_DISABLE;
 VidCfg.LPHorizontalBackPorchEnable = DSI_LP_HBP_DISABLE;
 VidCfg.LPVerticalActiveEnable = DSI_LP_VACT_DISABLE;
 VidCfg.LPVerticalFrontPorchEnable = DSI_LP_VFP_DISABLE;
 VidCfg.LPVerticalBackPorchEnable = DSI_LP_VBP_DISABLE;
 VidCfg.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_DISABLE;
 VidCfg.FrameBTAAcknowledgeEnable = DSI_FBTAA_DISABLE;
 if (HAL_DSI_ConfigVideoMode(&hdsi, &VidCfg) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_DSI_SetGenericVCID(&hdsi, 0) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN DSIHOST_Init 2 */
 /* USER CODE END DSIHOST_Init 2 */

}

void HAL_DSI_MspInit(DSI_HandleTypeDef* dsiHandle)
{

 GPIO_InitTypeDef GPIO_InitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 if(dsiHandle->Instance==DSI)
 {
 /* USER CODE BEGIN DSI_MspInit 0 */

 /* USER CODE END DSI_MspInit 0 */

 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_DSI;
 PeriphClkInitStruct.DsiClockSelection = RCC_DSICLKSOURCE_PHY;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /* DSI clock enable */
 __HAL_RCC_DSI_CLK_ENABLE();

 __HAL_RCC_GPIOJ_CLK_ENABLE();
 /**DSIHOST GPIO Configuration
 DSI_D1P ------> DSIHOST_D1P
 DSI_D1N ------> DSIHOST_D1N
 DSI_CKP ------> DSIHOST_CKP
 DSI_CKN ------> DSIHOST_CKN
 DSI_D0P ------> DSIHOST_D0P
 DSI_D0N ------> DSIHOST_D0N
 PJ2 ------> DSIHOST_TE
 */
 GPIO_InitStruct.Pin = GPIO_PIN_2;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF13_DSI;
 HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);

 /* DSI interrupt Init */
 HAL_NVIC_SetPriority(DSI_IRQn, 15, 0);
 HAL_NVIC_EnableIRQ(DSI_IRQn);
 /* USER CODE BEGIN DSI_MspInit 1 */

 /* USER CODE END DSI_MspInit 1 */
 }
}

 


I have created a new function for sending commands

 

HAL_StatusTypeDef DSI_Packet_Write_Short_DCS(uint32_t command, uint32_t parameter, uint8_t has_parameter) {
 uint32_t mode;

 //- Set mode according to if the command has a parameter or not
 if (has_parameter > 0) {
 mode = DSI_DCS_SHORT_PKT_WRITE_P0; // Mode DCS, 0 parameter
 } else {
 mode = DSI_DCS_SHORT_PKT_WRITE_P1; // Mode DCS, 1 parameter
 }

 HAL_StatusTypeDef result = HAL_DSI_ShortWrite(&hdsi, 0, mode, command, parameter);
 return result;
}

 

 

And this is the init in my main

 

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_MDMA_Init();
 MX_FMC_Init();
 MX_SDMMC1_SD_Init();
 MX_FATFS_Init();
 MX_QUADSPI_Init();
 MX_LTDC_Init();
 MX_DSIHOST_DSI_Init();
 MX_DMA2D_Init();
 /* USER CODE BEGIN 2 */

 HAL_LTDC_MspInit(&hltdc);
 HAL_DMA2D_MspInit(&hdma2d);
 HAL_DSI_MspInit(&hdsi);
// DSI_Reset();
 HAL_DSI_Start(&hdsi);

 


When I call packet write I get HAL_OK but nothing on bus.

I have some doubts if it is possible to send DCS packets while in video mode, in the example it initializes the DSI in video mode and then it reads a register from the LCD (plus there are some other settings about commands in video mode) so I guessed it is possible (correct me if I am wrong)

My first target is to send some config to LCD (power, gamma, etc, as provided by the manufacturer) and then continue with LTDC generated frames but I probably missing something and can't write anything on lanes.

    This topic has been closed for replies.

    1 reply

    ST Employee
    July 19, 2024

    hello @Stefanos_Sem ,

     I would like to point out that our firmware package, STM32CubeH7, includes several DSI examples specifically for the STM32H747I-DK. If you use one of these examples and test it, you will find that the HAL_DSI_ShortWrite API works correctly for all examples. This can serve as a good reference to ensure your configuration and initialization are correct.

    below all DSI examples for STM32H747I-DK board : 

    STM32CubeH7/Projects/STM32H747I-DISCO/Examples/LCD_DSI at master · STMicroelectronics/STM32CubeH7 · GitHub

    Thank you

    Br