cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H747XI DSIHost - No output on HAL_DSI_ShortWrite

Stefanos_Sem
Associate

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.

1 REPLY 1
MOBEJ
ST Employee

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

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.