/** ****************************************************************************** * @file stm32_psram_driver.c * @author MCD Application Team * @brief This file implements the PSRAM driver. ****************************************************************************** * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32_extmem.h" #include "stm32_extmem_conf.h" #if EXTMEM_DRIVER_PSRAM == 1 #if EXTMEM_SAL_XSPI == 1 #include "../sal/stm32_sal_xspi_api.h" #else #error "the driver PSRAM requires the enable of EXTMEM_SAL_XSPI" #endif /* EXTMEM_SAL_XSPI */ #include "stm32_psram_driver_api.h" #if EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) #include #endif /* EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && EXTMEM_MACRO_DEBUG */ /** @defgroup PSRAM PSRAM driver * @ingroup EXTMEM_DRIVER * @{ */ /* Private Macro ------------------------------------------------------------*/ /** @defgroup PSRAM_Private_Macro Private Macro * @{ */ /** * @brief Default Timeout value (ms) */ #define DRIVER_DEFAULT_TIMEOUT 300 #if EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) /** * @brief Debug macro for a string */ #define DEBUG_STR(_STR_) { \ EXTMEM_MACRO_DEBUG("\tPSRAM::"); \ EXTMEM_MACRO_DEBUG(_STR_); \ EXTMEM_MACRO_DEBUG("\n\r"); \ } #else /** * @brief Debug macro for a string */ #define DEBUG_STR(_STR_) #endif /* EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) */ /** * @} */ /* Private typedefs ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /** @defgroup PSRAM_Private_Functions Private Functions * @{ */ EXTMEM_DRIVER_PSRAM_StatusTypeDef PSRAM_ExecuteCommand(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject, uint8_t Index); /** * @} */ /** @defgroup PSRAM_Exported_Functions Exported Functions * @{ */ /** * @brief Initializes the PSRAM driver. * @param Peripheral Pointer to the peripheral handle. * @param Config Link configuration. * @param ClockInput Input clock frequency. * @param PsramObject Pointer to the PSRAM driver object. * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef */ EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Init(void *Peripheral, EXTMEM_LinkConfig_TypeDef Config, uint32_t ClockInput, EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject) { EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; uint32_t ClockOut; SAL_XSPI_PhysicalLinkTypeDef linkvalue; /* Initialize the instance */ DEBUG_STR("initialize the instance") /* Initialize XSPI low layer */ (void)SAL_XSPI_Init(&PsramObject->psram_private.SALObject, Peripheral); /* Abort any ongoing XSPI action */ (void)SAL_XSPI_DisableMapMode(&PsramObject->psram_private.SALObject); /* Set the frequency prescaler */ DEBUG_STR("set memory speed according freqIn and freqMax supported by the memory") if (HAL_OK != SAL_XSPI_SetClock(&PsramObject->psram_private.SALObject, ClockInput, PsramObject->psram_public.FreqMax, &ClockOut)) { retr = EXTMEM_DRIVER_PSRAM_ERROR; goto error; } /* Set the memory size */ DEBUG_STR("set memory size according") (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_FLASHSIZE, &PsramObject->psram_public.MemorySize); /* Set the memory size */ DEBUG_STR("set xspi link config") linkvalue = PHY_LINK_RAM8; (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_PHY_LINK, &linkvalue); /* Set the configuration to perform register operation */ (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_DUMMY_CYCLES, &PsramObject->psram_public.REG_DummyCycle); /* Execute the command sequence */ for (uint8_t command_index = 0u; command_index < PsramObject->psram_public.NumberOfConfig; command_index++) { retr = PSRAM_ExecuteCommand(PsramObject, command_index); if (retr != EXTMEM_DRIVER_PSRAM_OK) { goto error; } } switch (Config) { case EXTMEM_LINK_CONFIG_16LINES: linkvalue = PHY_LINK_RAM16; (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_PHY_LINK, &linkvalue); break; case EXTMEM_LINK_CONFIG_8LINES: linkvalue = PHY_LINK_RAM8; (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_PHY_LINK, &linkvalue); break; default: retr = EXTMEM_DRIVER_PSRAM_ERROR; goto error; break; } error: return retr; } /** * @brief Deinitializes the PSRAM driver. * @param PsramObject Pointer to the PSRAM driver object. * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef */ EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_DeInit(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject) { /* Abort any ongoing XSPI action */ (void)SAL_XSPI_DisableMapMode(&PsramObject->psram_private.SALObject); return EXTMEM_DRIVER_PSRAM_OK; } /** * @brief Enables memory-mapped mode for the PSRAM device. * @param PsramObject Pointer to the PSRAM driver object. * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef */ EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Enable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject) { EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; /* Configure the read wrap mode */ if (HAL_OK != SAL_XSPI_ConfigureWrappMode(&PsramObject->psram_private.SALObject, PsramObject->psram_public.WrapRead_command, PsramObject->psram_public.Write_DummyCycle)) { retr = EXTMEM_DRIVER_PSRAM_ERROR_MAP_ENABLE; } /* Enable memory mapped mode */ if (HAL_OK != SAL_XSPI_EnableMapMode(&PsramObject->psram_private.SALObject, PsramObject->psram_public.Read_command, PsramObject->psram_public.Read_DummyCycle, PsramObject->psram_public.Write_command, PsramObject->psram_public.Write_DummyCycle)) { retr = EXTMEM_DRIVER_PSRAM_ERROR_MAP_ENABLE; } return retr; } /** * @brief Disables memory-mapped mode for the PSRAM device. * @param PsramObject Pointer to the PSRAM driver object. * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef */ EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Disable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject) { EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; /* Disable memory mapped mode */ if (HAL_OK != SAL_XSPI_DisableMapMode(&PsramObject->psram_private.SALObject)) { retr = EXTMEM_DRIVER_PSRAM_ERROR_MAP_DISABLE; } return retr; } /** * @} */ /** @addtogroup PSRAM_Private_Functions * @{ */ /** * @brief Executes a configuration command for the PSRAM device. * * @param PsramObject Pointer to the PSRAM driver object. * @param Index Index of the command to execute. * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef */ EXTMEM_DRIVER_PSRAM_StatusTypeDef PSRAM_ExecuteCommand(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject, uint8_t Index) { EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; uint8_t regval[2]; if (PsramObject->psram_public.ReadREGSize > 2u) { retr = EXTMEM_DRIVER_PSRAM_ERROR_REGSIZE; goto error; } if (HAL_OK != SAL_XSPI_Read(&PsramObject->psram_private.SALObject, PsramObject->psram_public.ReadREG, PsramObject->psram_public.config[Index].REGAddress, regval, PsramObject->psram_public.ReadREGSize)) { retr = EXTMEM_DRIVER_PSRAM_ERROR_READREG; goto error; } MODIFY_REG(regval[0], PsramObject->psram_public.config[Index].WriteMask, PsramObject->psram_public.config[Index].WriteValue); if (HAL_OK != SAL_XSPI_Write(&PsramObject->psram_private.SALObject, PsramObject->psram_public.WriteREG, PsramObject->psram_public.config[Index].REGAddress, regval, PsramObject->psram_public.ReadREGSize)) { retr = EXTMEM_DRIVER_PSRAM_ERROR_WRITEREG; goto error; } error: return retr; } /** * @} */ /** * @} */ #endif /* EXTMEM_DRIVER_PSRAM == 1 */