This commit is contained in:
Thomas Laduguie committed 2026-09-04 09:57:30 +02:00
commit 75fbf8809d
489 files changed
+398278

No files matched your search

@@ -0,0 +1,80 @@
SLA0044 Rev5/February 2018
## Software license agreement
### __ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT__
BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE
OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS
INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES
(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON
BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES
TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT.
Under STMicroelectronics’ intellectual property rights, the redistribution,
reproduction and use in source and binary forms of the software or any part
thereof, with or without modification, are permitted provided that the following
conditions are met:
1. Redistribution of source code (modified or not) must retain any copyright
notice, this list of conditions and the disclaimer set forth below as items 10
and 11.
2. Redistributions in binary form, except as embedded into microcontroller or
microprocessor device manufactured by or for STMicroelectronics or a software
update for such device, must reproduce any copyright notice provided with the
binary code, this list of conditions, and the disclaimer set forth below as
items 10 and 11, in documentation and/or other materials provided with the
distribution.
3. Neither the name of STMicroelectronics nor the names of other contributors to
this software may be used to endorse or promote products derived from this
software or part thereof without specific written permission.
4. This software or any part thereof, including modifications and/or derivative
works of this software, must be used and execute solely and exclusively on or in
combination with a microcontroller or microprocessor device manufactured by or
for STMicroelectronics.
5. No use, reproduction or redistribution of this software partially or totally
may be done in any manner that would subject this software to any Open Source
Terms. “Open Source Terms” shall mean any open source license which requires as
part of distribution of software that the source code of such software is
distributed therewith or otherwise made available, or open source license that
substantially complies with the Open Source definition specified at
www.opensource.org and any other comparable open source license such as for
example GNU General Public License (GPL), Eclipse Public License (EPL), Apache
Software License, BSD license or MIT license.
6. STMicroelectronics has no obligation to provide any maintenance, support or
updates for the software.
7. The software is and will remain the exclusive property of STMicroelectronics
and its licensors. The recipient will not take any action that jeopardizes
STMicroelectronics and its licensors' proprietary rights or acquire any rights
in the software, except the limited rights specified hereunder.
8. The recipient shall comply with all applicable laws and regulations affecting
the use of the software or any part thereof including any applicable export
control law or regulation.
9. Redistribution and use of this software or any part thereof other than as
permitted under this license is void and will automatically terminate your
rights under this license.
10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE
DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL
STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER
EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY
RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.
@@ -0,0 +1,191 @@
/**
******************************************************************************
* @file stm32_boot_xip.c
* @author MCD Application Team
* @brief This file manages booting in execute-in-place (XIP) mode.
******************************************************************************
* @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_boot_xip.h"
#include "stm32_extmem_conf.h"
/** @addtogroup BOOT
* @{
*/
/** @addtogroup BOOT_XIP
* @{
*/
/* Private typedefs ----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/* Offset of the image from the boot memory base */
#ifndef EXTMEM_XIP_IMAGE_OFFSET
#define EXTMEM_XIP_IMAGE_OFFSET 0
#endif /* EXTMEM_XIP_IMAGE_OFFSET */
/* Offset of the vector table from the start of the image */
#ifndef EXTMEM_HEADER_OFFSET
#define EXTMEM_HEADER_OFFSET 0
#endif /* EXTMEM_HEADER_OFFSET */
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
BOOTStatus_TypeDef JumpToApplication(void);
BOOTStatus_TypeDef MapMemory(void);
BOOTStatus_TypeDef GetBaseAddress(uint32_t MemIndex, uint32_t *BaseAddress);
/**
* @addtogroup BOOT_XIP_Exported_Functions Boot XIP exported functions
* @{
*/
/**
* @brief Boots the application by mapping the memory and jumping to the application.
* @retval BOOTStatus_TypeDef Status of the operation.
*/
BOOTStatus_TypeDef BOOT_Application(void)
{
BOOTStatus_TypeDef retr;
/* Mount the memory */
retr = MapMemory();
if (BOOT_OK == retr)
{
/* Jump on the application */
retr = JumpToApplication();
}
return retr;
}
/**
* @}
*/
/**
* @defgroup BOOT_XIP_Private_Functions Boot XIP private functions
* @{
*/
/**
* @brief Maps the external memory.
* @retval BOOTStatus_TypeDef Status of the operation.
*/
BOOTStatus_TypeDef MapMemory(void)
{
BOOTStatus_TypeDef retr = BOOT_OK;
/* Map all the memory */
for (uint8_t index = 0; index < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)); index++)
{
switch (EXTMEM_MemoryMappedMode(index, EXTMEM_ENABLE))
{
case EXTMEM_ERROR_NOTSUPPORTED :
if (EXTMEM_MEMORY_BOOTXIP == index)
{
retr = BOOT_ERROR_INCOMPATIBLEMEMORY;
}
else
{
/* We consider the memory will be not used any more */
EXTMEM_DeInit(index);
}
case EXTMEM_OK:
break;
default :
retr = BOOT_ERROR_MAPPEDMODEFAIL;
break;
}
}
return retr;
}
/**
* @brief Jumps to the application using its vector table.
* @retval BOOTStatus_TypeDef Status of the operation.
*/
BOOTStatus_TypeDef JumpToApplication(void)
{
uint32_t primask_bit;
typedef void (*pFunction)(void);
static pFunction JumpToApp;
uint32_t Application_vector;
if (EXTMEM_OK != EXTMEM_GetMapAddress(EXTMEM_MEMORY_BOOTXIP, &Application_vector))
{
return BOOT_ERROR_INCOMPATIBLEMEMORY;
}
/* Suspend SysTick */
HAL_SuspendTick();
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
/* if I-Cache is enabled, disable I-Cache-----------------------------------*/
if (SCB->CCR & SCB_CCR_IC_Msk)
{
SCB_DisableICache();
}
#endif /* __ICACHE_PRESENT */
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
/* if D-Cache is enabled, disable D-Cache-----------------------------------*/
if (SCB->CCR & SCB_CCR_DC_Msk)
{
SCB_DisableDCache();
}
#endif /* __DCACHE_PRESENT */
/* Initialize user application's Stack Pointer & Jump to user application */
primask_bit = __get_PRIMASK();
__disable_irq();
/* Apply offsets for image location and vector table offset */
Application_vector += EXTMEM_XIP_IMAGE_OFFSET + EXTMEM_HEADER_OFFSET;
SCB->VTOR = (uint32_t)Application_vector;
JumpToApp = (pFunction)(*(__IO uint32_t *)(Application_vector + 4u));
#if (defined(__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))
/* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */
__set_MSPLIM(0x00000000);
#elif (defined(__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1))
/* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */
__set_MSPLIM(0x00000000);
#elif (defined(__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1))
/* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */
__set_MSPLIM(0x00000000);
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8_1M_MAIN__ or __ARM_ARCH_8M_BASE__ */
__set_MSP(*(__IO uint32_t *) Application_vector);
/* Re-enable the interrupts */
__set_PRIMASK(primask_bit);
JumpToApp();
return BOOT_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,76 @@
/**
******************************************************************************
* @file stm32_boot_xip.h
* @author MCD Application Team
* @brief Header for stm32_boot_xip.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2023 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_BOOT_XIP_H__
#define __STM32_BOOT_XIP_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/** @addtogroup BOOT_XIP
* @{
*/
/* Exported defines ---------------------------------------------------------*/
/**
* @defgroup BOOT_XIP_Private_Defines Boot XIP exported definitions
* @{
*/
/**
* @brief List of status codes for XIP
*/
typedef enum
{
BOOT_OK, /*!< Operation successful */
BOOT_ERROR_UNSUPPORTED_MEMORY, /*!< Unsupported memory type */
BOOT_ERROR_NOBASEADDRESS, /*!< No base address for the memory */
BOOT_ERROR_MAPPEDMODEFAIL, /*!< Error during memory mapping */
BOOT_ERROR_INCOMPATIBLEMEMORY, /*!< Selected memory not compatible with XIP boot */
BOOT_ERROR_DRIVER, /*!< Error in driver operation */
} BOOTStatus_TypeDef;
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/**
* @defgroup BOOT_XIP_Exported_Functions Boot XIP exported functions
* @{
*/
BOOTStatus_TypeDef BOOT_Application(void);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_BOOT_XIP_H__ */
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,147 @@
/**
******************************************************************************
* @file stm32_sfdp_data.h
* @author MCD Application Team
* @brief This file contains the sfdp functions prototypes.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SFDP_DATA_H
#define __STM32_SFDP_DATA_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#if EXTMEM_SAL_XSPI == 1
#include "../sal/stm32_sal_xspi_api.h"
#else
#error "the driver SFDP requires the enable of EXTMEM_SAL_XSPI"
#endif /* EXTMEM_SAL_XSPI_ENABLED */
/**
* @addtogroup NOR_SFDP_DATA
* @ingroup NOR_SFDP
* @{
*/
/* Exported constants --------------------------------------------------------*/
/**
* @brief Maximum number of SFDP parameter in SFDP table
*/
#define SFDP_MAX_NB_OF_PARAM 10U
/* Exported types ------------------------------------------------------------*/
/** @defgroup NOR_SFDP_DATA_Exported_Types Exported Types
* @ingroup NOR_SFDP_DATA
* @{
*/
/**
* @brief SFDP parameter table ID
*/
typedef enum
{
SFDP_PARAMID_UNKNOWN = 0x00000U,
SFDP_PARAMID_VENDOR = 0x00001U,
SFDP_PARAMID_FUNCTION_VENDOR = 0x00002U,
SFDP_PARAMID_FUNCTION_JEDEC = 0x00004U,
SFDP_PARAMID_BASIC_SPIPROTOCOL = 0x00008U,
SFDP_PARAMID_SECTORMAP = 0x00010U,
SFDP_PARAMID_RPMC = 0x00020U,
SFDP_PARAMID_4BYTE_ADDRESS_INSTRUCTION = 0x00040U,
SFDP_PARAMID_XSPI_V1_0 = 0x00080U,
SFDP_PARAMID_XSPI_V2_0 = 0x00100U,
SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP = 0x00200U,
SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP_MULTICHIP = 0x00400U,
SFDP_PARAMID_STATUS_CONTROL_CONFIG_XSPI_V2_0 = 0x00800U,
SFDP_PARAMID_OCTAL_DDR = 0x01000U,
SFDP_PARAMID_MSPT = 0x02000U,
SFDP_PARAMID_X4QUAD_DS = 0x04000U,
SFDP_PARAMID_QUAD_DDR = 0x08000U,
SFDP_PARAMID_SECURE_PACKET_READ_WRITE = 0x10000U,
SFDP_PARAMID_RESERVED = 0x20000U
} SFDP_ParamID_TypeDef;
/**
* @brief SFDP status typedef
*/
typedef enum
{
EXTMEM_SFDP_OK, /*!< Status OK */
EXTMEM_SFDP_ERROR_PARAM,
EXTMEM_SFDP_ERROR_NOREADFUNCTION,
EXTMEM_SFDP_ERROR_SFDPREAD,
EXTMEM_SFDP_ERROR_SIGNATURE, /*!< Signature is invalid */
EXTMEM_SFDP_ERROR_SIGNATUREMTYPE, /*!< Signature is invalid due to wrong memory type */
EXTMEM_SFDP_ERROR_PARAMTABLE_NOTFOUND,
EXTMEM_SFDP_ERROR_NO_PARAMTABLE_BASIC,
EXTMEM_SFDP_ERROR_NO_32BITADDRESSING,
EXTMEM_SFDP_ERROR_JEDECBASIC_D14,
EXTMEM_SFDP_ERROR_JEDECBASIC_D16,
EXTMEM_SFDP_ERROR_OCTALMODE,
EXTMEM_SFDP_ERROR_DRIVER,
EXTMEM_SFDP_ERROR_SETCLOCK,
EXTMEM_SFDP_ERROR_CONFIGDUMMY,
EXTMEM_SFDP_ERROR_NOTYETHANDLED
} SFDP_StatusTypeDef;
/**
* @brief SFDP header
*/
typedef struct
{
uint32_t Signature; /*!< Signature value */
uint8_t Minor_revision; /*!< Minor revision */
uint8_t Major_revision; /*!< Major revision */
uint8_t param_number; /*!< Number of parameters */
uint8_t AccessProtocol; /*!< Access protocol type */
} SFDP_HeaderTypeDef;
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup NOR_SFDP_Data_Exported_Functions Exported Functions
* @{
*/
SFDP_StatusTypeDef SFDP_GetHeader(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object,
SFDP_HeaderTypeDef *sfdp_header);
SFDP_StatusTypeDef SFDP_ReadHeader(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object,
SFDP_HeaderTypeDef *sfdp_header);
SFDP_StatusTypeDef SFDP_CollectData(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object);
SFDP_StatusTypeDef SFDP_MemoryReset(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object);
SFDP_StatusTypeDef SFDP_BuildGenericDriver(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint8_t *FreqUpdated);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef driver_check_FlagBUSY(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
uint32_t Timeout);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SFDP_DATA_H */
@@ -0,0 +1,816 @@
/**
******************************************************************************
* @file stm32_sfdp_driver.c
* @author MCD Application Team
* @brief This file includes a driver for SFDP 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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32_extmem_conf.h"
#if EXTMEM_DRIVER_NOR_SFDP == 1
#include "stm32_sfdp_driver_type.h"
#include "stm32_sfdp_driver_api.h"
#include "stm32_sfdp_data.h"
#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL != 0 && defined(EXTMEM_MACRO_DEBUG)
#include <stdio.h>
#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL != 0 && EXTMEM_MACRO_DEBUG */
#include <string.h>
/** @defgroup NOR_SFDP NOR SFDP driver
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Private Macros ------------------------------------------------------------*/
/** @defgroup NOR_SFDP_Private_Macro DRIVER NOR SFDP Private Macro
* @{
*/
/**
* @brief MIN macro
*/
#define MIN(_A_,_B_) ((_A_) > (_B_))?(_B_):(_A_);
/**
* @brief Default timeout
*/
#define DRIVER_DEFAULT_TIMEOUT 300
/**
* @brief Default clock value to read SFDP data
*/
#define DRIVER_SFDP_DEFAULT_CLOCK 50000000u
/**
* @brief DEBUG macro
*/
#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 1 && defined(EXTMEM_MACRO_DEBUG)
/**
* @brief Debug macro for a string
* @param _STR_ string
*/
#define SFDP_DEBUG_STR(_STR_) \
{ \
EXTMEM_MACRO_DEBUG("\tSFDP::"); \
EXTMEM_MACRO_DEBUG(_STR_); \
EXTMEM_MACRO_DEBUG("\n\r"); \
}
/**
* @brief debug macro for low level
*/
#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 2
#define DEBUG_DRIVER(_STR_) \
{ \
EXTMEM_MACRO_DEBUG("\tSFDP::DRIVER::"); \
EXTMEM_MACRO_DEBUG(_STR_); \
EXTMEM_MACRO_DEBUG("\n"); \
}
#else
#define DEBUG_DRIVER(_STR_)
#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 2 */
/**
* @brief debug macro for an integer
*/
#define DEBUG_ID(_ID_) \
{ \
char StrID[40]; \
EXTMEM_MACRO_DEBUG("\tSFDP:: Flash ID("); \
(void)sprintf(StrID, "0x%x:0x%x:0x%x:0x%x", \
_ID_[0],_ID_[1],_ID_[2],_ID_[3]); \
EXTMEM_MACRO_DEBUG(StrID); \
EXTMEM_MACRO_DEBUG(")\n"); \
}
/**
* @brief Debug macro for error
*/
#define DEBUG_DRIVER_ERROR(_STR_) SFDP_DEBUG_STR(_STR_)
#else
#define DEBUG_ID(_ID_)
#define SFDP_DEBUG_STR(_STR_)
#define DEBUG_DRIVER(_STR_)
#define DEBUG_DRIVER_ERROR(_STR_)
#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 1 && EXTMEM_MACRO_DEBUG */
/**
* @}
*/
/* Private typedefs ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup DRIVER_SFDP_Private_Functions DRIVER SFDP Private Functions
* @{
*/
static EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef driver_set_FlagWEL(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
uint32_t Timeout);
__weak void EXTMEM_MemCopy(uint32_t *Destination_Address, const uint8_t *ptrData, uint32_t DataSize);
/**
* @}
*/
/** @defgroup DRIVER_SFDP_Exported_Functions DRIVER SFDP Exported Functions
* @{
*/
/**
* @brief Initializes the NOR SFDP driver.
* @param Peripheral Pointer to peripheral.
* @param Config Configuration type.
* @param ClockInput Clock input value.
* @param SFDPObject Pointer to memory object.
* @retval EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef Status of the operation.
*/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Init(void *Peripheral, EXTMEM_LinkConfig_TypeDef Config,
uint32_t ClockInput,
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK;
SFDP_HeaderTypeDef JEDEC_SFDP_Header;
uint8_t FreqUpdate = 0u;
uint8_t DataID[6];
uint32_t ClockOut;
/* Reset data of SFDPObject to zero */
SFDP_DEBUG_STR("1 - reset data SFDPObject to zero")
(void)memset((void *)&SFDPObject->sfdp_private, 0x0, sizeof(SFDPObject->sfdp_private));
/* Initialize the SFDPObject */
SFDP_DEBUG_STR("2 - initialize the SFDPObject")
SFDPObject->sfdp_private.Config = Config;
SFDPObject->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_1S1S1S;
SFDPObject->sfdp_private.DriverInfo.ClockIn = ClockInput;
SAL_XSPI_SET_SFDPDUMMYCYLE(SFDPObject->sfdp_private.SALObject, EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_DEFAULT);
/* Set memory speed to 50Mhz maximum */
SFDP_DEBUG_STR("3 - set memory link and speed to 50Mhz maximum")
(void)SAL_XSPI_Init(&SFDPObject->sfdp_private.SALObject, Peripheral);
(void)SAL_XSPI_SetClock(&SFDPObject->sfdp_private.SALObject, ClockInput, DRIVER_SFDP_DEFAULT_CLOCK, &ClockOut);
/* Abort any ongoing XSPI action */
(void)SAL_XSPI_DisableMapMode(&SFDPObject->sfdp_private.SALObject);
/* Analyze the SFDP structure to get driver information */
SFDP_DEBUG_STR("4 - analyze the SFDP structure to get driver information")
if (EXTMEM_SFDP_OK != SFDP_GetHeader(SFDPObject, &JEDEC_SFDP_Header))
{
/* Perform SFDP Header reading (several modes are tried) */
SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP;
goto error;
}
/* Reset the memory */
SFDP_DEBUG_STR("5 - reset the memory")
if (EXTMEM_SFDP_OK != SFDP_MemoryReset(SFDPObject))
{
/* Memory Reset is considered unsuccessful.
Try to continue Initialisation procedure anyway. */
SFDP_DEBUG_STR("ERROR::on the call of SFDP_MemoryReset but no error returned")
}
/* Wait few ms after the reset operation, this is done to avoid issue on SFDP read */
HAL_Delay(10);
/* Analyze the SFDP structure to get driver information after the reset */
SFDP_DEBUG_STR("6 - analyze the SFDP structure to get driver information")
if (EXTMEM_SFDP_OK != SFDP_GetHeader(SFDPObject, &JEDEC_SFDP_Header))
{
/* SFDP header reading is considered unsuccessful.
Abort Initialisation procedure. */
SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP;
goto error;
}
/* Save information from the SFDP table
Nb of parameters starts at 0 (0 means 1 parameter) */
if (JEDEC_SFDP_Header.param_number >= SFDP_MAX_NB_OF_PARAM)
{
SFDPObject->sfdp_private.Sfdp_param_number = SFDP_MAX_NB_OF_PARAM - 1;
}
else
{
SFDPObject->sfdp_private.Sfdp_param_number = JEDEC_SFDP_Header.param_number;
}
SFDPObject->sfdp_private.Sfdp_AccessProtocol = JEDEC_SFDP_Header.AccessProtocol;
/* Read the flash ID.
This Flash ID could later be used to perform specific operations for some identified references. */
SFDP_DEBUG_STR("7 - read the flash ID")
(void)SAL_XSPI_GetId(&SFDPObject->sfdp_private.SALObject, DataID, EXTMEM_READ_JEDEC_ID_SIZE);
DEBUG_ID(DataID);
/* Keep manufacturer information, it could be used to help in
building of consistent driver */
SFDPObject->sfdp_private.ManuID = DataID[0];
/* Get the complete SFDP data */
SFDP_DEBUG_STR("8 - collect the SFDP data")
if (EXTMEM_SFDP_OK != SFDP_CollectData(SFDPObject))
{
SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP;
goto error;
}
/* Setup the generic driver information and prepare the physical layer */
SFDP_DEBUG_STR("9 - build the generic driver information and prepare the physical layer")
if (EXTMEM_SFDP_OK != SFDP_BuildGenericDriver(SFDPObject, &FreqUpdate))
{
SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_BUILD")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_BUILD;
goto error;
}
/* Adjust frequency supplied to memory, if required */
SFDP_DEBUG_STR("10 - adjust the frequency if required")
if ((FreqUpdate == 0u) && (SFDPObject->sfdp_public.MaxFreq != 0u))
{
(void)SAL_XSPI_SetClock(&SFDPObject->sfdp_private.SALObject, ClockInput,
SFDPObject->sfdp_public.MaxFreq, &ClockOut);
SFDP_DEBUG_STR("--> new freq configured");
}
/* Read again SFDP header to confirm memory access is properly setup */
SFDP_DEBUG_STR("11 - read again the SFDP header to adjust memory type if necessary")
if (EXTMEM_SFDP_OK != SFDP_ReadHeader(SFDPObject, &JEDEC_SFDP_Header))
{
SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_MEMTYPE_CHECK")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_MEMTYPE_CHECK;
goto error;
}
error:
return retr;
}
/**
* @brief This function un-initializes the NOR SFDP driver
*
* @param SFDPObject Memory object
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_DeInit(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject)
{
SFDPObject->sfdp_private.FlashSize = 0;
return EXTMEM_DRIVER_NOR_SFDP_OK;
}
/**
* @brief This function returns the flash memory information
*
* @param SFDPObject Memory object
* @param FlashInfo Pointer on flash info structure
**/
void EXTMEM_DRIVER_NOR_SFDP_GetFlashInfo(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
EXTMEM_NOR_SFDP_FlashInfoTypeDef *FlashInfo)
{
DEBUG_DRIVER((uint8_t *)__func__)
/* Format the info into structure */
FlashInfo->FlashSize = SFDPObject->sfdp_private.FlashSize;
FlashInfo->PageSize = SFDPObject->sfdp_private.PageSize;
FlashInfo->EraseType1Size = (SFDPObject->sfdp_private.DriverInfo.EraseType1Size == 0u) ? 0u :
((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType1Size);
FlashInfo->EraseType2Size = (SFDPObject->sfdp_private.DriverInfo.EraseType2Size == 0u) ? 0u :
((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType2Size);
FlashInfo->EraseType3Size = (SFDPObject->sfdp_private.DriverInfo.EraseType3Size == 0u) ? 0u :
((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType3Size);
FlashInfo->EraseType4Size = (SFDPObject->sfdp_private.DriverInfo.EraseType4Size == 0u) ? 0u :
((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType4Size);
}
/**
* @brief This function reads the memory
*
* @param SFDPObject Memory object
* @param Address Memory address
* @param Data Pointer on the data
* @param Size Data size to read (in bytes)
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Read(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
uint32_t Address, uint8_t *Data, uint32_t Size)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr;
DEBUG_DRIVER((uint8_t *)__func__)
/* Check busy flag */
retr = driver_check_FlagBUSY(SFDPObject, 5000);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Read::ERROR_CHECK_BUSY")
goto error;
}
/* Perform read access using SAL service */
if (HAL_OK != SAL_XSPI_Read(&SFDPObject->sfdp_private.SALObject, SFDPObject->sfdp_private.DriverInfo.ReadInstruction,
Address, Data, Size))
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Read::ERROR_READ")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_READ;
}
error :
return retr;
}
/**
* @brief This function writes data in the memory
*
* @param SFDPObject Memory object
* @param Address Memory address
* @param Data Pointer on the data
* @param Size Data size to write
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Write(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
uint32_t Address, const uint8_t *Data, uint32_t Size)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr;
uint32_t size_write;
uint32_t local_size = Size;
uint32_t local_Address = Address;
uint32_t local_Data = (uint32_t)Data;
uint32_t misalignment = 0u;
if (0u != (local_Address % SFDPObject->sfdp_private.PageSize))
{
misalignment = 1u;
}
DEBUG_DRIVER((uint8_t *)__func__)
while (local_size != 0u)
{
if (misalignment == 1u)
{
size_write = SFDPObject->sfdp_private.PageSize - (local_Address % SFDPObject->sfdp_private.PageSize);
size_write = MIN(local_size, size_write);
misalignment = 0u;
}
else
{
size_write = MIN(local_size, SFDPObject->sfdp_private.PageSize);
}
/* Check WIP flag */
retr = driver_check_FlagBUSY(SFDPObject, 5000u);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_CHECK_BUSY")
goto error;
}
/* Wait for WEL flag */
retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_CHECK_WEL")
goto error;
}
/* Write the data */
if (HAL_OK != SAL_XSPI_Write(&SFDPObject->sfdp_private.SALObject,
SFDPObject->sfdp_private.DriverInfo.PageProgramInstruction,
local_Address, (uint8_t *)local_Data, size_write))
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_WRITE")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITE;
goto error;
}
local_size = local_size - size_write;
local_Address = local_Address + size_write;
local_Data = local_Data + size_write;
}
/* Check busy flag */
retr = driver_check_FlagBUSY(SFDPObject, 5000);
#if EXTMEM_MACRO_DEBUG
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_CHECK_BUSY_ON_EXIT")
}
#endif /* EXTMEM_MACRO_DEBUG */
error:
return retr;
}
/**
* @brief This function writes data in the memory in mapped mode
*
* @param SFDPObject Memory object
* @param Address Memory address in mapped mode
* @param Data Pointer on the data
* @param Size Data size to write
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_WriteInMappedMode(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef
*SFDPObject, uint32_t Address,
const uint8_t *Data, uint32_t Size)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK;
uint32_t size_write;
uint32_t local_size = Size;
uint32_t local_Address = Address;
const uint8_t *local_Data = Data;
uint32_t size;
uint32_t misalignment = 0u;
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint8_t dcache_status = 1;
#endif /* __DCACHE_PRESENT */
DEBUG_DRIVER((uint8_t *)__func__)
/* Check if the input address is 32bit aligned */
if (0u != (local_Address % 4u))
{
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_ADDRESS_ALIGNMENT;
goto error;
}
if (0u != (local_Address % SFDPObject->sfdp_private.PageSize))
{
misalignment = 1u;
}
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
/* Check if DCache is already enabled */
if (SCB->CCR & SCB_CCR_DC_Msk)
{
dcache_status = 1;
}
else
{
dcache_status = 0;
/* Enable DCache */
SCB_EnableDCache();
}
#endif /* __DCACHE_PRESENT */
while (local_size != 0u)
{
if (misalignment == 1u)
{
size_write = SFDPObject->sfdp_private.PageSize - (local_Address % SFDPObject->sfdp_private.PageSize);
size_write = MIN(local_size, size_write);
misalignment = 0u;
}
else
{
if (local_size > SFDPObject->sfdp_private.PageSize)
{
size_write = SFDPObject->sfdp_private.PageSize;
}
else
{
size_write = local_size;
if (0u != (local_size % sizeof(uint32_t)))
{
size_write = size_write + sizeof(uint32_t) - (local_size % sizeof(uint32_t));
}
}
}
/* Wait for Write enable flag */
retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_write::ERROR_CHECK_WEL")
goto error;
}
/* Enter the mapped mode */
retr = EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode(SFDPObject);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
goto error;
}
size = size_write;
/* Execute the copy */
EXTMEM_MemCopy((uint32_t *)local_Address, local_Data, size_write);
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
/* Clean DCache starting from a 32 byte aligned address in 32 byte granularity */
SCB_CleanDCache_by_Addr((void *)(local_Address), size_write);
#endif /* __DCACHE_PRESENT */
/* Enter the mapped mode */
retr = EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode(SFDPObject);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
goto error;
}
/* Check busy flag */
retr = driver_check_FlagBUSY(SFDPObject, 5000);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_write::ERROR_CHECK_BUSY_ON_EXIT")
goto error;
}
/* Decrement the transfer size */
if (local_size > size)
{
local_size = local_size - size;
local_Data = &local_Data[size];
local_Address = local_Address + size;
}
else
{
local_size = 0;
}
}
error:
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
/* Disable DCache if deactivated previously */
if (!dcache_status)
{
SCB_DisableDCache();
}
#endif /* __DCACHE_PRESENT */
return retr;
}
/**
* @brief This function erases all the memory
*
* @param SFDPObject Memory object
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_MassErase(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr;
DEBUG_DRIVER((uint8_t *)__func__)
/* Check busy flag */
retr = driver_check_FlagBUSY(SFDPObject, 1000);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_read::ERROR_CHECK_BUSY")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_FLASHBUSY;
goto error;
}
/* Wait for write enable flag */
retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_read::ERROR_CHECK_WEL")
goto error;
}
/* Launch mass erase command */
(void)SAL_XSPI_CommandSendData(&SFDPObject->sfdp_private.SALObject, SFDP_DRIVER_ERASE_CHIP_COMMAND, NULL, 0);
/* Check busy flag : time to used should be set according the memory characteristic */
retr = driver_check_FlagBUSY(SFDPObject, SFDPObject->sfdp_private.DriverInfo.EraseChipTiming);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_MassErase::ERROR_CHECK_BUSY_ON_EXIT")
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_ERASE_TIMEOUT;
goto error;
}
error:
return retr;
}
/**
* @brief This function erases memory sector
*
* @param SFDPObject Memory object
* @param Address Memory address to start erase operation
* @param SectorType Type of sector
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_SectorErase(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef
*SFDPObject, uint32_t Address,
EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef
SectorType)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr;
uint8_t command;
uint8_t size;
uint32_t timeout;
DEBUG_DRIVER((uint8_t *)__func__)
/* Check if the selected sector type is available */
switch (SectorType)
{
case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1:
command = SFDPObject->sfdp_private.DriverInfo.EraseType1Command;
size = SFDPObject->sfdp_private.DriverInfo.EraseType1Size;
timeout = SFDPObject->sfdp_private.DriverInfo.EraseType1Timing;
break;
case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE2:
command = SFDPObject->sfdp_private.DriverInfo.EraseType2Command;
size = SFDPObject->sfdp_private.DriverInfo.EraseType2Size;
timeout = SFDPObject->sfdp_private.DriverInfo.EraseType2Timing;
break;
case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE3:
command = SFDPObject->sfdp_private.DriverInfo.EraseType3Command;
size = SFDPObject->sfdp_private.DriverInfo.EraseType3Size;
timeout = SFDPObject->sfdp_private.DriverInfo.EraseType3Timing;
break;
case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE4:
command = SFDPObject->sfdp_private.DriverInfo.EraseType4Command;
size = SFDPObject->sfdp_private.DriverInfo.EraseType4Size;
timeout = SFDPObject->sfdp_private.DriverInfo.EraseType4Timing;
break;
default :
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE;
goto error;
break;
}
/* Check if the command for this sector size is available */
if (0x0u == command)
{
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE_UNAVAILABLE;
goto error;
}
/* Check address alignment */
if (0x0u != (Address % ((uint32_t)1u << size)))
{
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_ADDRESS_ALIGNMENT;
goto error;
}
/* Check busy flag */
retr = driver_check_FlagBUSY(SFDPObject, 5000u);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
goto error;
}
/* Wait for write enable flag */
retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
goto error;
}
/* Launch erase command */
(void)SAL_XSPI_CommandSendAddress(&SFDPObject->sfdp_private.SALObject, command, Address);
/* Check busy flag */
/* Timeout is set according the memory characteristic */
retr = driver_check_FlagBUSY(SFDPObject, timeout);
if (EXTMEM_DRIVER_NOR_SFDP_OK != retr)
{
goto error;
}
error:
return retr;
}
/**
* @brief This function enables the memory mapped mode
*
* @param SFDPObject Memory object
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode(
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK;
/* Enter the mapped mode */
if (HAL_OK != SAL_XSPI_EnableMapMode(&SFDPObject->sfdp_private.SALObject,
SFDPObject->sfdp_private.DriverInfo.ReadInstruction,
(uint8_t)SFDPObject->sfdp_private.SALObject.Commandbase.DummyCycles,
SFDPObject->sfdp_private.DriverInfo.PageProgramInstruction, 0))
{
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_MAP_ENABLE;
}
return retr;
}
/**
* @brief This function disables the memory mapped mode
*
* @param SFDPObject Memory object
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode(
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK;
/* Exit the mapped mode */
if (HAL_OK != SAL_XSPI_DisableMapMode(&SFDPObject->sfdp_private.SALObject))
{
retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_MAP_ENABLE;
}
return retr;
}
/**
* @}
*/
/** @addtogroup DRIVER_SFDP_Internal_Functions DRIVER SFDP Internal Functions
* @{
*/
/**
* @}
*/
/** @addtogroup DRIVER_SFDP_Private_Functions DRIVER SFDP Private Functions
* @{
*/
/**
* @brief This function enables the WEL Flag and checks its activation
*
* @param SFDPObject Memory object
* @param timeout Timeout value
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef driver_set_FlagWEL(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
uint32_t Timeout)
{
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITEENABLE;
DEBUG_DRIVER((uint8_t *)__func__)
/* Send the command write enable */
(void)SAL_XSPI_CommandSendData(&SFDPObject->sfdp_private.SALObject,
SFDPObject->sfdp_private.DriverInfo.WriteWELCommand, NULL, 0);
/* Wait for write enable status */
if (0u != SFDPObject->sfdp_private.DriverInfo.ReadWELCommand)
{
/* Check if flag write enable is enabled */
if (HAL_OK == SAL_XSPI_CheckStatusRegister(&SFDPObject->sfdp_private.SALObject,
SFDPObject->sfdp_private.DriverInfo.ReadWELCommand,
SFDPObject->sfdp_private.DriverInfo.WELAddress,
((SFDPObject->sfdp_private.DriverInfo.WELBusyPolarity == 0u) ? 1u : 0u)
<< SFDPObject->sfdp_private.DriverInfo.WELPosition,
1u << SFDPObject->sfdp_private.DriverInfo.WELPosition,
SFDPObject->sfdp_private.ManuID, Timeout))
{
retr = EXTMEM_DRIVER_NOR_SFDP_OK;
}
}
return retr;
}
/**
* @brief This function provides a default implementation of MemCopy functionality
*
* @param Destination_Address Destination Address where data is to be copied
* @param ptrData Pointer on source data to be copied
* @param DataSize Size of data to be copied (in bytes)
* @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef
**/
__weak void EXTMEM_MemCopy(uint32_t *Destination_Address, const uint8_t *ptrData, uint32_t DataSize)
{
uint32_t *ptrDest = Destination_Address;
/* Write the data */
for (uint32_t index = 0u; index < DataSize; index = index + 4u)
{
*ptrDest = ((uint32_t)ptrData[index] | ((uint32_t)ptrData[index + 1u] << 8u) |
((uint32_t)ptrData[index + 2u] << 16u) | ((uint32_t)ptrData[index + 3u] << 24u));
ptrDest++;
}
}
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
@@ -0,0 +1,121 @@
/**
******************************************************************************
* @file stm32_sfdp_driver_api.h
* @author MCD Application Team
* @brief This file contains the sfdp driver definition.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_NOR_SFDP_DRIVER_API_H
#define __STM32_NOR_SFDP_DRIVER_API_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/** @addtogroup NOR_SFDP
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup DRIVER_SFDP_Exported_Types DRIVER SFDP Memory Exported Types
* @{
*/
/**
* @brief List of error codes for the SFDP driver.
*/
typedef enum
{
EXTMEM_DRIVER_NOR_SFDP_OK = 0,
EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP = -1,
EXTMEM_DRIVER_NOR_SFDP_ERROR_READ = -2,
EXTMEM_DRIVER_NOR_SFDP_ERROR_BUILD = -3,
EXTMEM_DRIVER_NOR_SFDP_ERROR_UNKNOWN_COMMAND = -4,
EXTMEM_DRIVER_NOR_SFDP_ERROR_BUSY = -5,
EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITEENABLE = -6,
EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITE = -7,
EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE = -8,
EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE_UNAVAILABLE = -9,
EXTMEM_DRIVER_NOR_SFDP_ERROR_ADDRESS_ALIGNMENT = -10,
EXTMEM_DRIVER_NOR_SFDP_ERROR_ERASE_TIMEOUT = -11,
EXTMEM_DRIVER_NOR_SFDP_ERROR_FLASHBUSY = -12,
EXTMEM_DRIVER_NOR_SFDP_ERROR_MAP_ENABLE = -13,
EXTMEM_DRIVER_NOR_SFDP_ERROR_MEMTYPE_CHECK = -14,
EXTMEM_DRIVER_NOR_SFDP_ERROR = -128,
} EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef;
/**
* @brief List of sector types for the SFDP driver.
*/
typedef enum
{
EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1,
EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE2,
EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE3,
EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE4
} EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef;
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/**
* @addtogroup DRIVER_SFDP_Exported_Functions DRIVER SFDP exported functions
* @{
*/
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Init(void *Peripheral, EXTMEM_LinkConfig_TypeDef Config,
uint32_t ClockInput,
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_DeInit(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject);
void EXTMEM_DRIVER_NOR_SFDP_GetFlashInfo(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
EXTMEM_NOR_SFDP_FlashInfoTypeDef *FlashInfo);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Read(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
uint32_t Address, uint8_t *Data, uint32_t Size);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Write(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject,
uint32_t Address, const uint8_t *Data, uint32_t Size);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_WriteInMappedMode(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef
*SFDPObject, uint32_t Address,
const uint8_t *Data, uint32_t Size);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_MassErase(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_SectorErase(
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef
*SFDPObject, uint32_t Address,
EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef SectorType);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode(
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject);
EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode(
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_NOR_SFDP_DRIVER_API_H */
@@ -0,0 +1,156 @@
/**
******************************************************************************
* @file stm32_sfdp_driver_type.h
* @author MCD Application Team
* @brief This file contains the sfdp driver definition.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SFDP_DRIVER_TYPE_H
#define __STM32_SFDP_DRIVER_TYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/** @addtogroup NOR_SFDP
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Exported constants --------------------------------------------------------*/
/**
* @brief Instruction ID for common JEDEC commands
*/
#define SFDP_DRIVER_READ_COMMAND 0x03U
#define SFDP_DRIVER_PAGE_PROGRAM_COMMAND 0x02U
#define SFDP_DRIVER_READ_STATUS_REGISTER_COMMAND 0x05U
#define SFDP_DRIVER_WRITE_ENABLE_50H_COMMAND 0x50U
#define SFDP_DRIVER_WRITE_ENABLE_06H_COMMAND 0x06U
#define SFDP_DRIVER_ERASE_CHIP_COMMAND 0x60U
/* Exported types ------------------------------------------------------------*/
/** @defgroup DRIVER_SFDP_Exported_Types DRIVER SFDP Memory Exported Types
* @{
*/
/**
* @brief driver data used to manage the flash
*/
typedef struct
{
SAL_XSPI_PhysicalLinkTypeDef SpiPhyLink; /*!< Physical link information */
uint32_t ClockIn; /*!< Input Clock */
/* Table of instructions (an instruction equal to zero means not supported) */
/* WIP : write in progress */
uint8_t ReadWIPCommand; /*!< Read write in progress command */
uint8_t WIPPosition; /*!< Write in progress byte position */
uint8_t WIPBusyPolarity; /*!< 0: Positive (WIP=1 means write is in progress)
1: Inverted (WIP=0 means write is in progress) */
uint8_t WIPAddress; /*!< Read write in progress address */
/* WEL: write enable */
uint8_t WriteWELCommand; /*!< Write enable command */
/* WEL : read write enable */
uint8_t ReadWELCommand; /*!< Read write enable status command */
uint8_t WELPosition; /*!< Write enable position */
uint8_t WELBusyPolarity; /*!< 0: Positive (WEL=1 means write is enabled)
1: Inverted (WEL=0 means write is enabled) */
uint8_t WELAddress; /*!< write enable address */
/* Page Program */
uint8_t PageProgramInstruction; /*!< Page program command */
/* Read management */
uint8_t ReadInstruction; /*!< Read command */
/* Erase management */
uint8_t EraseType1Size; /*!< Erase 1 size */
uint8_t EraseType1Command; /*!< Erase 1 command */
uint8_t EraseType2Size; /*!< Erase 2 size */
uint8_t EraseType2Command; /*!< Erase 2 command */
uint8_t EraseType3Size; /*!< Erase 3 size */
uint8_t EraseType3Command; /*!< Erase 3 command */
uint8_t EraseType4Size; /*!< Erase 4 size */
uint8_t EraseType4Command; /*!< Erase 4 command */
uint32_t EraseType1Timing; /*!< Erase 1 timing */
uint32_t EraseType2Timing; /*!< Erase 2 timing */
uint32_t EraseType3Timing; /*!< Erase 3 timing */
uint32_t EraseType4Timing; /*!< Erase 4 timing */
uint32_t EraseChipTiming; /*!< Erase chip timing */
} EXTMEM_DRIVER_NOR_SFDP_InfoTypeDef;
/**
* @brief driver SFDP Object definition
*/
typedef struct
{
struct
{
uint32_t MaxFreq; /*!< Maximum frequency supported by the memory.
@note If the value is zero, the parameter is ignored. */
uint8_t DtrReadDummyCycle; /*!< Number of dummy cycles for DTR read command.
@note Used only for JEDEC basic with DTR option. */
} sfdp_public;
struct
{
SAL_XSPI_ObjectTypeDef SALObject; /*!< Instance of the memory */
EXTMEM_LinkConfig_TypeDef Config; /*!< Memory configuration */
uint8_t ManuID; /*!< Manufacturer ID */
uint8_t FlashSize; /*!< Flash size as a power of two */
uint32_t PageSize; /*!< Page size */
EXTMEM_DRIVER_NOR_SFDP_InfoTypeDef DriverInfo; /*!< Driver information */
uint32_t Sfdp_table_mask; /*!< Sfdp table mask */
uint32_t Reset_info; /*!< Copy of JEDEC Basic 16 Reset/Rescue info */
uint8_t Sfdp_param_number; /*!< Number of parameters from the SFDP header table */
uint8_t Sfdp_AccessProtocol; /*!< Access protocol type from the SFDP header table */
} sfdp_private;
} EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef;
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/**
* @addtogroup DRIVER_SFDP_Exported_Functions DRIVER SFDP exported functions
* @{
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SFDP_DRIVER_TYPE_H */
@@ -0,0 +1,283 @@
/**
******************************************************************************
* @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 */
@@ -0,0 +1,87 @@
/**
******************************************************************************
* @file stm32_psram_driver_api.h
* @author MCD Application Team
* @brief This file contains PSRAM driver API definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_PSRAM_DRIVER_H
#define __STM32_PSRAM_DRIVER_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#if EXTMEM_DRIVER_PSRAM == 1
/** @addtogroup PSRAM
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup PSRAM_Exported_Types Exported Types
* @{
*/
/**
* @brief Enumeration of error codes for the PSRAM driver.
*/
typedef enum
{
EXTMEM_DRIVER_PSRAM_OK = 0,
EXTMEM_DRIVER_PSRAM_ERROR_READREG = -1,
EXTMEM_DRIVER_PSRAM_ERROR_WRITEREG = -2,
EXTEM_DRIVER_PSRAM_ERROR_READ = -3,
EXTEM_DRIVER_PSRAM_ERROR_WRITE = -4,
EXTMEM_DRIVER_PSRAM_ERROR_MAP_ENABLE = -5,
EXTMEM_DRIVER_PSRAM_ERROR_MAP_DISABLE = -6,
EXTMEM_DRIVER_PSRAM_ERROR_REGSIZE = -7,
EXTMEM_DRIVER_PSRAM_ERROR = -128,
} EXTMEM_DRIVER_PSRAM_StatusTypeDef;
/* Exported functions --------------------------------------------------------*/
/**
* @addtogroup PSRAM_Exported_Functions Exported Functions
* @{
*/
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 EXTMEM_DRIVER_PSRAM_DeInit(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject);
EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Enable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef
*PsramObject);
EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Disable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef
*PsramObject);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#ifdef __cplusplus
}
#endif
#endif /* __STM32_PSRAM_DRIVER_H */
@@ -0,0 +1,106 @@
/**
******************************************************************************
* @file stm32_psram_driver_type.h
* @author MCD Application Team
* @brief This file contains PSRAM driver type definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_PSRAM_TYPE_H
#define __STM32_PSRAM_TYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/** @addtogroup PSRAM
* @ingroup EXTMEM_DRIVER
* @{
*/
#if EXTMEM_DRIVER_PSRAM == 1
/* Exported constants --------------------------------------------------------*/
/** @defgroup PSRAM_Exported_constants Exported constants
* @{
*/
/**
* @brief PSRAM driver maximum number of commands
*/
#define PSRAM_MAX_COMMAND 3u
/**
* @}
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup PSRAM_Exported_Types Exported Types
* @{
*/
/**
* @brief PSRAM driver object definition
*/
typedef struct
{
struct
{
SAL_XSPI_ObjectTypeDef SALObject; /*!< SAL XSPI object. */
} psram_private; /*!< Private data for the PSRAM driver object. */
struct
{
uint32_t MemorySize; /*!< Memory size (see @ref XSPI_MemorySize). */
uint32_t FreqMax; /*!< Maximum supported memory frequency. */
/* Configuration */
uint8_t NumberOfConfig; /*!< Number of configuration steps; each step performs a read and write operation. */
struct
{
uint8_t WriteMask; /*!< Mask for write operation. */
uint8_t WriteValue; /*!< Value to write. */
uint8_t REGAddress; /*!< Address of the register. */
} config[PSRAM_MAX_COMMAND];
/* Command REG */
uint8_t ReadREG;
uint8_t WriteREG;
uint8_t ReadREGSize;
uint8_t REG_DummyCycle;
/* Command Read and Write */
uint8_t Write_command;
uint8_t Write_DummyCycle;
uint8_t Read_command;
uint8_t WrapRead_command;
uint8_t Read_DummyCycle;
} psram_public; /*!< Public data for the PSRAM driver object. */
} EXTMEM_DRIVER_PSRAM_ObjectTypeDef;
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#ifdef __cplusplus
}
#endif
#endif /* __STM32_PSRAM_TYPE_H */
@@ -0,0 +1,236 @@
/**
******************************************************************************
* @file stm32_sal_sd.c
* @author MCD Application Team
* @brief This file implements the software adaptation layer for SD.
******************************************************************************
* @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_SAL_SD_DEBUG_LEVEL != 0 && defined(EXTMEM_MACRO_DEBUG)
#include <stdio.h>
#endif /* EXTMEM_SAL_SD_DEBUG_LEVEL != 0 && EXTMEM_MACRO_DEBUG */
#if EXTMEM_SAL_SD == 1
#include "stm32_sal_sd_type.h"
#include "stm32_sal_sd_api.h"
/** @defgroup SAL_SD SAL_SD : Software adaptation layer for the HAL_SD
* @ingroup EXTMEM_SAL
* @{
*/
/**
* @brief Ready timeout value
*/
#define READY_TIMEOUT 1000u
/* Private Macros ------------------------------------------------------------*/
/** @defgroup SAL_SD_Private_Macros SAL SD Private Macros
* @{
*/
#if EXTMEM_SAL_SD_DEBUG_LEVEL == 0 || !defined(EXTMEM_MACRO_DEBUG)
#define DEBUG_PARAM_BEGIN()
#define DEBUG_PARAM_DATA(_STR_)
#define DEBUG_PARAM_INT(_INT_ )
#define DEBUG_PARAM_END()
#else
/**
* @brief Trace header macro.
*/
#define DEBUG_PARAM_BEGIN() EXTMEM_MACRO_DEBUG("\t\tSALSD::");
/**
* @brief Trace data string macro.
*/
#define DEBUG_PARAM_DATA(_STR_) EXTMEM_MACRO_DEBUG(_STR_);
/**
* @brief Trace data integer macro
*/
#define DEBUG_PARAM_INT(_INT_ ) { \
char str[10]; \
(void)snprintf(str, sizeof(str), "0x%x", _INT_);\
EXTMEM_MACRO_DEBUG(str); \
}
/**
* @brief Trace close macro
*/
#define DEBUG_PARAM_END() EXTMEM_MACRO_DEBUG("\n");
#endif /* EXTMEM_SFDP_DEBUG */
/**
* @}
*/
/* Private typedefs ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup SAL_SD_Private_Functions SAL XSP Private Functions
* @{
*/
/**
* @}
*/
/* Exported variables ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/** @defgroup SAL_SD_Exported_Functions SAL XSP Exported Functions
* @{
*/
/**
* @brief This function initializes the SD SAL context
* @param SalSD SAL SD Object
* @param HALHandle HAL handle
* @param Info Information on the SD card
* @return @ref HAL_StatusTypeDef
**/
HAL_StatusTypeDef SAL_SD_Init(SAL_SD_ObjectTypeDef *SalSD, void *HALHandle, EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info)
{
SalSD->hSD = (SD_HandleTypeDef *)HALHandle;
Info->BlockNbr = SalSD->hSD->SdCard.BlockNbr;
Info->BlockSize = SalSD->hSD->SdCard.BlockSize;
/* Switch to the highest Speed mode supported by the sd-card */
return HAL_SD_ConfigSpeedBusOperation(SalSD->hSD, SDMMC_SPEED_MODE_AUTO);
}
/**
* @brief This function un-initializes the SD SAL context
* @param SalSD SAL SD Object
* @return @ref HAL_StatusTypeDef
**/
HAL_StatusTypeDef SAL_SD_DeInit(SAL_SD_ObjectTypeDef *SalSD)
{
SalSD->hSD->SdCard.BlockNbr = 0;
return HAL_OK;
}
/**
* @brief This function reads data from the SD
* @param SalSD SAL SD Object
* @param BlockIdx Block index
* @param Data Data pointer
* @param NumberOfBlock Number of block
* @return @ref HAL_StatusTypeDef
**/
HAL_StatusTypeDef SAL_SD_ReadData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint8_t *Data, uint32_t NumberOfBlock)
{
uint32_t timeout = 100UL * NumberOfBlock;
HAL_StatusTypeDef retr = HAL_SD_ReadBlocks(SalSD->hSD, (uint8_t *)Data, BlockIdx, NumberOfBlock, timeout);
if (HAL_OK == retr)
{
timeout = HAL_GetTick();
/* Check the SD status */
while (HAL_SD_GetCardState(SalSD->hSD) != HAL_SD_CARD_TRANSFER)
{
if ((HAL_GetTick() - timeout) > READY_TIMEOUT)
{
retr = HAL_TIMEOUT;
break;
}
}
}
return retr;
}
/**
* @brief This function writes data on the SD
* @param SalSD SAL SD Object
* @param BlockIdx block index
* @param Data data pointer
* @param NumberOfBlock number of block
* @return @ref HAL_StatusTypeDef
**/
HAL_StatusTypeDef SAL_SD_WriteData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, const uint8_t *const Data,
uint32_t NumberOfBlock)
{
uint32_t timeout = 100UL * NumberOfBlock;
HAL_StatusTypeDef retr;
retr = HAL_SD_WriteBlocks(SalSD->hSD, Data, BlockIdx, NumberOfBlock, timeout);
if (HAL_OK == retr)
{
timeout = HAL_GetTick();
/* Check the SD status */
while (HAL_SD_GetCardState(SalSD->hSD) != HAL_SD_CARD_TRANSFER)
{
if ((HAL_GetTick() - timeout) > READY_TIMEOUT)
{
retr = HAL_TIMEOUT;
break;
}
}
}
return retr;
}
/**
* @brief This function erases an amount of blocks on the SD
* @param SalSD SAL SD Object
* @param BlockIdx block index
* @param BlockCount number of block
* @return @ref HAL_StatusTypeDef
**/
HAL_StatusTypeDef SAL_SD_EraseBlock(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint32_t BlockCount)
{
uint32_t timeout;
HAL_StatusTypeDef retr;
retr = HAL_SD_Erase(SalSD->hSD, BlockIdx, BlockIdx + BlockCount);
if (HAL_OK == retr)
{
timeout = HAL_GetTick();
/* Check the SD status */
while (HAL_SD_GetCardState(SalSD->hSD) != HAL_SD_CARD_TRANSFER)
{
if ((HAL_GetTick() - timeout) > (READY_TIMEOUT * BlockCount))
{
retr = HAL_TIMEOUT;
break;
}
}
}
return retr;
}
/**
* @brief This function erases all the SD
* @param SalSD SAL SD Object
* @return @ref HAL_StatusTypeDef
**/
HAL_StatusTypeDef SAL_SD_MassErase(SAL_SD_ObjectTypeDef *SalSD)
{
return SAL_SD_EraseBlock(SalSD, 0, SalSD->hSD->SdCard.BlockNbr);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_SAL_SD == 1 */
@@ -0,0 +1,77 @@
/**
******************************************************************************
* @file stm32_sal_sd_api.h
* @author MCD Application Team
* @brief This file contains SAL SD function prototypes.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SAL_SD_API_H
#define __STM32_SAL_SD_API_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup SAL_SD
* @ingroup EXTMEM_SAL
* @{
*/
/** @defgroup SAL_SD
* @{
*/
/* Includes ------------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup SAL_SD_Exported_types SAL SD exported types
* @{
*/
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup SAL_SD_Exported_Functions SAL SD Exported Functions
* @{
*/
HAL_StatusTypeDef SAL_SD_Init(SAL_SD_ObjectTypeDef *SalSD, void *HALHandle, EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info);
HAL_StatusTypeDef SAL_SD_DeInit(SAL_SD_ObjectTypeDef *SalSD);
HAL_StatusTypeDef SAL_SD_ReadData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint8_t *Data,
uint32_t NumberOfBlock);
HAL_StatusTypeDef SAL_SD_WriteData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, const uint8_t *const Data,
uint32_t NumberOfBlock);
HAL_StatusTypeDef SAL_SD_EraseBlock(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint32_t BlockCount);
HAL_StatusTypeDef SAL_SD_MassErase(SAL_SD_ObjectTypeDef *SalSD);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SAL_SD_API_H */
@@ -0,0 +1,74 @@
/**
******************************************************************************
* @file stm32_sal_sd_type.h
* @author MCD Application Team
* @brief This file contains SAL SD type definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SAL_SD_TYPE_H
#define __STM32_SAL_SD_TYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup SAL_SD
* @ingroup EXTMEM_SAL
* @{
*/
/** @defgroup SAL_SD
* @{
*/
/* Includes ------------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup SAL_SD_Exported_types SAL SD exported types
* @{
*/
typedef struct
{
SD_HandleTypeDef *hSD; /*!< Pointer to the SD instance handle. */
} SAL_SD_ObjectTypeDef;
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup SAL_SD_Exported_Functions SAL XSP Exported Functions
* @{
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SAL_SD_TYPE_H */
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,100 @@
/**
******************************************************************************
* @file stm32_sal_xspi_api.h
* @author MCD Application Team
* @brief This file contains SAL XSPI function prototypes.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SAL_XSPI_API_H
#define __STM32_SAL_XSPI_API_H
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup SAL_XSPI
* @ingroup EXTMEM_SAL
* @{
*/
/* Includes ------------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup SAL_XSPI_Exported_types SAL XSPI exported types
* @{
*/
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup SAL_XSPI_Exported_Functions SAL XSPI Exported Functions
* @{
*/
HAL_StatusTypeDef SAL_XSPI_SetClock(SAL_XSPI_ObjectTypeDef *SalXspi, uint32_t ClockIn, uint32_t ClockRequested,
uint32_t *ClockReal);
HAL_StatusTypeDef SAL_XSPI_Init(SAL_XSPI_ObjectTypeDef *SalXspi, void *HALHandle);
HAL_StatusTypeDef SAL_XSPI_MemoryConfig(SAL_XSPI_ObjectTypeDef *SalXspi, SAL_XSPI_MemParamTypeTypeDef ParametersType,
void *ParamVal);
HAL_StatusTypeDef SAL_XSPI_GetSFDP(SAL_XSPI_ObjectTypeDef *SalXspi, uint32_t Address,
uint8_t *Data, uint32_t DataSize);
HAL_StatusTypeDef SAL_XSPI_GetId(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t *Data, uint32_t DataSize);
HAL_StatusTypeDef SAL_XSPI_Read(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address, uint8_t *Data,
uint32_t DataSize);
HAL_StatusTypeDef SAL_XSPI_Write(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address,
const uint8_t *Data, uint32_t DataSize);
HAL_StatusTypeDef SAL_XSPI_CommandSendAddress(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address);
HAL_StatusTypeDef SAL_XSPI_CommandSendData(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command,
uint8_t *Data, uint16_t DataSize);
HAL_StatusTypeDef SAL_XSPI_SendReadCommand(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command,
uint8_t *Data, uint16_t DataSize);
HAL_StatusTypeDef SAL_XSPI_CommandSendReadAddress(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command,
uint32_t Address, uint8_t *Data, uint16_t DataSize,
uint8_t ManuId);
HAL_StatusTypeDef SAL_XSPI_CheckStatusRegister(SAL_XSPI_ObjectTypeDef *SalXspi,
uint8_t Command, uint32_t Address, uint8_t MatchValue, uint8_t MatchMask,
uint8_t ManuId, uint32_t Timeout);
HAL_StatusTypeDef SAL_XSPI_ConfigureWrappMode(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t WrapCommand, uint8_t WrapDummy);
HAL_StatusTypeDef SAL_XSPI_EnableMapMode(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t CommandRead, uint8_t DummyRead,
uint8_t CommandWrite, uint8_t DummyWrite);
HAL_StatusTypeDef SAL_XSPI_DisableMapMode(SAL_XSPI_ObjectTypeDef *SalXspi);
HAL_StatusTypeDef SAL_XSPI_UpdateMemoryType(SAL_XSPI_ObjectTypeDef *SalXspi, SAL_XSPI_DataOrderTypeDef DataOrder);
/**
* @brief This function aborts the transaction
* @param SalXspi SAL XSPI handle
* @return @ref HAL_StatusTypeDef
**/
HAL_StatusTypeDef SAL_XSPI_Abort(SAL_XSPI_ObjectTypeDef *SalXspi);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SAL_XSPI_API_H */
@@ -0,0 +1,130 @@
/**
******************************************************************************
* @file stm32_sal_xspi_type.h
* @author MCD Application Team
* @brief This file contains SAL XSPI type definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SAL_XSPI_TYPE_H
#define __STM32_SAL_XSPI_TYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup SAL_XSPI
* @ingroup EXTMEM_SAL
* @{
*/
/* Includes ------------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup SAL_XSPI_Exported_types SAL XSPI exported types
* @{
*/
/**
* @brief Data order information.
*/
typedef enum
{
SAL_XSPI_ORDERINVERTED = 0,
} SAL_XSPI_DataOrderTypeDef;
/**
* @brief Enumeration of supported physical link configurations.
*/
typedef enum
{
PHY_LINK_1S1S1S, /*!< Physical link configure in 1S1S1S */
PHY_LINK_1S1S2S, /*!< Physical link configure in 1S1S2S */
PHY_LINK_1S2S2S, /*!< Physical link configure in 1S2S2S */
PHY_LINK_1S1D1D, /*!< Physical link configure in 1S1D1D */
PHY_LINK_4S4S4S, /*!< Physical link configure in 4S4S4S */
PHY_LINK_4S4D4D, /*!< Physical link configure in 4S4D4D */
PHY_LINK_4D4D4D, /*!< Physical link configure in 4D4D4D */
PHY_LINK_1S8S8S, /*!< Physical link configure in 1S8S8S */
PHY_LINK_8S8D8D, /*!< Physical link configure in 8S8D8D */
PHY_LINK_8D8D8D, /*!< Physical link configure in 8D8D8D */
PHY_LINK_RAM8, /*!< Physical link configure for RAM 8lines of data */
#if defined(HAL_XSPI_DATA_16_LINES)
PHY_LINK_RAM16, /*!< Physical link configure for RAM 16lines of data */
#endif /* defined(HAL_XSPI_DATA_16_LINES) */
} SAL_XSPI_PhysicalLinkTypeDef;
typedef struct
{
XSPI_HandleTypeDef *hxspi; /*!< Handle on the XSPI instance */
XSPI_RegularCmdTypeDef Commandbase; /*!< Command base configuration */
uint8_t CommandExtension; /*!< Flag on the 16-bit command extension 0 inverted 1 the same */
uint8_t SFDPDummyCycle; /*!< SDPF dummy cycle */
SAL_XSPI_PhysicalLinkTypeDef PhyLink; /*!< Only used for data Read in 4S4D4d 2S2D2D 1S1D1D */
uint8_t DTRDummyCycle; /*!< Specify that DTR read only valid for data read using DTRDummyCycle value */
} SAL_XSPI_ObjectTypeDef;
/**
* @brief define the list of the parameter
*/
typedef enum
{
PARAM_PHY_LINK, /*!< Physical link parameter */
PARAM_DUMMY_CYCLES, /*!< Dummy cycle parameter */
PARAM_ADDRESS_4BYTES, /*!< Address size parameter */
PARAM_DATA_STROBE, /*!< Data strobe parameter */
PARAM_FLASHSIZE, /*!< Flash size parameter */
} SAL_XSPI_MemParamTypeTypeDef;
/**
* @}
*/
/* Exported Macro ------------------------------------------------------------*/
#define SAL_XSPI_SET_DTRREADDUMMYCYLE(_OBJ_,_VAL_) (_OBJ_).DTRDummyCycle = (_VAL_)
#define SAL_XSPI_SET_SFDPDUMMYCYLE(_OBJ_,_VAL_) (_OBJ_).SFDPDummyCycle = (_VAL_)
#define SAL_XSPI_SET_COMMANDEXTENSION(_OBJ_,_VAL_) (_OBJ_).CommandExtension = (_VAL_)
#define SAL_XSPI_FORMAT_COMMANDSEND(_PTR_, _CMD_) \
_PTR_.CommandType = SAL_XSPI_COMMAND_SEND; \
_PTR_.Command = _CMD_;
/* Exported functions --------------------------------------------------------*/
/** @defgroup SAL_XSPI_Exported_Functions SAL XSP Exported Functions
* @{
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SAL_XSPI_TYPE_H */
@@ -0,0 +1,354 @@
/**
******************************************************************************
* @file stm32_sdcard_driver.c
* @author MCD Application Team
* @brief This file implements the SDCARD 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_SDCARD == 1
#if EXTMEM_SAL_SD == 1
#include "../sal/stm32_sal_sd_api.h"
#endif /* EXTMEM_SAL_SD */
#if EXTMEM_SAL_MMC == 1
#include "../sal/stm32_sal_mmc_api.h"
#endif /* EXTMEM_SAL_MMC */
#include "stm32_sdcard_driver_api.h"
#if EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG)
#include "string.h"
#include "stdio.h"
#endif /* EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 || defined(EXTMEM_MACRO_DEBUG) */
/** @defgroup SDCARD SDCARD driver
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Private Macros ------------------------------------------------------------*/
/** @defgroup SDCARD_Private_Macro Private Macro
* @{
*/
/**
* @brief Default Timeout value (ms)
*/
#define DRIVER_DEFAULT_TIMEOUT 300
/**
* @brief Debug macro for a string.
*/
#if EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG)
#define SDCARD_DEBUG_STR(_STR_) { \
EXTMEM_MACRO_DEBUG("\tSDCARD::"); \
EXTMEM_MACRO_DEBUG(_STR_); \
EXTMEM_MACRO_DEBUG("\n\r"); \
}
#else
#define SDCARD_DEBUG_STR(_STR_)
#endif /* EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 || defined(EXTMEM_MACRO_DEBUG) */
/**
* @}
*/
/* Private typedefs ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup SDCARD_Exported_Functions Exported Functions
* @{
*/
/**
* @brief Initializes the SDCARD driver.
* @param Peripheral Pointer to the peripheral object.
* @param SDCARDObject Pointer to the SDCARD driver object.
* @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Init(void *Peripheral,
EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject)
{
EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK;
/* initialize the instance */
SDCARD_DEBUG_STR("initialize the instance")
switch (SDCARDObject->sdcard_public.Link)
{
case EXTMEM_DRIVER_SDCARD_LINKSD :
if (HAL_OK != SAL_SD_Init(&SDCARDObject->sdcard_private.SALObject.SDObject, Peripheral,
&SDCARDObject->sdcard_private.Info))
{
retr = EXTMEM_DRIVER_SDCARD_ERROR;
}
break;
#if EXTMEM_SAL_MMC == 1
case EXTMEM_DRIVER_SDCARD_LINKMMC:
if (HAL_OK != SAL_MMC_Init(&SDCARDObject->SALObject.MMCObject, Peripheral))
{
retr = EXTMEM_DRIVER_SDCARD_ERROR;
}
break;
#endif /* EXTMEM_SAL_MMC == 1 */
default :
retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE;
break;
}
return retr;
}
/**
* @brief Deinitializes the SDCARD driver.
* @param SDCARDObject Pointer to the SDCARD driver object.
* @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_DeInit(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject)
{
EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK;
SDCARDObject->sdcard_private.Info.BlockNbr = 0;
return retr;
}
/**
* @brief Reads data from the SDCARD memory.
* @param SDCARDObject Pointer to the SDCARD driver object.
* @param Address Memory address.
* @param Data Pointer to the data buffer to store the read data.
* @param Size Size of data to read (in bytes).
* @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Read(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
uint32_t Address, uint8_t *Data, uint32_t Size)
{
EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK;
HAL_StatusTypeDef hal_status = HAL_OK;
uint32_t block_size = SDCARDObject->sdcard_private.Info.BlockSize;
if (block_size == 0u)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR;
}
else
{
uint32_t block_num = Address / block_size;
uint32_t block_count = Size / block_size;
/* Check if Address and size are multiple of block size */
if (((Address % block_size) != 0u) || ((Size % block_size) != 0u))
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM;
goto error;
}
if (block_count > SDCARDObject->sdcard_private.Info.BlockNbr)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM;
goto error;
}
switch (SDCARDObject->sdcard_public.Link)
{
case EXTMEM_DRIVER_SDCARD_LINKSD :
hal_status = SAL_SD_ReadData(&SDCARDObject->sdcard_private.SALObject.SDObject, block_num, Data, block_count);
break;
#if EXTMEM_SAL_MMC == 1
case EXTMEM_DRIVER_SDCARD_LINKMMC:
hal_status = SAL_MMC_Read(&SDCARDObject->sdcard_private.SALObject.MMCObject, block_num, Data, block_count);
break;
#endif /* EXTMEM_SAL_MMC == 1 */
default :
retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE;
break;
}
if (HAL_OK != hal_status)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_READ;
}
}
error:
return retr;
}
/**
* @brief Writes data to the SDCARD memory.
* @param SDCARDObject Pointer to the SDCARD driver object.
* @param Address Memory address.
* @param Data Pointer to the data buffer to be written.
* @param Size Size of data to be written (in bytes).
* @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Write(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
uint32_t Address, const uint8_t *Data, uint32_t Size)
{
EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK;
HAL_StatusTypeDef hal_status = HAL_OK;
uint32_t block_size = SDCARDObject->sdcard_private.Info.BlockSize;
if (block_size == 0u)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR;
}
else
{
uint32_t block_num = Address / block_size;
uint32_t block_count = Size / block_size;
/* Check if Address and size are multiple of block size */
if (((Address % block_size) != 0u) || ((Size % block_size) != 0u))
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM;
goto error;
}
if (block_count > SDCARDObject->sdcard_private.Info.BlockNbr)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM;
goto error;
}
switch (SDCARDObject->sdcard_public.Link)
{
case EXTMEM_DRIVER_SDCARD_LINKSD :
hal_status = SAL_SD_WriteData(&SDCARDObject->sdcard_private.SALObject.SDObject, block_num, Data, block_count);
break;
case EXTMEM_DRIVER_SDCARD_LINKMMC:
default :
retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE;
break;
}
if (HAL_OK != hal_status)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_WRITE;
}
}
error:
return retr;
}
/**
* @brief Erases blocks in the SDCARD memory.
* @param SDCARDObject Pointer to the SDCARD driver object.
* @param Address Memory address.
* @param Size Size of data to erase (in bytes).
* @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_EraseBlock(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
uint32_t Address, uint32_t Size)
{
EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK;
HAL_StatusTypeDef hal_status = HAL_OK;
uint32_t block_size = SDCARDObject->sdcard_private.Info.BlockSize;
if (block_size == 0u)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR;
}
else
{
uint32_t block_num = Address / block_size;
uint32_t block_count = Size / block_size;
if ((Size % block_size) != 0u)
{
block_count = block_count + 1u;
}
/* Check if Address is multiple of block size */
if ((Address % block_size) != 0u)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM;
goto error;
}
if (block_count > SDCARDObject->sdcard_private.Info.BlockNbr)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM;
goto error;
}
switch (SDCARDObject->sdcard_public.Link)
{
case EXTMEM_DRIVER_SDCARD_LINKSD :
hal_status = SAL_SD_EraseBlock(&SDCARDObject->sdcard_private.SALObject.SDObject, block_num, block_count);
break;
case EXTMEM_DRIVER_SDCARD_LINKMMC:
default :
retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE;
break;
}
if (HAL_OK != hal_status)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR;
}
}
error:
return retr;
}
/**
* @brief Performs a mass erase of the SDCARD memory.
* @param SDCARDObject Pointer to the SDCARD driver object.
* @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Erase(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject)
{
EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK;
HAL_StatusTypeDef hal_status = HAL_OK;
switch (SDCARDObject->sdcard_public.Link)
{
case EXTMEM_DRIVER_SDCARD_LINKSD :
hal_status = SAL_SD_MassErase(&SDCARDObject->sdcard_private.SALObject.SDObject);
break;
case EXTMEM_DRIVER_SDCARD_LINKMMC:
default :
retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE;
break;
}
if (HAL_OK != hal_status)
{
retr = EXTMEM_DRIVER_SDCARD_ERROR;
}
return retr;
}
/**
* @brief Retrieves SDCARD information.
* @param SDCARDObject Pointer to the SDCARD driver object.
* @param Info Pointer to the SDCARD information structure to be filled.
* @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_GetInfo(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info)
{
Info->BlockSize = SDCARDObject->sdcard_private.Info.BlockSize;
Info->BlockNbr = SDCARDObject->sdcard_private.Info.BlockNbr;
return EXTMEM_DRIVER_SDCARD_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
@@ -0,0 +1,91 @@
/**
******************************************************************************
* @file stm32_sdcard_driver_api.h
* @author MCD Application Team
* @brief This file contains SDCARD driver API definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SDCARD_DRIVER_API_H
#define __STM32_SDCARD_DRIVER_API_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#if EXTMEM_DRIVER_SDCARD == 1
/** @addtogroup SDCARD
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @addtogroup SDCARD_Exported_Types
* @{
*/
/**
* @brief Enumeration of error codes for the SDCARD driver.
*/
typedef enum
{
EXTMEM_DRIVER_SDCARD_OK = 0, /*!< status ok */
EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE = -1, /*!< error on the link type */
EXTMEM_DRIVER_SDCARD_ERROR_READ = -2, /*!< error on the read operation */
EXTMEM_DRIVER_SDCARD_ERROR_WRITE = -3, /*!< error on the write operation */
EXTMEM_DRIVER_SDCARD_ERROR_PARAM = -4, /*!< error on the parameter */
EXTMEM_DRIVER_SDCARD_ERROR = -128, /*!< error */
} EXTMEM_DRIVER_SDCARD_StatusTypeDef;
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/**
* @addtogroup SDCARD_Exported_Functions Exported Functions
* @{
*/
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Init(void *Peripheral,
EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject);
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_DeInit(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject);
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Read(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
uint32_t Address, uint8_t *Data, uint32_t Size);
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Write(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
uint32_t Address, const uint8_t *Data, uint32_t Size);
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_EraseBlock(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
uint32_t Address, uint32_t Size);
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Erase(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject);
EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_GetInfo(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject,
EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info);
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SDCARD_DRIVER_API_H */
@@ -0,0 +1,91 @@
/**
******************************************************************************
* @file stm32_sdcard_type.h
* @author MCD Application Team
* @brief This file contains SDCARD driver type definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_SDCARD_TYPE_H
#define __STM32_SDCARD_TYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#if EXTMEM_DRIVER_SDCARD == 1
/** @addtogroup SDCARD
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup SDCARD_Exported_Types Exported Types
* @{
*/
/**
* @brief Enumeration of physical link types for SDCARD communication.
*/
typedef enum
{
EXTMEM_DRIVER_SDCARD_LINKSD, /*!< link SD card */
EXTMEM_DRIVER_SDCARD_LINKMMC, /*!< link EMMC card */
EXTMEM_DRIVER_SDCARD_LINKSPI /*!< link SPI card */
} SDCardLinkTypeDef;
/**
* @brief Driver SDCARD instance definition
*/
typedef struct
{
struct
{
SDCardLinkTypeDef Link; /*!< Physical link type. */
} sdcard_public;
struct
{
EXTMEM_DRIVER_SDCARD_InfoTypeDef Info; /*!< SDCARD information. */
union
{
#if EXTMEM_SAL_SD == 1
SAL_SD_ObjectTypeDef SDObject; /*!< SAL SD object. */
#endif /* EXTMEM_SAL_SD == 1 */
#if EXTMEM_SAL_MMC == 1
SAL_MMC_ObjectTypeDef MMCObject; /*!< SAL MMC object. */
#endif /* EXTMEM_SAL_MMC == 1 */
} SALObject;
} sdcard_private;
} EXTMEM_DRIVER_SDCARD_ObjectTypeDef;
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#ifdef __cplusplus
}
#endif
#endif /* __STM32_SDCARD_TYPE_H */
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,165 @@
/**
******************************************************************************
* @file stm32_extmem.h
* @author MCD Application Team
* @brief This file contains the external memory functions prototypes.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_EXTMEM_H_
#define __STM32_EXTMEM_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup EXTMEM
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup EXTMEM_Exported_Types External Memory Exported Types
* @{
*/
/**
* @brief Middleware version number
*/
#define EXTMEM_VERSION 0x00010500 /* Version v1.5.0 */
/**
* @brief Types of supported memories
*/
typedef enum
{
EXTMEM_NOR_SFDP,
EXTMEM_NOR_CFI,
EXTMEM_PSRAM,
EXTMEM_SDCARD,
EXTMEM_CUSTOM,
EXTMEM_USER
} EXTMEM_TypeTypeDef;
/**
* @brief EXTMEM module function call return values
*/
typedef enum
{
EXTMEM_OK, /*!< Action performed with a status ok */
EXTMEM_ERROR_NOTSUPPORTED = -1, /*!< Action not supported by the memory type */
EXTMEM_ERROR_UNKNOWNMEMORY = -2, /*!< Unknown memory type */
EXTMEM_ERROR_DRIVER = -3, /*!< Error return by the driver layer */
EXTMEM_ERROR_SECTOR_SIZE = -4, /*!< Inconsistency between the size and the sector size of the memory */
EXTMEM_ERROR_INVALID_ID = -5, /*!< Invalid memory ID */
EXTMEM_ERROR_PARAM = -6, /*!< Parameter value error */
} EXTMEM_StatusTypeDef;
/**
* @brief Enable/disable state of the module
*/
typedef enum
{
EXTMEM_ENABLE, /*!< State enable */
EXTMEM_DISABLE /*!< State disable */
} EXTMEM_StateTypeDef;
/**
* @brief NOR SFDP memory information structure
*/
typedef struct
{
uint8_t FlashSize; /*!< Specifies the flash size as a power of 2 */
uint32_t PageSize; /*!< Page size in bytes */
uint32_t EraseType1Size; /*!< Erase Type 1 size */
uint32_t EraseType2Size; /*!< Erase Type 2 size */
uint32_t EraseType3Size; /*!< Erase Type 3 size */
uint32_t EraseType4Size; /*!< Erase Type 4 size */
} EXTMEM_NOR_SFDP_FlashInfoTypeDef;
/**
* @brief USER memory information structure
*/
typedef struct
{
uint8_t MemSize; /*!< Specifies the memory size as a power of 2 */
uint32_t MpuCache; /*!< MPU Cache */
} EXTMEM_USER_MemInfoTypeDef;
/**
* @brief SD card information structure
*/
typedef struct
{
uint32_t CardType; /*!< Specifies the card type */
uint32_t CardVersion; /*!< Specifies the card version */
uint32_t Class; /*!< Specifies the card class */
uint32_t RelCardAdd; /*!< Specifies the relative card address */
uint32_t BlockNbr; /*!< Specifies the card capacity in blocks */
uint32_t BlockSize; /*!< Specifies the block size in bytes */
uint32_t LogBlockNbr; /*!< Specifies the card logical capacity in blocks */
uint32_t LogBlockSize; /*!< Specifies the logical block size in bytes */
uint32_t CardSpeed; /*!< Specifies the card speed */
} EXTMEM_DRIVER_SDCARD_InfoTypeDef;
/**
* @brief Number of physical I/O line(s) connected with the memory
*/
typedef enum
{
EXTMEM_LINK_CONFIG_1LINE, /*!< Configuration using 1 line */
EXTMEM_LINK_CONFIG_2LINES, /*!< Configuration using 2 lines */
EXTMEM_LINK_CONFIG_4LINES, /*!< Configuration using 4 lines */
EXTMEM_LINK_CONFIG_8LINES, /*!< Configuration using 8 lines */
EXTMEM_LINK_CONFIG_16LINES, /*!< Configuration using 16 lines */
} EXTMEM_LinkConfig_TypeDef;
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup EXTMEM_Exported_Functions External Memory Exported Functions
* @{
*/
EXTMEM_StatusTypeDef EXTMEM_Init(uint32_t MemId, uint32_t ClockInput);
EXTMEM_StatusTypeDef EXTMEM_DeInit(uint32_t MemId);
EXTMEM_StatusTypeDef EXTMEM_Read(uint32_t MemId, uint32_t Address, uint8_t *Data, uint32_t Size);
EXTMEM_StatusTypeDef EXTMEM_Write(uint32_t MemId, uint32_t Address, const uint8_t *Data, uint32_t Size);
EXTMEM_StatusTypeDef EXTMEM_WriteInMappedMode(uint32_t MemId, uint32_t Address, const uint8_t *const Data,
uint32_t Size);
EXTMEM_StatusTypeDef EXTMEM_EraseSector(uint32_t MemId, uint32_t Address, uint32_t Size);
EXTMEM_StatusTypeDef EXTMEM_EraseAll(uint32_t MemId);
EXTMEM_StatusTypeDef EXTMEM_GetInfo(uint32_t MemId, void *Info);
EXTMEM_StatusTypeDef EXTMEM_MemoryMappedMode(uint32_t MemId, EXTMEM_StateTypeDef State);
EXTMEM_StatusTypeDef EXTMEM_GetMapAddress(uint32_t MemId, uint32_t *BaseAddress);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_EXTMEM_H_ */
@@ -0,0 +1,158 @@
/**
******************************************************************************
* @file stm32_extmem_type.h
* @author MCD Application Team
* @brief This file contains the external memory type definition.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_EXTMEM_TYPE_H_
#define __STM32_EXTMEM_TYPE_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup EXTMEM
* @{
*/
/* Includes ------------------------------------------------------------------*/
#if EXTMEM_SAL_XSPI == 1
#include "sal/stm32_sal_xspi_type.h"
#endif /* EXTMEM_SAL_XSPI */
#if EXTMEM_SAL_SD == 1
#include "sal/stm32_sal_sd_type.h"
#endif /* EXTMEM_SAL_SD */
#if EXTMEM_SAL_MMC == 1
#include "sal/stm32_sal_mmc_type.h"
#endif /* EXTMEM_SAL_MMC */
#if EXTMEM_DRIVER_NOR_SFDP == 1
#include "nor_sfdp/stm32_sfdp_driver_type.h"
#endif /* DRIVER_SFDP_ENABLED */
#if EXTMEM_DRIVER_SDCARD == 1
#include "sdcard/stm32_sdcard_driver_type.h"
#endif /* DRIVER_SDCARD_ENABLED */
#if EXTMEM_DRIVER_PSRAM == 1
#include "psram/stm32_psram_driver_type.h"
#endif /* DRIVER_PSRAM_ENABLED */
#if EXTMEM_DRIVER_CUSTOM == 1
#include "custom/stm32_custom_driver_type.h"
#endif /* DRIVER_USER_ENABLED */
#if EXTMEM_DRIVER_USER == 1
#include "user/stm32_user_driver_type.h"
#endif /* DRIVER_USER_ENABLED */
/* Exported macros -----------------------------------------------------------*/
/** @defgroup EXTMEM_Exported_Macros External Memory Exported Macros
* @{
*/
/**
* @brief Macro to get the minimum value
*/
#define EXTMEM_MIN(_A_,_B_) ((_A_)>(_B_))?(_B_):(_A_);
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup EXTMEM_Exported_Constants External Memory Exported Constants
* @{
*/
/** @defgroup EXTMEM_Manufacturer_IDs EXTMEM JEDEC Manufacturer IDs
* @{
*/
#define EXTMEM_MANUFACTURER_MACRONIX (0xC2U) /*!< JEDEC ID for Macronix */
#define EXTMEM_MANUFACTURER_GIGADEVICE (0xC8U) /*!< JEDEC ID for GigaDevice */
#define EXTMEM_MANUFACTURER_ISSI (0x9DU) /*!< JEDEC ID for ISSI */
/**
* @}
*/
/** @defgroup EXTMEM_Common_JEDEC_Commands EXTMEM Common JEDEC commands identifiers
* @{
*/
#define EXTMEM_READ_JEDEC_ID_SPI_COMMAND 0x9FU
#define EXTMEM_READ_JEDEC_ID_SIZE 0x04U
#define EXTMEM_READ_SFDP_COMMAND 0x5AU
#define EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_DEFAULT 8U
#define EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_OPI 20U
#define EXTMEM_FAST_READ_NB_DUMMY_CYCLES_DEFAULT 8U
/**
* @}
*/
/**
* @}
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup EXTMEM_Exported_TypeDefinitions External Memory Exported Type Definitions
* @{
*/
/**
* @brief Definition of the memory
*/
typedef struct
{
EXTMEM_TypeTypeDef MemType; /*!< Specifies the memory driver type */
void *Handle; /*!< Pointer to HAL handle */
EXTMEM_LinkConfig_TypeDef ConfigType; /*!< Specifies the physical link configuration */
union
{
#if EXTMEM_DRIVER_NOR_SFDP == 1
EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef NorSfdpObject; /*!< Object for NOR SFDP driver */
#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */
#if EXTMEM_DRIVER_SDCARD == 1
EXTMEM_DRIVER_SDCARD_ObjectTypeDef SdCardObject; /*!< Object for SD Card driver */
#endif /* EXTMEM_DRIVER_SDCARD == 1 */
#if EXTMEM_DRIVER_PSRAM == 1
EXTMEM_DRIVER_PSRAM_ObjectTypeDef PsramObject; /*!< Object for PSRAM driver */
#endif /* EXTMEM_DRIVER_PSRAM == 1 */
#if EXTMEM_DRIVER_CUSTOM == 1
EXTMEM_DRIVER_CUSTOM_ObjectTypeDef CustomObject; /*!< Object for Custom driver */
#endif /* EXTMEM_DRIVER_CUSTOM == 1 */
#if EXTMEM_DRIVER_USER == 1
EXTMEM_DRIVER_USER_ObjectTypeDef UserObject; /*!< Object for User driver */
#endif /* EXTMEM_DRIVER_USER == 1 */
};
} EXTMEM_DefinitionTypeDef;
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32_EXTMEM_TYPE_H_ */
@@ -0,0 +1,212 @@
/**
******************************************************************************
* @file stm32_user_driver.c
* @author MCD Application Team
* @brief This file implements the USER 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_USER == 1
#include "stm32_user_driver_api.h"
#include "stm32_user_driver_type.h"
/** @defgroup USER USER driver
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Private Macro ------------------------------------------------------------*/
/** @defgroup USER_Private_Macro Private Macro
* @{
*/
/**
* @}
*/
/* Private typedefs ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup USER_Exported_Functions Exported Functions
* @{
*/
/**
* @brief Initializes the USER driver.
* @param MemoryId Memory ID.
* @param UserObject Pointer to the USER driver object.
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Init(uint32_t MemoryId,
EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
UserObject->MemID = MemoryId; /* Store the memory ID; can be used to control multiple user memories. */
UserObject->PtrUserDriver = NULL; /* Can be used to link data with the memory ID. */
return retr;
}
/**
* @brief Deinitializes the USER driver.
* @param UserObject Pointer to the USER driver object.
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_DeInit(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)UserObject;
return retr;
}
/**
* @brief Reads data from the USER memory.
* @param UserObject Pointer to the USER driver object.
* @param Address Memory address.
* @param Data Pointer to the data buffer to store the read data.
* @param Size Size of data to read (in bytes).
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Read(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t Address, uint8_t *Data, uint32_t Size)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
(void)Address;
(void)Data;
(void)Size;
return retr;
}
/**
* @brief Writes data to the USER memory.
* @param UserObject Pointer to the USER driver object.
* @param Address Memory address.
* @param Data Pointer to the data buffer to be written.
* @param Size Size of data to be written (in bytes).
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Write(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t Address, const uint8_t *Data, uint32_t Size)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
(void)Address;
(void)Data;
(void)Size;
return retr;
}
/**
* @brief Erases sectors in the USER memory.
* @param UserObject Pointer to the USER driver object.
* @param Address Memory address.
* @param Size Size of data to erase (in bytes).
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_EraseSector(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t Address, uint32_t Size)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
(void)Address;
(void)Size;
return retr;
}
/**
* @brief Performs a mass erase of the USER memory.
* @param UserObject Pointer to the USER driver object.
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_MassErase(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
return retr;
}
/**
* @brief Enables memory-mapped mode for the USER device.
* @param UserObject Pointer to the USER driver object.
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Enable_MemoryMappedMode(EXTMEM_DRIVER_USER_ObjectTypeDef
*UserObject)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
return retr;
}
/**
* @brief Disables memory-mapped mode for the USER device.
* @param UserObject Pointer to the USER driver object.
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Disable_MemoryMappedMode(
EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
return retr;
}
/**
* @brief Retrieves the mapped address.
* @param UserObject Pointer to the USER driver object.
* @param BaseAddress Pointer to store the mapped base address.
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetMapAddress(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t *BaseAddress)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
(void)BaseAddress;
return retr;
}
/**
* @brief Retrieves USER memory information.
* @param UserObject Pointer to the USER driver object.
* @param MemInfo Pointer to the USER memory information structure to be filled.
* @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef
*/
__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetInfo(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
EXTMEM_USER_MemInfoTypeDef *MemInfo)
{
EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED;
(void)*UserObject;
(void)MemInfo;
return retr;
}
/**
* @}
*/
/** @addtogroup USER_Private_Functions
* @{
*/
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_USER == 1 */
@@ -0,0 +1,103 @@
/**
******************************************************************************
* @file stm32_user_driver_api.h
* @author MCD Application Team
* @brief This file contains USER driver API definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_USER_DRIVER_API_H
#define __STM32_USER_DRIVER_API_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#if EXTMEM_DRIVER_USER == 1
/** @addtogroup USER
* @ingroup EXTMEM_DRIVER
* @{
*/
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup USER_Exported_Types Exported Types
* @{
*/
/**
* @brief Enumeration of error codes for the USER driver.
*/
typedef enum
{
EXTMEM_DRIVER_USER_OK = 0,
EXTMEM_DRIVER_USER_ERROR_1 = -1,
EXTMEM_DRIVER_USER_ERROR_2 = -2,
EXTMEM_DRIVER_USER_ERROR_3 = -3,
EXTMEM_DRIVER_USER_ERROR_4 = -4,
EXTMEM_DRIVER_USER_ERROR_5 = -5,
EXTMEM_DRIVER_USER_ERROR_6 = -6,
EXTMEM_DRIVER_USER_ERROR_7 = -7,
EXTMEM_DRIVER_USER_ERROR_8 = -8,
EXTMEM_DRIVER_USER_ERROR_9 = -9,
EXTMEM_DRIVER_USER_ERROR_10 = -10,
EXTMEM_DRIVER_USER_NOTSUPPORTED = -128
} EXTMEM_DRIVER_USER_StatusTypeDef;
/* Exported functions --------------------------------------------------------*/
/**
* @addtogroup USER_Exported_Functions Exported functions
* @{
*/
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Init(uint32_t MemoryId,
EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_DeInit(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Read(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t Address, uint8_t *Data, uint32_t Size);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Write(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t Address, const uint8_t *Data, uint32_t Size);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_EraseSector(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t Address, uint32_t Size);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_MassErase(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Enable_MemoryMappedMode(EXTMEM_DRIVER_USER_ObjectTypeDef
*UserObject);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Disable_MemoryMappedMode(EXTMEM_DRIVER_USER_ObjectTypeDef
*UserObject);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetMapAddress(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
uint32_t *BaseAddress);
EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetInfo(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject,
EXTMEM_USER_MemInfoTypeDef *MemInfo);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_USER == 1 */
#ifdef __cplusplus
}
#endif
#endif /* __STM32_USER_DRIVER_API_H */
@@ -0,0 +1,72 @@
/**
******************************************************************************
* @file stm32_user_driver_type.h
* @author MCD Application Team
* @brief This file contains USER driver type definitions.
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_USER_DRIVER_TYPE_H
#define __STM32_USER_DRIVER_TYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/** @addtogroup USER
* @ingroup EXTMEM_DRIVER
* @{
*/
#if EXTMEM_DRIVER_USER == 1
/* Exported constants --------------------------------------------------------*/
/** @defgroup USER_Exported_constants Exported constants
* @{
*/
/**
* @}
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup USER_Exported_Types Exported Types
* @{
*/
/**
* @brief USER driver object definition.
*/
typedef struct
{
uint32_t MemID; /*!< Memory ID. */
void *PtrUserDriver; /*!< Pointer to the user driver instance. */
} EXTMEM_DRIVER_USER_ObjectTypeDef;
/**
* @}
*/
/**
* @}
*/
#endif /* EXTMEM_DRIVER_USER == 1 */
#ifdef __cplusplus
}
#endif
#endif /* __STM32_USER_DRIVER_TYPE_H */