Skip to main content
Associate II
July 10, 2025
Question

Scroll List flickering

  • July 10, 2025
  • 1 reply
  • 227 views

Hello everyone,

I’m working on a custom board built around the STM32F769BIT6. I’ve configured the SDRAM timings according to the datasheet and set the LTDC to RGB888. The same TouchGFX project runs flawlessly on the STM32F769I-Discovery board, but on my custom hardware the display begins to flicker whenever I scroll through a list.

Has anyone run into this before, or can you suggest where I should focus my debugging? Below are my SDRAM and LTDC settings. Any guidance would be greatly appreciated!

SDRAM timings.png

static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
 __IO uint32_t tmpmrd =0;
 /* Step 3: Configure a clock configuration enable command */
 Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
 Command->AutoRefreshNumber = 1;
 Command->ModeRegisterDefinition = 0;

 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

 /* Step 4: Insert 100 us minimum delay */
 /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
 HAL_Delay(1);

 /* Step 5: Configure a PALL (precharge all) command */
 Command->CommandMode = FMC_SDRAM_CMD_PALL;
 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
 Command->AutoRefreshNumber = 1;
 Command->ModeRegisterDefinition = 0;

 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

 /* Step 6 : Configure a Auto-Refresh command */
 Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
 Command->AutoRefreshNumber = 8;
 Command->ModeRegisterDefinition = 0;

 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

 /* Step 7: Program the external memory mode register */
 tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
 SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
 SDRAM_MODEREG_CAS_LATENCY_2 |
 SDRAM_MODEREG_OPERATING_MODE_STANDARD |
 SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

 Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
 Command->AutoRefreshNumber = 1;
 Command->ModeRegisterDefinition = tmpmrd;

 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

 /* Step 8: Set the refresh rate counter */
 /* (15.62 us x Freq) - 20 */
 /* Set the device refresh counter */
 hsdram->Instance->SDRTR |= ((uint32_t)((1542)<< 1));

}
/* USER CODE END 0 */

SDRAM_HandleTypeDef hsdram1;

/* FMC initialization function */
void MX_FMC_Init(void)
{
 /* USER CODE BEGIN FMC_Init 0 */

 /* USER CODE END FMC_Init 0 */

 FMC_SDRAM_TimingTypeDef SdramTiming = {0};

 /* USER CODE BEGIN FMC_Init 1 */

 /* USER CODE END FMC_Init 1 */

 /** Perform the SDRAM1 memory initialization sequence
 */
 hsdram1.Instance = FMC_SDRAM_DEVICE;
 /* hsdram1.Init */
 hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
 hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
 hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
 hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
 hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
 hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
 hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
 hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
 hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
 hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
 /* SdramTiming */
 SdramTiming.LoadToActiveDelay = 2;
 SdramTiming.ExitSelfRefreshDelay = 6;
 SdramTiming.SelfRefreshTime = 4;
 SdramTiming.RowCycleDelay = 6;
 SdramTiming.WriteRecoveryTime = 2;
 SdramTiming.RPDelay = 2;
 SdramTiming.RCDDelay = 2;

 if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
 {
 Error_Handler( );
 }

 /* USER CODE BEGIN FMC_Init 2 */
 FMC_SDRAM_CommandTypeDef command;

 /* Program the SDRAM external device */
 BSP_SDRAM_Initialization_Sequence(&hsdram1, &command);

 //Deactivate speculative/cache access to first FMC Bank to save FMC bandwidth
 FMC_Bank1->BTCR[0] = 0x000030D2;
 /* USER CODE END FMC_Init 2 */
}

 

LCD Datasheet.png

void MX_LTDC_Init(void)
{

 /* USER CODE BEGIN LTDC_Init 0 */
	 __HAL_LTDC_DISABLE(&hltdc);

 /* USER CODE END LTDC_Init 0 */

 LTDC_LayerCfgTypeDef pLayerCfg = {0};

 /* USER CODE BEGIN LTDC_Init 1 */

 /* USER CODE END LTDC_Init 1 */
 hltdc.Instance = LTDC;
 hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
 hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
 hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
 hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
 hltdc.Init.HorizontalSync = 47;
 hltdc.Init.VerticalSync = 0;
 hltdc.Init.AccumulatedHBP = 87;
 hltdc.Init.AccumulatedVBP = 31;
 hltdc.Init.AccumulatedActiveW = 887;
 hltdc.Init.AccumulatedActiveH = 511;
 hltdc.Init.TotalWidth = 927;
 hltdc.Init.TotalHeigh = 524;
 hltdc.Init.Backcolor.Blue = 0;
 hltdc.Init.Backcolor.Green = 0;
 hltdc.Init.Backcolor.Red = 0;
 if (HAL_LTDC_Init(&hltdc) != HAL_OK)
 {
 Error_Handler();
 }
 pLayerCfg.WindowX0 = 0;
 pLayerCfg.WindowX1 = 800;
 pLayerCfg.WindowY0 = 0;
 pLayerCfg.WindowY1 = 480;
 pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
 pLayerCfg.Alpha = 255;
 pLayerCfg.Alpha0 = 0;
 pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
 pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
 pLayerCfg.FBStartAdress = 0xC0000000;
 pLayerCfg.ImageWidth = 800;
 pLayerCfg.ImageHeight = 480;
 pLayerCfg.Backcolor.Blue = 0;
 pLayerCfg.Backcolor.Green = 0;
 pLayerCfg.Backcolor.Red = 0;
 if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN LTDC_Init 2 */

 HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_RESET);
 HAL_Delay(20);

 HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_RESET);
 HAL_Delay(20);
 HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_SET);
 HAL_Delay(20);

 HAL_GPIO_WritePin(LCD_INIT_GPIO_Port, LCD_INIT_Pin, GPIO_PIN_RESET);
 HAL_Delay(10);
 HAL_GPIO_WritePin(LCD_INIT_GPIO_Port, LCD_INIT_Pin, GPIO_PIN_SET);
 HAL_Delay(30);

 HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_SET);
 HAL_Delay(20);

 HAL_LTDC_Reload(&hltdc, LTDC_RELOAD_VERTICAL_BLANKING);
 __HAL_LTDC_ENABLE(&hltdc);

 /* USER CODE END LTDC_Init 2 */

}

For reference, i have set HCLK to 200MHz and the LCD pixel clock to 29.2MHz.

 

 

 

1 reply

GaetanGodart
Technical Moderator
July 14, 2025

Hello @walidhmz ,

 

Can you test the performance?
Maybe the list takes a big area of your screen and it is too much to render for a single frame?

https://support.touchgfx.com/docs/development/touchgfx-hal-development/scenarios/scenarios-measure-performance

 

Regards,