cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7R7 with APS6408 PSRAM

geriTricky
Associate II

Hi there,

I have been struggling with the PSRAM. I bought the STM32H7S78 board to pick up the know-how to understand how I should configure the PSRAM at XSPI1 via the EXT MEM manager at my own board. 

My clock speed is 200MHZ XSPI. 
PSRAM MPN: APS6408L-OBMX-BA
MCU type is slightly different (STM32H7R7L8H6)
For sure, I connected the programmer to configure the sbs since the VIO is 1.8V. What I missed from the HW was that I forgot to add the pull-up resistor at the CE pin. Note: I desoldered from the original ST board to check the behaviour and did not influence its behaviour. The reset is connected to the NRST by a diode. Note: Checked the connections, footprints. GND is on the mid1 layer and all of the connections are on the top layer. The length is less than 14mm and the distance between the track are usually 0.2~0.25mm.
So all in all, I excluded the HW errors. Note: I bought the same PSRAM as on the ST board and I can use those configs after all. However, before I desolder the BGA I want to check the experts' opinions about these.

staus_psram return with EXTMEM_ERROR_DRIVER and it came from the HAL TIMEOUT from STm32_sal_xspi.c
XSPI_Receive somehow returns with HAL_TIMEOUT. I increased the timeout to be 1000, but without any success.

Thank you for your support in advance!

 
  /* Configure the command */
  retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE);
  if (retr  != HAL_OK)
  {
    goto error;
  }

  /* Read data */
  retr = XSPI_Receive(SalXspi, Data);

error:
  if (retr != HAL_OK)
  {
    /* Abort any ongoing transaction for the next action */
    (void)HAL_XSPI_Abort(SalXspi->hxspi);
  }
  return retr;
}


XSPI1 code:

  /* USER CODE END XSPI1_Init 0 */

  XSPIM_CfgTypeDef sXspiManagerCfg = {0};

  /* USER CODE BEGIN XSPI1_Init 1 */

  /* USER CODE END XSPI1_Init 1 */
  hxspi1.Instance = XSPI1;
  hxspi1.Init.FifoThresholdByte = 1;
  hxspi1.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;
  hxspi1.Init.MemoryType = HAL_XSPI_MEMTYPE_APMEM;
  hxspi1.Init.MemorySize = HAL_XSPI_SIZE_64MB;
  hxspi1.Init.ChipSelectHighTimeCycle = 2;
  hxspi1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;
  hxspi1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;
  hxspi1.Init.WrapSize = HAL_XSPI_WRAP_32_BYTES;
  hxspi1.Init.ClockPrescaler = 0;
  hxspi1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE;
  hxspi1.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_1KB;
  hxspi1.Init.MaxTran = 0;
  hxspi1.Init.Refresh = 800;
  hxspi1.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1;
  if (HAL_XSPI_Init(&hxspi1) != HAL_OK)
  {
    Error_Handler();
  }
  sXspiManagerCfg.nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1;
  sXspiManagerCfg.IOPort = HAL_XSPIM_IOPORT_1;
  sXspiManagerCfg.Req2AckTime = 1;
  if (HAL_XSPIM_Config(&hxspi1, &sXspiManagerCfg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN XSPI1_Init 2 */


EXM MEM code:

  /* USER CODE BEGIN MX_EXTMEM_Init_PreTreatment */

  /* USER CODE END MX_EXTMEM_Init_PreTreatment */
  HAL_RCCEx_EnableClockProtection(RCC_CLOCKPROTECT_XSPI);

  /* Initialization of the memory parameters */
  memset(extmem_list_config, 0x0, sizeof(extmem_list_config));

  /* EXTMEMORY_1 */
  extmem_list_config[0].MemType = EXTMEM_NOR_SFDP;
  extmem_list_config[0].Handle = (void*)&hxspi2;
  extmem_list_config[0].ConfigType = EXTMEM_LINK_CONFIG_8LINES;

  /* EXTMEMORY_2 */
  extmem_list_config[1].MemType = EXTMEM_PSRAM;
  extmem_list_config[1].Handle = (void*)&hxspi1;
  extmem_list_config[1].ConfigType = EXTMEM_LINK_CONFIG_8LINES;

  extmem_list_config[1].PsramObject.psram_public.MemorySize = HAL_XSPI_SIZE_64MB;
  extmem_list_config[1].PsramObject.psram_public.FreqMax = 200 * 1000000u;
  extmem_list_config[1].PsramObject.psram_public.NumberOfConfig = 2u;

  /* Config */
  extmem_list_config[1].PsramObject.psram_public.config[0].WriteMask = 0x1Cu;
  extmem_list_config[1].PsramObject.psram_public.config[0].WriteValue = 0x10u;
  extmem_list_config[1].PsramObject.psram_public.config[0].REGAddress = 0x00u;

  extmem_list_config[1].PsramObject.psram_public.config[1].WriteMask = 0xE0u;
  extmem_list_config[1].PsramObject.psram_public.config[1].WriteValue = 0x20u;
  extmem_list_config[1].PsramObject.psram_public.config[1].REGAddress = 0x04u;

  /* Memory command configuration */
  extmem_list_config[1].PsramObject.psram_public.ReadREG           = 0x40u;
  extmem_list_config[1].PsramObject.psram_public.WriteREG          = 0xC0u;
  extmem_list_config[1].PsramObject.psram_public.ReadREGSize       = 2u;
  extmem_list_config[1].PsramObject.psram_public.REG_DummyCycle    = 1u;
  extmem_list_config[1].PsramObject.psram_public.Write_command     = 0xA0u;
  extmem_list_config[1].PsramObject.psram_public.Write_DummyCycle  = 7u;
  extmem_list_config[1].PsramObject.psram_public.Read_command      = 0x20u;
  extmem_list_config[1].PsramObject.psram_public.WrapRead_command  = 0x00u;
  extmem_list_config[1].PsramObject.psram_public.Read_DummyCycle   = 7u;

  // EXTMEM_Init(EXTMEMORY_1, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI2));
  // EXTMEM_Init(EXTMEMORY_2, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI1));

  /* USER CODE BEGIN MX_EXTMEM_Init_PostTreatment */
  EXTMEM_StatusTypeDef status_psram, status_flash;
  status_flash = EXTMEM_Init(EXTMEMORY_1, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI2));
  status_psram = EXTMEM_Init(EXTMEMORY_2, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI1));

 

geriTricky_0-1767745738189.png


Edited to apply source code formatting - please see How to insert source code for future reference.

2 REPLIES 2
KDJEM.1
ST Employee

Hello @geriTricky ;

 

The XSPI clock speed 200MHz is the maximum clock speed supported. You must therefore respect the hardware and the software constraints to achieve this frequency.

KDJEM1_0-1767868046984.png

For that I recommend you to refer to Getting started with STM32H7Rx/7Sx MCUs hardware development - Application note application note to check you hardware:

KDJEM1_1-1767868095025.png

 

Is the problem still there when you decrease the XSPI frequency?

Is the IO compensation cell enabled?

Thank you.

Kaouthar

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.

Mikk Leini
Senior

You need that external CS pull-up for cases when MCU is not driving the CS (while booting up) to avoid memory chip picking up noise as a transmission.

Don't forget the HSLV fuses if you use high frequencies:
https://community.st.com/t5/stm32-mcus/recommendations-for-high-speed-low-voltage-mode-hslv-on-the/ta-p/760516

But general recommendation is to start from lower frequency (few MHz) and use an oscilloscope (with high input impedance!) to check if there is any clock going out and it has the frequency you expect it to have.

Also check that you're not mixing up XSPI1 and 2.