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));
