cancel
Showing results for 
Search instead for 
Did you mean: 

U5 DSI Communications Issues

jadczak_slr
Associate

This is a repost of the message I left on the "STM32 MCUs Touch GFX and GUI" and I'm hoping that it gets some more traction in this section of the forum.

Apologies for the repost.

 

I'm in the process of migrating from an STM32F779AIY6TR to an STM32U5A9NJH6Q and I'm running into issues with the DSI communications to my LCD on the U5 platform that were not present with the F7 when using the same parameters.

 

Hardware setup:

LCD Panel - E30RB-I-MW340-N (Sitronix ST7701S TFT IC) Focus LCD: MIPI Driver Pseudocode 

U5 Processor (DSI not working) STM32U5A9NJH6Q

F7 Processor (DSI working) STM32F779AIY6TR 

 

Modes:

Video Mode, Non Burst Mode with Event

LP transitions are enabled for all video areas.

16 Byte command maximums

Commands are transmitted in Low Power mode

 

Clock and other parameters that seem potentially relevant (same for both platforms generated from CubeMX):

PHY DSI 240MHz

DSI lane byte clock 30 MHz

DSI txclkesc 6 MHz

Automatic clock lane control is disabled (per the U5 Errata)

PHY Low Power offset 0 CLK

BTA is enabled

 

Issues / Symptoms / Oddities:

  • Short writes seem to be working on the U5.  Issuing simple commands to the LCD like "All pixels on" are responded to.
  • Long writes do not seem to be working consistently.  Issuing the commands to display the Sitronix's built in test image work <5% of the time (but do seldom work).
  • Deriving the Byte Land Clock from the PHY DSI breaks the DSI peripheral on the U5.  The Byte Lane Clock has to be derived from PLL3P for unknown reasons.  Looking at the U5 Discovery code, the procedure for clock configuration on that product is different from what CubeMx is generating for my U5 platform. 

    For example the U5 Discovery code has the DSI peripheral started and then the clock source switched over to the DSI PHY (see below).

 

 // Start DSI
  if (HAL_DSI_Start(&hdsi) != HAL_OK)
  {
    Error_Handler();
  }

  /* Switch to DSI PHY PLL clock */
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_DSI;
  PeriphClkInit.DsiClockSelection    = RCC_DSICLKSOURCE_DSIPHY;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
  /* USER CODE END DSIHOST_Init 2 */


While the CubeMX generated code for my platform handles this inside of HAL_DSI_MspInit(DSI_HandleTypeDef* dsiHandle).

 

  • Differential DSI clocks look roughly between the same for the F7 and U5 when scoped (My scope is limited to 5Gsps / 1GHz BW and I don't have active probes so I'm pushing the limits of what I can realistically measure).  But the peak to peak is ~500mV for the clock lines and the frequency is on target.
  • The U5 clock does not seem to consistently transfer to LP (I'm not seeing the differential high speed clocks going to the LP logic levels the same way as the F7).  Though my measurements on the U5 were taken prior starting FreeRTOS (but after initializing the DSI / LTDC / TouchGFX) so this might not be an apples to apples comparison with the F7, where I measured while video was streaming.

Things tried:

  1. I've adjusted the PHY DSI clocks down to 120MHz and up to 500MHz on the U5 to see if there is a signaling issues with going too fast or slow for what the hardware can handled (all DSI data and clock lines are matched length and 100ohm impedance in the layout, so everything should be ok from a layout perspective).
  2. Adjusted the PHY LP offset to every value possible
  3. Disabled BTA on the U5 (unsurprisingly this breaks comms completely).
  4. Tried various combinations of Flow Control Configuration.
  5. Confirmed clock and data lane pins are correctly mapped in the IOC.
  6. Enabled Contention Error Detection
  7. Restricted LP commands to only the vertical blanking period and adjusted the maximum packet size down as low as 8 bytes and up to 32 bytes.
  8. Adjusted the PHY Timings (LP to HS and HS to LP transition timings) to various values.


At this point, I'm at a loss for what to look into next.  The autogenerated peripheral configuration code for the F7 and U5 differs in various ways when I run a diff.  Most of the differences seem to relate to a general refactoring of code but there are configuration parameters on the U5 that aren't present in the F7.  For example PLLInit.PLLVCORange, PLLInit.PLLChargePump, and PLLInit.PLLTuning are present in the U5 as configurable parameters, but not in the F7.

 

Any help would be appreciated on the matter.  

5 REPLIES 5
STOne-32
ST Employee

Dear @jadczak_slr ,

Sorry for the late response, just wanted to close the loop as you contacted us via our Online support channel with thus case number 00197041 and my colleagues and FAEs in our touch with you , indeed your case is a bit complex and and require a deep debugging with our experts as the architecture for both HW/SW from STM32F7 to STM32U5 on DSI is different.

stay tuned !

Cheers,

STOne-32

Good afternoon,

For a couple of months, we have been having the same issues while integrating a slightly different controller (Sitronix ST7796).

All the points that jadczak_slr is mentioning are somehow the same as we are facing.

We managed to get something partially displayed (1/3 of the display has the image warped by 45 degrees) using the CubeMX configuration but it's really flaky: as soon as the content in the framebuffer is changed - e.g. adding different colors, drawing on different areas - the result spans from being worse to completely broken (blank display).

The picture shows the best result we could achieve, and how it should look (the bars' height dynamically changes over time so they don't match 1:1)

dannti_2-1707923505793.pngdannti_1-1707923378238.png

Are there any updates that could help us proceed with the development? At the moment we already tried all the possible combinations in CubeMX.

 

Looking forward to receiving your kind support,

Regards

STOne-32
ST Employee

Dear @dannti  @jadczak_slr ,

We have an on-going version of STM32Cube U5 that will update the DSI driver and will align DSI Initialization sequence to the recommended ‘Programming procedure overview’ part to avoid DSI read LCD controller register 0x0A error. It will be released during Q1/2024 and if it might help you here is a patch , if you can try it from now :

 

////////////////////////////////////////////////////Version 1.4.0 //////////////////////////////////////////////////
/*************************** Set the PHY parameters ***************************/
/* D-PHY clock and digital enable*/
hdsi->Instance->PCTLR |= (DSI_PCTLR_CKE | DSI_PCTLR_DEN);

/* Clock lane configuration */
hdsi->Instance->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
hdsi->Instance->CLCR |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);

/* Configure the number of active data lanes */
hdsi->Instance->PCONFR &= ~DSI_PCONFR_NL;
hdsi->Instance->PCONFR |= hdsi->Init.NumberOfLanes;


/************************ Set the DSI clock parameters ************************/
/* Set the TX escape clock division factor */
hdsi->Instance->CCR &= ~DSI_CCR_TXECKDIV;
hdsi->Instance->CCR |= hdsi->Init.TXEscapeCkdiv;


/****************************** Error management *****************************/
/* Disable all error interrupts and reset the Error Mask */
hdsi->Instance->IER[0U] = 0U;
hdsi->Instance->IER[1U] = 0U;
hdsi->ErrorMsk = 0U;



////////////////////////////////////////////////////Version 1.5.0 //////////////////////////////////////////////////

__HAL_DSI_ENABLE(hdsi);

/************************ Set the DSI clock parameters ************************/
/* Set the TX escape clock division factor */
hdsi->Instance->CCR &= ~DSI_CCR_TXECKDIV;
hdsi->Instance->CCR |= hdsi->Init.TXEscapeCkdiv;

/*************************** Set the PHY parameters ***************************/
/* D-PHY clock and digital enable*/
hdsi->Instance->PCTLR |= DSI_PCTLR_DEN;

/************************ Set D-PHY Band Control registers ******************************/
/* Set Band Control Frequency and LPX Offset */
DSI_ConfigBandControl(hdsi);

/* Set PLL Tuning */
DSI_SetWrapperPLLTuning(hdsi, PLLInit);

hdsi->Instance->PCTLR |= DSI_PCTLR_CKE;


/* Configure the number of active data lanes */
hdsi->Instance->PCONFR &= ~DSI_PCONFR_NL;
hdsi->Instance->PCONFR |= hdsi->Init.NumberOfLanes;

/* Get tick */
tickstart = HAL_GetTick();
if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
{
while ((hdsi->Instance->PSR & (DSI_PSR_PSS0 | DSI_PSR_PSSC)) != (DSI_PSR_PSS0 | DSI_PSR_PSSC))
{
if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
{
/* Process Unlocked */
__HAL_UNLOCK(hdsi);

return HAL_TIMEOUT;
}
}
}
else
{
while ((hdsi->Instance->PSR & (DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_PSSC)) != (DSI_PSR_PSS0 | \
DSI_PSR_PSS1 | DSI_PSR_PSSC))
{
if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
{
/* Process Unlocked */
__HAL_UNLOCK(hdsi);

return HAL_TIMEOUT;
}
}
}

/****************************** Error management *****************************/
/* Disable all error interrupts and reset the Error Mask */
hdsi->Instance->IER[0U] = 0U;
hdsi->Instance->IER[1U] = 0U;
hdsi->ErrorMsk = 0U;

__HAL_DSI_DISABLE(hdsi);

/* Clock lane configuration */
hdsi->Instance->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
hdsi->Instance->CLCR |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);

 

Hope it will help you,

 

Cheers,

 

STOne-32

 

Can you walk me through this, because at first glace the 1.5 code doesn't fully make sense to me.

It looks like we're

  1. Enabling the DSI
  2. setting up the escape clock
  3. configuring the PHY
  4. waiting for the DSI to be idle `(hdsi->Instance->PSR & (DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_PSSC))`
  5. Configuring some error management
  6. Disabling the DSI
  7. Disabling automatic lane control

Presumably I need to re-enable the DSI `__HAL_DSI_ENABLE(hdsi)` at this point in time?

I'm also not sure how this is fundamentally different than the 1.4 with automatic clock lane control.  We've reordered some stuff and did some clock configuration with the DSI off...

You said that this will resolve 0x0A errors (DSI read LCD control), but I'm not getting those errors to the best of my knowledge (I'm not trying to read any registers).

Hello,

I just wanted to update the thread because we managed to have something displayed. It still has some bugs (but that could be related to other issues not strictly related to the U5 or the controller).

We started with an example from the TouchGFX which was also based on RGB565. We made some changes according to the controller pseudocode given by the display supplier and some hit&tries.

The crucial parts were the following:

  • Enable all the low-power transitions in the DSI section

        dannti_1-1708348153115.png

  • Set the main parameters as the following, used for both the LTDC and DSI sections

         dannti_0-1708347707206.png

  • DSIHOST configuration:

         dannti_2-1708348263513.png

         dannti_3-1708348306992.png

  • Clock configuration. Note the source of txclxesc and DSI lane byte clock source is not the DSI PHY but the PLL3P. Also the LTDC clock has PLL3 as the source. The PLL3 is derived by the HSE like the DSI PHY. In this way, we have "in-phase" clocks multiple of each other for the whole "subsystem".

       dannti_4-1708348407551.pngdannti_5-1708348602966.png

 

Tell me if this helped you somehow.

 

Cheers