cancel
Showing results for 
Search instead for 
Did you mean: 

LCD 1024x600, LTDC screen tearing using STM32H725

Jan Nowak_2
Associate II

Hello everyone,

Because I haven't found anything similar, I would like to ask you about my issue. The problem is screen tearing on the LCD with 1024x600 screen resolution. I'm using LTDC with RGB888 interface and RGB565 color format, so I have 16 bpp color depth. Because internal SRAM of STM32H725AE is not able to store such big framebuffer (1,2 MB). I'm stroing it in external memory which is APS6408L-3OBM-BA 133MHz, OctoSPI, PSRAM by AP Memory. LTDC clock is running at 51.2 MHz clock rate according to LCD datasheet and the memory is running at 130 MHz. I configured the MPU as well as ICashe and DCashe to increase the memory performance. I've also chcecked if I have any FIFO underrun flag set during the write to memory, but the flag is unset.

0693W00000WIC2hQAH.pngBR,

Jan

6 REPLIES 6
MM..1
Chief III

On your image i dont see tearing, seems other troubles.

Maybe bad PSRAM soldering or wiring on pcb.

Jan Nowak_2
Associate II

Perhaps it's not the tearing effect, but some let's say noise. Yeah for sure it might be related to PSRAM...

Mtopa.1
Associate II

Can you share octoSPI calibration setting and initial configuration for ram APS6408L-3OBM-BA ?

I wasn't calibrating OCTOSPI, this is my init function:

/* OCTOSPI1 init function */
void MX_OCTOSPI1_Init(void)
{
 
  /* USER CODE BEGIN OCTOSPI1_Init 0 */
 
  /* USER CODE END OCTOSPI1_Init 0 */
 
  OSPIM_CfgTypeDef sOspiManagerCfg = {0};
 
  /* USER CODE BEGIN OCTOSPI1_Init 1 */
 
  /* USER CODE END OCTOSPI1_Init 1 */
  hospi1.Instance = OCTOSPI1;
  hospi1.Init.FifoThreshold = 1;
  hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
  hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_APMEMORY;
  hospi1.Init.DeviceSize = 23;
  hospi1.Init.ChipSelectHighTime = 1;
  hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
  hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
  hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
  hospi1.Init.ClockPrescaler = 2;
  hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
  hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
  hospi1.Init.ChipSelectBoundary = 10;
  hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
  hospi1.Init.MaxTran = 0;
  hospi1.Init.Refresh = 241;
  if (HAL_OSPI_Init(&hospi1) != HAL_OK)
  {
    Error_Handler();
  }
  sOspiManagerCfg.ClkPort = 1;
  sOspiManagerCfg.DQSPort = 1;
  sOspiManagerCfg.NCSPort = 1;
  sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
  sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
  if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN OCTOSPI1_Init 2 */
 
  /* USER CODE END OCTOSPI1_Init 2 */
 
}

APS initial configuration, I was using this library with my little modification

https://github.com/STMicroelectronics/stm32-aps6408

   APS6408_Reset(&hospi1);
   /* Give memory some time to stablilise */
   HAL_Delay(10);
 
   APS6408_EnableMemoryMappedMode(&hospi1, DUMMY_CLOCK_CYCLES_READ, DUMMY_CLOCK_CYCLES_WRITE, 1);
int32_t APS6408_Reset(OSPI_HandleTypeDef *Ctx)
{
  OSPI_RegularCmdTypeDef sCommand = {0};
 
  /* Initialize the command */
  sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
  sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
  sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;
  sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;
  sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
  sCommand.Instruction        = APS6408_RESET_CMD;
  sCommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;
  sCommand.AddressSize        = HAL_OSPI_ADDRESS_24_BITS;
  sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_DISABLE;
  sCommand.Address            = 0;
  sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
  sCommand.DataMode           = HAL_OSPI_DATA_NONE;
  sCommand.NbData             = 0;
  sCommand.DummyCycles        = 0;
  sCommand.DQSMode            = HAL_OSPI_DQS_DISABLE;
  sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
  /* Configure the command */
  if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return APS6408_ERROR;
  }
 
  /* Need to wait tRST */
  HAL_Delay(1);
 
  return APS6408_OK;
}
 
int32_t APS6408_EnableMemoryMappedMode(OSPI_HandleTypeDef *Ctx, uint32_t ReadLatencyCode, uint32_t WriteLatencyCode,
                                       uint32_t BurstType)
{
  OSPI_RegularCmdTypeDef   sCommand;
  OSPI_MemoryMappedTypeDef sMemMappedCfg;
 
  /* Initialize the write command */
  sCommand.OperationType      = HAL_OSPI_OPTYPE_WRITE_CFG;
  sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
  sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;
  sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;
  sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
  sCommand.Instruction        = (BurstType == 0U) ? APS6408_WRITE_LINEAR_BURST_CMD : APS6408_WRITE_CMD;
  sCommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;
  sCommand.AddressSize        = HAL_OSPI_ADDRESS_32_BITS;
  sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_ENABLE;
  sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
  sCommand.DataMode           = HAL_OSPI_DATA_8_LINES;
  sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_ENABLE;
  sCommand.DummyCycles        = WriteLatencyCode;
  sCommand.DQSMode            = HAL_OSPI_DQS_ENABLE;
  sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
  if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return APS6408_ERROR;
  }
 
  /* Initialize the read command */
  sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
  sCommand.Instruction   = APS6408_READ_CMD;
  sCommand.DummyCycles   = ReadLatencyCode;
 
  if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return APS6408_ERROR;
  }
 
  /* OctoSPI activation of memory-mapped mode */
  sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE;
  sMemMappedCfg.TimeOutPeriod     = 0x34U;
 
  if (HAL_OSPI_MemoryMapped(Ctx, &sMemMappedCfg) != HAL_OK)
  {
    return APS6408_ERROR;
  }
 
   /* Wait some amout of time to stabilize memory */
   HAL_Delay(10);
 
  return APS6408_OK;
}

I hope it would help you.

Alex - APMemory
Senior II

Hi,

Calibration should solve the issue, is it OK?

Alex