284 lines
9.2 KiB
C
284 lines
9.2 KiB
C
/**
|
|
******************************************************************************
|
|
* @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 <stdio.h>
|
|
#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 */
|