Files
CelloEffects/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c
T
2026-09-04 09:57:30 +02:00

1190 lines
37 KiB
C

/**
******************************************************************************
* @file stm32_extmem.c
* @author MCD Application Team
* @brief This file includes a driver for external memory support
******************************************************************************
* @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.
*
******************************************************************************
*/
/**
* @brief Macro to get memory table definition
*/
#define EXTMEM_C
/* Includes ------------------------------------------------------------------*/
#include "stm32_extmem.h"
#include "stm32_extmem_conf.h"
#if EXTMEM_DRIVER_NOR_SFDP == 1
#include "nor_sfdp/stm32_sfdp_driver_api.h"
#endif /* EXTMEM_DRIVER_NOR_SFDP */
#if EXTMEM_DRIVER_PSRAM == 1
#include "psram/stm32_psram_driver_api.h"
#endif /* EXTMEM_DRIVER_PSRAM */
#if EXTMEM_DRIVER_SDCARD == 1
#include "sdcard/stm32_sdcard_driver_api.h"
#endif /* EXTMEM_DRIVER_SDCARD */
#if EXTMEM_DRIVER_CUSTOM == 1
#include "custom/stm32_custom_driver_api.h"
#endif /* EXTMEM_DRIVER_CUSTOM */
#if EXTMEM_DRIVER_USER == 1
#include "user/stm32_user_driver_api.h"
#endif /* EXTMEM_DRIVER_USER */
/**
* @defgroup EXTMEM_DRIVER
* @{
*/
/**
* @}
*/
/**
* @defgroup EXTMEM_SAL
* @{
*/
/**
* @}
*/
/**
* @defgroup EXTMEM
* @{
*/
/* Private Macros ------------------------------------------------------------*/
/**
* @defgroup EXTMEM_Private_Macros External Memory Private Macros
* @{
*/
/**
* @brief EXTMEM debug function
*/
/**
* @brief Macro used to trace EXTMEM function calls
*/
#if defined(EXTMEM_DEBUG_LEVEL) && defined(EXTMEM_MACRO_DEBUG)
#if EXTMEM_DEBUG_LEVEL > 0
#define EXTMEM_DEBUG(_MSG_) EXTMEM_MACRO_DEBUG(_MSG_)
#if EXTMEM_DEBUG_LEVEL > 1
#define EXTMEM_FUNC_CALL() \
do \
{ \
EXTMEM_DEBUG(__func__); \
EXTMEM_DEBUG("\n"); \
} while (0);
#else
#define EXTMEM_FUNC_CALL()
#endif /* EXTMEM_DEBUG_LEVEL > 1 */
#else
#define EXTMEM_DEBUG(_MSG_)
#define EXTMEM_FUNC_CALL()
#endif /* EXTMEM_DEBUG_LEVEL > 0 */
#else
#define EXTMEM_DEBUG(_MSG_)
#define EXTMEM_FUNC_CALL()
#endif /* defined(EXTMEM_DEBUG_LEVEL) && defined(EXTMEM_MACRO_DEBUG) */
/**
* @brief Macro used to trace EXTMEM debug information
*/
#define EXTMEM_DEBUG_ENDL(_STRING_) \
do \
{ \
EXTMEM_DEBUG(_STRING_); \
EXTMEM_DEBUG("\n"); \
} while (0);
/**
* @}
*/
/* Private typedefs ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported variables ---------------------------------------------------------*/
/** @defgroup EXTMEM_Exported_Functions External Memory Exported Functions
* @{
*/
/**
* @brief Initializes the external memory.
* @param MemId Memory identifier.
* @param ClockInput Clock input value for the memory.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_Init(uint32_t MemId, uint32_t ClockInput)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL();
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Initialize the memory using NOR SFDP driver */
if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_Init(extmem_list_config[MemId].Handle,
extmem_list_config[MemId].ConfigType,
ClockInput,
&extmem_list_config[MemId].NorSfdpObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD:
{
/* Initialize the memory using SDCARD driver */
if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Init(extmem_list_config[MemId].Handle,
&extmem_list_config[MemId].SdCardObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
{
/* Initialize the memory using PSRAM driver */
if (EXTMEM_DRIVER_PSRAM_OK != EXTMEM_DRIVER_PSRAM_Init(extmem_list_config[MemId].Handle,
extmem_list_config[MemId].ConfigType,
ClockInput,
&extmem_list_config[MemId].PsramObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Initialize the memory using CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_Init(extmem_list_config[MemId].Handle,
ClockInput,
&extmem_list_config[MemId].CustomObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Initialize the memory using USER driver */
EXTMEM_DRIVER_USER_StatusTypeDef status;
status = EXTMEM_DRIVER_USER_Init(MemId,
&extmem_list_config[MemId].UserObject);
switch (status)
{
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
{
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
}
case EXTMEM_DRIVER_USER_OK:
{
/* Nothing to do */
retr = EXTMEM_OK;
break;
}
default:
{
retr = EXTMEM_ERROR_DRIVER;
break;
}
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Deinitializes the external memory.
* @param MemId Memory identifier.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_DeInit(uint32_t MemId)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL();
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Uninitialize the memory using NOR SFDP driver */
/* Return is always OK no need to test the returned value */
(void)EXTMEM_DRIVER_NOR_SFDP_DeInit(&extmem_list_config[MemId].NorSfdpObject);
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD:
{
/* Uninitialize the memory using SDCARD driver */
if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_DeInit(&extmem_list_config[MemId].SdCardObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
{
/* Uninitialize the memory using PSRAM driver */
/* Return is always OK no need to test the returned value */
(void)EXTMEM_DRIVER_PSRAM_DeInit(&extmem_list_config[MemId].PsramObject);
break;
}
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Uninitialize the memory using CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_DeInit(&extmem_list_config[MemId].CustomObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Uninitialize the memory using USER driver */
EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_DeInit(&extmem_list_config[MemId].UserObject);
switch (status)
{
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
case EXTMEM_DRIVER_USER_OK:
/* Nothing to do, the returned status is already set to EXTMEM_OK */
break;
default:
retr = EXTMEM_ERROR_DRIVER;
break;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Reads data from the external memory.
* @param MemId Memory identifier.
* @param Address Address in memory to read from.
* @param Data Pointer to buffer where read data will be stored.
* @param Size Number of bytes to read.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_Read(uint32_t MemId, uint32_t Address, uint8_t *Data, uint32_t Size)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL()
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Perform the Read operation using the NOR SFDP driver */
if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_Read(&extmem_list_config[MemId].NorSfdpObject,
Address, Data, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD:
{
/* Perform the Read operation using the SDCARD driver */
if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Read(&extmem_list_config[MemId].SdCardObject,
Address, Data, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
{
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
}
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Perform the Read operation using the CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_Read(&extmem_list_config[MemId].CustomObject,
Address, Data, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Perform the Read operation using the USER driver */
EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_Read(&extmem_list_config[MemId].UserObject,
Address, Data, Size);
switch (status)
{
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
case EXTMEM_DRIVER_USER_OK:
/* Nothing to do, the returned status is already set to EXTMEM_OK */
break;
default:
retr = EXTMEM_ERROR_DRIVER;
break;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Writes data to the external memory.
* @param MemId Memory identifier.
* @param Address Address in memory to write to.
* @param Data Pointer to buffer containing data to be written.
* @param Size Number of bytes to write.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_Write(uint32_t MemId, uint32_t Address, const uint8_t *Data, uint32_t Size)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL()
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Perform the Write operation using the NOR SFDP driver */
if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_Write(&extmem_list_config[MemId].NorSfdpObject,
Address, Data, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD:
{
/* Perform the Write operation using the SDCARD driver */
if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Write(&extmem_list_config[MemId].SdCardObject,
Address, Data, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
{
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
}
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Perform the Write operation using the CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_Write(&extmem_list_config[MemId].CustomObject,
Address, Data, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Perform the Write operation using the USER driver */
EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_Write(&extmem_list_config[MemId].UserObject,
Address, Data, Size);
switch (status)
{
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
case EXTMEM_DRIVER_USER_OK:
break;
default:
retr = EXTMEM_ERROR_DRIVER;
break;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Writes data to the external memory in mapped mode.
* @param MemId Memory identifier.
* @param Address Address in memory to write to.
* @param Data Pointer to buffer (must be 32-bit aligned) containing data to be written.
* @param Size Number of bytes to write.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*
* @note This function performs write operations in mapped mode and requires specific processing due
* to write enable management when the memory is mapped. The operation splits the write into packets
* of page size, and for each packet, performs a write before entering mapped mode.
*
* @note To avoid issues during this process, it is mandatory that the targeted memory area has the following
* characteristics: the write region must be non-bufferable, non-shareable, and non-cacheable.
*/
EXTMEM_StatusTypeDef EXTMEM_WriteInMappedMode(uint32_t MemId, uint32_t Address, const uint8_t *const Data,
uint32_t Size)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL()
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
/* Perform the Write in mapped mode operation using the NOR SFDP driver */
case EXTMEM_NOR_SFDP:
{
if (EXTMEM_DRIVER_NOR_SFDP_OK !=
EXTMEM_DRIVER_NOR_SFDP_WriteInMappedMode(&extmem_list_config[MemId].NorSfdpObject,
Address, Data, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD :
/* Functionality not supported in this driver */
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
/* Functionality not supported in this driver */
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
/* Functionality not supported in this driver */
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
/* Functionality not supported in this driver */
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Erases a number of sectors in the external memory.
* @param MemId Memory identifier.
* @param Address Address in memory to start erase operation.
* @param Size Number of bytes to erase.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_EraseSector(uint32_t MemId, uint32_t Address, uint32_t Size)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL()
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Perform the Sector Erase operation using the NOR SFDP driver */
const EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *const object = &extmem_list_config[MemId].NorSfdpObject;
EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1;
uint32_t local_address = Address;
uint32_t local_size = Size;
uint32_t sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType4Size;
while (local_size != 0u)
{
/* if address is a modulo a sector size if sector */
if ((object->sfdp_private.DriverInfo.EraseType4Size != 0u)
&& (local_size >= sector_size)
&& ((local_address % sector_size) == 0u))
{
sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE4;
}
else
{
sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType3Size;
if ((object->sfdp_private.DriverInfo.EraseType3Size != 0u)
&& (local_size >= sector_size)
&& ((local_address % sector_size) == 0u))
{
sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE3;
}
else
{
sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType2Size;
if ((object->sfdp_private.DriverInfo.EraseType2Size != 0u)
&& (local_size >= sector_size)
&& ((local_address % sector_size) == 0u))
{
sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE2;
}
else
{
sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType1Size;
if ((object->sfdp_private.DriverInfo.EraseType1Size != 0u)
&& ((local_address % sector_size) == 0u))
{
sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1;
}
else
{
retr = EXTMEM_ERROR_SECTOR_SIZE;
}
}
}
}
if (retr == EXTMEM_OK)
{
if (EXTMEM_DRIVER_NOR_SFDP_OK !=
EXTMEM_DRIVER_NOR_SFDP_SectorErase(&extmem_list_config[MemId].NorSfdpObject,
local_address, sector_type))
{
retr = EXTMEM_ERROR_DRIVER;
}
}
if (retr != EXTMEM_OK)
{
local_size = 0u;
}
else
{
local_address = local_address + sector_size;
if (sector_size > local_size)
{
local_size = 0u;
}
else
{
local_size = local_size - sector_size;
}
}
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD:
{
/* Perform the Sector Erase operation using the SDCARD driver */
if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_EraseBlock(&extmem_list_config[MemId].SdCardObject,
Address, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
{
/* Functionality not supported in this driver */
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
}
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Perform the Sector Erase operation using the CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_EraseSector(&extmem_list_config[MemId].CustomObject,
Address, Size))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Perform the Sector Erase operation using the USER driver */
EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_EraseSector(&extmem_list_config[MemId].UserObject,
Address, Size);
switch (status)
{
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
case EXTMEM_DRIVER_USER_OK:
break;
default:
retr = EXTMEM_ERROR_DRIVER;
break;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Erases all sectors in the external memory.
* @param MemId Memory identifier.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_EraseAll(uint32_t MemId)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL()
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Perform the Mass Erase operation using the NOR SFDP driver */
if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_MassErase(&extmem_list_config[MemId].NorSfdpObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD:
{
/* Perform the Mass Erase operation using the SD CARD driver */
if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Erase(&extmem_list_config[MemId].SdCardObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM:
{
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
}
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Perform the Mass Erase operation using the CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_MassErase(&extmem_list_config[MemId].CustomObject))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Perform the Mass Erase operation using the USER driver */
EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_MassErase(&extmem_list_config[MemId].UserObject);
switch (status)
{
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
case EXTMEM_DRIVER_USER_OK:
break;
default:
retr = EXTMEM_ERROR_DRIVER;
break;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Returns information about the external memory.
* @param MemId Memory identifier.
* @param Info Pointer to structure to receive memory information.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_GetInfo(uint32_t MemId, void *Info)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL()
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Perform the Get Information operation using the NOR SFDP driver */
EXTMEM_DRIVER_NOR_SFDP_GetFlashInfo(&extmem_list_config[MemId].NorSfdpObject,
(EXTMEM_NOR_SFDP_FlashInfoTypeDef *)Info);
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD :
{
/* Perform the Get Information operation using the SDCARD driver */
if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_GetInfo(&extmem_list_config[MemId].SdCardObject,
(EXTMEM_DRIVER_SDCARD_InfoTypeDef *)Info))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Perform the Get Information operation using the CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_GetInfo(&extmem_list_config[MemId].CustomObject,
(EXTMEM_DRIVER_CUSTOM_MemInfoTypeDef *)Info))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Perform the Get Information operation using the USER driver */
if (EXTMEM_DRIVER_USER_OK != EXTMEM_DRIVER_USER_GetInfo(&extmem_list_config[MemId].UserObject,
(EXTMEM_USER_MemInfoTypeDef *)Info))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
/* Functionality not supported in this driver */
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Enables or disables the memory mapped mode.
* @param MemId Memory identifier.
* @param State Enable or disable state (@ref EXTMEM_StateTypeDef).
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_MemoryMappedMode(uint32_t MemId, EXTMEM_StateTypeDef State)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL();
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
case EXTMEM_NOR_SFDP:
{
/* Perform the memory Map operation using the NOR SFDP driver */
if (EXTMEM_ENABLE == State)
{
/* Start the memory mapped mode */
if (EXTMEM_DRIVER_NOR_SFDP_OK !=
EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode(&extmem_list_config[MemId].NorSfdpObject))
{
return EXTMEM_ERROR_DRIVER;
}
}
else
{
/* Stop the memory mapped mode */
if (EXTMEM_DRIVER_NOR_SFDP_OK !=
EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode(&extmem_list_config[MemId].NorSfdpObject))
{
return EXTMEM_ERROR_DRIVER;
}
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM :
{
/* Perform the memory Map operation using the PSRAM driver */
if (EXTMEM_ENABLE == State)
{
/* Start the memory mapped mode */
if (EXTMEM_DRIVER_PSRAM_OK !=
EXTMEM_DRIVER_PSRAM_Enable_MemoryMappedMode(&extmem_list_config[MemId].PsramObject))
{
return EXTMEM_ERROR_DRIVER;
}
}
else
{
/* Stop the memory mapped mode */
if (EXTMEM_DRIVER_PSRAM_OK !=
EXTMEM_DRIVER_PSRAM_Disable_MemoryMappedMode(&extmem_list_config[MemId].PsramObject))
{
return EXTMEM_ERROR_DRIVER;
}
}
break;
}
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM :
{
/* Perform the memory Map operation using the CUSTOM driver */
if (EXTMEM_ENABLE == State)
{
/* Start the memory mapped mode */
if (EXTMEM_DRV_CUSTOM_OK !=
EXTMEM_DRIVER_CUSTOM_Enable_MemoryMappedMode(&extmem_list_config[MemId].CustomObject))
{
return EXTMEM_ERROR_DRIVER;
}
}
else
{
/* Stop the memory mapped mode */
if (EXTMEM_DRV_CUSTOM_OK !=
EXTMEM_DRIVER_CUSTOM_Disable_MemoryMappedMode(&extmem_list_config[MemId].CustomObject))
{
return EXTMEM_ERROR_DRIVER;
}
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER :
{
/* Perform the memory Map operation using the USER driver */
EXTMEM_DRIVER_USER_StatusTypeDef status;
if (EXTMEM_ENABLE == State)
{
/* Start the memory mapped mode */
status = EXTMEM_DRIVER_USER_Enable_MemoryMappedMode(&extmem_list_config[MemId].UserObject);
}
else
{
/* Stop the memory mapped mode */
status = EXTMEM_DRIVER_USER_Disable_MemoryMappedMode(&extmem_list_config[MemId].UserObject);
}
switch (status)
{
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
case EXTMEM_DRIVER_USER_OK:
break;
default:
retr = EXTMEM_ERROR_DRIVER;
break;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD :
/* Functionality not supported in this driver */
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
/* Unknown type of EXTMEM driver */
default:
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @brief Gets the base address of the mapped external memory.
* @param MemId Memory identifier.
* @param BaseAddress Pointer to variable to receive the base address.
* @retval EXTMEM_StatusTypeDef Status of the operation.
*/
EXTMEM_StatusTypeDef EXTMEM_GetMapAddress(uint32_t MemId, uint32_t *BaseAddress)
{
EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID;
EXTMEM_FUNC_CALL();
/* Check the memory ID */
if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)))
{
retr = EXTMEM_OK;
/* Check type of EXTMEM driver used to access memory */
switch (extmem_list_config[MemId].MemType)
{
#if EXTMEM_DRIVER_NOR_SFDP == 1 || EXTMEM_DRIVER_PSRAM == 1
case EXTMEM_PSRAM:
case EXTMEM_NOR_SFDP:
{
/* Define Map address based on Instance used for memory access */
#if defined(XSPI1)
if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == XSPI1)
{
*BaseAddress = XSPI1_BASE;
}
#if defined(XSPI2)
else if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == XSPI2)
{
*BaseAddress = XSPI2_BASE;
}
#if defined(XSPI3)
else if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == XSPI3)
{
*BaseAddress = XSPI3_BASE;
}
#endif /* XSPI3 */
#endif /* XSPI2 */
#else /* XSPI1 */
if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == OCTOSPI1)
{
*BaseAddress = OCTOSPI1_BASE;
}
#endif /* XSPI1 */
else
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 || EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
case EXTMEM_SDCARD :
{
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
}
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
case EXTMEM_CUSTOM:
{
/* Perform the Get Map Address operation using the CUSTOM driver */
if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_GetMapAddress(&extmem_list_config[MemId].CustomObject,
BaseAddress))
{
retr = EXTMEM_ERROR_DRIVER;
}
break;
}
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
case EXTMEM_USER:
{
/* Perform the Get Map Address operation using the USER driver */
switch (EXTMEM_DRIVER_USER_GetMapAddress(&extmem_list_config[MemId].UserObject, BaseAddress))
{
case EXTMEM_DRIVER_USER_OK:
break;
case EXTMEM_DRIVER_USER_NOTSUPPORTED:
retr = EXTMEM_ERROR_NOTSUPPORTED;
break;
default :
retr = EXTMEM_ERROR_DRIVER;
break;
}
break;
}
#endif /* EXTMEM_DRIVER_USER == 1 */
/* Unknown type of EXTMEM driver */
default :
{
EXTMEM_DEBUG("\terror : unknown memory type\n");
retr = EXTMEM_ERROR_UNKNOWNMEMORY;
break;
}
}
}
return retr;
}
/**
* @}
*/
/**
* @}
*/