From 51da26e5029998f89bc029b2c7228cb55913c113 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Mon, 12 Aug 2024 13:37:49 +0700 Subject: [PATCH 1/5] s32: drivers: s32ze: add QSPI baremetal driver This is the Mem_ExFls Qspi baremetal driver for s32ze Signed-off-by: Cong Nguyen Huu --- .../BaseNXP/include/Mem_43_EXFLS_MemMap.h | 5 + s32/drivers/s32ze/CMakeLists.txt | 1 + s32/drivers/s32ze/Mem_EXFLS/CMakeLists.txt | 8 + s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip.h | 452 ++ .../s32ze/Mem_EXFLS/include/Qspi_Ip_Common.h | 115 + .../Mem_EXFLS/include/Qspi_Ip_Controller.h | 286 ++ .../Mem_EXFLS/include/Qspi_Ip_HwAccess.h | 1894 ++++++++ .../Mem_EXFLS/include/Qspi_Ip_Hyperflash.h | 151 + .../include/Qspi_Ip_HyperflashRegs.h | 189 + .../include/Qspi_Ip_HyperflashTypes.h | 215 + .../include/Qspi_Ip_TrustedFunctions.h | 105 + .../s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h | 701 +++ s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c | 1970 ++++++++ .../s32ze/Mem_EXFLS/src/Qspi_Ip_Controller.c | 2359 ++++++++++ .../s32ze/Mem_EXFLS/src/Qspi_Ip_Hyperflash.c | 1170 +++++ .../s32ze/Mem_EXFLS/src/Qspi_Ip_Sfdp.c | 4077 +++++++++++++++++ s32/drivers/s32ze/Rte/CMakeLists.txt | 1 + .../s32ze/Rte/include/SchM_Mem_43_EXFLS.h | 120 + s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c | 609 +++ 19 files changed, 14428 insertions(+) create mode 100644 s32/drivers/s32ze/BaseNXP/include/Mem_43_EXFLS_MemMap.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/CMakeLists.txt create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Common.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Controller.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HwAccess.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Hyperflash.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashRegs.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashTypes.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_TrustedFunctions.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h create mode 100644 s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c create mode 100644 s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Controller.c create mode 100644 s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Hyperflash.c create mode 100644 s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Sfdp.c create mode 100644 s32/drivers/s32ze/Rte/include/SchM_Mem_43_EXFLS.h create mode 100644 s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c diff --git a/s32/drivers/s32ze/BaseNXP/include/Mem_43_EXFLS_MemMap.h b/s32/drivers/s32ze/BaseNXP/include/Mem_43_EXFLS_MemMap.h new file mode 100644 index 000000000..7fbbf83b9 --- /dev/null +++ b/s32/drivers/s32ze/BaseNXP/include/Mem_43_EXFLS_MemMap.h @@ -0,0 +1,5 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ diff --git a/s32/drivers/s32ze/CMakeLists.txt b/s32/drivers/s32ze/CMakeLists.txt index e9ee2a3ba..58dc1bf7d 100644 --- a/s32/drivers/s32ze/CMakeLists.txt +++ b/s32/drivers/s32ze/CMakeLists.txt @@ -13,3 +13,4 @@ if (CONFIG_ETH_NXP_S32_NETC) add_subdirectory(EthSwt_NETC) endif() add_subdirectory_ifdef(CONFIG_CAN_NXP_S32_CANXL Can_CANEXCEL) +add_subdirectory_ifdef(CONFIG_MEMC_NXP_S32_QSPI Mem_EXFLS) diff --git a/s32/drivers/s32ze/Mem_EXFLS/CMakeLists.txt b/s32/drivers/s32ze/Mem_EXFLS/CMakeLists.txt new file mode 100644 index 000000000..569b6ecd3 --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: BSD-3-Clause + +zephyr_include_directories(include) +zephyr_library_sources(src/Qspi_Ip.c) +zephyr_library_sources(src/Qspi_Ip_Controller.c) +zephyr_library_sources(src/Qspi_Ip_Hyperflash.c) +zephyr_library_sources(src/Qspi_Ip_Sfdp.c) diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip.h new file mode 100644 index 000000000..9bf1d8fae --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip.h @@ -0,0 +1,452 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_H +#define QSPI_IP_H + +/** +* @file Qspi_Ip.h +* +* @defgroup IPV_QSPI QSPI IPV Driver +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "Qspi_Ip_Types.h" +#include "Qspi_Ip_Cfg.h" + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_VENDOR_ID_H 43 +#define QSPI_IP_AR_RELEASE_MAJOR_VERSION_H 4 +#define QSPI_IP_AR_RELEASE_MINOR_VERSION_H 7 +#define QSPI_IP_AR_RELEASE_REVISION_VERSION_H 0 +#define QSPI_IP_SW_MAJOR_VERSION_H 2 +#define QSPI_IP_SW_MINOR_VERSION_H 0 +#define QSPI_IP_SW_PATCH_VERSION_H 0 + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +/* Check if current file and Qspi_Ip_Types header file are of the same vendor */ +#if (QSPI_IP_TYPES_VENDOR_ID_CFG != QSPI_IP_VENDOR_ID_H) + #error "Qspi_Ip.h and Qspi_Ip_Types.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Types header file are of the same Autosar version */ +#if ((QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.h and Qspi_Ip_Types.h are different" +#endif +/* Check if current file and Qspi_Ip_Types header file are of the same Software version */ +#if ((QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG != QSPI_IP_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_TYPES_SW_MINOR_VERSION_CFG != QSPI_IP_SW_MINOR_VERSION_H) || \ + (QSPI_IP_TYPES_SW_PATCH_VERSION_CFG != QSPI_IP_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip.h and Qspi_Ip_Types.h are different" +#endif + +/* Check if current file and Qspi_Ip_Cfg header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_H != QSPI_IP_VENDOR_ID_CFG) + #error "Qspi_Ip.h and Qspi_Ip_Cfg.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Cfg header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_H != QSPI_IP_AR_RELEASE_MAJOR_VERSION_CFG) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_H != QSPI_IP_AR_RELEASE_MINOR_VERSION_CFG) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_H != QSPI_IP_AR_RELEASE_REVISION_VERSION_CFG) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.h and Qspi_Ip_Cfg.h are different" +#endif +/* Check if current file and Qspi_Ip_Cfg header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_H != QSPI_IP_SW_MAJOR_VERSION_CFG) || \ + (QSPI_IP_SW_MINOR_VERSION_H != QSPI_IP_SW_MINOR_VERSION_CFG) || \ + (QSPI_IP_SW_PATCH_VERSION_H != QSPI_IP_SW_PATCH_VERSION_CFG) \ + ) + #error "Software Version Numbers of Qspi_Ip.h and Qspi_Ip_Cfg.h are different" +#endif + +/******************************************************************************* + * Definitions. + ******************************************************************************/ + +/*! Maximum number of bytes then can be read in one operation */ +#define QSPI_IP_MAX_READ_SIZE (FEATURE_QSPI_RX_BUF_SIZE) +/*! Maximum number of bytes then can be written in one operation */ +#define QSPI_IP_MAX_WRITE_SIZE (FEATURE_QSPI_TX_BUF_SIZE) + +/******************************************************************************* + * API + ******************************************************************************/ +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +/*! + * @brief Initializes the serial flash memory driver + * + * This function initializes the external flash driver and prepares it for operation. + * + * @param instance External flash instance number + * @param pConfig Pointer to the driver configuration structure. + * @param pConnect Pointer to the flash device connection structure. + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_Init(uint32 instance, + const Qspi_Ip_MemoryConfigType * pConfig, + const Qspi_Ip_MemoryConnectionType * pConnect + ); + + +/*! + * @brief De-initializes the serial flash memory driver + * + * This function de-initializes the qspi driver. The driver can't be used + * again until reinitialized. The state structure is no longer needed by the driver and + * may be freed after calling this function. + * + * @param instance External flash instance number + * @return void + */ +Qspi_Ip_StatusType Qspi_Ip_Deinit(uint32 instance); + + +/*! + * @brief Erase a sector in the serial flash. + * + * This function performs one erase sector (block) operation on the external flash. The erase size must match one of + * the device's erase types. + * + * @param instance External flash instance number + * @param address Address of sector to be erased + * @param size Size of the sector to be erase. The sector size must match one of the supported erase sizes of the device. + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_EraseBlock(uint32 instance, + uint32 address, + uint32 size + ); + +/*! + * @brief Erase the entire serial flash + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_EraseChip(uint32 instance); + +/*! + * @brief Check the status of the flash device + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_GetMemoryStatus(uint32 instance); + + +/*! + * @brief Sets the protection bits to the requested value. + * + * @param instance External flash instance number + * @param value New value for the protection bits + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_SetProtection(uint32 instance, + uint8 value + ); + + +/*! + * @brief Returns the current value of the protection bits + * + * @param instance External flash instance number + * @param value Current value of the protection bits + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_GetProtection(uint32 instance, + uint8 *value + ); + + +/*! + * @brief Resets the flash device + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_Reset(uint32 instance); + + +/*! + * @brief Enters 0-X-X (no command) mode. This mode assumes only reads are performed. + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_Enter0XX(uint32 instance); + + +/*! + * @brief Exits 0-X-X (no command) mode. This allows operations other than reads to be performed. + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_Exit0XX(uint32 instance); + + +/*! + * @brief Suspends a program operation. + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ProgramSuspend(uint32 instance); + + +/*! + * @brief Resumes a program operation. + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ProgramResume(uint32 instance); + + +/*! + * @brief Suspends an erase operation. + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_EraseSuspend(uint32 instance); + + +/*! + * @brief Resumes an erase operation. + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_EraseResume(uint32 instance); + + +/*! + * @brief Read data from serial flash + * + * @param instance External flash instance number + * @param address Start address for read operation + * @param data Buffer where to store read data + * @param size Size of data buffer + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_Read(uint32 instance, + uint32 address, + uint8 * data, + uint32 size + ); + + +/*! + * @brief Read manufacturer ID/device ID from serial flash + * + * @param instance External flash instance number + * @param data Buffer where to store read data. Buffer size must match ReadId initialization settings. + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ReadId(uint32 instance, + uint8 * data + ); + + +/*! + * @brief Verifies the correctness of the programmed data + * + * @param instance External flash instance number + * @param address Start address of area to be verified + * @param data Data to be verified + * @param size Size of area to be verified + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ProgramVerify(uint32 instance, + uint32 address, + const uint8 * data, + uint32 size + ); + + +/*! + * @brief Checks whether or not an area in the serial flash is erased + * + * @param instance External flash instance number + * @param address Start address of area to be verified + * @param size Size of area to be verified + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_EraseVerify(uint32 instance, + uint32 address, + uint32 size + ); + +/*! + * @brief Writes data in serial flash + * + * @details Writes data in serial flash memory then exits (Async mode) + * The status of the flash memory must be verified by calling asynchronously the Qspi_Ip_GetMemoryStatus function + * until it is not busy, meaning that the write operation is complete. + * The maximum supported size is equal to the Qspi hardware TxBuffer size. + * + * @param instance External flash instance number + * @param address Start address of area to be programmed + * @param data Data to be programmed in flash + * @param size Size of data buffer + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_Program(uint32 instance, + uint32 address, + const uint8 * data, + uint32 size + ); + + +/*! + * @brief Launches a simple command for the serial flash. + * + * @param instance External flash instance number + * @param lut Index of command in virtual LUT + * @param addr Address used in the command, or base address of the target serial flash + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_RunCommand(uint32 instance, + uint16 lut, + uint32 addr + ); + + +/*! + * @brief Launches a read command for the serial flash + * + * This function can launch a read command in 3 modes: + * - normal read (dataRead != NULL_PTR): Data is read from serial flash and placed in the buffer + * - verify (dataRead == NULL_PTR, dataCmp != NULL_PTR): Data is read from serial flash and compared to the reference buffer + * - blank check (dataRead == NULL_PTR, dataCmp == NULL_PTR): Data is read from serial flash and compared to 0xFF + * + * @param instance External flash instance number + * @param lut Index of command in virtual LUT + * @param addr Start address for read operation in serial flash + * @param dataRead Buffer where to store read data + * @param dataCmp Buffer to be compared to read data + * @param size Size of data buffer + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_RunReadCommand(uint32 instance, + uint16 lut, + uint32 addr, + uint8 * dataRead, + const uint8 * dataCmp, + uint32 size + ); + + +/*! + * @brief Launches a write command for the serial flash + * + * @param instance External flash instance number + * @param lut Index of command in virtual LUT + * @param addr Start address for write operation in serial flash + * @param data Data to be programmed in flash + * @param size Size of data buffer + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_RunWriteCommand(uint32 instance, + uint16 lut, + uint32 addr, + const uint8 * data, + uint32 size + ); + +/*! + * @brief Sets up AHB reads to the serial flash + * + * @param instance External flash instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_AhbReadEnable(uint32 instance); + + +/*! + * @brief Check the status of the QSPI controller + * + * @param instance QSPI peripheral instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ControllerGetStatus(uint32 instance); + + +/*! + * @brief Initializes the qspi driver + * + * This function initializes the qspi driver and prepares it for operation. + * + * @param instance QSPI peripheral instance number + * @param userConfigPtr Pointer to the qspi configuration structure. + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ControllerInit(uint32 instance, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ); + +/*! + * @brief De-initialize the qspi driver + * + * This function de-initializes the qspi driver. The driver can't be used + * again until reinitialized. The context structure is no longer needed by the driver and + * can be freed after calling this function. + * + * @param instance QSPI peripheral instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ControllerDeinit(uint32 instance); + +/*! + * @brief Aborts any on-going transactions + * + * Force the Qspi controller to cancel the on-going IP transaction by performing the software reset sequence. + * + * @param instance QSPI peripheral instance number + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_Abort(uint32 instance); + +/*! + * @brief Initializes the serial flash memory configuration from SFDP table + * + * This function uses the information in the SFDP table to auto-fill the memory configuration structure. + * + * @param pConfig Pointer to the driver configuration structure. + * @param pConnect Pointer to the flash device connection structure. + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_ReadSfdp(Qspi_Ip_MemoryConfigType * pConfig, + const Qspi_Ip_MemoryConnectionType * pConnect + ); + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif /* QSPI_IP_H */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Common.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Common.h new file mode 100644 index 000000000..0ba4b2990 --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Common.h @@ -0,0 +1,115 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_COMMON_H +#define QSPI_IP_COMMON_H + +/** +* @file Qspi_Ip_Common.h +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_COMMON_VENDOR_ID_H 43 +#define QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H 4 +#define QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H 7 +#define QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H 0 +#define QSPI_IP_COMMON_SW_MAJOR_VERSION_H 2 +#define QSPI_IP_COMMON_SW_MINOR_VERSION_H 0 +#define QSPI_IP_COMMON_SW_PATCH_VERSION_H 0 + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ + +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/******************************************************************************* + * Enumerations. + ******************************************************************************/ + + +/******************************************************************************* +* Definitions +******************************************************************************/ + +/*! + * @brief Driver configuration structure + * + * This structure is used to provide configuration parameters for the external flash driver + * at initialization time. + */ +typedef struct +{ + const Qspi_Ip_MemoryConfigType *configuration; /*!< Serial flash device configuration */ + const Qspi_Ip_MemoryConnectionType *connection; /*!< Connection to a QSPI device */ + uint32 baseAddress; /*!< Base address of serial flash device */ + Qspi_Ip_LastCommandType lastCommand; /*!< Last command sent to the flash device */ + uint16 activeReadLut; /*!< LUT number for currently active read mode */ +} Qspi_Ip_StateType; + + +/******************************************************************************* + * External variable declarations. + ******************************************************************************/ + + /* Physical LUT seq to use for all flash commands */ +#define QSPI_IP_COMMAND_LUT 0U + /* Physical LUT seq to use for AHB reads */ +#define QSPI_IP_AHB_LUT 1U + +#define MEM_43_EXFLS_START_SEC_CONST_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + +/* Table of AHB addresses for QuadSPI instances. */ +extern const uint32 Qspi_Ip_AhbAddress[QuadSPI_INSTANCE_COUNT]; + +#define MEM_43_EXFLS_STOP_SEC_CONST_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + + +/*When multicore type3 is enabled on MemAcc, global variables must be allocated to share memory section */ +#if( QSPI_IP_MULTICORE_ENABLED == STD_ON) +#define MEM_43_EXFLS_START_SEC_VAR_SHARED_CLEARED_UNSPECIFIED_NO_CACHEABLE +#else +#define MEM_43_EXFLS_START_SEC_VAR_CLEARED_UNSPECIFIED +#endif +#include "Mem_43_EXFLS_MemMap.h" + +/* Pointer to runtime state structures */ +extern Qspi_Ip_StateType Qspi_Ip_MemoryStateStructure[]; + +#if( QSPI_IP_MULTICORE_ENABLED == STD_ON) +#define MEM_43_EXFLS_STOP_SEC_VAR_SHARED_CLEARED_UNSPECIFIED_NO_CACHEABLE +#else +#define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_UNSPECIFIED +#endif +#include "Mem_43_EXFLS_MemMap.h" + +/******************************************************************************* + * API + ******************************************************************************/ + +#endif /* QSPI_IP_MEM_INSTANCE_COUNT */ + + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_COMMON_H */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Controller.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Controller.h new file mode 100644 index 000000000..66aa61902 --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Controller.h @@ -0,0 +1,286 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_CONTROLLER_H +#define QSPI_IP_CONTROLLER_H + +/** +* @file Qspi_Ip_Controller.h +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "Qspi_Ip_Types.h" +#include "Qspi_Ip_Cfg.h" +#include "Qspi_Ip_Common.h" + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_CONTROLLER_VENDOR_ID_H 43 +#define QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H 4 +#define QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H 7 +#define QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H 0 +#define QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H 2 +#define QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H 0 +#define QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H 0 +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +/* Check if current file and Qspi_Ip_Types.h header file are of the same vendor */ +#if (QSPI_IP_CONTROLLER_VENDOR_ID_H != QSPI_IP_TYPES_VENDOR_ID_CFG) + #error "Qspi_Ip_Controller.h and Qspi_Ip_Types.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Types.h header file are of the same Autosar version */ +#if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H != QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H != QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H != QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.h and Qspi_Ip_Types.h are different" +#endif +/* Check if current file and Qspi_Ip_Types.h header file are of the same Software version */ +#if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H != QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H != QSPI_IP_TYPES_SW_MINOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H != QSPI_IP_TYPES_SW_PATCH_VERSION_CFG) \ + ) + #error "Software Version Numbers of Qspi_Ip_Controller.h and Qspi_Ip_Types.h are different" +#endif + +/* Check if current file and Qspi_Ip_Cfg.h header file are of the same vendor */ +#if (QSPI_IP_CONTROLLER_VENDOR_ID_H != QSPI_IP_VENDOR_ID_CFG) + #error "Qspi_Ip_Controller.h and Qspi_Ip_Cfg.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Cfg.h header file are of the same Autosar version */ +#if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H != QSPI_IP_AR_RELEASE_MAJOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H != QSPI_IP_AR_RELEASE_MINOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H != QSPI_IP_AR_RELEASE_REVISION_VERSION_CFG) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.h and Qspi_Ip_Cfg.h are different" +#endif +/* Check if current file and Qspi_Ip_Cfg.h header file are of the same Software version */ +#if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H != QSPI_IP_SW_MAJOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H != QSPI_IP_SW_MINOR_VERSION_CFG) || \ + (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H != QSPI_IP_SW_PATCH_VERSION_CFG) \ + ) + #error "Software Version Numbers of Qspi_Ip_Controller.h and Qspi_Ip_Cfg.h are different" +#endif + +/* Check if current file and Qspi_Ip_Common.h header file are of the same vendor */ +#if (QSPI_IP_CONTROLLER_VENDOR_ID_H != QSPI_IP_COMMON_VENDOR_ID_H) + #error "Qspi_Ip_Controller.h and Qspi_Ip_Common.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Common.h header file are of the same Autosar version */ +#if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H != QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H != QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H != QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.h and Qspi_Ip_Common.h are different" +#endif +/* Check if current file and Qspi_Ip_Common.h header file are of the same Software version */ +#if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H != QSPI_IP_COMMON_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H != QSPI_IP_COMMON_SW_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H != QSPI_IP_COMMON_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Controller.h and Qspi_Ip_Common.h are different" +#endif + +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/******************************************************************************* + * Macros + ******************************************************************************/ +#if (QSPI_IP_ENABLE_USER_MODE_SUPPORT == STD_ON) + #define Qspi_Ip_WriteLuts(Instance, StartLutRegister, Data, Size) \ + OsIf_Trusted_Call4params(Qspi_Ip_WriteLuts_Privileged, Instance, StartLutRegister, Data, Size) + + #define Qspi_Ip_SetAhbSeqId(instance, seqID) \ + OsIf_Trusted_Call2params(Qspi_Ip_SetAhbSeqId_Privileged, instance, seqID) + +#else + #define Qspi_Ip_WriteLuts(Instance, StartLutRegister, Data, Size) \ + Qspi_Ip_WriteLuts_Privileged(Instance, StartLutRegister, Data, Size) + + #define Qspi_Ip_SetAhbSeqId(instance, seqID) \ + Qspi_Ip_SetAhbSeqId_Privileged(instance, seqID) + +#endif + +/******************************************************************************* + * Enumerations. + ******************************************************************************/ + +/******************************************************************************* +* Definitions +******************************************************************************/ + +#define MEM_43_EXFLS_START_SEC_CONST_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + +extern QuadSPI_Type * const Qspi_Ip_BaseAddress[]; + +#define MEM_43_EXFLS_STOP_SEC_CONST_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + + +#define MEM_43_EXFLS_START_SEC_VAR_CLEARED_8 +#include "Mem_43_EXFLS_MemMap.h" + +/* The padding bytes information to handle unaligned read/write operation for QuadSPI instances */ +extern uint8 Qspi_Ip_MemoryPadding[QuadSPI_INSTANCE_COUNT]; + +#define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_8 +#include "Mem_43_EXFLS_MemMap.h" + + +/******************************************************************************* + * API + ******************************************************************************/ +/*! + * @name QuadSPI Driver + * @{ + */ + + +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + + +/*! + * @brief Configures LUT commands + * + * This function configures a pair of LUT commands in the specified LUT register. + * LUT sequences start at index multiple of 4 and can have up to 8 commands + * + * @param instance QuadSPI peripheral instance number + * @param LutRegister Index in physical LUT array + * @param operation0 First operation + * @param operation1 Second operation + * Implements Qspi_Ip_SetLut_Activity + */ +void Qspi_Ip_SetLut(uint32 instance, + uint8 LutRegister, + Qspi_Ip_InstrOpType operation0, + Qspi_Ip_InstrOpType operation1 + ); + +/*! + * @brief Configures LUT commands + * + * This function configures pairs of LUT commands from the specified LUT register. + * + * @param Instance QuadSPI peripheral instance number + * @param StartLutRegister Start index in physical LUT array + * @param Data Data to be written in LUT register + * @param Size Size of data buffer + */ +void Qspi_Ip_WriteLuts_Privileged(uint32 Instance, + uint8 StartLutRegister, + const uint32 *Data, + uint8 Size + ); + +/*! + * @brief Sets sequence ID for AHB operations + * + * @param instance QuadSPI peripheral instance number + * @param seqID Sequence ID in LUT for read operation + * Implements Qspi_Ip_SetAhbSeqId_Activity + */ +void Qspi_Ip_SetAhbSeqId_Privileged(uint32 instance, + uint8 seqID + ); + +/*! + * @brief Returns the physical base address of a flash device + * + * This function returns the physical base address of a flash device, depending on the QSPI connection. + * The controller must be initialized prior to calling this function. + * + * @param instance QuadSPI peripheral instance number + * @param connectionType Connection of the flash device to QSPI + */ +uint32 Qspi_Ip_GetBaseAdress(uint32 instance, + Qspi_Ip_ConnectionType connectionType + ); + +/*! + * @brief Launches a simple IP command + * + * @param instance QuadSPI peripheral instance number + * @param SeqId Sequence ID where the command is to be found + * @param addr Address of the target serial flash + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_IpCommand(uint32 instance, + uint8 SeqId, + uint32 addr + ); + + +/*! + * @brief Launches an IP read command + * + * This function can launch a read command in 3 modes: + * - normal read (dataRead != NULL_PTR): Data is read from serial flash and placed in the buffer + * - verify (dataRead == NULL_PTR, dataCmp != NULL_PTR): Data is read from serial flash and compared to the reference buffer + * - blank check (dataRead == NULL_PTR, dataCmp == NULL_PTR): Data is read from serial flash and compared to 0xFF + * Only normal read mode can use DMA. + * + * @param instance QuadSPI peripheral instance number + * @param SeqId Sequence ID where the command is to be found + * @param addr Start address for read operation in serial flash + * @param dataRead Buffer where to store read data + * @param dataCmp Buffer to be compared to read data + * @param size Size of data buffer + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_IpRead(uint32 instance, + uint8 SeqId, + uint32 addr, + uint8 * dataRead, + const uint8 * dataCmp, + uint32 size + ); + + +/*! + * @brief Launches an IP write command + * + * @param instance QuadSPI peripheral instance number + * @param SeqId Sequence ID where the command is to be found + * @param addr Start address for write operation in serial flash + * @param data Data to be programmed in flash + * @param size Size of data buffer + * @return Error or success status returned by API + */ +Qspi_Ip_StatusType Qspi_Ip_IpWrite(uint32 instance, + uint8 SeqId, + uint32 addr, + const uint8 * data, + uint32 size + ); + + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +#endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_CONTROLLER_H */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HwAccess.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HwAccess.h new file mode 100644 index 000000000..15930311f --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HwAccess.h @@ -0,0 +1,1894 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_HWACCESS_H +#define QSPI_IP_HWACCESS_H + +/** +* @file Qspi_Ip_HwAccess.h +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_HW_ACCESS_VENDOR_ID_H 43 +#define QSPI_IP_HW_ACCESS_AR_RELEASE_MAJOR_VERSION_H 4 +#define QSPI_IP_HW_ACCESS_AR_RELEASE_MINOR_VERSION_H 7 +#define QSPI_IP_HW_ACCESS_AR_RELEASE_REVISION_VERSION_H 0 +#define QSPI_IP_HW_ACCESS_SW_MAJOR_VERSION_H 2 +#define QSPI_IP_HW_ACCESS_SW_MINOR_VERSION_H 0 +#define QSPI_IP_HW_ACCESS_SW_PATCH_VERSION_H 0 + + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ + +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define QSPI_IP_RX_READOUT_IP 1U /* RX Buffer content is read using the AHB Bus registers QSPI_ARDBn */ + +/******************************************************************************* + * API + ******************************************************************************/ + + +/* + * Triggers an IP transaction + */ +static inline void Qspi_Ip_IpTrigger(QuadSPI_Type *BaseAddr, + uint8 SeqID, + uint16 DataSize + ) +{ +#ifdef S32N2RT + /*Todo: using SFP_TG_IPCR instead*/ +#else + BaseAddr->IPCR = QuadSPI_IPCR_SEQID(SeqID) + | QuadSPI_IPCR_IDATSZ(DataSize); +#endif +} + + +/* + * Clear Rx buffer + */ +static inline void Qspi_Ip_ClearRxBuf(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR |= QuadSPI_MCR_CLR_RXF_MASK; + +} + + +/* + * Clear Tx buffer + */ +static inline void Qspi_Ip_ClearTxBuf(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR |= QuadSPI_MCR_CLR_TXF_MASK; + +} + + +/* + * Checks the Tx buffer clear flag + * Returns TRUE if the Tx buffer content is invalidated. + */ +static inline boolean Qspi_Ip_GetClrTxStatus(const QuadSPI_Type *BaseAddr) +{ + uint32 RegValue = (uint32)BaseAddr->MCR; + + RegValue = (RegValue & QuadSPI_MCR_CLR_TXF_MASK) >> QuadSPI_MCR_CLR_TXF_SHIFT; + return (0U == RegValue)? TRUE : FALSE; +} + + +#ifdef QuadSPI_SPTRCLR_ABRT_CLR_MASK +/* + * Clear AHB buffer + */ +static inline void Qspi_Ip_ClearAhbBuf(QuadSPI_Type *BaseAddr) +{ + BaseAddr->SPTRCLR |= QuadSPI_SPTRCLR_ABRT_CLR_MASK; +} + +/* + * Checks the Ahb buffer clear flag + * Returns TRUE if the Ahb buffer content is invalidated. + */ +static inline boolean Qspi_Ip_GetClrAhbStatus(const QuadSPI_Type *BaseAddr) +{ + uint32 RegValue = (uint32)BaseAddr->SPTRCLR; + + RegValue = (RegValue & QuadSPI_SPTRCLR_ABRT_CLR_MASK) >> QuadSPI_SPTRCLR_ABRT_CLR_SHIFT; + return (0U == RegValue)? TRUE : FALSE; +} +#endif + + +/*! + * @brief Clears IP sequence pointer + * + */ +static inline void Qspi_Ip_ClearIpSeqPointer(QuadSPI_Type *BaseAddr) +{ + BaseAddr->SPTRCLR = QuadSPI_SPTRCLR_IPPTRC_MASK; +} + + +/*! + * @brief Clears AHB sequence pointer + * + */ +static inline void Qspi_Ip_ClearAHBSeqPointer(QuadSPI_Type *BaseAddr) +{ + BaseAddr->SPTRCLR = QuadSPI_SPTRCLR_BFPTRC_MASK; +} + + +/* + * Enable QuadSPI device + */ +static inline void Qspi_Ip_Enable(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR &= ~QuadSPI_MCR_MDIS_MASK; + +} + + +/* + * Disable QuadSPI device + */ +static inline void Qspi_Ip_Disable(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR |= QuadSPI_MCR_MDIS_MASK; + +} + +#ifdef QuadSPI_MCR_DDR_EN_MASK +/* + * Enable DDR mode + */ +static inline void QSPI_DDR_Enable(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR |= QuadSPI_MCR_DDR_EN_MASK; +} + +/* + * Disable DDR mode + */ +static inline void QSPI_DDR_Disable(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR &= ~QuadSPI_MCR_DDR_EN_MASK; +} + +#else +/* + * Enable DDR mode + */ +static inline void QSPI_DDR_Enable(const QuadSPI_Type *BaseAddr) +{ + /* Unused variable */ + (void)BaseAddr; +} + +static inline void QSPI_DDR_Disable(const QuadSPI_Type *BaseAddr) +{ + /* Unused variable */ + (void)BaseAddr; +} +#endif + + + + + +/* + * Enable DQS + */ +#ifdef QuadSPI_MCR_DQS_EN_MASK +static inline void QSPI_DQS_Enable(QuadSPI_Type *BaseAddr) +{ + /* Enable DQS */ + BaseAddr->MCR |= QuadSPI_MCR_DQS_EN_MASK; +} +#else +static inline void QSPI_DQS_Enable(const QuadSPI_Type *BaseAddr) +{ + /* Unused variable */ + (void)BaseAddr; +} +#endif + +/* + * Disable DQS + */ +#ifdef QuadSPI_MCR_DQS_EN_MASK +static inline void QSPI_DQS_Disable(QuadSPI_Type *BaseAddr) +{ + /* Disable DQS */ + BaseAddr->MCR &= ~QuadSPI_MCR_DQS_EN_MASK; +} +#else +static inline void QSPI_DQS_Disable(const QuadSPI_Type *BaseAddr) +{ + /* Unused variable */ + (void)BaseAddr; +} +#endif + + +/* + * Assert QuadSPI sw reset bits + */ +static inline void Qspi_Ip_SwResetOn(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR |= QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK; + +} + + +/* + * Deassert QuadSPI sw reset bits + */ +static inline void Qspi_Ip_SwResetOff(QuadSPI_Type *BaseAddr) +{ + BaseAddr->MCR &= ~(QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK); + +} + + +/* + * Configure idle values for data lines 2:3 + */ +static inline void Qspi_Ip_SetIdleLineValuesB(QuadSPI_Type *BaseAddr, + uint8 Iofb2IdleValue, + uint8 Iofb3IdleValue + ) +{ + /* get value MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + /* set mask for ISD2FB, ISD3FB */ + RegValue &= (uint32)(~(QuadSPI_MCR_ISD2FB_MASK | QuadSPI_MCR_ISD3FB_MASK)); + RegValue |= (QuadSPI_MCR_ISD2FB(Iofb2IdleValue) | QuadSPI_MCR_ISD3FB(Iofb3IdleValue)); + + /* set again the MCR register */ + BaseAddr->MCR = (uint32)RegValue; +} + +#ifdef QuadSPI_MCR_ISD2FA_MASK +static inline void Qspi_Ip_SetIdleLineValuesA(QuadSPI_Type *BaseAddr, + uint8 Iofa2IdleValue, + uint8 Iofa3IdleValue + ) +{ + /* get value MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + /* set mask for ISD2FA, ISD3FA */ + RegValue &= (uint32)(~(QuadSPI_MCR_ISD2FA_MASK | QuadSPI_MCR_ISD3FA_MASK)); + RegValue |= (QuadSPI_MCR_ISD2FA(Iofa2IdleValue) | QuadSPI_MCR_ISD3FA(Iofa3IdleValue)); + + /* set again the MCR register */ + BaseAddr->MCR = (uint32)RegValue; +} +#else +static inline void Qspi_Ip_SetIdleLineValuesA(const QuadSPI_Type *BaseAddr, + uint8 Iofa2IdleValue, + uint8 Iofa3IdleValue + ) +{ + /* Unused variable */ + (void)BaseAddr; + (void)Iofa2IdleValue; + (void)Iofa3IdleValue; +} +#endif + + + +/* + * Enable/Disable DQS slave delay chain + */ +static inline void Qspi_Ip_DLLSlaveEnA(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for EN */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_SLV_EN_MASK)); + RegValue |= QuadSPI_DLLCRA_SLV_EN(Enable? 1U : 0U); + BaseAddr->DLLCRA = (uint32)RegValue; +} + +/* + * Activates/Deactivates DQS slave delay chain update + */ +static inline void Qspi_Ip_DLLSlaveUpdateA(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for EN */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_SLV_UPD_MASK)); + RegValue |= QuadSPI_DLLCRA_SLV_UPD(Enable? 1U : 0U); + BaseAddr->DLLCRA = (uint32)RegValue; +} + +/* + * Activates/Deactivates DQS slave delay chain update + */ +#ifdef QuadSPI_DLLCRA_DLLEN_MASK +static inline void Qspi_Ip_DLLEnableA(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for DLLEN */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_DLLEN_MASK)); + RegValue |= QuadSPI_DLLCRA_DLLEN(Enable? 1U : 0U); + BaseAddr->DLLCRA = (uint32)RegValue; +} +#else +static inline void Qspi_Ip_DLLEnableA(const QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* Unused variable */ + (void)BaseAddr; + (void)Enable; +} +#endif + +/* + * Activates/Deactivates slave DLL bypass + */ +static inline void Qspi_Ip_DLLSlaveBypassA(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for BYPASS */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_SLV_DLL_BYPASS_MASK)); + RegValue |= QuadSPI_DLLCRA_SLV_DLL_BYPASS(Enable? 1U : 0U); + BaseAddr->DLLCRA = (uint32)RegValue; +} + +/* + * Activates/Deactivates slave auto update + */ +#ifdef QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK +static inline void Qspi_Ip_DLLSlaveAutoUpdateA(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for UPDT */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_SLAVE_AUTO_UPDT_MASK)); + RegValue |= QuadSPI_DLLCRA_SLAVE_AUTO_UPDT(Enable? 1U : 0U); + BaseAddr->DLLCRA = (uint32)RegValue; +} +#else +static inline void Qspi_Ip_DLLSlaveAutoUpdateA(const QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + (void)BaseAddr; + (void)Enable; +} +#endif + +/* + * Activates/Deactivates delay-chain for high frequency of operation + */ +static inline void Qspi_Ip_DLLFreqEnA(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for FREQEN */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_FREQEN_MASK)); + RegValue |= QuadSPI_DLLCRA_FREQEN(Enable? 1U : 0U); + BaseAddr->DLLCRA = (uint32)RegValue; +} + +/* + * Sets slave delay chain coarse delay for DLL bypass mode + */ +static inline void Qspi_Ip_DLLSetDelayCoarseA(QuadSPI_Type *BaseAddr, + uint8 CoarseDelay + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for COARSE */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_SLV_DLY_COARSE_MASK)); + RegValue |= QuadSPI_DLLCRA_SLV_DLY_COARSE(CoarseDelay); + BaseAddr->DLLCRA = (uint32)RegValue; +} + + +/* + * Sets DLL reference counter + */ +#ifdef QuadSPI_DLLCRA_DLL_REFCNTR_MASK +static inline void Qspi_Ip_DLLSetReferenceCounterA(QuadSPI_Type *BaseAddr, + uint8 ReferenceCounter + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for REFCNTR */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_DLL_REFCNTR_MASK)); + RegValue |= QuadSPI_DLLCRA_DLL_REFCNTR(ReferenceCounter); + BaseAddr->DLLCRA = (uint32)RegValue; +} +#endif /* QuadSPI_DLLCRA_DLL_REFCNTR_MASK */ + +#ifdef QuadSPI_DLLCRA_DLLRES_MASK +/* + * Sets DLL resolution + */ +static inline void Qspi_Ip_DLLSetResolutionA(QuadSPI_Type *BaseAddr, + uint8 Resolution + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for DLLRES */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_DLLRES_MASK)); + RegValue |= QuadSPI_DLLCRA_DLLRES(Resolution); + BaseAddr->DLLCRA = (uint32)RegValue; +} +#endif /* QuadSPI_DLLCRA_DLLRES_MASK */ + +/* + * Sets slave delay chain coarse offset + */ +static inline void Qspi_Ip_DLLSetDelayOffsetA(QuadSPI_Type *BaseAddr, + uint8 CoarseDelay + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for OFFSET */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_SLV_DLY_OFFSET_MASK)); + RegValue |= QuadSPI_DLLCRA_SLV_DLY_OFFSET(CoarseDelay); + BaseAddr->DLLCRA = (uint32)RegValue; +} + +/* + * Sets slave delay chain fine offset + */ +static inline void Qspi_Ip_DLLSetFineOffsetA(QuadSPI_Type *BaseAddr, + uint8 FineDelay + ) +{ + /* get value DLLCRA register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRA; + /* set mask for OFFSET */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRA_SLV_FINE_OFFSET_MASK)); + RegValue |= QuadSPI_DLLCRA_SLV_FINE_OFFSET(FineDelay); + BaseAddr->DLLCRA = (uint32)RegValue; +} + + +/* + * Checks high frequency slave delay chain lock status + */ +static inline boolean Qspi_Ip_DLLGetSlaveLockStatusA(const QuadSPI_Type *BaseAddr) +{ +#ifdef QuadSPI_DLLSR_SLVA_LOCK_MASK + /* get value DLLSR register */ + uint32 RegValue = (uint32)BaseAddr->DLLSR; + /* set mask for LOCK */ + RegValue = (RegValue & QuadSPI_DLLSR_SLVA_LOCK_MASK); + return (RegValue != 0U)? TRUE : FALSE; +#else + (void)BaseAddr; + return FALSE; +#endif +} + + +/* + * Checks DLL lock status + */ +static inline boolean Qspi_Ip_DLLGetLockStatusA(const QuadSPI_Type *BaseAddr) +{ +#ifdef QuadSPI_DLLSR_DLLA_LOCK_MASK + /* get value DLLSR register */ + uint32 RegValue = (uint32)BaseAddr->DLLSR; + /* set mask for LOCK */ + RegValue = (RegValue & QuadSPI_DLLSR_DLLA_LOCK_MASK); + return (RegValue != 0U)? TRUE : FALSE; +#else + (void)BaseAddr; + return FALSE; +#endif +} + +/* + * Checks high frequency slave delay chain error status + */ +static inline boolean Qspi_Ip_DLLGetErrorStatusA(const QuadSPI_Type *BaseAddr) +{ +#ifdef QuadSPI_DLLSR_DLLA_RANGE_ERR_MASK + /* get value DLLSR register */ + uint32 RegValue = (uint32)BaseAddr->DLLSR; + /* set mask for UNDERFLOW, ERR */ + RegValue = RegValue & (QuadSPI_DLLSR_DLLA_RANGE_ERR_MASK | QuadSPI_DLLSR_DLLA_FINE_UNDERFLOW_MASK); + return (RegValue != 0U)? TRUE : FALSE; +#else + (void)BaseAddr; + return FALSE; +#endif +} + +/* + * Enable/Disable DQS slave delay chain + */ +static inline void Qspi_Ip_DLLSlaveEnB(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + /* set mask for EN */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_SLV_EN_MASK)); + RegValue |= QuadSPI_DLLCRB_SLV_EN(Enable? 1U : 0U); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Activates/Deactivates DQS slave delay chain update + */ +static inline void Qspi_Ip_DLLSlaveUpdateB(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + /* set mask for UPD */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_SLV_UPD_MASK)); + RegValue |= QuadSPI_DLLCRB_SLV_UPD(Enable? 1U : 0U); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Activates/Deactivates DQS slave delay chain update + */ +static inline void Qspi_Ip_DLLEnableB(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + /* set mask for DLLEN */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_DLLEN_MASK)); + RegValue |= QuadSPI_DLLCRB_DLLEN(Enable? 1U : 0U); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Activates/Deactivates slave DLL bypass + */ +static inline void Qspi_Ip_DLLSlaveBypassB(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + /* set mask for BYPASS */ + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_SLV_DLL_BYPASS_MASK)); + RegValue |= QuadSPI_DLLCRB_SLV_DLL_BYPASS(Enable? 1U : 0U); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Activates/Deactivates slave auto update + */ +static inline void Qspi_Ip_DLLSlaveAutoUpdateB(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + (void)BaseAddr; + (void)Enable; + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_SLAVE_AUTO_UPDT_MASK)); + RegValue |= QuadSPI_DLLCRB_SLAVE_AUTO_UPDT(Enable? 1U : 0U); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Activates/Deactivates delay-chain for high frequency of operation + */ +static inline void Qspi_Ip_DLLFreqEnB(QuadSPI_Type *BaseAddr, + boolean Enable + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_FREQEN_MASK)); + RegValue |= QuadSPI_DLLCRB_FREQEN(Enable? 1U : 0U); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Sets slave delay chain coarse delay for DLL bypass mode + */ +static inline void Qspi_Ip_DLLSetDelayCoarseB(QuadSPI_Type *BaseAddr, + uint8 CoarseDelay + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_SLV_DLY_COARSE_MASK)); + RegValue |= QuadSPI_DLLCRB_SLV_DLY_COARSE(CoarseDelay); + BaseAddr->DLLCRB = (uint32)RegValue; +} + + +/* + * Sets reference counter + */ +static inline void Qspi_Ip_DLLSetReferenceCounterB(QuadSPI_Type *BaseAddr, + uint8 ReferenceCounter + ) +{ +#ifdef QuadSPI_DLLCRB_DLL_REFCNTR_MASK + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_DLL_REFCNTR_MASK)); + RegValue |= QuadSPI_DLLCRB_DLL_REFCNTR(ReferenceCounter); + BaseAddr->DLLCRB = (uint32)RegValue; +#else + (void)BaseAddr; + (void)ReferenceCounter; +#endif /* QuadSPI_DLLCRB_DLL_REFCNTR_MASK */ +} +/* + * Sets Resolution + */ +static inline void Qspi_Ip_DLLSetResolutionB(QuadSPI_Type *BaseAddr, + uint8 Resolution + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_DLLRES_MASK)); + RegValue |= QuadSPI_DLLCRB_DLLRES(Resolution); + BaseAddr->DLLCRB = (uint32)RegValue; +} + + +/* + * Sets slave delay chain coarse offset + */ +static inline void Qspi_Ip_DLLSetDelayOffsetB(QuadSPI_Type *BaseAddr, + uint8 CoarseDelay + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_SLV_DLY_OFFSET_MASK)); + RegValue |= QuadSPI_DLLCRB_SLV_DLY_OFFSET(CoarseDelay); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Sets slave delay chain fine offset + */ +static inline void Qspi_Ip_DLLSetFineOffsetB(QuadSPI_Type *BaseAddr, + uint8 FineDelay + ) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLCRB; + + RegValue &= (uint32)(~((uint32)QuadSPI_DLLCRB_SLV_FINE_OFFSET_MASK)); + RegValue |= QuadSPI_DLLCRB_SLV_FINE_OFFSET(FineDelay); + BaseAddr->DLLCRB = (uint32)RegValue; +} + +/* + * Checks high frequency slave delay chain lock status + */ +static inline boolean Qspi_Ip_DLLGetSlaveLockStatusB(const QuadSPI_Type *BaseAddr) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLSR; + + RegValue = (RegValue & QuadSPI_DLLSR_SLVB_LOCK_MASK); + return (RegValue != 0U)? TRUE : FALSE; +} + +/* + * Checks DLL lock status + */ +static inline boolean Qspi_Ip_DLLGetLockStatusB(const QuadSPI_Type *BaseAddr) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLSR; + + RegValue = (RegValue & QuadSPI_DLLSR_DLLB_LOCK_MASK); + return (RegValue != 0U)? TRUE : FALSE; +} + +/* + * Checks high frequency slave delay chain error status + */ +static inline boolean Qspi_Ip_DLLGetErrorStatusB(const QuadSPI_Type *BaseAddr) +{ + /* get value DLLCRB register */ + uint32 RegValue = (uint32)BaseAddr->DLLSR; + + RegValue = RegValue & (QuadSPI_DLLSR_DLLB_RANGE_ERR_MASK | QuadSPI_DLLSR_DLLB_FINE_UNDERFLOW_MASK); + return (RegValue != 0U)? TRUE : FALSE; +} + + + +/* + * Configure external flash memory map size A + */ +static inline void Qspi_Ip_SetMemMapSizeA(uint32 instance, + QuadSPI_Type *BaseAddr, + uint32 SizeA1, + uint32 SizeA2 + ) +{ + BaseAddr->SFA1AD = Qspi_Ip_AhbAddress[instance] + SizeA1; + BaseAddr->SFA2AD = Qspi_Ip_AhbAddress[instance] + SizeA1 + SizeA2; +} + +/* + * Configure external flash memory map size B + */ +static inline void Qspi_Ip_SetMemMapSizeB(QuadSPI_Type *BaseAddr, + uint32 SizeB1, + uint32 SizeB2 + ) +{ + /* Get memory address of size A2 */ + uint32 RegValue = (uint32)BaseAddr->SFA2AD; + + BaseAddr->SFB1AD = RegValue + SizeB1; + BaseAddr->SFB2AD = RegValue + SizeB1 + SizeB2; +} + +/* + * Set CS hold time in serial clock Cycles + */ +static inline void Qspi_Ip_SetCsHoldTime(QuadSPI_Type *BaseAddr, + uint8 Cycles + ) +{ + /* get value FLSHCR register */ + uint32 RegValue = (uint32)BaseAddr->FLSHCR; + + RegValue &= (uint32)(~((uint32)QuadSPI_FLSHCR_TCSH_MASK)); + RegValue |= QuadSPI_FLSHCR_TCSH(Cycles); + BaseAddr->FLSHCR = (uint32)RegValue; +} + + +/* + * Set CS setup time + */ +static inline void Qspi_Ip_SetCsSetupTime(QuadSPI_Type *BaseAddr, + uint8 Cycles + ) +{ + /* get value FLSHCR register */ + uint32 RegValue = (uint32)BaseAddr->FLSHCR; + + RegValue &= (uint32)(~((uint32)QuadSPI_FLSHCR_TCSS_MASK)); + RegValue |= QuadSPI_FLSHCR_TCSS(Cycles); + BaseAddr->FLSHCR = (uint32)RegValue; +} + + +/* + * Set data in hold time + */ +#ifdef QuadSPI_FLSHCR_TDH_MASK +static inline void Qspi_Ip_SetDataInHoldTime(QuadSPI_Type *BaseAddr, + Qspi_Ip_FlashDataAlignType Enable + ) +{ + /* get value FLSHCR register */ + uint32 RegValue = (uint32)BaseAddr->FLSHCR; + + RegValue &= (uint32)(~(QuadSPI_FLSHCR_TDH_MASK)); + RegValue |= QuadSPI_FLSHCR_TDH(Enable); + BaseAddr->FLSHCR = (uint32)RegValue; +} +#else +static inline void Qspi_Ip_SetDataInHoldTime(const QuadSPI_Type *BaseAddr, + Qspi_Ip_FlashDataAlignType Enable + ) +{ + /* Unused variable */ + (void)BaseAddr; + (void)Enable; +} +#endif + + +/* + * Sets AHB buffer 0 configuration + */ +static inline void Qspi_Ip_SetAhbBuf0(QuadSPI_Type *BaseAddr, + uint16 Size, + uint8 Master + ) +{ + BaseAddr->BUF0CR = QuadSPI_BUF0CR_ADATSZ((uint32)Size >> 3U) + | QuadSPI_BUF0CR_MSTRID(Master); +} + + +/* + * Sets AHB buffer 1 configuration + */ +static inline void Qspi_Ip_SetAhbBuf1(QuadSPI_Type *BaseAddr, + uint16 Size, + uint8 Master + ) +{ + BaseAddr->BUF1CR = QuadSPI_BUF1CR_ADATSZ((uint32)Size >> 3U) + | QuadSPI_BUF1CR_MSTRID(Master); +} + + +/* + * Sets AHB buffer 2 configuration + */ +static inline void Qspi_Ip_SetAhbBuf2(QuadSPI_Type *BaseAddr, + uint16 Size, + uint8 Master + ) +{ + BaseAddr->BUF2CR = QuadSPI_BUF2CR_ADATSZ((uint32)Size >> 3U) + | QuadSPI_BUF2CR_MSTRID(Master); +} + + +/* + * Sets AHB buffer 3 configuration + */ +static inline void Qspi_Ip_SetAhbBuf3(QuadSPI_Type *BaseAddr, + uint16 Size, + uint8 Master, + boolean AllMasters + ) +{ + BaseAddr->BUF3CR = QuadSPI_BUF3CR_ADATSZ((uint32)Size >> 3U) + | QuadSPI_BUF3CR_MSTRID(Master) + | QuadSPI_BUF3CR_ALLMST(AllMasters? 1U : 0U); +} + + +/* + * Sets AHB buffer 0 index. Parameter represents desired end index of the buffer. + */ +static inline void Qspi_Ip_SetAhbBuf0Ind(QuadSPI_Type *BaseAddr, + uint32 Index + ) +{ + BaseAddr->BUF0IND = Index; +} + + +/* + * Sets AHB buffer 1 index. Parameter represents desired end index of the buffer. + */ +static inline void Qspi_Ip_SetAhbBuf1Ind(QuadSPI_Type *BaseAddr, + uint32 Index + ) +{ + BaseAddr->BUF1IND = Index; +} + + +/* + * Sets AHB buffer 2 index. Parameter represents desired end index of the buffer. + */ +static inline void Qspi_Ip_SetAhbBuf2Ind(QuadSPI_Type *BaseAddr, + uint32 Index + ) +{ + BaseAddr->BUF2IND = Index; +} + + +/* + * Sets address for IP transactions + */ +static inline void Qspi_Ip_SetIpAddr(QuadSPI_Type *BaseAddr, + uint32 Addr + ) +{ +#ifdef S32N2RT + /* Todo: using FP_TG_SFAR instead*/ +#else + BaseAddr->SFAR = Addr; +#endif +} + + +/* + * Sets flash address options + */ +#ifdef QuadSPI_SFACR_CAS_MASK +static inline void Qspi_Ip_SetAddrOptions(QuadSPI_Type *BaseAddr, + uint32 ColumnAddr, + boolean WordAdressable + ) +{ + /* Set a value for SAFCR */ + BaseAddr->SFACR = QuadSPI_SFACR_CAS(ColumnAddr) + | QuadSPI_SFACR_WA(WordAdressable? 1U : 0U); +} +#else +static inline void Qspi_Ip_SetAddrOptions(const QuadSPI_Type *BaseAddr, + uint32 ColumnAddr, + boolean WordAdressable + ) +{ + /* Unused variable */ + (void)BaseAddr; + (void)ColumnAddr; + (void)WordAdressable; +} +#endif + + +/* + * Configures parameters related to sampling Rx data + */ +static inline void Qspi_Ip_SetRxCfg(QuadSPI_Type *BaseAddr, + Qspi_Ip_SampleDelayType Delay, + Qspi_Ip_SamplePhaseType ClockPhase + ) +{ + BaseAddr->SMPR = QuadSPI_SMPR_FSPHS(ClockPhase) + | QuadSPI_SMPR_FSDLY(Delay); +} + + +/* + * Configures parameters related to sampling Rx data + */ +static inline void Qspi_Ip_SetRxDLLTapA(QuadSPI_Type *BaseAddr, + uint8 Taps + ) +{ + /* get value SMPR register */ + uint32 RegValue = BaseAddr->SMPR; + + RegValue &= ~QuadSPI_SMPR_DLLFSMPFA_MASK; + RegValue |= QuadSPI_SMPR_DLLFSMPFA(Taps); + BaseAddr->SMPR = RegValue; +} + + +/* + * Configures parameters related to sampling Rx data + */ +static inline void Qspi_Ip_SetRxDLLTapB(QuadSPI_Type *BaseAddr, + uint8 Taps + ) +{ + /* get value SMPR register */ + uint32 RegValue = BaseAddr->SMPR; + + RegValue &= ~QuadSPI_SMPR_DLLFSMPFB_MASK; + RegValue |= QuadSPI_SMPR_DLLFSMPFB(Taps); + BaseAddr->SMPR = RegValue; +} + + + +/* + * Checks if module is busy with a transaction + */ +static inline boolean Qspi_Ip_GetBusyStatus(const QuadSPI_Type *BaseAddr) +{ + /* get value SR register */ + uint32 RegValue = (uint32)BaseAddr->SR; + + RegValue = (RegValue & QuadSPI_SR_BUSY_MASK); + return (RegValue != 0U)? TRUE : FALSE; +} + + +/* + * Returns the current fill level of the Rx buffer + */ +static inline uint32 Qspi_Ip_GetRxBufFill(const QuadSPI_Type *BaseAddr) +{ + /* get value RBSR register */ + uint32 RegValue = (uint32)BaseAddr->RBSR; + + RegValue = (RegValue & QuadSPI_RBSR_RDBFL_MASK) >> QuadSPI_RBSR_RDBFL_SHIFT; + return RegValue; +} + + +/* + * Checks if enough Rx data is available, according to the Watermark setting + */ +static inline boolean Qspi_Ip_GetRxDataEvent(const QuadSPI_Type *BaseAddr) +{ + /* get value SR register */ + uint32 RegValue = (uint32)BaseAddr->SR; + + RegValue = (RegValue & QuadSPI_SR_RXWE_MASK); + return (RegValue != 0U)? TRUE : FALSE; +} + + +/* + * Returns Tx buffer fill level expressed in 4-byte entries + */ +static inline uint32 Qspi_Ip_GetTxBufFill(const QuadSPI_Type *BaseAddr) +{ + /* get value TBSR register */ + uint32 RegValue = (uint32)BaseAddr->TBSR; + + RegValue = (RegValue & QuadSPI_TBSR_TRBFL_MASK) >> QuadSPI_TBSR_TRBFL_SHIFT; + return RegValue; +} + + +#ifdef QuadSPI_SR_TXWA_MASK +/* + * Checks the Tx buffer Watermark. + * Returns TRUE if number of buffer entries specified by the Watermark is available. + */ +static inline boolean Qspi_Ip_GetTxWatermarkAvailable(const QuadSPI_Type *BaseAddr) +{ + /* get value SR register */ + uint32 RegValue = (uint32)BaseAddr->SR; + + RegValue = (RegValue & QuadSPI_SR_TXWA_MASK); + return (RegValue != 0U)? TRUE : FALSE; +} +#endif + + +/* + * Writes data in the Tx buffer + */ +static inline void Qspi_Ip_WriteTxData(QuadSPI_Type *BaseAddr, uint32 Data) +{ + BaseAddr->TBDR = Data; +} + + +/* + * Returns the address of the Tx data register + */ +static inline uint32 Qspi_Ip_GetTxDataAddr(const QuadSPI_Type *BaseAddr) +{ + return (Qspi_Ip_UintPtrType)&(BaseAddr->TBDR); +} + + +/* + * Returns the address of the first Rx data register + */ +static inline uint32 Qspi_Ip_GetRxDataAddr(const QuadSPI_Type *BaseAddr) +{ + return (Qspi_Ip_UintPtrType)&(BaseAddr->RBDR[0U]); +} + +#ifdef XSPI_RSER_TBFDE_MASK +/* + * Enables Tx DMA request (when Tx buffer has room for more data) + */ +static inline void Qspi_Ip_EnableTxDmaReq(QuadSPI_Type *BaseAddr) +{ + BaseAddr->RSER |= QuadSPI_RSER_TBFDE_MASK; +} + + +/* + * Enables Rx DMA request (when Rx buffer has room for more data) + */ +static inline void Qspi_Ip_EnableRxDmaReq(QuadSPI_Type *BaseAddr) +{ + BaseAddr->RSER |= QuadSPI_RSER_RBDDE_MASK; +} + + +/* + * Disables both Rx and Tx DMA requests + */ +static inline void Qspi_Ip_DisableDmaReq(QuadSPI_Type *BaseAddr) +{ + BaseAddr->RSER &= ~(QuadSPI_RSER_TBFDE_MASK | QuadSPI_RSER_RBDDE_MASK); +} +#endif + +/* + * Perform a POP operation on the Rx buffer, removing Rx_watermark entries + */ +static inline void Qspi_Ip_RxPop(QuadSPI_Type *BaseAddr) +{ + BaseAddr->FR = QuadSPI_FR_RBDF_MASK; +} + + +/* + * Configures the Watermark for the Rx buffer, expressed in number of 4-byte entries + */ +static inline void Qspi_Ip_SetRxWatermark(QuadSPI_Type *BaseAddr, + uint8 Watermark + ) +{ + /* get value RBCT register */ + uint32 RegValue = (uint32)BaseAddr->RBCT; + + RegValue &= (uint32)(~((uint32)QuadSPI_RBCT_WMRK_MASK)); + RegValue |= QuadSPI_RBCT_WMRK((uint32)Watermark - 1U); + BaseAddr->RBCT = (uint32)RegValue; +} + + +#ifdef QuadSPI_RBCT_RXBRD_MASK +/* + * Configures the rx for the Rx buffer, expressed in number of 4-byte entries + */ +static inline void Qspi_Ip_SetRxBufReadout(QuadSPI_Type *BaseAddr, + uint8 Readout + ) +{ + /* get value RBCT register */ + uint32 RegValue = (uint32)BaseAddr->RBCT; + + RegValue &= (uint32)(~((uint32)QuadSPI_RBCT_RXBRD_MASK)); + RegValue |= QuadSPI_RBCT_RXBRD(Readout); + BaseAddr->RBCT = (uint32)RegValue; +} +#endif + + +/* + * Configures the Watermark for the Tx buffer, expressed in number of 4-byte entries + */ +static inline void Qspi_Ip_SetTxWatermark(QuadSPI_Type *BaseAddr, + uint8 Watermark + ) +{ + /* get value TBCT register */ + uint32 RegValue = (uint32)BaseAddr->TBCT; + + RegValue &= (uint32)(~((uint32)QuadSPI_TBCT_WMRK_MASK)); + RegValue |= QuadSPI_TBCT_WMRK(Watermark); + BaseAddr->TBCT = (uint32)RegValue; +} + + +/* + * Enables interrupts specified by the mask parameter + */ +static inline void Qspi_Ip_EnableInt(QuadSPI_Type *BaseAddr, + uint32 Mask + ) +{ + BaseAddr->RSER |= Mask; +} + + +/* + * Disables interrupts specified by the mask parameter + */ +static inline void Qspi_Ip_DisableInt(QuadSPI_Type *BaseAddr, + uint32 Mask + ) +{ + BaseAddr->RSER &= ~Mask; +} + + +/* + * Clears interrupt flags specified by the mask parameter + */ +static inline void Qspi_Ip_ClearIntFlag(QuadSPI_Type *BaseAddr, + uint32 Mask + ) +{ + BaseAddr->FR = Mask; +} + + +/* + * Configure DQS clock for sampling read data + */ +static inline void Qspi_Ip_SetDQSSourceA(QuadSPI_Type *BaseAddr, + Qspi_Ip_ReadModeType ReadModeA) +{ + /* get the value of MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + RegValue &= (uint32)(~QuadSPI_MCR_DQS_FA_SEL_MASK); + /* switch for modes */ + switch (ReadModeA) + { +#if (FEATURE_QSPI_INTERNAL_DQS == 1) + case QSPI_IP_READ_MODE_INTERNAL_DQS: + /* if it is DQS internal */ + RegValue |= QuadSPI_MCR_DQS_FA_SEL(0U); + break; +#endif +#if (FEATURE_QSPI_LOOPBACK == 1) + case QSPI_IP_READ_MODE_LOOPBACK: + /* if it is Pad loopback */ + RegValue |= QuadSPI_MCR_DQS_FA_SEL(1U); + break; +#endif +#if (FEATURE_QSPI_LOOPBACK_DQS == 1) + case QSPI_IP_READ_MODE_LOOPBACK_DQS: + /* if it is DQS pad loopback */ + RegValue |= QuadSPI_MCR_DQS_FA_SEL(2U); + break; +#endif + case QSPI_IP_READ_MODE_EXTERNAL_DQS: + /* if it is DQS external */ + RegValue |= QuadSPI_MCR_DQS_FA_SEL(3U); + break; + default: + ; /* Not possible */ + break; + } + BaseAddr->MCR = (uint32)RegValue; +} + + +static inline void Qspi_Ip_SetDQSSourceB(QuadSPI_Type *BaseAddr, + Qspi_Ip_ReadModeType ReadModeB) +{ + /* get the value of MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + RegValue &= (uint32)(~QuadSPI_MCR_DQS_FB_SEL_MASK); + /* switch for modes */ + switch (ReadModeB) + { +#if (FEATURE_QSPI_INTERNAL_DQS == 1) + case QSPI_IP_READ_MODE_INTERNAL_DQS: + /* if it is DQS internal */ + RegValue |= QuadSPI_MCR_DQS_FB_SEL(0U); + break; +#endif +#if (FEATURE_QSPI_LOOPBACK == 1) + case QSPI_IP_READ_MODE_LOOPBACK: + /* if it is Pad loopback */ + RegValue |= QuadSPI_MCR_DQS_FB_SEL(1U); + break; +#endif +#if (FEATURE_QSPI_LOOPBACK_DQS == 1) + case QSPI_IP_READ_MODE_LOOPBACK_DQS: + /* if it is DQS pad loopback */ + RegValue |= QuadSPI_MCR_DQS_FB_SEL(2U); + break; +#endif + case QSPI_IP_READ_MODE_EXTERNAL_DQS: + /* if it is DQS external */ + RegValue |= QuadSPI_MCR_DQS_FB_SEL(3U); + break; + default: + ; /* Not possible */ + break; + } + BaseAddr->MCR = (uint32)RegValue; +} + + + +static inline void Qspi_Ip_SetCenterAlignedStrobeA(QuadSPI_Type *BaseAddr, + boolean CenterAlignedStrobe + ) +{ + /* Get the value of MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + /* Set mask */ + RegValue &= (uint32)(~QuadSPI_MCR_CK2_DCARS_FA_MASK); + RegValue |= QuadSPI_MCR_CK2_DCARS_FA(CenterAlignedStrobe? 1U : 0U); + /* Update again the MCR register */ + BaseAddr->MCR = (uint32)RegValue; +} +static inline void Qspi_Ip_SetCenterAlignedStrobeB(QuadSPI_Type *BaseAddr, + boolean CenterAlignedStrobe + ) +{ + /* Get the value of MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + /* Set mask */ + RegValue &= (uint32)(~QuadSPI_MCR_CK2_DCARS_FB_MASK); + RegValue |= QuadSPI_MCR_CK2_DCARS_FB(CenterAlignedStrobe? 1U : 0U); + /* Update again the MCR register */ + BaseAddr->MCR = (uint32)RegValue; +} + +static inline void Qspi_Ip_SetDifferentialClockA(QuadSPI_Type *BaseAddr, + boolean DifferentialClock + ) +{ + /* Get the value of MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + /* Set mask */ + RegValue &= (uint32)(~QuadSPI_MCR_CKN_FA_EN_MASK); + RegValue |= QuadSPI_MCR_CKN_FA_EN(DifferentialClock? 1U : 0U); + /* update again the MCR register */ + BaseAddr->MCR = (uint32)RegValue; +} +static inline void Qspi_Ip_SetDifferentialClockB(QuadSPI_Type *BaseAddr, + boolean DifferentialClock + ) +{ + /* Get the value of MCR register */ + uint32 RegValue = (uint32)BaseAddr->MCR; + + /* Set mask */ + RegValue &= (uint32)(~QuadSPI_MCR_CKN_FB_EN_MASK); + RegValue |= QuadSPI_MCR_CKN_FB_EN(DifferentialClock? 1U : 0U); + /* Update again the MCR register */ + BaseAddr->MCR = (uint32)RegValue; +} + + +#ifdef QuadSPI_SFACR_BYTE_SWAP_MASK +static inline void Qspi_Ip_SetByteSwap(QuadSPI_Type *BaseAddr, + boolean ByteSwap + ) +{ + /* Get the value of SFACR register */ + uint32 RegValue = (uint32)BaseAddr->SFACR; + + /* Set mask */ + RegValue &= (uint32)(~QuadSPI_SFACR_BYTE_SWAP_MASK); + RegValue |= QuadSPI_SFACR_BYTE_SWAP(ByteSwap? 1U : 0U); + /* Update again the SFACR register */ + BaseAddr->SFACR = (uint32)RegValue; +} +#else +static inline void Qspi_Ip_SetByteSwap(const QuadSPI_Type *BaseAddr, + boolean ByteSwap + ) +{ + /* Unused variable */ + (void)BaseAddr; + (void)ByteSwap; +} +#endif + +#ifdef QuadSPI_MCR_SCLKCFG_MASK +/* + * Configure chip-specific clock options + */ +static inline void Qspi_Ip_SetClockOptions(QuadSPI_Type *BaseAddr, + uint8 Option + ) +{ + uint32 RegValue = (uint32)BaseAddr->MCR; + + RegValue &= (uint32)(~QuadSPI_MCR_SCLKCFG_MASK); + RegValue |= QuadSPI_MCR_SCLKCFG(Option); + BaseAddr->MCR = (uint32)RegValue; +} +#endif + +#ifdef QuadSPI_SOCCR_SOCCFG_MASK +/* + * Configure chip-specific options + */ +static inline void Qspi_Ip_SetChipOptions(QuadSPI_Type *BaseAddr, + uint32 Option + ) +{ + BaseAddr->SOCCR = Option; +} +#endif + + + + +#if (FEATURE_QSPI_HAS_SFP == 1) + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Enable/disable all or just MDAD/FRAD access controls. + * + * Master Global Configuration (MGC): + * - Global Valid access control (GVLD) + * - Global Valid MDAD (GVLDMDAD) + * - Global Valid FRAD (GVLDFRAD) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] AccessControl an enum selecting all or just MDAD/FRAD access controls + * @param[in] Enabled the value of the selected field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetAccessControls +( + QuadSPI_Type * BaseAddr, + Qspi_Ip_Sfp_AccessControlType AccessControl, + uint8 Enabled) +{ + uint32 RegValue = BaseAddr->MGC; + + switch (AccessControl) + { + case QSPI_IP_SFP_ALL: + { + RegValue &= ~QuadSPI_MGC_GVLD_MASK; + RegValue |= QuadSPI_MGC_GVLD(Enabled); + } + break; + + case QSPI_IP_SFP_MDAD: + { + RegValue &= ~QuadSPI_MGC_GVLDMDAD_MASK; + RegValue |= QuadSPI_MGC_GVLDMDAD(Enabled); + } + break; + + case QSPI_IP_SFP_FRAD: + { + RegValue &= ~QuadSPI_MGC_GVLDFRAD_MASK; + RegValue |= QuadSPI_MGC_GVLDFRAD(Enabled); + } + break; + + default: + /* invalid selection */ + break; + } + + BaseAddr->MGC = RegValue; +} + +#if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON) + +#if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON) + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Program the VLD bit of a Target Group queue + * + * Target Group n Master Domain Access Descriptor (TG0MDAD - TG1MDAD): + * - Valid (VLD) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] MdadInstance index of the target group to be configured + * @param[in] Valid value to be written into the VLD bit + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetTgValid +( + QuadSPI_Type * BaseAddr, + uint8 MdadInstance, + boolean Valid) +{ + if (MdadInstance < QuadSPI_MDAD_COUNT) + { + uint32 RegValue = BaseAddr->MDAD[MdadInstance].TGMDAD; + RegValue &= ~QuadSPI_TGMDAD_VLD_MASK; + RegValue |= QuadSPI_TGMDAD_VLD(Valid ? 1U : 0U); + BaseAddr->MDAD[MdadInstance].TGMDAD = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the Secure Attribute field of a Target Group queue + * + * Target Group n Master Domain Access Descriptor (TG0MDAD - TG1MDAD): + * - Secure Attribute (SA) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] MdadInstance index of the target group to be configured + * @param[in] SecureAttribute value of the SA field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetTgSecureAttribute +( + QuadSPI_Type * BaseAddr, + uint8 MdadInstance, + Qspi_Ip_SfpSaType SecureAttribute) +{ + if (MdadInstance < QuadSPI_MDAD_COUNT) + { + uint32 RegValue = BaseAddr->MDAD[MdadInstance].TGMDAD; + RegValue &= ~QuadSPI_TGMDAD_SA_MASK; + RegValue |= QuadSPI_TGMDAD_SA(SecureAttribute); + BaseAddr->MDAD[MdadInstance].TGMDAD = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the MASKTYPE field of the given target group queue. + * + * Target Group n Master Domain Access Descriptor (TG0MDAD - TG1MDAD): + * - Mask Type (MASKTYPE) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] MdadInstance index of the target group to be configured + * @param[in] MaskType value to be written in the mask type field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetTgMaskType +( + QuadSPI_Type * BaseAddr, + uint8 MdadInstance, + Qspi_Ip_SfpMasktypeType MaskType) +{ + if (MdadInstance < QuadSPI_MDAD_COUNT) + { + uint32 RegValue = BaseAddr->MDAD[MdadInstance].TGMDAD; + RegValue &= ~QuadSPI_TGMDAD_MASKTYPE_MASK; + RegValue |= QuadSPI_TGMDAD_MASKTYPE(MaskType); + BaseAddr->MDAD[MdadInstance].TGMDAD = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the MASK field of the given target group queue. + * + * Target Group n Master Domain Access Descriptor (TG0MDAD - TG1MDAD): + * - Mask (MASK) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] MdadInstance index of the target group to be configured + * @param[in] Mask value that is written into the 6-bit mask + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetTgMask +( + QuadSPI_Type * BaseAddr, + uint8 MdadInstance, + uint8 Mask) +{ + if (MdadInstance < QuadSPI_MDAD_COUNT) + { + uint32 RegValue = BaseAddr->MDAD[MdadInstance].TGMDAD; + RegValue &= ~QuadSPI_TGMDAD_MASK_MASK; + RegValue |= QuadSPI_TGMDAD_MASK(Mask); + BaseAddr->MDAD[MdadInstance].TGMDAD = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the Domain ID reference of the given target group queue. + * + * Target Group n Master Domain Access Descriptor (TG0MDAD - TG1MDAD): + * - Domain ID Reference (MIDMATCH) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] MdadInstance index of the target group to be configured + * @param[in] DomainIdMatch value of MIDMATCH field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetTgDomainIdMatch +( + QuadSPI_Type * BaseAddr, + uint8 MdadInstance, + uint8 DomainIdMatch) +{ + if (MdadInstance < QuadSPI_MDAD_COUNT) + { + uint32 RegValue = BaseAddr->MDAD[MdadInstance].TGMDAD; + RegValue &= ~QuadSPI_TGMDAD_MIDMATCH_MASK; + RegValue |= QuadSPI_TGMDAD_MIDMATCH(DomainIdMatch); + BaseAddr->MDAD[MdadInstance].TGMDAD = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Indicates whether the IPCR-IDATZ, IPCR-SEQID and PAR stored in this target group queue is + * valid and queue is locked. + * + * Target Group n IPCR Status (TG0IPCRS - TG1IPCRS): + * - Valid (VLD) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] MdadInstance index of the target group to be configured + * + * @retval TRUE: valid + * @retval FALSE: invalid + * @retval FALSE: the MdadInstance is invalid + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline boolean Qspi_Ip_Sfp_TgIpcrsValid +( + QuadSPI_Type const * BaseAddr, + uint8 MdadInstance) +{ + uint32 RegValue = 0U; + if (MdadInstance < QuadSPI_MDAD_COUNT) + { + RegValue = (BaseAddr->MDAD[MdadInstance].TGIPCRS & QuadSPI_TGIPCRS_VLD_MASK) >> QuadSPI_TGIPCRS_VLD_SHIFT; + } + return (RegValue != 0U) ? TRUE : FALSE; +} + +#endif /* QSPI_IP_SFP_ENABLE_MDAD */ + +#if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON) + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Specifies the specific flash memory region starting address (around 64 KB boundary). + * + * Flash Region Start Address (FRAD0_WORD0 - FRAD7_WORD0) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] StartAddress 64 KB aligned start address of the flash region + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradStartAddress +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + uint32 StartAddress) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + BaseAddr->FRAD[FradInstance].WORD0 = StartAddress; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Specifies the specific flash memory region end address (around 64 KB boundary). + * + * Flash Region End Address (FRAD0_WORD1 - FRAD7_WORD1) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] EndAddress 64 KB aligned end address of the flash region + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradEndAddress +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + uint32 EndAddress) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + BaseAddr->FRAD[FradInstance].WORD1 = EndAddress; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the MD0ACP field in WORD2. + * + * Flash Region Privileges (FRAD0_WORD2 - FRAD7_WORD2): + * - Master Domain Access Control Policy (MD0ACP) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] MdAcp value to be written in MD0ACP + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradMd0Acp +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + uint8 MdAcp) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + uint32 RegValue = BaseAddr->FRAD[FradInstance].WORD2; + RegValue &= ~QuadSPI_WORD2_MD0ACP_MASK; + RegValue |= QuadSPI_WORD2_MD0ACP(MdAcp); + BaseAddr->FRAD[FradInstance].WORD2 = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the MD1ACP field in WORD2. + * + * Flash Region Privileges (FRAD0_WORD2 - FRAD7_WORD2): + * - Master Domain Access Control Policy (MD1ACP) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] MdAcp value to be written in MD0ACP + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradMd1Acp +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + uint8 MdAcp) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + uint32 RegValue = BaseAddr->FRAD[FradInstance].WORD2; + RegValue &= ~QuadSPI_WORD2_MD1ACP_MASK; + RegValue |= QuadSPI_WORD2_MD1ACP(MdAcp); + BaseAddr->FRAD[FradInstance].WORD2 = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Program the VLD bit of a FRAD descriptor. + * + * Flash Region Lock Control (FRAD0_WORD3 - FRAD7_WORD3): + * - Valid (VLD) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] Valid value to be written into VLD bit + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradValid +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + boolean Valid) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + uint32 RegValue = BaseAddr->FRAD[FradInstance].WORD3; + RegValue &= ~QuadSPI_WORD3_VLD_MASK; + RegValue |= QuadSPI_WORD3_VLD(Valid ? 1U : 0U); + BaseAddr->FRAD[FradInstance].WORD3 = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Program the LOCK field of a FRAD descriptor. + * + * Flash Region Lock Control (FRAD0_WORD3 - FRAD7_WORD3): + * - Descriptor Lock (LOCK) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] Lock value to be written into LOCK field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradLock +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + uint8 Lock) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + uint32 RegValue = BaseAddr->FRAD[FradInstance].WORD3; + RegValue &= ~QuadSPI_WORD3_LOCK_MASK; + RegValue |= QuadSPI_WORD3_LOCK(Lock); + BaseAddr->FRAD[FradInstance].WORD3 = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Program the EALO field of a FRAD descriptor. + * + * Flash Region Privileges (FRAD0_WORD2 - FRAD7_WORD2): + * - Exclusive Access Lock Owner (EALO) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] EaOwner value to be written into EALO field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradEaOwner +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + uint8 EaOwner) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + uint32 RegValue = BaseAddr->FRAD[FradInstance].WORD2; + RegValue &= ~QuadSPI_WORD2_EALO_MASK; + RegValue |= QuadSPI_WORD2_EALO(EaOwner); + BaseAddr->FRAD[FradInstance].WORD2 = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Program the EAL field of a FRAD descriptor. + * + * Flash Region Lock Control (FRAD0_WORD3 - FRAD7_WORD3): + * - Exclusive Access Lock (EAL) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * @param[in] EaLock value to be written into EAL field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetFradEaLock +( + QuadSPI_Type * BaseAddr, + uint8 FradInstance, + Qspi_Ip_SfpEalType EaLock) +{ + if (FradInstance < QuadSPI_FRAD_COUNT) + { + uint32 RegValue = BaseAddr->FRAD[FradInstance].WORD3; + RegValue &= ~QuadSPI_WORD3_EAL_MASK; + RegValue |= QuadSPI_WORD3_EAL(EaLock); + BaseAddr->FRAD[FradInstance].WORD3 = RegValue; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief This field provides exclusive write lock over a FRAD region based on MDnACP. + * + * Flash Region Lock Control (FRAD0_WORD3 - FRAD7_WORD3): + * - Exclusive Access Lock (EAL) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] FradInstance index of the FRAD descriptor to be configured + * + * @return the value read from the EAL field + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline uint8 Qspi_Ip_Sfp_FradEaLock +( + QuadSPI_Type const * BaseAddr, + uint8 FradInstance) +{ + uint32 RegValue = 0U; + if (FradInstance < QuadSPI_FRAD_COUNT) + { + RegValue = (BaseAddr->FRAD[FradInstance].WORD3 & QuadSPI_WORD3_LOCK_MASK) >> QuadSPI_WORD3_LOCK_SHIFT; + } + return (uint8)RegValue; +} + +#endif /* QSPI_IP_SFP_ENABLE_FRAD */ + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the timeout to abort the ongoing write or read command. + * + * Master Timeout (MTO): + * - Write Timeout (WRITE_TO) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] Timeout timeout value to be programmed into the register + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static inline void Qspi_Ip_Sfp_SetMasterTimeout +( + QuadSPI_Type * BaseAddr, + uint32 Timeout) +{ + BaseAddr->MTO = Timeout; +} + +#endif /* QSPI_IP_SFP_ENABLE_GLOBAL */ + +#endif /* FEATURE_QSPI_HAS_SFP */ + + +#endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_HWACCESS_H */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Hyperflash.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Hyperflash.h new file mode 100644 index 000000000..1629a886f --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Hyperflash.h @@ -0,0 +1,151 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_HYPERFLASH_H +#define QSPI_IP_HYPERFLASH_H + +/** +* @file Qspi_Ip_Hyperflash.h +* +* @addtogroup IPV_QSPI +* @{ +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + + + +/*================================================================================================== + * INCLUDE FILES +==================================================================================================*/ +#include "Qspi_Ip_Types.h" + + +/*================================================================================================== + * SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_HYPERFLASH_VENDOR_ID_H 43 +#define QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_H 4 +#define QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_H 7 +#define QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_H 0 +#define QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_H 2 +#define QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_H 0 +#define QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_H 0 + +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/*================================================================================================== + * FILE VERSION CHECKS +==================================================================================================*/ +/* Check if current file and Qspi_Ip_Types header file are of the same vendor */ +#if (QSPI_IP_HYPERFLASH_VENDOR_ID_H != QSPI_IP_TYPES_VENDOR_ID_CFG) + #error "Qspi_Ip_Hyperflash.h and Qspi_Ip_Types.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Types header file are of the same Autosar version */ +#if ((QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_H != QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_H != QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_H != QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Hyperflash.h and Qspi_Ip_Types.h are different" +#endif +/* Check if current file and Qspi_Ip_Types header file are of the same Software version */ +#if ((QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_H != QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG) || \ + (QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_H != QSPI_IP_TYPES_SW_MINOR_VERSION_CFG) || \ + (QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_H != QSPI_IP_TYPES_SW_PATCH_VERSION_CFG) \ + ) + #error "Software Version Numbers of Qspi_Ip_Hyperflash.h and Qspi_Ip_Types.h are different" +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +/*! + * @brief Initializes the hyper flash memory device + */ +Qspi_Ip_StatusType Qspi_Ip_HyperflashInit(uint32 instance); + + +/*! + * @brief Erases a specific sector. + * + */ +Qspi_Ip_StatusType Qspi_Ip_HyperflashSectorErase(uint32 instance, + uint32 sectorAddress + ); + + +/*! + * @brief Chip erase + */ +Qspi_Ip_StatusType Qspi_Ip_HyperflashChipErase(uint32 instance); + + +/*! + * @brief Writes between 1 and 512 bytes to write buffer. Addresses should be on the same line of data buffer. + */ +Qspi_Ip_StatusType Qspi_Ip_HyperflashProgram(uint32 instance, + uint32 address, + const uint8 * data, + uint32 size + ); + + +/*! + * @brief Read manufacturer ID from hyper flash. + */ +Qspi_Ip_StatusType Qspi_Ip_HyperflashReadId(uint32 instance, + uint32 wordAddress, + uint8 * data, + uint32 size + ); + + +/*! + * @brief Checks if the chip or a specific sector is erased + */ +Qspi_Ip_StatusType Qspi_Ip_HyperflashSectorBlankCheck(uint32 instance, + uint32 sectorAddress + ); + + +/*! + * @brief Returns the status of the last command + */ +Qspi_Ip_StatusType Qspi_Ip_HyperflashGetMemoryStatus(uint32 instance); + + +/*! + * @brief Patch a read command with the configured dummy cycles count + */ +void Qspi_Ip_HyperflashPatchReadCommand(uint32 instance, + uint16 lut + ); + + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +#endif /* QSPI_IP_MEM_INSTANCE_COUNT */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* QSPI_IP_HYPERFLASH_H */ + +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashRegs.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashRegs.h new file mode 100644 index 000000000..c2664ece0 --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashRegs.h @@ -0,0 +1,189 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_HYPERFLASHREGS_H +#define QSPI_IP_HYPERFLASHREGS_H + +#ifdef __cplusplus +extern "C"{ +#endif + + +/*================================================================================================== + * SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_HYPERFLASHREGS_VENDOR_ID_H 43 +#define QSPI_IP_HYPERFLASHREGS_AR_RELEASE_MAJOR_VERSION_H 4 +#define QSPI_IP_HYPERFLASHREGS_AR_RELEASE_MINOR_VERSION_H 7 +#define QSPI_IP_HYPERFLASHREGS_AR_RELEASE_REVISION_VERSION_H 0 +#define QSPI_IP_HYPERFLASHREGS_SW_MAJOR_VERSION_H 2 +#define QSPI_IP_HYPERFLASHREGS_SW_MINOR_VERSION_H 0 +#define QSPI_IP_HYPERFLASHREGS_SW_PATCH_VERSION_H 0 + + +/******************************************************************************* + * DEFINITIONS + ******************************************************************************/ + +/* Macros for Status Register bits manipulation */ + +#define QSPI_IP_HF_SR_ESTAT_MASK 0x100u +#define QSPI_IP_HF_SR_ESTAT_SHIFT 8u +#define QSPI_IP_HF_SR_ESTAT(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_ESTAT_SHIFT))&QSPI_IP_HF_SR_ESTAT_MASK) + +#define QSPI_IP_HF_SR_SLSB_MASK 0x200u +#define QSPI_IP_HF_SR_SLSB_SHIFT 9u +#define QSPI_IP_HF_SR_SLSB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_SLSB_SHIFT))&QSPI_IP_HF_SR_SLSB_MASK) + +#define QSPI_IP_HF_SR_PSSB_MASK 0x400u +#define QSPI_IP_HF_SR_PSSB_SHIFT 10u +#define QSPI_IP_HF_SR_PSSB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_PSSB_SHIFT))&QSPI_IP_HF_SR_PSSB_MASK) + +#define QSPI_IP_HF_SR_WBASB_MASK 0x800u +#define QSPI_IP_HF_SR_WBASB_SHIFT 11u +#define QSPI_IP_HF_SR_WBASB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_WBASB_SHIFT))&QSPI_IP_HF_SR_WBASB_MASK) + +#define QSPI_IP_HF_SR_PSB_MASK 0x1000u +#define QSPI_IP_HF_SR_PSB_SHIFT 12u +#define QSPI_IP_HF_SR_PSB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_PSB_SHIFT))&QSPI_IP_HF_SR_PSB_MASK) + +#define QSPI_IP_HF_SR_ESB_MASK 0x2000u +#define QSPI_IP_HF_SR_ESB_SHIFT 13u +#define QSPI_IP_HF_SR_ESB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_ESB_SHIFT))&QSPI_IP_HF_SR_ESB_MASK) + +#define QSPI_IP_HF_SR_ESSB_MASK 0x4000u +#define QSPI_IP_HF_SR_ESSB_SHIFT 14u +#define QSPI_IP_HF_SR_ESSB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_ESSB_SHIFT))&QSPI_IP_HF_SR_ESSB_MASK) + +#define QSPI_IP_HF_SR_DRB_MASK 0x8000u +#define QSPI_IP_HF_SR_DRB_SHIFT 15u +#define QSPI_IP_HF_SR_DRB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_DRB_SHIFT))&QSPI_IP_HF_SR_DRB_MASK) + +#define QSPI_IP_HF_SR_CRCSSB_MASK 0x1u +#define QSPI_IP_HF_SR_CRCSSB_SHIFT 1u +#define QSPI_IP_HF_SR_CRCSSB(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_SR_CRCSSB_SHIFT))&QSPI_IP_HF_SR_CRCSSB_MASK) + + /* Macros for x-Volatile Configuration Register */ + +#define QSPI_IP_HF_xVCR_BL_MASK 0x300u +#define QSPI_IP_HF_xVCR_BL_SHIFT 8u +#define QSPI_IP_HF_xVCR_BL(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_xVCR_BL_SHIFT))&QSPI_IP_HF_xVCR_BL_MASK) + +#define QSPI_IP_HF_xVCR_RWDS_MASK 0x400u +#define QSPI_IP_HF_xVCR_RWDS_SHIFT 10u +#define QSPI_IP_HF_xVCR_RWDS(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_xVCR_RWDS_SHIFT))&QSPI_IP_HF_xVCR_RWDS_MASK) + +#define QSPI_IP_HF_xVCR_RL_MASK 0xF000u +#define QSPI_IP_HF_xVCR_RL_SHIFT 12u +#define QSPI_IP_HF_xVCR_RL(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_xVCR_RL_SHIFT))&QSPI_IP_HF_xVCR_RL_MASK) + +#define QSPI_IP_HF_xVCR_PSM_MASK 0x3u +#define QSPI_IP_HF_xVCR_PSM_SHIFT 0u +#define QSPI_IP_HF_xVCR_PSM(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_xVCR_PSM_SHIFT))&QSPI_IP_HF_xVCR_PSM_MASK) + +#define QSPI_IP_HF_xVCR_SSR_MASK 0x4u +#define QSPI_IP_HF_xVCR_SSR_SHIFT 2u +#define QSPI_IP_HF_xVCR_SSR(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_xVCR_SSR_SHIFT))&QSPI_IP_HF_xVCR_SSR_MASK) + +#define QSPI_IP_HF_xVCR_FRZ_MASK 0x8u +#define QSPI_IP_HF_xVCR_FRZ_SHIFT 3u +#define QSPI_IP_HF_xVCR_FRZ(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_xVCR_FRZ_SHIFT))&QSPI_IP_HF_xVCR_FRZ_MASK) + +#define QSPI_IP_HF_xVCR_DS_MASK 0x70u +#define QSPI_IP_HF_xVCR_DS_SHIFT 4u +#define QSPI_IP_HF_xVCR_DS(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_xVCR_DS_SHIFT))&QSPI_IP_HF_xVCR_DS_MASK) + +/* Reserved bits of the Volatile/Non-Volatile Configuration register */ + +#define QSPI_IP_HF_xVCR_RESERVED_BIT_3 0x800u +#define QSPI_IP_HF_xVCR_RESERVED_BIT_16 0x80 + +/* Macros for ASP Register bits manipulation */ +#define QSPI_IP_HF_ASPR_READ_PASS_MODE_MASK 0x2000u +#define QSPI_IP_HF_ASPR_READ_PASS_MODE_SHIFT 13u +#define QSPI_IP_HF_ASPR_READ_PASS_MODE(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ASPR_READ_PASS_MODE_SHIFT))&QSPI_IP_HF_ASPR_READ_PASS_MODE_MASK) + +#define QSPI_IP_HF_ASPR_PROTECT_MODE_MASK 0x600u +#define QSPI_IP_HF_ASPR_PROTECT_MODE_SHIFT 9u +#define QSPI_IP_HF_ASPR_PROTECT_MODE(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ASPR_PROTECT_MODE_SHIFT))&QSPI_IP_HF_ASPR_PROTECT_MODE_MASK) + +#define QSPI_IP_HF_ASPR_HYB_BURST_MASK 0x8u +#define QSPI_IP_HF_ASPR_HYB_BURST_SHIFT 3u +#define QSPI_IP_HF_ASPR_HYB_BURST(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ASPR_HYB_BURST_SHIFT))&QSPI_IP_HF_ASPR_HYB_BURST_MASK) + +#define QSPI_IP_HF_ASPR_DEC_ECC_MASK 0x2u +#define QSPI_IP_HF_ASPR_DEC_ECC_SHIFT 1u +#define QSPI_IP_HF_ASPR_DEC_ECC(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ASPR_DEC_ECC_SHIFT))&QSPI_IP_HF_ASPR_DEC_ECC_MASK) + +#define QSPI_IP_HF_ASPR_RESERVED_MASK 0xD9F4u + +/* Interrupt Configuration Register bits manipulation */ + +#define QSPI_IP_HF_ICR_IOE_MASK 0x80u +#define QSPI_IP_HF_ICR_IOE_SHIFT 7u +#define QSPI_IP_HF_ICR_IOE(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ICR_IOE_SHIFT))&QSPI_IP_HF_ICR_IOE_MASK) + +#define QSPI_IP_HF_ICR_READY_MASK 0x1000u +#define QSPI_IP_HF_ICR_READY_SHIFT 12u +#define QSPI_IP_HF_ICR_READY(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ICR_READY_SHIFT))&QSPI_IP_HF_ICR_READY_MASK) + +#define QSPI_IP_HF_ICR_2BIT_DET_MASK 0x200u +#define QSPI_IP_HF_ICR_2BIT_DET_SHIFT 9u +#define QSPI_IP_HF_ICR_2BIT_DET(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ICR_2BIT_DET_SHIFT))&QSPI_IP_HF_ICR_2BIT_DET_MASK) + +#define QSPI_IP_HF_ICR_1BIT_DET_MASK 0x100u +#define QSPI_IP_HF_ICR_1BIT_DET_SHIFT 8u +#define QSPI_IP_HF_ICR_1BIT_DET(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ICR_1BIT_DET_SHIFT))&QSPI_IP_HF_ICR_1BIT_DET_MASK) + +/* Interrupt Status Register bits manipulation */ + +#define QSPI_IP_HF_ISR_IOE_MASK 0x80u +#define QSPI_IP_HF_ISR_IOE_SHIFT 7u +#define QSPI_IP_HF_ISR_IOE(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ISR_IOE_SHIFT))&QSPI_IP_HF_ISR_IOE_MASK) + +#define QSPI_IP_HF_ISR_POR_MASK 0x400u +#define QSPI_IP_HF_ISR_POR_SHIFT 10u +#define QSPI_IP_HF_ISR_POR(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ISR_POR_SHIFT))&QSPI_IP_HF_ISR_POR_MASK) + +#define QSPI_IP_HF_ISR_READY_MASK 0x1000u +#define QSPI_IP_HF_ISR_READY_SHIFT 12u +#define QSPI_IP_HF_ISR_READY(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ISR_READY_SHIFT))&QSPI_IP_HF_ISR_READY_MASK) + +#define QSPI_IP_HF_ISR_2BIT_DET_MASK 0x200u +#define QSPI_IP_HF_ISR_2BIT_DET_SHIFT 9u +#define QSPI_IP_HF_ISR_2BIT_DET(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ISR_2BIT_DET_SHIFT))&QSPI_IP_HF_ISR_2BIT_DET_MASK) + +#define QSPI_IP_HF_ISR_1BIT_DET_MASK 0x100u +#define QSPI_IP_HF_ISR_1BIT_DET_SHIFT 8u +#define QSPI_IP_HF_ISR_1BIT_DET(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ISR_1BIT_DET_SHIFT))&QSPI_IP_HF_ISR_1BIT_DET_MASK) + +/* ECC Status Register bits manipulation */ +#define QSPI_IP_HF_ECCSR_2BIT_DET_MASK 0x1000u +#define QSPI_IP_HF_ECCSR_2BIT_DET_SHIFT 12u +#define QSPI_IP_HF_ECCSR_2BIT_DET(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ECCSR_2BIT_DET_SHIFT))&QSPI_IP_HF_ECCSR_2BIT_DET_MASK) + +#define QSPI_IP_HF_ECCSR_1BIT_CR_MASK 0x800u +#define QSPI_IP_HF_ECCSR_1BIT_CR_SHIFT 11u +#define QSPI_IP_HF_ECCSR_1BIT_CR(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ECCSR_1BIT_CR_SHIFT))&QSPI_IP_HF_ECCSR_1BIT_CR_MASK) + +#define QSPI_IP_HF_ECCSR_ERR_ECC_MASK 0x400u +#define QSPI_IP_HF_ECCSR_ERR_ECC_SHIFT 10u +#define QSPI_IP_HF_ECCSR_ERR_ECC(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ECCSR_ERR_ECC_SHIFT))&QSPI_IP_HF_ECCSR_ERR_ECC_MASK) + +#define QSPI_IP_HF_ECCSR_ERRECC_UNIT_MASK 0x200u +#define QSPI_IP_HF_ECCSR_ERRECC_UNIT_SHIFT 9u +#define QSPI_IP_HF_ECCSR_ERRECC_UNIT(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ECCSR_ERRECC_UNIT_SHIFT))&QSPI_IP_HF_ECCSR_ERRECC_UNIT_MASK) + +#define QSPI_IP_HF_ECCSR_ECC_DISABLED_MASK 0x100u +#define QSPI_IP_HF_ECCSR_ECC_DISABLED_SHIFT 8u +#define QSPI_IP_HF_ECCSR_ECC_DISABLED(x) (((uint16)(((uint16)(x)) << QSPI_IP_HF_ECCSR_ECC_DISABLED_SHIFT))&QSPI_IP_HF_ECCSR_ECC_DISABLED_MASK) + +#ifdef __cplusplus +} +#endif + + +#endif /* QSPI_IP_HYPERFLASHREGS_H */ diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashTypes.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashTypes.h new file mode 100644 index 000000000..6e89a1e84 --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_HyperflashTypes.h @@ -0,0 +1,215 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_HYPERFLASHTYPES_H +#define QSPI_IP_HYPERFLASHTYPES_H + +/** +* @file Qspi_Ip_HyperflashTypes.h +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +/*================================================================================================== + * INCLUDE FILES +==================================================================================================*/ +#include "Std_Types.h" + + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_HYPERFLASHTYPES_VENDOR_ID 43 +#define QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_MAJOR_VERSION 4 +#define QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_MINOR_VERSION 7 +#define QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_REVISION_VERSION 0 +#define QSPI_IP_HYPERFLASHTYPES_SW_MAJOR_VERSION 2 +#define QSPI_IP_HYPERFLASHTYPES_SW_MINOR_VERSION 0 +#define QSPI_IP_HYPERFLASHTYPES_SW_PATCH_VERSION 0 + + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK + /* Check if Qspi_Ip_HyperflashTypes header file and Std_Types.h header file are of the same Autosar version */ + #if ((QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_MAJOR_VERSION != STD_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_MINOR_VERSION != STD_AR_RELEASE_MINOR_VERSION) \ + ) + #error "Autosar Version Numbers of Qspi_Ip_HyperflashTypes.h and Std_Types.h are different" + #endif +#endif + + +/******************************************************************************* +* Definitions +******************************************************************************/ + +/* Address of the sector selected. Address bits AMAX-A17 for 256KB sectors and AMAX-A11 for 4KB parameter sectors + Parameter-sectors need A[16:11] to identify the target address during erase and program command sequences + Unused bits are "no matter" (memory device will ignore them), so just use the smallest size in both cases + */ +#define QSPI_IP_HYPERFLASH_SECTOR_SIZE 0x1000U /* 4096-byte */ + + +/* LUT entries used for hyperflash command sequences */ +#define QSPI_IP_HF_LUT_COMMON_555_AA 0U /* Pre-command with address 0x555 and operand 0xAA */ +#define QSPI_IP_HF_LUT_COMMON_2AA_55 6U /* Pre-command with address 0x2AA and operand 0x55 */ +#define QSPI_IP_HF_LUT_READ 12U /* Read data linear */ +#define QSPI_IP_HF_LUT_WRITE 18U /* Write data */ +#define QSPI_IP_HF_LUT_RDSR 23U /* Read status register */ +#define QSPI_IP_HF_LUT_RDSR_SEQ2 29U /* Read status register second sequence */ +#define QSPI_IP_HF_LUT_WP 35U /* Word Programming */ +#define QSPI_IP_HF_LUT_WP_SEQ1 41U /* Word Programming second sequence */ + +#define QSPI_IP_HF_LUT_CMD_80 46U +#define QSPI_IP_HF_LUT_CMD_AA 52U +#define QSPI_IP_HF_LUT_CMD_55 58U +#define QSPI_IP_HF_LUT_SE 64U +#define QSPI_IP_HF_LUT_CE 70U +#define QSPI_IP_HF_LUT_RST 76U +#define QSPI_IP_HF_LUT_SRC 82U +#define QSPI_IP_HF_LUT_BC 88U +#define QSPI_IP_HF_LUT_CMD_25 94U +#define QSPI_IP_HF_LUT_WC 100U +#define QSPI_IP_HF_LUT_WB 106U +#define QSPI_IP_HF_LUT_PBF 111U +#define QSPI_IP_HF_LUT_PS 117U /* Program suspend */ +#define QSPI_IP_HF_LUT_PR 123U /* Program resume */ +#define QSPI_IP_HF_LUT_ES 129U /* Erase suspend */ +#define QSPI_IP_HF_LUT_ER 135U /* Erase resume */ +#define QSPI_IP_HF_LUT_RDNVCR 141U +#define QSPI_IP_HF_LUT_ENVCR 147U +#define QSPI_IP_HF_LUT_PNVCR 153U +#define QSPI_IP_HF_LUT_LDVCR 159U +#define QSPI_IP_HF_LUT_CMD_98 165U + +#define QSPI_IP_HF_LUT_SIZE 171U +#define QSPI_IP_HF_LUT_NAME Qspi_Ip_HyperflashLutTable + +/* Number of commands in the software reset sequence */ +#define QSPI_IP_HF_RST_CNT 1U + + +/******************************************************************************* + * Enumerations. + ******************************************************************************/ + +/*! +* @brief Parameter sector map +* +* This structure is used to configure how the Parameter-Sectors are used and how they are mapped into the address map. +*/ +typedef enum +{ + QSPI_IP_HF_PARAM_AND_PASSWORD_MAP_LOW = 0x00U, + QSPI_IP_HF_PARAM_AND_PASSWORD_MAP_HIGH = 0x01U, + QSPI_IP_HF_UNIFORM_SECTORS_READ_PASSWORD_LOW = 0x02U, + QSPI_IP_HF_UNIFORM_SECTORS_READ_PASSWORD_HIGH = 0x03U +} Qspi_Ip_HyperflashParamSectorMapType; + + +/*! +* @brief Drive strength +* +* Hyperflash driver strength settings. +*/ +typedef enum +{ + QSPI_IP_HF_DRV_STRENGTH_000 = 0x00U, /*!< Typical Impedance for 1.8V: 27, Typical Impedance 3V: 20 */ + QSPI_IP_HF_DRV_STRENGTH_001 = 0x01U, /*!< Typical Impedance for 1.8V: 117, Typical Impedance 3V: 71 */ + QSPI_IP_HF_DRV_STRENGTH_002 = 0x02U, /*!< Typical Impedance for 1.8V: 68, Typical Impedance 3V: 40 */ + QSPI_IP_HF_DRV_STRENGTH_003 = 0x03U, /*!< Typical Impedance for 1.8V: 45, Typical Impedance 3V: 27 */ + QSPI_IP_HF_DRV_STRENGTH_004 = 0x04U, /*!< Typical Impedance for 1.8V: 34, Typical Impedance 3V: 20 */ + QSPI_IP_HF_DRV_STRENGTH_005 = 0x05U, /*!< Typical Impedance for 1.8V: 27, Typical Impedance 3V: 16 */ + QSPI_IP_HF_DRV_STRENGTH_006 = 0x06U, /*!< Typical Impedance for 1.8V: 24, Typical Impedance 3V: 14 */ + QSPI_IP_HF_DRV_STRENGTH_007 = 0x07U /*!< Typical Impedance for 1.8V: 20, Typical Impedance 3V: 12 */ +} Qspi_Ip_HyperflashDrvStrengthType; + + +/*! +* @brief Read latency +* +*/ +typedef enum +{ + QSPI_IP_HF_READ_LATENCY_5_CLOCKS = 0U, /*!< Read latency 5 clocks */ + QSPI_IP_HF_READ_LATENCY_6_CLOCKS = 1U, /*!< Read latency 6 clocks */ + QSPI_IP_HF_READ_LATENCY_7_CLOCKS = 2U, /*!< Read latency 7 clocks */ + QSPI_IP_HF_READ_LATENCY_8_CLOCKS = 3U, /*!< Read latency 8 clocks */ + QSPI_IP_HF_READ_LATENCY_9_CLOCKS = 4U, /*!< Read latency 9 clocks */ + QSPI_IP_HF_READ_LATENCY_10_CLOCKS = 5U, /*!< Read latency 10 clocks */ + QSPI_IP_HF_READ_LATENCY_11_CLOCKS = 6U, /*!< Read latency 11 clocks */ + QSPI_IP_HF_READ_LATENCY_12_CLOCKS = 7U, /*!< Read latency 12 clocks */ + QSPI_IP_HF_READ_LATENCY_13_CLOCKS = 8U, /*!< Read latency 13 clocks */ + QSPI_IP_HF_READ_LATENCY_14_CLOCKS = 9U, /*!< Read latency 14 clocks */ + QSPI_IP_HF_READ_LATENCY_15_CLOCKS = 10U, /*!< Read latency 15 clocks */ + QSPI_IP_HF_READ_LATENCY_16_CLOCKS = 11U /*!< Read latency 16 clocks */ +} Qspi_Ip_HyperflashReadLatencyType; + + +/* ASO entries */ +typedef enum +{ + QSPI_IP_HF_PASSWORD_ASO_ENTRY = 0x60, /*!< Password ASO Entry command */ + QSPI_IP_HF_PPB_ASO_ENTRY = 0xC0, /*!< PPB ASO Entry command */ + QSPI_IP_HF_PPB_LOCK_ASO_ENTRY = 0x50, /*!< PPB Lock ASO Entry command */ + QSPI_IP_HF_DYB_ASO_ENTRY = 0xE0, /*!< DYB ASO Entry command */ + QSPI_IP_HF_ECC_ASO_ENTRY = 0x75, /*!< ECC ASO Entry command */ + QSPI_IP_HF_SSR_ASO_ENTRY = 0x88, /*!< Secure Silicon Region command */ + QSPI_IP_HF_CRC_ASO_ENTRY = 0x78, /*!< CRC ASO Entry command */ + QSPI_IP_HF_ASPR_ASO_ENTRY = 0x40, /*!< ASP Configuration Register ASO entry command */ + QSPI_IP_HF_FLASH_MEMORY_ARRAY = 0x00 /*!< No ASO entry */ +} Qspi_Ip_HyperflashAsoEntryCommandsType; + + +/*! +* @brief Sector protection type +* +*/ +typedef enum +{ + QSPI_IP_HF_SECTOR_UNLOCKED = 1U, /* Sector is not protected */ + QSPI_IP_HF_SECTOR_LOCKED_BY_PPB = 2U, /* Sector is protected by PPB bit */ + QSPI_IP_HF_SECTOR_LOCKED_BY_DYB = 3U, /* Sector is protected by DYB bit */ + QSPI_IP_HF_SECTOR_LOCKED_BY_PPB_DYB = 4U /* Sector is protected by PPB and DYB bits */ +} Qspi_Ip_HyperflashSectorProtectionType; + + +/******************************************************************************* +* Structures +******************************************************************************/ + +/*! +* @brief Hyperflash configuration structure +* + * This structure is used to provide configuration parameters for HyperFlash + * at initialization time. +*/ +typedef struct +{ + Qspi_Ip_HyperflashDrvStrengthType outputDriverStrength; /*!< Output driver level of the device */ + boolean RWDSLowOnDualError; /*!< Specifies if RWDS will stall upon Dual Error Detect */ + boolean secureRegionUnlocked; /*!< If true, the secure silicon region will be locked */ + Qspi_Ip_HyperflashReadLatencyType readLatency; /*!< Read latency */ + Qspi_Ip_HyperflashParamSectorMapType paramSectorMap; /*!< Parameter sector mapping */ + uint32 deviceIdWordAddress; /*!< The word address of the device Id in ASO */ +} Qspi_Ip_HyperFlashConfigType; + + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_HYPERFLASHTYPES_H */ diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_TrustedFunctions.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_TrustedFunctions.h new file mode 100644 index 000000000..8bbbaa79c --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_TrustedFunctions.h @@ -0,0 +1,105 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_TRUSTEDFUNCTIONS_H +#define QSPI_IP_TRUSTEDFUNCTIONS_H + +/** +* @file Qspi_Ip_TrustedFunctions.h +* +* @addtogroup IPV_QSPI +* @{ +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "Qspi_Ip_Types.h" + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_TRUSTEDFUNCTIONS_VENDOR_ID_H 43 +#define QSPI_IP_TRUSTEDFUNCTIONS_AR_RELEASE_MAJOR_VERSION_H 4 +#define QSPI_IP_TRUSTEDFUNCTIONS_AR_RELEASE_MINOR_VERSION_H 7 +#define QSPI_IP_TRUSTEDFUNCTIONS_AR_RELEASE_REVISION_VERSION_H 0 +#define QSPI_IP_TRUSTEDFUNCTIONS_SW_MAJOR_VERSION_H 2 +#define QSPI_IP_TRUSTEDFUNCTIONS_SW_MINOR_VERSION_H 0 +#define QSPI_IP_TRUSTEDFUNCTIONS_SW_PATCH_VERSION_H 0 + + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +/* Check if current file and Qspi_Ip_Types header file are of the same vendor */ +#if (QSPI_IP_TYPES_VENDOR_ID_CFG != QSPI_IP_TRUSTEDFUNCTIONS_VENDOR_ID_H) + #error "Qspi_Ip_TrustedFunctions.h and Qspi_Ip_Types.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Types header file are of the same Autosar version */ +#if ((QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG != QSPI_IP_TRUSTEDFUNCTIONS_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG != QSPI_IP_TRUSTEDFUNCTIONS_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG != QSPI_IP_TRUSTEDFUNCTIONS_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_TrustedFunctions.h and Qspi_Ip_Types.h are different" +#endif +/* Check if current file and Qspi_Ip_Types header file are of the same Software version */ +#if ((QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG != QSPI_IP_TRUSTEDFUNCTIONS_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_TYPES_SW_MINOR_VERSION_CFG != QSPI_IP_TRUSTEDFUNCTIONS_SW_MINOR_VERSION_H) || \ + (QSPI_IP_TYPES_SW_PATCH_VERSION_CFG != QSPI_IP_TRUSTEDFUNCTIONS_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_TrustedFunctions.h and Qspi_Ip_Types.h are different" +#endif + +/*================================================================================================== +* DEFINES AND MACROS +==================================================================================================*/ + + +/*================================================================================================== + GLOBAL VARIABLES +==================================================================================================*/ + + +/*================================================================================================== +* FUNCTION PROTOTYPES +==================================================================================================*/ + +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +#if (QSPI_IP_ENABLE_USER_MODE_SUPPORT == STD_ON) + +extern void Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr, + Qspi_Ip_ControllerConfigType const * userConfigPtr); + +extern void Qspi_Ip_Sfp_ClearLatchedErrors_Privileged(QuadSPI_Type * BaseAddr); + +extern void Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type * BaseAddr); + +extern void Qspi_Ip_WriteLuts_Privileged(uint32 Instance, + uint8 StartLutRegister, + const uint32 *Data, + uint8 Size + ); + +extern void Qspi_Ip_SetAhbSeqId_Privileged(uint32 instance, uint8 seqID); + +#endif /* QSPI_IP_ENABLE_USER_MODE_SUPPORT == STD_ON */ + + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_TRUSTEDFUNCTIONS_H */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h new file mode 100644 index 000000000..a7d1d19ff --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h @@ -0,0 +1,701 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_TYPES_H +#define QSPI_IP_TYPES_H + +/** +* @file Qspi_Ip_Types.h +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "Std_Types.h" +#include "Qspi_Ip_Features.h" +#include "Qspi_Ip_CfgDefines.h" +#include "Qspi_Ip_HyperflashTypes.h" + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_TYPES_VENDOR_ID_CFG 43 +#define QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG 4 +#define QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG 7 +#define QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG 0 +#define QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG 2 +#define QSPI_IP_TYPES_SW_MINOR_VERSION_CFG 0 +#define QSPI_IP_TYPES_SW_PATCH_VERSION_CFG 0 + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK + /* Check if Qspi_Ip_Types header file and Std_Types.h header file are of the same Autosar version */ + #if ((QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG != STD_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG != STD_AR_RELEASE_MINOR_VERSION) \ + ) + #error "Autosar Version Numbers of Qspi_Ip_Types.h and Std_Types.h are different" + #endif +#endif + +/* Check if current file and Qspi_Ip_Features header file are of the same vendor */ +#if (QSPI_IP_TYPES_VENDOR_ID_CFG != QSPI_IP_FEATURES_VENDOR_ID_CFG) + #error "Qspi_Ip_Types.h and Qspi_Ip_Features.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Features header file are of the same Autosar version */ +#if ((QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG != QSPI_IP_FEATURES_AR_RELEASE_MAJOR_VERSION_CFG) || \ + (QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG != QSPI_IP_FEATURES_AR_RELEASE_MINOR_VERSION_CFG) || \ + (QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG != QSPI_IP_FEATURES_AR_RELEASE_REVISION_VERSION_CFG) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Types.h and Qspi_Ip_Features.h are different" +#endif +/* Check if current file and Qspi_Ip_Features header file are of the same Software version */ +#if ((QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG != QSPI_IP_FEATURES_SW_MAJOR_VERSION_CFG) || \ + (QSPI_IP_TYPES_SW_MINOR_VERSION_CFG != QSPI_IP_FEATURES_SW_MINOR_VERSION_CFG) || \ + (QSPI_IP_TYPES_SW_PATCH_VERSION_CFG != QSPI_IP_FEATURES_SW_PATCH_VERSION_CFG) \ + ) + #error "Software Version Numbers of Qspi_Ip_Types.h and Qspi_Ip_Features.h are different" +#endif + +/* Check if current file and Qspi_Ip_CfgDefines header file are of the same vendor */ +#if (QSPI_IP_TYPES_VENDOR_ID_CFG != QSPI_IP_VENDOR_ID_CFG_DEFINES) + #error "Qspi_Ip_Types.h and Qspi_Ip_CfgDefines.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_CfgDefines header file are of the same Autosar version */ +#if ((QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG != QSPI_IP_AR_RELEASE_MAJOR_VERSION_CFG_DEFINES) || \ + (QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG != QSPI_IP_AR_RELEASE_MINOR_VERSION_CFG_DEFINES) || \ + (QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG != QSPI_IP_AR_RELEASE_REVISION_VERSION_CFG_DEFINES) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Types.h and Qspi_Ip_CfgDefines.h are different" +#endif +/* Check if current file and Qspi_Ip_CfgDefines header file are of the same Software version */ +#if ((QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG != QSPI_IP_SW_MAJOR_VERSION_CFG_DEFINES) || \ + (QSPI_IP_TYPES_SW_MINOR_VERSION_CFG != QSPI_IP_SW_MINOR_VERSION_CFG_DEFINES) || \ + (QSPI_IP_TYPES_SW_PATCH_VERSION_CFG != QSPI_IP_SW_PATCH_VERSION_CFG_DEFINES) \ + ) + #error "Software Version Numbers of Qspi_Ip_Types.h and Qspi_Ip_CfgDefines.h are different" +#endif + +/* Check if current file and Qspi_Ip_HyperflashTypes header file are of the same vendor */ +#if (QSPI_IP_TYPES_VENDOR_ID_CFG != QSPI_IP_HYPERFLASHTYPES_VENDOR_ID) + #error "Qspi_Ip_Types.h and Qspi_Ip_HyperflashTypes.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_HyperflashTypes header file are of the same Autosar version */ +#if ((QSPI_IP_TYPES_AR_RELEASE_MAJOR_VERSION_CFG != QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_TYPES_AR_RELEASE_MINOR_VERSION_CFG != QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_MINOR_VERSION) || \ + (QSPI_IP_TYPES_AR_RELEASE_REVISION_VERSION_CFG != QSPI_IP_HYPERFLASHTYPES_AR_RELEASE_REVISION_VERSION) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Types.h and Qspi_Ip_HyperflashTypes.h are different" +#endif +/* Check if current file and Qspi_Ip_HyperflashTypes header file are of the same Software version */ +#if ((QSPI_IP_TYPES_SW_MAJOR_VERSION_CFG != QSPI_IP_HYPERFLASHTYPES_SW_MAJOR_VERSION) || \ + (QSPI_IP_TYPES_SW_MINOR_VERSION_CFG != QSPI_IP_HYPERFLASHTYPES_SW_MINOR_VERSION) || \ + (QSPI_IP_TYPES_SW_PATCH_VERSION_CFG != QSPI_IP_HYPERFLASHTYPES_SW_PATCH_VERSION) \ + ) + #error "Software Version Numbers of Qspi_Ip_Types.h and Qspi_Ip_HyperflashTypes.h are different" +#endif + + +/******************************************************************************* + * Macros. + ******************************************************************************/ + +#if (CPU_TYPE == CPU_TYPE_64) + typedef uint64 Qspi_Ip_UintPtrType; +#elif (CPU_TYPE == CPU_TYPE_32) + typedef uint32 Qspi_Ip_UintPtrType; +#else + #error "Unsupported CPU_TYPE" +#endif + +/*! Number of erase types that can be supported by a flash device */ +#define QSPI_IP_ERASE_TYPES (4U) + +/*! @brief Number of AHB buffers in the device */ +#define QSPI_IP_AHB_BUFFERS (4U) + +/*! Invalid index in virtual LUT, used for unsupported features */ +#define QSPI_IP_LUT_INVALID (uint16)0xFFFFU + +/*! End operation for a LUT sequence */ +#define QSPI_IP_LUT_SEQ_END (uint16)0x0U + +/*! Pack the two operations into a LUT register (each operation is a pair of instruction-operand) */ +#define QSPI_IP_PACK_LUT_REG(ops0, ops1) ( (uint32)(ops0) + ((uint32)(ops1) << 16U) ) + + +/******************************************************************************* + * Enumerations. + ******************************************************************************/ + +/*! @brief qspi return codes + */ +typedef enum +{ + STATUS_QSPI_IP_SUCCESS = 0x00U, /*!< Successful job */ + STATUS_QSPI_IP_ERROR = 0x01U, /*!< IP is performing an operation */ + STATUS_QSPI_IP_BUSY = 0x02U, /*!< Error - general code */ + STATUS_QSPI_IP_TIMEOUT = 0x03U, /*!< Error - exceeded timeout */ + STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY = 0x04U, /*!< Error - selected memory area doesn't contain desired value */ + STATUS_QSPI_IP_ERROR_BLANK_CHECK = 0x05U, /*!< Error - selected memory area isn't in erased state */ +} Qspi_Ip_StatusType; + + +/*! @brief flash connection to the QSPI module + */ +typedef enum +{ + QSPI_IP_SIDE_A1 = 0x00U, /*!< Serial flash connected on side A1 */ + QSPI_IP_SIDE_A2 = 0x01U, /*!< Serial flash connected on side A2 */ + QSPI_IP_SIDE_B1 = 0x02U, /*!< Serial flash connected on side B1 */ + QSPI_IP_SIDE_B2 = 0x03U, /*!< Serial flash connected on side B2 */ +} Qspi_Ip_ConnectionType; + + +/*! @brief flash operation type + */ +typedef enum +{ + QSPI_IP_OP_TYPE_CMD = 0x00U, /*!< Simple command */ + QSPI_IP_OP_TYPE_WRITE_REG = 0x01U, /*!< Write value in external flash register */ + QSPI_IP_OP_TYPE_RMW_REG = 0x02U, /*!< RMW command on external flash register */ + QSPI_IP_OP_TYPE_READ_REG = 0x03U, /*!< Read external flash register until expected value is read */ + QSPI_IP_OP_TYPE_QSPI_CFG = 0x04U, /*!< Re-configure QSPI controller */ +} Qspi_Ip_OpType; + +/*! @brief Lut commands + */ +typedef enum +{ + QSPI_IP_LUT_INSTR_STOP = (0U << 10U), /*!< End of sequence */ + QSPI_IP_LUT_INSTR_CMD = (1U << 10U), /*!< Command */ + QSPI_IP_LUT_INSTR_ADDR = (2U << 10U), /*!< Address */ + QSPI_IP_LUT_INSTR_DUMMY = (3U << 10U), /*!< Dummy cycles */ + QSPI_IP_LUT_INSTR_MODE = (4U << 10U), /*!< 8-bit mode */ + QSPI_IP_LUT_INSTR_MODE2 = (5U << 10U), /*!< 2-bit mode */ + QSPI_IP_LUT_INSTR_MODE4 = (6U << 10U), /*!< 4-bit mode */ + QSPI_IP_LUT_INSTR_READ = (7U << 10U), /*!< Read data */ + QSPI_IP_LUT_INSTR_WRITE = (8U << 10U), /*!< Write data */ + QSPI_IP_LUT_INSTR_JMP_ON_CS = (9U << 10U), /*!< Jump on chip select deassert and stop */ + QSPI_IP_LUT_INSTR_ADDR_DDR = (10U << 10U), /*!< Address - DDR mode */ + QSPI_IP_LUT_INSTR_MODE_DDR = (11U << 10U), /*!< 8-bit mode - DDR mode */ + QSPI_IP_LUT_INSTR_MODE2_DDR = (12U << 10U), /*!< 2-bit mode - DDR mode */ + QSPI_IP_LUT_INSTR_MODE4_DDR = (13U << 10U), /*!< 4-bit mode - DDR mode */ + QSPI_IP_LUT_INSTR_READ_DDR = (14U << 10U), /*!< Read data - DDR mode */ + QSPI_IP_LUT_INSTR_WRITE_DDR = (15U << 10U), /*!< Write data - DDR mode */ + QSPI_IP_LUT_INSTR_DATA_LEARN = (16U << 10U), /*!< Data learning pattern */ + QSPI_IP_LUT_INSTR_CMD_DDR = (17U << 10U), /*!< Command - DDR mode */ + QSPI_IP_LUT_INSTR_CADDR = (18U << 10U), /*!< Column address */ + QSPI_IP_LUT_INSTR_CADDR_DDR = (19U << 10U), /*!< Column address - DDR mode */ + QSPI_IP_LUT_INSTR_JMP_TO_SEQ = (20U << 10U), /*!< Jump on chip select deassert and continue */ +} Qspi_Ip_LutCommandsType; + +/*! @brief Lut pad options + */ +typedef enum +{ + QSPI_IP_LUT_PADS_1 = (0U << 8U), /*!< 1 Pad */ + QSPI_IP_LUT_PADS_2 = (1U << 8U), /*!< 2 Pads */ + QSPI_IP_LUT_PADS_4 = (2U << 8U), /*!< 4 Pads */ + QSPI_IP_LUT_PADS_8 = (3U << 8U), /*!< 8 Pads */ +} Qspi_Ip_LutPadsType; + +/*! + * @brief Operation in a LUT sequence. + * + * This type describes one basic operation inside a LUT sequence. Each operation contains: + * - instruction (6 bits) + * - number of PADs (2 bits) + * - operand (8 bits) + * Qspi_Ip_LutCommandsType and Qspi_Ip_LutPadsType types should be used to form operations + */ +typedef uint16 Qspi_Ip_InstrOpType; + +/*! @brief Read mode + */ +typedef enum +{ +#if (FEATURE_QSPI_INTERNAL_DQS == 1) + QSPI_IP_READ_MODE_INTERNAL_DQS = 0U, /*!< Use internally generated strobe signal */ +#endif +#if (FEATURE_QSPI_LOOPBACK == 1) + QSPI_IP_READ_MODE_LOOPBACK = 1U, /*!< Use loopback clock from PAD as strobe signal */ +#endif +#if (FEATURE_QSPI_LOOPBACK_DQS == 1) + QSPI_IP_READ_MODE_LOOPBACK_DQS = 2U, /*!< Use loopback clock from PAD as strobe signal */ +#endif + QSPI_IP_READ_MODE_EXTERNAL_DQS = 3U, /*!< Use external strobe signal */ +} Qspi_Ip_ReadModeType; + + +/*! @brief Clock phase used for sampling Rx data + */ +typedef enum +{ + QSPI_IP_DATA_RATE_SDR = 0U, /*!< Single data rate */ + QSPI_IP_DATA_RATE_DDR = 1U, /*!< Double data rate */ +} Qspi_Ip_DataRateType; + + +/*! @brief Delay used for sampling Rx data + */ +typedef enum +{ + QSPI_IP_SAMPLE_DELAY_SAME_DQS = 0U, /*!< Same DQS */ + QSPI_IP_SAMPLE_DELAY_HALFCYCLE_EARLY_DQS = 1U, /*!< Half-cycle early DQS */ +} Qspi_Ip_SampleDelayType; + +/*! @brief Clock phase used for sampling Rx data + */ +typedef enum +{ + QSPI_IP_SAMPLE_PHASE_NON_INVERTED = 0U, /*!< Sampling at non-inverted clock */ + QSPI_IP_SAMPLE_PHASE_INVERTED = 1U, /*!< Sampling at inverted clock */ +} Qspi_Ip_SamplePhaseType; + +/*! @brief Alignment of outgoing data with serial clock + */ +typedef enum +{ + QSPI_IP_FLASH_DATA_ALIGN_REFCLK = 0U, /*!< Data aligned with the posedge of Internal reference clock of QSPI */ + QSPI_IP_FLASH_DATA_ALIGN_2X_REFCLK = 1U, /*!< Data aligned with 2x serial flash half clock */ +} Qspi_Ip_FlashDataAlignType; + +/*! @brief DLL configuration modes + */ +typedef enum +{ + QSPI_IP_DLL_BYPASSED = 0U, /*!< DLL bypass mode */ + QSPI_IP_DLL_MANUAL_UPDATE = 1U, /*!< DLL manual update mode */ + QSPI_IP_DLL_AUTO_UPDATE = 2U, /*!< DLL auto update mode */ +} Qspi_Ip_DllModeType; + +/*! @brief Init callout pointer type +*/ +typedef Qspi_Ip_StatusType (*Qspi_Ip_InitCalloutPtrType)(uint32 instance); + +/*! @brief Reset callout pointer type +*/ +typedef Qspi_Ip_StatusType (*Qspi_Ip_ResetCalloutPtrType)(uint32 instance); + +/*! @brief Error Check callout pointer type +*/ +typedef Qspi_Ip_StatusType (*Qspi_Ip_ErrorCheckCalloutPtrType)(uint32 instance); + +/*! @brief Ecc Check callout pointer type +*/ +typedef Qspi_Ip_StatusType (*Qspi_Ip_EccCheckCalloutPtrType)(uint32 instance, uint32 startAddress, uint32 dataLength); + + +/******************************************************************************* +* Definitions +******************************************************************************/ + +/*! + * @brief DLL configuration structure + * + * This structure contains initialization settings for DLL and slave delay chain + */ +typedef struct +{ + Qspi_Ip_DllModeType dllMode; /*!< Mode in which DLL is used */ + boolean freqEnable; /*!< Selects delay-chain for high frequency of operation */ + uint8 referenceCounter; /*!< Select the "n+1" interval of DLL phase detection and reference delay updating interval */ + uint8 resolution; /*!< Minimum resolution for DLL phase detector */ + uint8 coarseDelay; /*!< Coarse delay DLL slave delay chain */ + uint8 fineDelay; /*!< Fine delay DLL slave delay chain */ + uint8 tapSelect; /*!< Selects the Nth tap provided by the slave delay-chain */ +} Qspi_Ip_DllSettingsType; + +/*! + * @brief AHB configuration structure + * + * This structure is used to provide configuration parameters for AHB access + * to the external flash + */ +typedef struct +{ + uint8 masters[QSPI_IP_AHB_BUFFERS]; /*!< List of AHB masters assigned to each buffer */ + uint16 sizes[QSPI_IP_AHB_BUFFERS]; /*!< List of buffer sizes */ + boolean allMasters; /*!< Indicates that any master may access the last buffer */ +} Qspi_Ip_ControllerAhbConfigType; + +#if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148) +/*! @brief Source of QuadSPI AHB read interface, module and bus interface clock + */ +typedef enum +{ + QSPI_IP_CLK_SRC_SYS_CLK = 0U, /*!< FIRC_DIV1 is clock source of QuadSPI internal reference clock */ + QSPI_IP_CLK_SRC_BUS_CLK = 1U, /*!< PLL_DIV1 is clock source of QuadSPI internal reference clock */ +} Qspi_Ip_ClockSourceType; + +/*! @brief Source of QuadSPI internal reference clock + */ +typedef enum +{ + QSPI_IP_CLK_REF_PLL_DIV1 = 0U, /*!< PLL_DIV1 is clock source of QuadSPI internal reference clock */ + QSPI_IP_CLK_REF_FIRC_DIV1 = 1U, /*!< FIRC_DIV1 is clock source of QuadSPI internal reference clock */ +} Qspi_Ip_ClockReferenceType; +#endif + + +#if (FEATURE_QSPI_HAS_SFP == 1) + +/** Access control type */ +typedef enum +{ + QSPI_IP_SFP_ALL, + QSPI_IP_SFP_MDAD, + QSPI_IP_SFP_FRAD +} Qspi_Ip_Sfp_AccessControlType; + +#if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON) + +#if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON) + +typedef enum +{ + QSPI_IP_SFP_RESERVED, + QSPI_IP_SFP_UNSECURE, + QSPI_IP_SFP_SECURE, + QSPI_IP_SFP_BOTH +} Qspi_Ip_SfpSaType; + +typedef enum +{ + QSPI_IP_SFP_MASK_AND, + QSPI_IP_SFP_MASK_OR +} Qspi_Ip_SfpMasktypeType; + +typedef struct +{ + Qspi_Ip_SfpSaType SecureAttribute; + Qspi_Ip_SfpMasktypeType MaskType; + boolean Valid; + uint8 Mask; + uint8 DomainId; +} Qspi_Ip_SfpTgCfgType; + +#endif /* QSPI_IP_SFP_ENABLE_MDAD */ + +#if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON) + +/** FRADn_WORD3 :: Exclusive access Lock [EAL] */ +typedef enum +{ + QSPI_IP_SFP_EAL_DISABLED = 0, + QSPI_IP_SFP_EAL_NONE = 2, + QSPI_IP_SFP_EAL_OWNER = 3 +} Qspi_Ip_SfpEalType; + +/** Access Control Policy for write operations */ +typedef enum +{ + QSPI_IP_SFP_ACP_NONE = 0, + QSPI_IP_SFP_ACP_SECURE = 4, + QSPI_IP_SFP_ACP_SECURE_PRIVILEGED = 5, + QSPI_IP_SFP_ACP_ALL = 6, + QSPI_IP_SFP_ACP_PRIVILEGED = 7 +} Qspi_Ip_SfpAcpType; + +typedef struct +{ + uint32 StartAddress; + uint32 EndAddress; + boolean Valid; + Qspi_Ip_SfpAcpType Md0Acp; + Qspi_Ip_SfpAcpType Md1Acp; + Qspi_Ip_SfpEalType ExclusiveAccessLock; + uint8 ExclusiveAccessOwner; +} Qspi_Ip_SfpFradCfgType; + +#endif /* QSPI_IP_SFP_ENABLE_FRAD */ + +typedef struct +{ + uint32 MasterTimeout; +#if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON) + Qspi_Ip_SfpTgCfgType Tg[QuadSPI_MDAD_COUNT]; +#endif +#if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON) + Qspi_Ip_SfpFradCfgType Frad[QuadSPI_FRAD_COUNT]; +#endif +} Qspi_Ip_SfpConfigType; + +#endif /* QSPI_IP_SFP_ENABLE_GLOBAL */ + +#endif /* FEATURE_QSPI_HAS_SFP */ + + +/*! + * @brief Driver configuration structure + * + * This structure is used to provide configuration parameters for the qspi driver + * at initialization time. + */ +typedef struct +{ +#if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148) + Qspi_Ip_ClockSourceType clockSrc; /*!< AHB read interface, module and bus interface clock */ + Qspi_Ip_ClockReferenceType clockRef; /*!< Internal reference clock (async clock domain) */ + uint8 clockRefDiv; /*!< Divider value for internal reference clock */ + boolean dqsInvertA; /*!< Inverted reference clock selection for DQS Flash A */ + boolean dqsInvertB; /*!< Inverted reference clock selection for DQS Flash B */ + uint8 dqsDelayA; /*!< Fine delay chain configuration for Flash A */ + uint8 dqsDelayB; /*!< Fine delay chain configuration for Flash B */ +#endif + + Qspi_Ip_DataRateType dataRate; /*!< Single/double data rate */ + uint32 memSizeA1; /*!< Size of serial flash A1 */ + uint32 memSizeA2; /*!< Size of serial flash A2 */ + uint32 memSizeB1; /*!< Size of serial flash B1 */ + uint32 memSizeB2; /*!< Size of serial flash B2 */ + uint8 csHoldTime; /*!< CS hold time, expressed in serial clock cycles */ + uint8 csSetupTime; /*!< CS setup time, expressed in serial clock cycles */ + uint8 columnAddr; /*!< Width of the column address, 0 if not used */ + boolean wordAddresable; /*!< True if serial flash is word addressable */ + Qspi_Ip_ReadModeType readModeA; /*!< Read mode for incoming data from serial flash A */ + Qspi_Ip_ReadModeType readModeB; /*!< Read mode for incoming data from serial flash B */ + Qspi_Ip_SampleDelayType sampleDelay; /*!< Delay (in clock cycles) used for sampling Rx data */ + Qspi_Ip_SamplePhaseType samplePhase; /*!< Clock phase used for sampling Rx data */ + + Qspi_Ip_DllSettingsType dllSettingsA; /*!< DLL settings for side A */ + Qspi_Ip_DllSettingsType dllSettingsB; /*!< DLL settings for side B */ + + boolean centerAlignedStrobeA; /*!< Enable center-aligned read strobe */ + boolean centerAlignedStrobeB; /*!< Enable center-aligned read strobe */ + boolean differentialClockA; /*!< Enable clock on differential CKN pad */ + boolean differentialClockB; /*!< Enable clock on differential CKN pad */ + Qspi_Ip_FlashDataAlignType dataAlign; /*!< Alignment of output data sent to serial flash */ + uint8 io2IdleValueA; /*!< (0 / 1) Logic level of IO[2] signal when not used on side A */ + uint8 io3IdleValueA; /*!< (0 / 1) Logic level of IO[3] signal when not used on side A */ + uint8 io2IdleValueB; /*!< (0 / 1) Logic level of IO[2] signal when not used on side B */ + uint8 io3IdleValueB; /*!< (0 / 1) Logic level of IO[3] signal when not used on side B */ + boolean byteSwap; /*!< Enable byte swap in octal DDR mode */ +#if (FEATURE_QSPI_HAS_SFP == 1) +#if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON) + Qspi_Ip_SfpConfigType SfpCfg; +#endif +#endif + Qspi_Ip_ControllerAhbConfigType ahbConfig; /*!< AHB buffers configuration */ +} Qspi_Ip_ControllerConfigType; + + /*! + * @brief Status register configuration structure + * + * This structure contains information about the status registers of the external flash + */ +typedef struct +{ + uint16 statusRegInitReadLut; /*!< Command used to read the status register during initialization */ + uint16 statusRegReadLut; /*!< Command used to read the status register */ + uint16 statusRegWriteLut; /*!< Command used to write the status register */ + uint16 writeEnableSRLut; /*!< Write enable command used before writing to status register */ + uint16 writeEnableLut; /*!< Write enable command used before write or erase operations */ + uint8 regSize; /*!< Size in bytes of status register */ + uint8 busyOffset; /*!< Position of "busy" bit inside status register */ + uint8 busyValue; /*!< Value of "busy" bit which indicates that the device is busy; can be 0 or 1 */ + uint8 writeEnableOffset; /*!< Position of "write enable" bit inside status register */ + uint8 blockProtectionOffset; /*!< Offset of block protection bits inside status register */ + uint8 blockProtectionWidth; /*!< Width of block protection bitfield */ + uint8 blockProtectionValue; /*!< Value of block protection bitfield, indicate the protected area */ +} Qspi_Ip_StatusConfigType; + + + /*! + * @brief Describes one type of erase + * + * This structure contains information about one type of erase supported by the external flash + */ +typedef struct +{ + uint16 eraseLut; /*!< Lut index for erase command */ + uint8 size; /*!< Size of the erased area: 2 ^ size; e.g. 0x0C means 4 Kbytes */ +} Qspi_Ip_EraseVarConfigType; + + + /*! + * @brief Erase capabilities configuration structure + * + * This structure contains information about the erase capabilities of the external flash + */ +typedef struct +{ + Qspi_Ip_EraseVarConfigType eraseTypes[QSPI_IP_ERASE_TYPES]; /*!< Erase types supported by the device */ + uint16 chipEraseLut; /*!< Lut index for chip erase command */ +} Qspi_Ip_EraseConfigType; + + + /*! + * @brief Read Id capabilities configuration structure + * + * This structure contains information about the read manufacturer/device ID command + */ +typedef struct +{ + uint16 readIdLut; /*!< Read Id command */ + uint8 readIdSize; /*!< Size of data returned by Read Id command */ + uint8 readIdExpected[FEATURE_EXFLS_FLASH_MDID_SIZE]; /*!< Device ID configured value (Memory density | Memory type | Manufacturer ID) */ +} Qspi_Ip_ReadIdConfigType; + + + /*! + * @brief Suspend capabilities configuration structure + * + * This structure contains information about the Program / Erase Suspend capabilities of the external flash + */ +typedef struct +{ + uint16 eraseSuspendLut; /*!< Lut index for the erase suspend operation */ + uint16 eraseResumeLut; /*!< Lut index for the erase resume operation */ + uint16 programSuspendLut; /*!< Lut index for the program suspend operation */ + uint16 programResumeLut; /*!< Lut index for the program resume operation */ +} Qspi_Ip_SuspendConfigType; + + +/*! + * @brief Soft Reset capabilities configuration structure + * + * This structure contains information about the Soft Reset capabilities of the external flash + */ +typedef struct +{ + uint16 resetCmdLut; /*!< First command in reset sequence */ + uint8 resetCmdCount; /*!< Number of commands in reset sequence */ +} Qspi_Ip_ResetConfigType; + + +/*! +* @brief Last command that was executed by the device flash +*/ +typedef enum +{ + QSPI_IP_LAST_COMMAND_NONE = 0U, /* Command in progress */ + QSPI_IP_LAST_COMMAND_WRITE = 1U, /* Erase command */ + QSPI_IP_LAST_COMMAND_ERASE = 2U, /* write command */ + QSPI_IP_LAST_COMMAND_WRITE_BUFFER_ABORT = 3U, /* Write buffer abort or CRC calculation abort */ + QSPI_IP_LAST_COMMAND_WRITE_SUSPEND = 4U, /* Write suspend command */ + QSPI_IP_LAST_COMMAND_ERASE_SUSPEND = 5U, /* Erase command */ + QSPI_IP_LAST_COMMAND_SECTOR_ERASE_STATUS = 6U, /* Sector erase command */ + QSPI_IP_LAST_COMMAND_CRC_SUSPEND = 7U /* CRC suspend command */ +} Qspi_Ip_LastCommandType; + + +/*! + * @brief List of LUT sequences. + * + * List of LUT sequences. Each sequence describes a command to the external flash. Sequences are separated by a 0 operation + */ +typedef struct +{ + uint16 opCount; /*!< Number of operations in the LUT table */ + Qspi_Ip_InstrOpType *lutOps; /*!< List of operations */ +} Qspi_Ip_LutConfigType; + + +/*! + * @brief Initialization operation + * + * This structure describes one initialization operation. + */ +typedef struct +{ + Qspi_Ip_OpType opType; /*!< Operation type */ + uint16 command1Lut; /*!< Index of first command sequence in Lut; for RMW type this is the read command */ + uint16 command2Lut; /*!< Index of second command sequence in Lut, only used for RMW type, this is the write command */ + uint16 weLut; /*!< Index of write enable sequence in Lut, only used for Write and RMW type */ + uint32 addr; /*!< Address, if used in command. */ + uint8 size; /*!< Size in bytes of configuration register */ + uint8 shift; /*!< Position of configuration field inside the register */ + uint8 width; /*!< Width in bits of configuration field. */ + uint32 value; /*!< Value to set in the field */ + const Qspi_Ip_ControllerConfigType *ctrlCfgPtr; /*!< New controller configuration, valid only for QSPI_IP_OP_TYPE_QSPI_CFG type */ +} Qspi_Ip_InitOperationType; + + +/*! + * @brief Initialization sequence + * + * Describe sequence that will be performed only once during initialization to put the flash in the desired state for operation. + * This may include, for example, setting the QE bit, activating 4-byte addressing, activating XPI mode + */ +typedef struct +{ + uint8 opCount; /*!< Number of operations */ + Qspi_Ip_InitOperationType * operations; /*!< List of operations */ +} Qspi_Ip_InitConfigType; + + +/*! +* @brief Parameter memory type +*/ +typedef enum +{ + QSPI_IP_HYPER_FLASH = 1U, /*!< Hyperbus devices */ + QSPI_IP_SERIAL_FLASH = 0U /*!< Traditional xSPI devices */ +} Qspi_Ip_FlashMemoryType; + + +/*! + * @brief Driver configuration structure + * + * This structure is used to provide configuration parameters for the external flash driver + * at initialization time. + */ +typedef struct +{ + Qspi_Ip_FlashMemoryType memType; /*!< Mmemory device type */ + const Qspi_Ip_HyperFlashConfigType * hfConfig; /*!< Hyperflash configuration, NULL if not used */ + uint32 memSize; /*!< Memory size (in bytes) */ + uint32 pageSize; /*!< Page size (in bytes) */ + uint16 readLut; /*!< Command used to read data from flash */ + uint16 writeLut; /*!< Command used to write data to flash */ + uint16 read0xxLut; /*!< 0-x-x mode read command */ + uint16 read0xxLutAHB; /*!< 0-x-x mode AHB read command */ + Qspi_Ip_ReadIdConfigType readIdSettings; /*!< Erase settings of the external flash */ + Qspi_Ip_EraseConfigType eraseSettings; /*!< Erase settings of the external flash */ + Qspi_Ip_StatusConfigType statusConfig; /*!< Status register information */ + Qspi_Ip_SuspendConfigType suspendSettings; /*!< Program / Erase Suspend settings */ + Qspi_Ip_ResetConfigType resetSettings; /*!< Soft Reset settings, used at runtime */ + Qspi_Ip_ResetConfigType initResetSettings; /*!< Soft Reset settings, used for first time reset */ + Qspi_Ip_InitConfigType initConfiguration; /*!< Operations for initial flash configuration */ + Qspi_Ip_LutConfigType lutSequences; /*!< List of LUT sequences describing flash commands */ + Qspi_Ip_InitCalloutPtrType initCallout; /*!< Pointer to init callout */ + Qspi_Ip_ResetCalloutPtrType resetCallout; /*!< Pointer to reset callout */ + Qspi_Ip_ErrorCheckCalloutPtrType errorCheckCallout; /*!< Pointer to error check callout */ + Qspi_Ip_EccCheckCalloutPtrType eccCheckCallout; /*!< Pointer to ecc check callout */ + const Qspi_Ip_ControllerConfigType * ctrlAutoCfgPtr; /*!< Initial controller configuration, if needed */ +} Qspi_Ip_MemoryConfigType; + + +/*! + * @brief Flash-controller conections configuration structure + * + * This structure specifies thte connecctions of each flash device to QSPI controllers + * at initialization time. + */ +typedef struct +{ + uint32 qspiInstance; /*!< QSPI Instance where this device is connected */ + Qspi_Ip_ConnectionType connectionType; /*!< Device connection to QSPI module */ + uint8 memAlignment; /*!< Memory alignment required by the external flash */ +} Qspi_Ip_MemoryConnectionType; + + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_TYPES_H */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c new file mode 100644 index 000000000..5672cc49d --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c @@ -0,0 +1,1970 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** +* @file Qspi_Ip.c +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "Mcal.h" +#include "OsIf.h" +#include "Qspi_Ip_Controller.h" +#include "Qspi_Ip_Common.h" +#include "Qspi_Ip.h" +#include "Qspi_Ip_Hyperflash.h" + + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_VENDOR_ID_C 43 +#define QSPI_IP_AR_RELEASE_MAJOR_VERSION_C 4 +#define QSPI_IP_AR_RELEASE_MINOR_VERSION_C 7 +#define QSPI_IP_AR_RELEASE_REVISION_VERSION_C 0 +#define QSPI_IP_SW_MAJOR_VERSION_C 2 +#define QSPI_IP_SW_MINOR_VERSION_C 0 +#define QSPI_IP_SW_PATCH_VERSION_C 0 +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK + /* Check if current file and Mcal.h header file are of the same Autosar version */ + #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != MCAL_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != MCAL_AR_RELEASE_MINOR_VERSION) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.c and Mcal.h are different" + #endif + + /* Check if current file and OsIf.h header file are of the same Autosar version */ + #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.c and OsIf.h are different" + #endif +#endif + +/* Check if current file and Qspi_Ip_Controller header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H) + #error "Qspi_Ip.c and Qspi_Ip_Controller.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip_Controller.h are different" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \ + (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip_Controller.h are different" +#endif + +/* Check if current file and Qspi_Ip_Common header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_C != QSPI_IP_COMMON_VENDOR_ID_H) + #error "Qspi_Ip.c and Qspi_Ip_Common.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Common header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip_Common.h are different" +#endif +/* Check if current file and Qspi_Ip_Common header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_COMMON_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_COMMON_SW_MINOR_VERSION_H) || \ + (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_COMMON_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip_Common.h are different" +#endif + +/* Check if current file and Qspi_Ip header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H) + #error "Qspi_Ip.c and Qspi_Ip.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip.h are different" +#endif +/* Check if current file and Qspi_Ip header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \ + (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip.h are different" +#endif + +/* Check if current file and Qspi_Ip_Hyperflash header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_C != QSPI_IP_HYPERFLASH_VENDOR_ID_H) + #error "Qspi_Ip.c and Qspi_Ip_Hyperflash.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Hyperflash header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip.c and Qspi_Ip_Hyperflash.h are different" +#endif +/* Check if current file and Qspi_Ip_Hyperflash header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_H) || \ + (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip.c and Qspi_Ip_Hyperflash.h are different" +#endif + + +/******************************************************************************* + * Variables + ******************************************************************************/ +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/*When multicore type3 is enabled on MemAcc, global variables must be allocated to share memory section */ +#if( QSPI_IP_MULTICORE_ENABLED == STD_ON) +#define MEM_43_EXFLS_START_SEC_VAR_SHARED_CLEARED_UNSPECIFIED_NO_CACHEABLE +#else +#define MEM_43_EXFLS_START_SEC_VAR_CLEARED_UNSPECIFIED +#endif +#include "Mem_43_EXFLS_MemMap.h" + +/* Pointer to runtime state structures */ +Qspi_Ip_StateType Qspi_Ip_MemoryStateStructure[QSPI_IP_MEM_INSTANCE_COUNT]; + +#if( QSPI_IP_MULTICORE_ENABLED == STD_ON) +#define MEM_43_EXFLS_STOP_SEC_VAR_SHARED_CLEARED_UNSPECIFIED_NO_CACHEABLE +#else +#define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_UNSPECIFIED +#endif +#include "Mem_43_EXFLS_MemMap.h" + +/******************************************************************************* + * Macros + ******************************************************************************/ + + +/******************************************************************************* + * Private Functions + ******************************************************************************/ + +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +static Qspi_Ip_StatusType Qspi_Ip_WriteEnable(uint32 instance); + +static Qspi_Ip_StatusType Qspi_Ip_InitReset(uint32 instance, + uint16 resetCmdLut, + uint8 resetCmdCount, + const Qspi_Ip_StateType *state + ); + +static Qspi_Ip_StatusType Qspi_Ip_InitWriteReg(uint32 instance, + const Qspi_Ip_InitOperationType *operation + ); + +static Qspi_Ip_StatusType Qspi_Ip_InitRMWReg(uint32 instance, + const Qspi_Ip_InitOperationType *operation + ); + +static Qspi_Ip_StatusType Qspi_Ip_InitReadReg(uint32 instance, + const Qspi_Ip_InitOperationType *operation + ); + +static Qspi_Ip_StatusType Qspi_Ip_InitProtection(uint32 instance, + const Qspi_Ip_StateType *state + ); + +static Qspi_Ip_StatusType Qspi_Ip_InitOperation(uint32 instance, + const Qspi_Ip_StateType *state, + uint8 initOp + ); + +static inline uint32 Qspi_Ip_CalcPaddingRead(const Qspi_Ip_StateType *state, + uint32 *address, + uint32 *size + ); + +static uint16 Qspi_Ip_InitLutSeq(uint32 instance, + uint16 VirtualLut, + uint8 LutRegister + ); + +static void Qspi_Ip_DeinitLutSeq(uint32 instance, + uint8 LutRegister + ); + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitLutSeq + * Description : Initializes one sequence in the LUT table from a virtual table sequence. Returns start index of next sequence. +*/ +static uint16 Qspi_Ip_InitLutSeq(uint32 instance, + uint16 VirtualLut, + uint8 LutRegister + ) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_InstrOpType *virtualLutTable = state->configuration->lutSequences.lutOps; + Qspi_Ip_InstrOpType operation1, operation2; + uint16 vLutIdx = VirtualLut; /* Index in virtual LUT */ + uint8 pLutIdx = 0U; /* Index in physical LUT */ + uint32 lutData[FEATURE_QSPI_LUT_SEQUENCE_SIZE]; /* Data to be written to the physical LUTs */ + + do + { +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(vLutIdx < state->configuration->lutSequences.opCount); +#endif + operation1 = virtualLutTable[vLutIdx]; + vLutIdx++; + operation2 = QSPI_IP_LUT_SEQ_END; + if (operation1 != QSPI_IP_LUT_SEQ_END) + { +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(vLutIdx < state->configuration->lutSequences.opCount); +#endif + operation2 = virtualLutTable[vLutIdx]; + vLutIdx++; + } + /* Add two operations to lut sequence */ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(pLutIdx < FEATURE_QSPI_LUT_SEQUENCE_SIZE); +#endif + lutData[pLutIdx] = QSPI_IP_PACK_LUT_REG(operation1, operation2); + pLutIdx++; + } + while (operation2 != QSPI_IP_LUT_SEQ_END); + +#if (FEATURE_QSPI_HAS_SFP == 1) + /* Clear the rest of sequence to avoid the effect of the previous command. + This prevent the SFP block from identifying the wrong type of transaction. + */ + for (; pLutIdx < FEATURE_QSPI_LUT_SEQUENCE_SIZE; pLutIdx++) + { + lutData[pLutIdx] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END); + } +#endif + + /* Write data to physical LUT registers */ + Qspi_Ip_WriteLuts(state->connection->qspiInstance, FEATURE_QSPI_LUT_SEQUENCE_SIZE * LutRegister, lutData, pLutIdx); + + return vLutIdx; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_DeinitLutSeq + * Description : DeInitializes one sequence in the LUT table from a virtual table sequence. +*/ +static void Qspi_Ip_DeinitLutSeq(uint32 instance, + uint8 LutRegister + ) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const uint32 lutData[FEATURE_QSPI_LUT_SEQUENCE_SIZE] = {0U}; /* Data to be written to the physical LUTs */ + + /* Write data to physical LUT registers */ + Qspi_Ip_WriteLuts(state->connection->qspiInstance, FEATURE_QSPI_LUT_SEQUENCE_SIZE * LutRegister, lutData, FEATURE_QSPI_LUT_SEQUENCE_SIZE); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetValue + * Description : Converts a long value in data to be sent to flash + */ +static inline void Qspi_Ip_SetValue(uint8 *data, + uint8 size, + uint32 value + ) +{ + uint8 cnt; + uint32 temp = value; + + /* Put value in the data buffer */ + for (cnt = 0U; cnt < size; cnt++) + { + data[cnt] = (uint8)(temp & 0xFFU); + temp >>= 8U; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetBitfield + * Description : Sets a new value in a register bitfield + */ +static void Qspi_Ip_SetBitfield(uint8 *data, + uint8 size, + uint8 shift, + uint8 width, + uint32 value + ) +{ + uint8 cnt; + uint32 longData = 0UL; + uint32 mask; + + /* Pack data in a long value (data[0] is LSB, data[size-1] is MSB) */ + for (cnt = 0U; cnt < size; cnt++) + { + longData = (longData << 8U) + data[size - 1U - cnt]; + } + /* Apply change */ + mask = ((1UL << (uint32)width) - 1UL) << (uint32)shift; + longData &= ~mask; + longData |= (value << shift) & mask; + /* Put data back in the data buffer (data[0] is LSB, data[size-1] is MSB) */ + for (cnt = 0U; cnt < size; cnt++) + { + data[cnt] = (uint8)(longData & 0xFFU); + longData >>= 8U; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_GetBitfield + * Description : Extracts the value of a register bitfield + */ +static uint32 Qspi_Ip_GetBitfield(const uint8 *data, + uint8 size, + uint8 shift, + uint8 width + ) +{ + uint8 cnt; + uint32 longData = 0U; + uint32 mask; + uint32 value; + + /* Pack data in a long value (data[0] is LSB, data[size-1] is MSB) */ + for (cnt = 0U; cnt < size; cnt++) + { + longData = (longData << 8U) + data[size - 1U - cnt]; + } + /* Extract field */ + mask = (1UL << (uint32)width) - 1UL; + value = (longData >> shift) & mask; + return value; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_UpdateStatusReg + * Description : Updates a bitfield in the status register +* @implements Qspi_Ip_UpdateStatusReg_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_UpdateStatusReg(uint32 instance, + uint8 offset, + uint8 width, + uint8 value + ) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig); + uint8 data[4U]; + Qspi_Ip_StatusType status; + + /* Read status register */ + status = Qspi_Ip_RunReadCommand(instance, statusConfig->statusRegReadLut, 0U, data, NULL_PTR, statusConfig->regSize); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Check existing value, write status register only if needed */ + if (value != Qspi_Ip_GetBitfield(data, statusConfig->regSize, offset, width)) + { + Qspi_Ip_SetBitfield(data, statusConfig->regSize, offset, width, value); + } + /* send WREN command for status register */ + if (statusConfig->writeEnableSRLut != QSPI_IP_LUT_INVALID) + { + status = Qspi_Ip_RunCommand(instance, statusConfig->writeEnableSRLut, 0U); + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* send write status register command */ + status = Qspi_Ip_RunWriteCommand(instance, statusConfig->statusRegWriteLut, 0U, data, statusConfig->regSize); + } + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_CheckStatusReg + * Description : Checks a bitfield in the status register +* @implements Qspi_Ip_CheckStatusReg_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_CheckStatusReg(uint32 instance, + uint8 offset, + uint8 width, + uint8 *value + ) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig); + uint8 data[4]; + Qspi_Ip_StatusType status; + + /* Read status register */ + status = Qspi_Ip_RunReadCommand(instance, statusConfig->statusRegReadLut, 0U, data, NULL_PTR, statusConfig->regSize); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Extract bit-field */ + *value = (uint8)Qspi_Ip_GetBitfield(data, statusConfig->regSize, offset, width); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_WriteEnable + * Description : Enables the serial flash memory for a program or erase operation +* @implements Qspi_Ip_WriteEnable_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_WriteEnable(uint32 instance) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig); + + uint32 retries = QSPI_IP_MAX_RETRY + 1U; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_TIMEOUT; + Qspi_Ip_StatusType cmdStatus; + uint8 welValue = 0U; + + MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND_WAIT_IN_WREN); + + while (retries > 0UL) + { + /* send WREN command */ + cmdStatus = Qspi_Ip_RunCommand(instance, statusConfig->writeEnableLut, 0U); + if (cmdStatus != STATUS_QSPI_IP_SUCCESS) + { + status = cmdStatus; + } + /* check WEL bit */ + cmdStatus = Qspi_Ip_CheckStatusReg(instance, statusConfig->writeEnableOffset, 1U, &welValue); + if (STATUS_QSPI_IP_SUCCESS == cmdStatus) + { + /* 1 == check WEL */ + if (1U == welValue) + { + status = STATUS_QSPI_IP_SUCCESS; + break; + } + } + else + { + /* record error */ + status = cmdStatus; + } + retries--; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SerialflashSectorErase + * Description : Erase a sector in the serial flash. + */ +static Qspi_Ip_StatusType Qspi_Ip_SerialflashSectorErase(uint32 instance, + uint32 address, + uint16 eraseLut + ) +{ + Qspi_Ip_StatusType status; + + /* enable write before erasing */ + status = Qspi_Ip_WriteEnable(instance); + + MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND_WAIT_IN_BASICERS); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* launch erase command and return */ + status = Qspi_Ip_RunCommand(instance, eraseLut, address); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_BasicErase + * Description : Perform one of the supported erase types in the serial flash. + * @implements Qspi_Ip_BasicErase_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_BasicErase(uint32 instance, + uint32 address, + uint16 eraseLut + ) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* Check device type */ + switch (state->configuration->memType) + { + case QSPI_IP_HYPER_FLASH: + status = Qspi_Ip_HyperflashSectorErase(instance, address); + break; + + case QSPI_IP_SERIAL_FLASH: + status = Qspi_Ip_SerialflashSectorErase(instance, address, eraseLut); + break; + default: + status = STATUS_QSPI_IP_ERROR; /* unknown operation */ + break; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_CheckMemoryStatus + * Description : Check that the memory is idle. Used internally by the driver during initialization + */ +static Qspi_Ip_StatusType Qspi_Ip_CheckMemoryStatus(uint32 instance, + uint16 virtualLut + ) +{ + Qspi_Ip_StatusType status; + uint8 busyValue; + uint8 data[4]; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig); + + /* Check if the QuadSPI controller is idle */ + status = Qspi_Ip_ControllerGetStatus(state->connection->qspiInstance); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Check if the operation has finished in the serial flash */ + /* Read status register */ + status = Qspi_Ip_RunReadCommand(instance, virtualLut, 0U, data, NULL_PTR, statusConfig->regSize); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Extract bit-field */ + busyValue = (uint8)Qspi_Ip_GetBitfield(data, statusConfig->regSize, statusConfig->busyOffset, 1U); + if (busyValue == statusConfig->busyValue) + { + /* Flash device is busy */ + status = STATUS_QSPI_IP_BUSY; + } + MCAL_FAULT_INJECTION_POINT(FLS_FIP_SR_BUSY_CHECKCOMMANDCOMPLETE); + } + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_WaitCommandComplete + * Description : Wait until external memory is not busy + */ +static Qspi_Ip_StatusType Qspi_Ip_WaitCommandComplete(uint32 instance, + uint16 VirtualLut + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint32 ElapsedTicks = 0UL; + uint32 TimeoutTicks; + uint32 CurrentTicks; + + /* Prepare timeout counter */ + TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_FLS_INIT_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + /* Wait for the command to complete */ + do + { + /* Get memory status */ + status = Qspi_Ip_CheckMemoryStatus(instance, VirtualLut); + ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + /* Check timeout */ + if (ElapsedTicks >= TimeoutTicks) + { + status = STATUS_QSPI_IP_TIMEOUT; + break; + } + } + while (STATUS_QSPI_IP_BUSY == status); + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_WaitResetComplete + * Description : Wait until external memory is available for operation after a reset +* @implements Qspi_Ip_CheckResetComplete_Activity */ +static void Qspi_Ip_WaitResetComplete(void) +{ + uint32 ElapsedTicks = 0UL; + uint32 TimeoutTicks; + uint32 CurrentTicks; + + /* Prepare timeout counter */ + TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_RESET_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + /* Wait for the specified time */ + do + { + ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + } + while (ElapsedTicks < TimeoutTicks); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitWriteReg + * Description : Write the configured value into a register of external flash device +* @implements Qspi_Ip_InitWriteReg_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_InitWriteReg(uint32 instance, + const Qspi_Ip_InitOperationType * operation + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint8 value[4U]; + + /* write a value in a register */ + if (QSPI_IP_LUT_INVALID != operation->weLut) + { + /* send WREN command */ + status = Qspi_Ip_RunCommand(instance, operation->weLut, operation->addr); + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + Qspi_Ip_SetValue(value, operation->size, operation->value); + status = Qspi_Ip_RunWriteCommand(instance, operation->command1Lut, operation->addr, value, operation->size); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitRMWReg + * Description : Change a bitfield in a register of external flash device +* @implements Qspi_Ip_InitRMWReg_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_InitRMWReg(uint32 instance, + const Qspi_Ip_InitOperationType *operation + ) +{ + Qspi_Ip_StatusType status; + uint32 fieldVal; + uint8 value[4U]; + + /* Read current register value */ + status = Qspi_Ip_RunReadCommand(instance, operation->command1Lut, operation->addr, value, NULL_PTR, operation->size); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Retrieve target bitfield */ + fieldVal = Qspi_Ip_GetBitfield(value, operation->size, operation->shift, operation->width); + if (fieldVal != operation->value) + { + /* Modify target bitfield */ + Qspi_Ip_SetBitfield(value, operation->size, operation->shift, operation->width, operation->value); + if (QSPI_IP_LUT_INVALID != operation->weLut) + { + /* Send WREN command */ + status = Qspi_Ip_RunCommand(instance, operation->weLut, operation->addr); + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Write back register value; use second LUT command */ + status = Qspi_Ip_RunWriteCommand(instance, operation->command2Lut, operation->addr, (uint8 *)&value, operation->size); + } + } + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitReadReg + * Description : Read the register's value of external flash device and loop until matching the configured one +* @implements Qspi_Ip_InitReadReg_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_InitReadReg(uint32 instance, + const Qspi_Ip_InitOperationType *operation + ) +{ + Qspi_Ip_StatusType status; + uint32 fieldVal = 0xFFFFFFFFUL; /* Invalid initial value */ + uint8 value[4U]; + uint32 ElapsedTicks = 0UL; + uint32 TimeoutTicks; + uint32 CurrentTicks; + + /* Prepare timeout counter */ + TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_FLS_INIT_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + do + { + /* read current register value */ + status = Qspi_Ip_RunReadCommand(instance, operation->command1Lut, operation->addr, value, NULL_PTR, operation->size); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* retrieve target bitfield */ + fieldVal = Qspi_Ip_GetBitfield(value, operation->size, operation->shift, operation->width); + } + ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + if (ElapsedTicks >= TimeoutTicks) + { + status = STATUS_QSPI_IP_TIMEOUT; + break; + } + } + while (fieldVal != operation->value); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitOperation + * Description : Execute initialization sequence to get the serial flash memory in the target state for operation */ +static Qspi_Ip_StatusType Qspi_Ip_InitOperation(uint32 instance, + const Qspi_Ip_StateType *state, + uint8 initOp + ) +{ + const Qspi_Ip_InitOperationType *initOperations = state->configuration->initConfiguration.operations; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + switch (initOperations[initOp].opType) + { + case QSPI_IP_OP_TYPE_CMD: + /* Execute a simple command */ + status = Qspi_Ip_RunCommand(instance, initOperations[initOp].command1Lut, initOperations[initOp].addr); + break; + + case QSPI_IP_OP_TYPE_WRITE_REG: + /* Write value into the register */ + status = Qspi_Ip_InitWriteReg(instance, &initOperations[initOp]); + break; + + case QSPI_IP_OP_TYPE_RMW_REG: + /* Change a bitfield in the register */ + status = Qspi_Ip_InitRMWReg(instance, &initOperations[initOp]); + break; + + case QSPI_IP_OP_TYPE_READ_REG: + /* Check a bitfield in the register */ + status = Qspi_Ip_InitReadReg(instance, &initOperations[initOp]); + break; + + case QSPI_IP_OP_TYPE_QSPI_CFG: + /* Re-initialize QSPI controller with the given configuration */ + (void)Qspi_Ip_ControllerDeinit(state->connection->qspiInstance); + status = Qspi_Ip_ControllerInit(state->connection->qspiInstance, initOperations[initOp].ctrlCfgPtr); + break; + + default: + status = STATUS_QSPI_IP_ERROR; /* unknown operation */ + break; + } /* switch */ + + return status; + +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitDevice + * Description : Execute initialization sequence to get the serial flash memory in the target state for operation +* @implements Qspi_Ip_InitDevice_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_InitDevice(uint32 instance, + const Qspi_Ip_StateType *state + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint8 initConfigOpCount = state->configuration->initConfiguration.opCount; + uint8 initOp; + + MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND_INITDEVICE); + + /* Perform operations in initialization list (common) */ + for (initOp = 0; initOp < initConfigOpCount; initOp++) + { + status = Qspi_Ip_InitOperation(instance, state, initOp); + + if (STATUS_QSPI_IP_SUCCESS != status) + { + break; + } + } + + /* Perform device initialization (specific) */ + if (STATUS_QSPI_IP_SUCCESS == status) + { + + if (QSPI_IP_HYPER_FLASH == state->configuration->memType) + { + status = Qspi_Ip_HyperflashInit(instance); + } + } + else + { + status = STATUS_QSPI_IP_ERROR; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitProtection + * Description : Update the protection configuration value if needed +* @implements Qspi_Ip_InitProtection_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_InitProtection(uint32 instance, + const Qspi_Ip_StateType *state + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint8 configProtection = state->configuration->statusConfig.blockProtectionValue; + uint8 getProtection = 0U; + + if (state->configuration->statusConfig.blockProtectionWidth != 0U) + { + /* Ensure the previous command is completed */ + status = Qspi_Ip_WaitCommandComplete(instance, state->configuration->statusConfig.statusRegReadLut); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Read and check the current setting */ + status = Qspi_Ip_GetProtection(instance, &getProtection); + if ((STATUS_QSPI_IP_SUCCESS == status) && (getProtection != configProtection)) + { + /* Set new setting */ + status = Qspi_Ip_SetProtection(instance, configProtection); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Ensure the write is completed */ + status = Qspi_Ip_WaitCommandComplete(instance, state->configuration->statusConfig.statusRegReadLut); + } + } + } + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InitReset + * Description : Perform the software reset sequence +* @implements Qspi_Ip_InitReset_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_InitReset(uint32 instance, + uint16 resetCmdLut, + uint8 resetCmdCount, + const Qspi_Ip_StateType *state + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint16 virtualLut = resetCmdLut; + uint8 cnt; + + if (QSPI_IP_LUT_INVALID != resetCmdLut) + { + for (cnt = 0U; cnt < resetCmdCount; cnt++) + { + /* Copy sequence in LUT registers */ + virtualLut = Qspi_Ip_InitLutSeq(instance, virtualLut, QSPI_IP_COMMAND_LUT); + + /* Run QSPI command */ + status = Qspi_Ip_IpCommand(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress); + if (status != STATUS_QSPI_IP_SUCCESS) + { + break; + } + + /* Clear sequence in LUT registers */ + Qspi_Ip_DeinitLutSeq(instance, QSPI_IP_COMMAND_LUT); + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Ensure flash is ready after reset */ + Qspi_Ip_WaitResetComplete(); + } + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SerialflashEraseChip + * Description : Erase the entire serial flash + */ +static Qspi_Ip_StatusType Qspi_Ip_SerialflashEraseChip(uint32 instance) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + + if (state->configuration->eraseSettings.chipEraseLut != QSPI_IP_LUT_INVALID) + { + /* enable write before erasing */ + status = Qspi_Ip_WriteEnable(instance); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* launch erase command */ + status = Qspi_Ip_RunCommand(instance, state->configuration->eraseSettings.chipEraseLut, 0U); + } + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SerialflashGetMemoryStatus + * Description : Get the status of the last operation + */ +static Qspi_Ip_StatusType Qspi_Ip_SerialflashGetMemoryStatus(uint32 instance) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig); + uint8 busyValue = 0xFFU; /* Invalid initial value */ + Qspi_Ip_StatusType status; + + /* Get the value of busy bit */ + status = Qspi_Ip_CheckStatusReg(instance, statusConfig->busyOffset, 1U, &busyValue); + /* Check BUSY value */ + if (busyValue == statusConfig->busyValue) + { + /* Write/erase in progress */ + status = STATUS_QSPI_IP_BUSY; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_PatchReadCommand + * Description : Patch the command sequence before using + */ +static void Qspi_Ip_PatchReadCommand(uint32 instance, + uint16 readLut + ) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + + /* Check device type */ + switch (state->configuration->memType) + { + case QSPI_IP_HYPER_FLASH: + Qspi_Ip_HyperflashPatchReadCommand(instance, readLut); + break; + + case QSPI_IP_SERIAL_FLASH: + /* Nothing to do with Serial flash */ + (void)readLut; + break; + + default: + (void)readLut; /* unknown operation */ + break; + } +} + + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_RunCommand + * Description : Launches a simple command for the serial flash +* @implements Qspi_Ip_RunCommand_Activity */ +Qspi_Ip_StatusType Qspi_Ip_RunCommand(uint32 instance, + uint16 lut, + uint32 addr + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(lut != QSPI_IP_LUT_INVALID); + DEV_ASSERT_QSPI(addr < state->configuration->memSize); +#endif + + if (lut != QSPI_IP_LUT_INVALID) + { + /* Copy sequence in LUT registers */ + (void)Qspi_Ip_InitLutSeq(instance, lut, QSPI_IP_COMMAND_LUT); + + /* Run QSPI command */ + status = Qspi_Ip_IpCommand(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress + addr); + + /* Clear sequence in LUT registers */ + Qspi_Ip_DeinitLutSeq(instance, QSPI_IP_COMMAND_LUT); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_RunReadCommand + * Description : Launches a read command for the serial flash +* @implements Qspi_Ip_RunReadCommand_Activity */ +Qspi_Ip_StatusType Qspi_Ip_RunReadCommand(uint32 instance, + uint16 lut, + uint32 addr, + uint8 * dataRead, + const uint8 * dataCmp, + uint32 size + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(lut != QSPI_IP_LUT_INVALID); + DEV_ASSERT_QSPI(addr < state->configuration->memSize); + DEV_ASSERT_QSPI((size > 0UL) && ((addr + size) <= state->configuration->memSize)); +#endif + + if (lut != QSPI_IP_LUT_INVALID) + { + /* Copy sequence in LUT registers */ + (void)Qspi_Ip_InitLutSeq(instance, lut, QSPI_IP_COMMAND_LUT); + + /* Run QSPI command */ + status = Qspi_Ip_IpRead(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress + addr, dataRead, dataCmp, size); + + /* Clear sequence in LUT registers */ + Qspi_Ip_DeinitLutSeq(instance, QSPI_IP_COMMAND_LUT); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_RunWriteCommand + * Description : Launches a write command for the serial flash + * @implements Qspi_Ip_RunWriteCommand_Activity */ +Qspi_Ip_StatusType Qspi_Ip_RunWriteCommand(uint32 instance, + uint16 lut, + uint32 addr, + const uint8 * data, + uint32 size + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(lut != QSPI_IP_LUT_INVALID); + DEV_ASSERT_QSPI(addr < state->configuration->memSize); + DEV_ASSERT_QSPI((size > 0UL) && ((addr + size) <= state->configuration->memSize)); + DEV_ASSERT_QSPI(data != NULL_PTR); +#endif + + if (lut != QSPI_IP_LUT_INVALID) + { + /* Copy sequence in LUT registers */ + (void)Qspi_Ip_InitLutSeq(instance, lut, QSPI_IP_COMMAND_LUT); + + /* Run QSPI command */ + status = Qspi_Ip_IpWrite(state->connection->qspiInstance, QSPI_IP_COMMAND_LUT, state->baseAddress + addr, data, size); + + /* Clear sequence in LUT registers */ + Qspi_Ip_DeinitLutSeq(instance, QSPI_IP_COMMAND_LUT); + } + + return status; +} + + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_EraseBlock + * Description : Erase a sector in the serial flash. + * The size must match one of the device's erase types. + * @implements Qspi_Ip_EraseBlock_Activity */ +Qspi_Ip_StatusType Qspi_Ip_EraseBlock(uint32 instance, + uint32 address, + uint32 size + ) +{ + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + uint8 eraseType; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(address < state->configuration->memSize); + DEV_ASSERT_QSPI((size > 0UL) && ((address + size) <= state->configuration->memSize)); +#endif + + /* Check address range */ + if (address < state->configuration->memSize) + { + /* find the suited erase type */ + for (eraseType = 0U; eraseType < QSPI_IP_ERASE_TYPES; eraseType++) + { + if ((state->configuration->eraseSettings.eraseTypes[eraseType].eraseLut != QSPI_IP_LUT_INVALID) && + (size == (uint32)((uint32)1U << (state->configuration->eraseSettings.eraseTypes[eraseType].size)))) + { + break; + } + } + /* if erase type was found, launch the erase */ + if (eraseType < QSPI_IP_ERASE_TYPES) + { + status = Qspi_Ip_BasicErase(instance, address, state->configuration->eraseSettings.eraseTypes[eraseType].eraseLut); + if (STATUS_QSPI_IP_SUCCESS == status) + { + state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE; + } + } + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_EraseChip + * Description : Erase the entire serial flash + * @implements Qspi_Ip_EraseChip_Activity */ +Qspi_Ip_StatusType Qspi_Ip_EraseChip(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* Check device type */ + switch (state->configuration->memType) + { + case QSPI_IP_HYPER_FLASH: + status = Qspi_Ip_HyperflashChipErase(instance); + break; + + case QSPI_IP_SERIAL_FLASH: + status = Qspi_Ip_SerialflashEraseChip(instance); + break; + + default: + status = STATUS_QSPI_IP_ERROR; /* unknown operation */ + break; + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ProgramSuspend + * Description : Suspends a program operation + * @implements Qspi_Ip_ProgramSuspend_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ProgramSuspend(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* Issue the Program Suspend command */ + status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.programSuspendLut, 0U); + state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE_SUSPEND; + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ProgramResume + * Description : Resumes a program operation + * @implements Qspi_Ip_ProgramResume_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ProgramResume(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* Issue the Program Resume command */ + status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.programResumeLut, 0U); + state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE; + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_EraseSuspend + * Description : Suspends an erase operation + * @implements Qspi_Ip_EraseSuspend_Activity */ +Qspi_Ip_StatusType Qspi_Ip_EraseSuspend(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* Issue the Erase Suspend command */ + status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.eraseSuspendLut, 0U); + state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE_SUSPEND; + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_EraseResume + * Description : Resumes an erase operation + * @implements Qspi_Ip_EraseResume_Activity */ +Qspi_Ip_StatusType Qspi_Ip_EraseResume(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* Issue the Erase Resume command */ + status = Qspi_Ip_RunCommand(instance, state->configuration->suspendSettings.eraseResumeLut, 0U); + state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE; + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Reset + * Description : Issues a software reset command + * @implements Qspi_Ip_Reset_Activity */ +Qspi_Ip_StatusType Qspi_Ip_Reset(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + uint16 resetCmdLut; /*!< First command in reset sequence */ + uint8 resetCmdCount; /*!< Number of commands in reset sequence */ + + resetCmdLut = state->configuration->resetSettings.resetCmdLut; + if (QSPI_IP_LUT_INVALID != resetCmdLut) + { + resetCmdCount = state->configuration->resetSettings.resetCmdCount; + /* Perform reset */ + status = Qspi_Ip_InitReset(instance, resetCmdLut, resetCmdCount, state); + /* Bring corresponding controller to initial configuration if required */ + if ((STATUS_QSPI_IP_SUCCESS == status) && (state->configuration->ctrlAutoCfgPtr != NULL_PTR)) + { + status = Qspi_Ip_ControllerInit(state->connection->qspiInstance, state->configuration->ctrlAutoCfgPtr); + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Execute initial setup of external device */ + status = Qspi_Ip_InitDevice(instance, state); + } + } + + /* If enabled, call the reset callout. */ + if (NULL_PTR != state->configuration->resetCallout) + { + status = state->configuration->resetCallout(instance); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_GetMemoryStatus + * Description : Get the status of the last operation + * @implements Qspi_Ip_GetMemoryStatus_Activity */ +Qspi_Ip_StatusType Qspi_Ip_GetMemoryStatus(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StatusType status; + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + + /* Check if the QuadSPI command is complete */ + status = Qspi_Ip_ControllerGetStatus(state->connection->qspiInstance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Check device type */ + switch (state->configuration->memType) + { + case QSPI_IP_HYPER_FLASH: + /* Check if the operation has finished in the hyper flash */ + status = Qspi_Ip_HyperflashGetMemoryStatus(instance); + break; + + case QSPI_IP_SERIAL_FLASH: + /* Check if the operation has finished in the serial flash */ + status = Qspi_Ip_SerialflashGetMemoryStatus(instance); + break; + default: + status = STATUS_QSPI_IP_ERROR; /* unknown operation */ + break; + } + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Call user callout, if available, to check operation result */ + if ((state->lastCommand != QSPI_IP_LAST_COMMAND_NONE) && (NULL_PTR != state->configuration->errorCheckCallout)) + { + status = state->configuration->errorCheckCallout(instance); + } + state->lastCommand = QSPI_IP_LAST_COMMAND_NONE; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_CalcPaddingRead + * Description : Calculates the number of padding bytes to handle reading from unaligned addresses + */ +static inline uint32 Qspi_Ip_CalcPaddingRead(const Qspi_Ip_StateType *state, + uint32 *address, + uint32 *size + ) +{ + const uint32 qspiInstance = state->connection->qspiInstance; + const uint32 readAlignment = state->connection->memAlignment; + + /* Checking for unaligned addresses */ + uint32 offset = *address & (readAlignment - 1U); + if (offset != 0U) + { + /* The number of padding bytes to handle unaligned address */ + Qspi_Ip_MemoryPadding[qspiInstance] = (uint8)offset; + /* Decreasing the address */ + *address -= offset; + /* Increasing the size to compensate */ + *size += offset; + } + + return offset; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Read + * Description : Read data from serial flash + * @implements Qspi_Ip_Read_Activity */ +Qspi_Ip_StatusType Qspi_Ip_Read(uint32 instance, + uint32 address, + uint8 * data, + uint32 size + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + uint32 crtAddress = address; + uint8 * crtData = data; + uint32 crtSize = size; + uint32 chunkSize = QSPI_IP_MAX_READ_SIZE; + uint32 offset; + uint32 ElapsedTicks = 0UL; + uint32 TimeoutTicks; + uint32 CurrentTicks; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(crtAddress < state->configuration->memSize); + DEV_ASSERT_QSPI((crtSize > 0UL) && ((crtAddress + crtSize) <= state->configuration->memSize)); + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(data != NULL_PTR); +#endif + + /* Checks and handles unaligned addresses */ + offset = Qspi_Ip_CalcPaddingRead(state, &crtAddress, &crtSize); + + /* Prepare timeout counter */ + TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_READ_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + while ((crtSize > 0UL) && (STATUS_QSPI_IP_SUCCESS == status)) + { + if (chunkSize > crtSize) + { + /* Adjust size for last chunk */ + chunkSize = crtSize; + } + /* Check timeout */ + ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + if (ElapsedTicks >= TimeoutTicks) + { + status = STATUS_QSPI_IP_TIMEOUT; + break; + } + + /* Patch the command sequence before using */ + Qspi_Ip_PatchReadCommand(instance, state->activeReadLut); + status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, crtAddress, crtData, NULL_PTR, chunkSize); + /* Move to next chunk */ + crtSize -= chunkSize; + crtAddress += chunkSize; + crtData = &(crtData[chunkSize - offset]); /* Handle alignment for the first read */ + offset = 0U; + + /* Call user callout, if available, to check ECC or CRC status */ + if ((STATUS_QSPI_IP_SUCCESS == status) && (NULL_PTR != state->configuration->eccCheckCallout)) + { + status = state->configuration->eccCheckCallout(instance, crtAddress, chunkSize); + } + } + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ReadId + * Description : Read manufacturer ID from serial flash + * @implements Qspi_Ip_ReadId_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ReadId(uint32 instance, + uint8 * data + ) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(data != NULL_PTR); +#endif + + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* Check device type */ + switch (state->configuration->memType) + { + case QSPI_IP_HYPER_FLASH: + status = Qspi_Ip_HyperflashReadId(instance, + state->configuration->hfConfig->deviceIdWordAddress, + data, + state->configuration->readIdSettings.readIdSize); + break; + + case QSPI_IP_SERIAL_FLASH: + status = Qspi_Ip_RunReadCommand(instance, + state->configuration->readIdSettings.readIdLut, + 0U, + data, + NULL_PTR, + state->configuration->readIdSettings.readIdSize); + break; + default: + status = STATUS_QSPI_IP_ERROR; /* unknown operation */ + break; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ProgramVerify + * Description : Verifies data written in serial flash + * @implements Qspi_Ip_ProgramVerify_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ProgramVerify(uint32 instance, + uint32 address, + const uint8 * data, + uint32 size + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + uint32 crtAddress = address; + const uint8 * crtData = data; + uint32 crtSize = size; + uint32 chunkSize = QSPI_IP_MAX_READ_SIZE; + uint32 offset; + uint32 ElapsedTicks = 0UL; + uint32 TimeoutTicks; + uint32 CurrentTicks; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(crtAddress < state->configuration->memSize); + DEV_ASSERT_QSPI((crtSize > 0UL) && ((crtAddress + crtSize) <= state->configuration->memSize)); + DEV_ASSERT_QSPI(data != NULL_PTR); + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + /* Checks and handles unaligned addresses */ + offset = Qspi_Ip_CalcPaddingRead(state, &crtAddress, &crtSize); + + /* Prepare timeout counter */ + TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_READ_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + while ((crtSize > 0U) && (STATUS_QSPI_IP_SUCCESS == status)) + { + if (chunkSize > crtSize) + { + /* Adjust size for last chunk */ + chunkSize = crtSize; + } + /* Check timeout */ + ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + if (ElapsedTicks >= TimeoutTicks) + { + status = STATUS_QSPI_IP_TIMEOUT; + break; + } + + /* Patch the command sequence before using */ + Qspi_Ip_PatchReadCommand(instance, state->activeReadLut); + status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, crtAddress, NULL_PTR, crtData, chunkSize); + /* Move to next chunk */ + crtSize -= chunkSize; + crtAddress += chunkSize; + crtData = &(crtData[chunkSize - offset]); /* Handle alignment for the first read */ + offset = 0U; + } + return status; +} + + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_EraseVerify + * Description : Verifies that an area in serial flash is in erased state + * @implements Qspi_Ip_EraseVerify_Activity */ +Qspi_Ip_StatusType Qspi_Ip_EraseVerify(uint32 instance, + uint32 address, + uint32 size + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + uint32 crtAddress = address; + uint32 crtSize = size; + uint32 chunkSize = QSPI_IP_MAX_READ_SIZE; + uint32 ElapsedTicks = 0UL; + uint32 TimeoutTicks; + uint32 CurrentTicks; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(crtAddress < state->configuration->memSize); + DEV_ASSERT_QSPI((crtSize > 0UL) && ((crtAddress + crtSize) <= state->configuration->memSize)); + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + /* Checks and handles unaligned addresses */ + (void)Qspi_Ip_CalcPaddingRead(state, &crtAddress, &crtSize); + + /* Prepare timeout counter */ + TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_READ_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + while ((crtSize > 0UL) && (STATUS_QSPI_IP_SUCCESS == status)) + { + if (chunkSize > crtSize) + { + /* Adjust size for last chunk */ + chunkSize = crtSize; + } + /* Check timeout */ + ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + if (ElapsedTicks >= TimeoutTicks) + { + status = STATUS_QSPI_IP_TIMEOUT; + break; + } + + /* Patch the command sequence before issuing */ + Qspi_Ip_PatchReadCommand(instance, state->activeReadLut); + status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, crtAddress, NULL_PTR, NULL_PTR, chunkSize); + /* Move to next chunk */ + crtSize -= chunkSize; + crtAddress += chunkSize; + } + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_CalcPaddingWrite + * Description : Calculates the number of padding bytes to handle writing to unaligned addresses + */ +static inline uint32 Qspi_Ip_CalcPaddingWrite(const Qspi_Ip_StateType *state, + uint32 address, + uint32 size + ) +{ + uint32 qspiInstance = state->connection->qspiInstance; + uint32 alignmentMask = (uint32)(state->connection->memAlignment) - 1UL; + + /* The number of pre-padding bytes */ + uint32 prePadding = address & alignmentMask; + + /* The number of post-padding bytes */ + uint32 endAddr = address + size - 1UL; + uint32 postPadding = alignmentMask - (endAddr & alignmentMask); + + /* Store padding information */ + Qspi_Ip_MemoryPadding[qspiInstance] = (uint8)((prePadding << 4UL) | postPadding); + + /* Decreasing the address */ + return (address - prePadding); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Program + * Description : Writes data in serial flash + * @implements Qspi_Ip_Program_Activity */ +Qspi_Ip_StatusType Qspi_Ip_Program(uint32 instance, + uint32 address, + const uint8 * data, + uint32 size + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + uint32 alignedAddress; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(address < state->configuration->memSize); + DEV_ASSERT_QSPI(data != NULL_PTR); + DEV_ASSERT_QSPI((size > 0UL) && ((address + size) <= state->configuration->memSize)); +#endif + + /* Check address range and page size */ + if ((address < state->configuration->memSize) && ((size <= state->configuration->pageSize))) + { + /* Write data to the flash device */ + switch (state->configuration->memType) + { + case QSPI_IP_HYPER_FLASH: + /* Perform alignment checking before write data */ + alignedAddress = Qspi_Ip_CalcPaddingWrite(state, address, size); + /* Write data to hyper flash */ + status = Qspi_Ip_HyperflashProgram(instance, alignedAddress, data, size); + break; + + case QSPI_IP_SERIAL_FLASH: + /* enable write before programming */ + status = Qspi_Ip_WriteEnable(instance); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Perform alignment checking before write data */ + alignedAddress = Qspi_Ip_CalcPaddingWrite(state, address, size); + /* Write data to serial flash */ + status = Qspi_Ip_RunWriteCommand(instance, state->configuration->writeLut, alignedAddress, data, size); + } + break; + default: + status = STATUS_QSPI_IP_ERROR; + break; + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE; + } + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Enter0XX + * Description : Enters 0-X-X mode (no command for read instructions) + * @implements Qspi_Ip_Enter0XX_Activity */ +Qspi_Ip_StatusType Qspi_Ip_Enter0XX(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + uint8 dummyData; + + if (state->configuration->read0xxLut != QSPI_IP_LUT_INVALID) + { + state->activeReadLut = state->configuration->read0xxLut; + /* Perform a dummy read to activate 0-X-X mode */ + status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, 0U, &dummyData, NULL_PTR, 1U); + } + + if (state->configuration->read0xxLutAHB != QSPI_IP_LUT_INVALID) + { + /* Set 0-x-x mode LUT sequence for AHB */ + (void)Qspi_Ip_InitLutSeq(instance, state->configuration->read0xxLutAHB, QSPI_IP_AHB_LUT); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Exit0XX + * Description : Exits 0-X-X mode (no command for read instructions) + * @implements Qspi_Ip_Exit0XX_Activity */ +Qspi_Ip_StatusType Qspi_Ip_Exit0XX(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + uint8 dummyData; + + if (state->configuration->read0xxLut != QSPI_IP_LUT_INVALID) + { + state->activeReadLut = state->configuration->readLut; + /* Perform a dummy read to disable 0-X-X mode */ + status = Qspi_Ip_RunReadCommand(instance, state->activeReadLut, 0U, &dummyData, NULL_PTR, 1U); + } + + if (state->configuration->read0xxLutAHB != QSPI_IP_LUT_INVALID) + { + /* Set back to normal mode LUT sequence for AHB */ + (void)Qspi_Ip_InitLutSeq(instance, state->configuration->readLut, QSPI_IP_AHB_LUT); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetProtection + * Description : Sets the protection bits of the device + * @implements Qspi_Ip_SetProtection_Activity */ +Qspi_Ip_StatusType Qspi_Ip_SetProtection(uint32 instance, + uint8 value + ) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig); + + return Qspi_Ip_UpdateStatusReg(instance, statusConfig->blockProtectionOffset, statusConfig->blockProtectionWidth, value); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_GetProtection + * Description : Returns the current protection bits of the device + * @implements Qspi_Ip_GetProtection_Activity */ +Qspi_Ip_StatusType Qspi_Ip_GetProtection(uint32 instance, + uint8 *value + ) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(value != NULL_PTR); +#endif + + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const Qspi_Ip_StatusConfigType *statusConfig = &(state->configuration->statusConfig); + + return Qspi_Ip_CheckStatusReg(instance, statusConfig->blockProtectionOffset, statusConfig->blockProtectionWidth, value); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_AhbReadEnable + * Description : Enables AHB reads for the current flash device + * @implements Qspi_Ip_AhbReadEnable_Activity */ +Qspi_Ip_StatusType Qspi_Ip_AhbReadEnable(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); +#endif + + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + + if (state->activeReadLut != QSPI_IP_LUT_INVALID) + { + /* Patch the command sequence before using */ + Qspi_Ip_PatchReadCommand(instance, state->activeReadLut); + /* Copy sequence in LUT registers */ + (void)Qspi_Ip_InitLutSeq(instance, state->activeReadLut, QSPI_IP_AHB_LUT); + /* Set sequence number */ + Qspi_Ip_SetAhbSeqId(state->connection->qspiInstance, QSPI_IP_AHB_LUT); + status = STATUS_QSPI_IP_SUCCESS; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Init + * Description : Initialize the serial flash memory driver + * + * @implements Qspi_Ip_Init_Activity */ +Qspi_Ip_StatusType Qspi_Ip_Init(uint32 instance, + const Qspi_Ip_MemoryConfigType * pConfig, + const Qspi_Ip_MemoryConnectionType * pConnect + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QSPI_IP_MEM_INSTANCE_COUNT); + DEV_ASSERT_QSPI(pConfig != NULL_PTR); + DEV_ASSERT_QSPI(pConnect != NULL_PTR); + DEV_ASSERT_QSPI(NULL_PTR == state->configuration); +#endif + + /* Copy configuration information to state structure */ + state->configuration = pConfig; + state->connection = pConnect; + state->activeReadLut = pConfig->readLut; /* 0-X-X mode disabled by default */ + state->lastCommand = QSPI_IP_LAST_COMMAND_NONE; + state->baseAddress = Qspi_Ip_GetBaseAdress(pConnect->qspiInstance, pConnect->connectionType); + +#if (QSPI_PERFORM_DEVICE_CONFIG == STD_ON) + /* Initialize corresponding controller if required */ + if (pConfig->ctrlAutoCfgPtr != NULL_PTR) + { + status = Qspi_Ip_ControllerInit(pConnect->qspiInstance, pConfig->ctrlAutoCfgPtr); + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Perform initial reset */ + status = Qspi_Ip_InitReset(instance, pConfig->initResetSettings.resetCmdLut, pConfig->initResetSettings.resetCmdCount, state); + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Execute initial setup of external device */ + status = Qspi_Ip_InitDevice(instance, state); + } + + /* If enabled, call the init callout, for additional QSPI IP or external memory settings. */ + if ((STATUS_QSPI_IP_SUCCESS == status) && (NULL_PTR != pConfig->initCallout)) + { + status = pConfig->initCallout(instance); + } + + /* Perform protection configuration */ + if (STATUS_QSPI_IP_SUCCESS == status) + { + status = Qspi_Ip_InitProtection(instance, state); + } +#endif + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Deinit + * Description : De-initialize the serial flash memory driver + * @implements Qspi_Ip_Deinit_Activity */ +Qspi_Ip_StatusType Qspi_Ip_Deinit(uint32 instance) +{ + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(state->configuration != NULL_PTR); +#endif + + state->configuration = NULL_PTR; + return STATUS_QSPI_IP_SUCCESS; +} + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +#endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */ + + +#ifdef __cplusplus +} +#endif + +/** @} */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Controller.c b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Controller.c new file mode 100644 index 000000000..3b2c090ee --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Controller.c @@ -0,0 +1,2359 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** +* @file Qspi_Ip_Controller.c +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "Mcal.h" +#include "OsIf.h" +#include "Qspi_Ip.h" +#include "Qspi_Ip_Controller.h" +#include "Qspi_Ip_HwAccess.h" + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_CONTROLLER_VENDOR_ID_C 43 +#define QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C 4 +#define QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C 7 +#define QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C 0 +#define QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C 2 +#define QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C 0 +#define QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C 0 + + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK + /* Check if current file and Mcal.h header file are of the same Autosar version */ + #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != MCAL_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != MCAL_AR_RELEASE_MINOR_VERSION) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Mcal.h are different" + #endif + + /* Check if current file and OsIf.h header file are of the same Autosar version */ + #if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and OsIf.h are different" + #endif +#endif + +/* Check if current file and Qspi_Ip_Controller header file are of the same vendor */ +#if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H) + #error "Qspi_Ip_Controller.c and Qspi_Ip_Controller.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */ +#if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_Controller.h are different" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Software version */ +#if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_Controller.h are different" +#endif + +/* Check if current file and Qspi_Ip_HwAccess header file are of the same vendor */ +#if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_HW_ACCESS_VENDOR_ID_H) + #error "Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_HwAccess header file are of the same Autosar version */ +#if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_HW_ACCESS_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_HW_ACCESS_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_HW_ACCESS_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h are different" +#endif +/* Check if current file and Qspi_Ip_HwAccess header file are of the same Software version */ +#if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_HW_ACCESS_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_HW_ACCESS_SW_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_HW_ACCESS_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip_HwAccess.h are different" +#endif + +/* Check if current file and Qspi_Ip header file are of the same vendor */ +#if (QSPI_IP_CONTROLLER_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H) + #error "Qspi_Ip_Controller.c and Qspi_Ip.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip header file are of the same Autosar version */ +#if ((QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip.h are different" +#endif +/* Check if current file and Qspi_Ip header file are of the same Software version */ +#if ((QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \ + (QSPI_IP_CONTROLLER_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Controller.c and Qspi_Ip.h are different" +#endif + +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148) + /* Bit-fields of chip-specific MCR[SCLKCFG] field */ + #define QSPI_MCR_SCLKCFG_INPUT_EN 0x80U /* Enable input buffer of QSPI pads */ + #define QSPI_MCR_SCLKCFG_CLK_MOD 0x40U /* Quadspi Clocking mode selection */ + #define QSPI_MCR_SCLKCFG_EXT_DQS 0x20U /* Use external DQS (HyperRAM mode) */ + #define QSPI_MCR_SCLKCFG_CLK_SRC 0x10U /* QuadSPI source clock selection */ + #define QSPI_MCR_SCLKCFG_DQS_INV_B 0x08U /* B-side DQS invert */ + #define QSPI_MCR_SCLKCFG_DQS_SEL_B 0x04U /* B-side DQS select */ + #define QSPI_MCR_SCLKCFG_DQS_INV_A 0x02U /* A-side DQS invert */ + #define QSPI_MCR_SCLKCFG_DQS_SEL_A 0x01U /* A-side DQS select */ + + /* Bit-fields of chip-specific SOCCR[SOCCFG] field */ + /* Programmable Divider Selection */ + #define QuadSPI_SOCCR_PD_MASK 0xE0000000u + #define QuadSPI_SOCCR_PD_SHIFT 29u + #define QuadSPI_SOCCR_PD(x) (((uint32)(((uint32)(x))< 4U) ? 4U : sizeRemaining; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ProcessDataRead + * Description : Processes read data + * @implements Qspi_Ip_ProcessDataRead_Activity */ +static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataRead(uint8 *dataRead, + uint32 size, + const QuadSPI_Type *baseAddr, + uint32 padding + ) +{ + uint8 * data = dataRead; + uint32 cnt = 0U; + uint32 recvData; + const uint8 *recvDataPtr = (uint8 *)(&recvData); + uint32 wordSize; + uint32 byteCnt; + uint32 sizeRemaining = size; + uint32 paddingBytes = padding; + + if (0U != paddingBytes) + { + /* Ignore all padding words, jump to the fist data */ + cnt = paddingBytes >> 2U; + sizeRemaining -= cnt << 2U; + paddingBytes &= 0x3U; + + /* Get first received word */ + recvData = baseAddr->RBDR[cnt]; + cnt++; + /* Get wordSize for the loop */ + wordSize = Qspi_Ip_GetWordSize(sizeRemaining); + + /* Ignore padding bytes and copy the rest to buffer */ + for (byteCnt = paddingBytes; byteCnt < wordSize; byteCnt++) + { + #if (defined(CORE_BIG_ENDIAN)) + *data = recvDataPtr[3U - byteCnt]; + #else + *data = recvDataPtr[byteCnt]; + #endif + + data++; + } + sizeRemaining -= wordSize; + } + + /* Check user buffer alignment */ + if (((Qspi_Ip_UintPtrType)data & 0x3U) == 0U) + { + /* Process 4 bytes at a time to speed up read */ + while (sizeRemaining >= 4U) + { + *((uint32 *)((Qspi_Ip_UintPtrType)data)) = baseAddr->RBDR[cnt]; /* Casting through uint32 to avoid Misra 11.3 */ + data = &(data[4U]); + cnt++; + sizeRemaining -= 4U; + } + } + + /* Process remaining bytes one by one */ + while (sizeRemaining > 0U) + { + /* Get next received word */ + recvData = baseAddr->RBDR[cnt]; + /* get wordSize for the loop */ + wordSize = Qspi_Ip_GetWordSize(sizeRemaining); + for (byteCnt = 0U; byteCnt < wordSize; byteCnt++) + { +#if (defined(CORE_BIG_ENDIAN)) + *data = (uint8)(recvData >> 24U); + recvData <<= 8U; +#else + *data = (uint8)(recvData & 0xFFU); + recvData >>= 8U; +#endif + data++; + sizeRemaining--; + } + cnt++; + } + return STATUS_QSPI_IP_SUCCESS; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ProcessDataVerify + * Description : Processes program verify data + * @implements Qspi_Ip_ProcessDataVerify_Activity */ +static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataVerify(const uint8 *dataCmp, + uint32 size, + const QuadSPI_Type *baseAddr, + uint32 padding + ) +{ + const uint8 * roData = dataCmp; + uint32 cnt = 0U; + uint32 recvData; + uint8 recvByte; + const uint8 *recvDataPtr = (uint8 *)(&recvData); + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint32 byteCnt; + uint32 wordSize; + uint32 paddingBytes = padding; + uint32 sizeRemaining = size; + + if (0U != paddingBytes) + { + /* Ignore all padding words, jump to the fist data */ + cnt = paddingBytes >> 2U; + sizeRemaining -= cnt << 2U; + paddingBytes &= 0x3U; + + /* Get first received word */ + recvData = baseAddr->RBDR[cnt]; + cnt++; + /* Get wordSize for the loop */ + wordSize = Qspi_Ip_GetWordSize(sizeRemaining); + sizeRemaining -= wordSize; + + /* Ignore padding bytes and compare the rest with user buffer */ + for (byteCnt = paddingBytes; byteCnt < wordSize; byteCnt++) + { + #if (defined(CORE_BIG_ENDIAN)) + recvByte = recvDataPtr[3U - byteCnt]; + #else + recvByte = recvDataPtr[byteCnt]; + #endif + + /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */ + if (*roData != recvByte) + { + status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY; + sizeRemaining = 0U; + break; + } + roData++; + } + } + + /* Check user buffer alignment */ + if (((Qspi_Ip_UintPtrType)roData & 0x3U) == 0U) + { + while (sizeRemaining >= 4U) + { + /* Process 4 bytes at a time to speed up read */ + if (*((const uint32 *)((Qspi_Ip_UintPtrType)roData)) != baseAddr->RBDR[cnt]) + { + /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */ + status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY; + sizeRemaining = 0U; + break; + } + /* update the roData */ + roData = &(roData[4U]); + cnt++; + sizeRemaining -= 4U; + } + } + + /* Process remaining bytes one by one */ + while (sizeRemaining > 0U) + { + /* Get next received word */ + recvData = baseAddr->RBDR[cnt]; + /* get wordSize for the loop */ + wordSize = Qspi_Ip_GetWordSize(sizeRemaining); + for (byteCnt = 0U; byteCnt < wordSize; byteCnt++) + { +#if (defined(CORE_BIG_ENDIAN)) + recvByte = (uint8)(recvData >> 24U); + recvData <<= 8U; +#else + recvByte = (uint8)(recvData & 0xFFU); + recvData >>= 8U; +#endif + /* return STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY if the data is not match */ + if (*roData != recvByte) + { + status = STATUS_QSPI_IP_ERROR_PROGRAM_VERIFY; + sizeRemaining = 0U; + break; + } + else + { + /* update the roData, sizeRemaining */ + roData++; + sizeRemaining--; + } + } + cnt++; + } + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ProcessDataBlankCheck + * Description : Processes blank check data + * @implements Qspi_Ip_ProcessDataBlankCheck_Activity */ +static inline Qspi_Ip_StatusType Qspi_Ip_ProcessDataBlankCheck(uint32 size, + const QuadSPI_Type *baseAddr, + uint32 padding + ) +{ + uint32 cnt = 0U; + uint32 recvData = 0U; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint32 dataSize; + uint32 sizeRemaining = size; + uint32 paddingBytes = padding; + + if (0U != paddingBytes) + { + /* Ignore all padding words, jump to the fist data */ + cnt = paddingBytes >> 2U; + sizeRemaining -= cnt << 2U; + paddingBytes &= 0x3U; + + /* Get first received word */ + recvData = ~(baseAddr->RBDR[cnt]); + cnt++; + /* Get wordSize for the blank check */ + dataSize = Qspi_Ip_GetWordSize(sizeRemaining); + sizeRemaining -= dataSize; + + /* Mask data: ignore padding at the beginning and unused bytes at the end */ +#if (defined(CORE_BIG_ENDIAN)) + recvData &= 0xFFFFFFFFUL << ((4UL - dataSize) * 8UL); + recvData &= 0xFFFFFFFFUL >> (paddingBytes * 8UL); +#else + recvData &= 0xFFFFFFFFUL >> ((4UL - dataSize) * 8UL); + recvData &= 0xFFFFFFFFUL << (paddingBytes * 8UL); +#endif + if (recvData != 0U) + { + /* The data is not blank */ + status = STATUS_QSPI_IP_ERROR_BLANK_CHECK; + sizeRemaining = 0U; + } + } + + /* Blank check */ + while (sizeRemaining >= 4U) + { + if (baseAddr->RBDR[cnt] != 0xFFFFFFFFU) + { + /* The data is not blank */ + status = STATUS_QSPI_IP_ERROR_BLANK_CHECK; + sizeRemaining = 0U; + break; + } + cnt++; + sizeRemaining -= 4U; + } + + if (sizeRemaining != 0U) + { + /* Process last few bytes */ + recvData = baseAddr->RBDR[size >> 2U]; +#if (defined(CORE_BIG_ENDIAN)) + if ((~recvData & ~(((uint32)1U << (((uint32)4U - sizeRemaining) * 8U)) - 1U)) != 0U) +#else + if ((~recvData & (((uint32)1U << (sizeRemaining * 8U)) - 1U)) != 0U) +#endif + { + /* The data is not blank */ + status = STATUS_QSPI_IP_ERROR_BLANK_CHECK; + } + } + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_FillTxBuf + * Description : Fill Tx buffer with the specified number of 4-byte entries +* @implements Qspi_Ip_FillTxBuf_Activity */ +static void Qspi_Ip_FillTxBuf(QuadSPI_Type *baseAddr, + const uint8 *roData, + uint32 size, + uint32 paddingInfo + ) +{ + uint32 sizeLeft = size; + uint32 wordSize; + uint32 data = 0xFFFFFFFFUL; + uint8 *dataPtr = (uint8 *)(&data); + uint32 byteCnt; + const uint8 * roDataPtr = roData; + + uint32 prePadding = paddingInfo >> 4U; + uint32 postPadding = paddingInfo & 0x0FU; + + /* Insert prePadding words */ + while (prePadding >= 4U) + { + Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFUL); + prePadding -= 4U; + } + + if (prePadding != 0U) + { + wordSize = prePadding + sizeLeft; + + if (wordSize > 4U) + { + wordSize = 4U; + sizeLeft -= (4U - prePadding); + } + else + { + /* Note for special case: prePadding + Data + postPadding are fit into a word + Decreaseing postPadding is not needed because out of user data, all branches below will be skipped + */ + sizeLeft = 0U; + } + + /* Fill user data between prePadding and postPadding */ + for (byteCnt = prePadding; byteCnt < wordSize; byteCnt++) + { + #if (defined(CORE_BIG_ENDIAN)) + dataPtr[3U - byteCnt] = *roDataPtr; + #else + dataPtr[byteCnt] = *roDataPtr; + #endif + + roDataPtr++; + } + Qspi_Ip_WriteTxData(baseAddr, data); + } + + /* Check user buffer alignment */ + if (((Qspi_Ip_UintPtrType)roDataPtr & 0x3U) == 0U) + { + /* Process 4 bytes at a time to speed things up */ + while (sizeLeft >= 4U) + { + data = *(const uint32 *)((Qspi_Ip_UintPtrType)roDataPtr); /* Casting through uint32 to avoid Misra 11.3 */ + sizeLeft -= 4U; + roDataPtr = &(roDataPtr[4U]); + Qspi_Ip_WriteTxData(baseAddr, data); + } + } + + /* Process remaining bytes one by one */ + while (sizeLeft > 0U) + { + /* Processes last few data bytes (less than 4) */ + data = 0xFFFFFFFFUL; + wordSize = Qspi_Ip_GetWordSize(sizeLeft); + + for (byteCnt = 0U; byteCnt < wordSize; byteCnt++) + { + #if (defined(CORE_BIG_ENDIAN)) + dataPtr[3U - byteCnt] = *roDataPtr; + #else + dataPtr[byteCnt] = *roDataPtr; + #endif + + roDataPtr++; + } + Qspi_Ip_WriteTxData(baseAddr, data); + sizeLeft -= wordSize; + } + + /* Insert postPadding words */ + while (postPadding >= 4U) + { + Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFUL); + postPadding -= 4U; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ErrorCheck + * Description : Checks if there were errors during IP command execution +* @implements Qspi_Ip_ErrorCheck_Activity */ +static inline Qspi_Ip_StatusType Qspi_Ip_ErrorCheck(QuadSPI_Type *baseAddr) +{ + Qspi_Ip_StatusType status; + + if ((baseAddr->FR & QSPI_ERR_FLAGS_MASK) != 0U) + { + /* clear error flags */ + baseAddr->FR = QSPI_ERR_FLAGS_MASK; + status = STATUS_QSPI_IP_ERROR; + } +#if (FEATURE_QSPI_HAS_SFP == 1) + else if (baseAddr->ERRSTAT != 0UL) + { + status = STATUS_QSPI_IP_ERROR; + } +#endif /* FEATURE_QSPI_HAS_SFP */ + else + { + status = STATUS_QSPI_IP_SUCCESS; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SwResetDelay + * Description : Insert waiting loops after changing the value of the software reset bits + */ +static inline void Qspi_Ip_SwResetDelay(void) +{ + /* Prepare timeout counter */ + volatile uint32 u32CurrentTicks = QSPI_IP_SOFTWARE_RESET_DELAY; + /* Insert delay after changing the value of the software reset bits. */ + while (u32CurrentTicks > 0U) + { + u32CurrentTicks--; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SwReset + * Description : Resets the QuadSPI device +* @implements Qspi_Ip_SwReset_Activity */ +static void Qspi_Ip_SwReset(QuadSPI_Type *baseAddr) +{ + /* Software reset AHB domain and Serial Flash domain at the same time. */ + Qspi_Ip_SwResetOn(baseAddr); + /* Insert delay after changing the value of the reset bits. */ + Qspi_Ip_SwResetDelay(); + /* Disable QuadSPI module before de-asserting the reset bits. */ + Qspi_Ip_Disable(baseAddr); + /* De-asset Software reset AHB domain and Serial Flash domain bits. */ + Qspi_Ip_SwResetOff(baseAddr); + /* Re-enable QuadSPI module after reset. */ + Qspi_Ip_Enable(baseAddr); + /* Insert delay after changing the value of the reset bits. */ + Qspi_Ip_SwResetDelay(); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_AhbFlush + * Description : Reset AHB buffers + */ +static void Qspi_Ip_AhbFlush(QuadSPI_Type *baseAddr) +{ +#ifdef QuadSPI_SPTRCLR_ABRT_CLR_MASK + uint32 u32ElapsedTicks = 0UL; + uint32 u32TimeoutTicks; + uint32 u32CurrentTicks; + + /* Use the AHB buffer clear bit to avoid losing the DLL lock */ + Qspi_Ip_ClearAhbBuf(baseAddr); + + /* Prepare timeout counter */ + u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_CMD_COMPLETE_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + u32CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + + /* Wait for clearing the AHB buffer pointers */ + while (!Qspi_Ip_GetClrAhbStatus(baseAddr)) + { + /* An exit point for safety purpose only, because this loop is not expected to happen in practice */ + u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + if (u32ElapsedTicks >= u32TimeoutTicks) + { + break; + } + } + +#else + /* Otherwise use the software reset */ + Qspi_Ip_SwReset(baseAddr); +#endif +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_WaitDLLASlaveLock + * Description : DLL side A - Wait for slave high lock status or DLL lock status + */ +static Qspi_Ip_StatusType Qspi_Ip_WaitDLLASlaveLock(const QuadSPI_Type *baseAddr, + boolean waitSlaveLock + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + boolean LockStatus; + + /* Prepare timeout counter */ + uint32 u32ElapsedTicks = 0UL; + uint32 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_DLL_LOCK_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + uint32 u32CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + + do + { + /* Wait for slave high lock status or DLL lock status */ + LockStatus = (waitSlaveLock) ? Qspi_Ip_DLLGetSlaveLockStatusA(baseAddr) : Qspi_Ip_DLLGetLockStatusA(baseAddr); + + /* Check for errors reported by DLL */ + if (Qspi_Ip_DLLGetErrorStatusA(baseAddr)) + { + status = STATUS_QSPI_IP_ERROR; + } + else + { + /* Check for timeout */ + u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + if (u32ElapsedTicks >= u32TimeoutTicks) + { + status = STATUS_QSPI_IP_TIMEOUT; + } + } + + if (STATUS_QSPI_IP_SUCCESS != status) + { + break; + } + } + while (!LockStatus); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLAByPass + * Description : Configures DLL - Side A (bypass mode) + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLAByPass(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Set DLL in bypass mode and configure coarse and fine delays */ + Qspi_Ip_DLLSlaveBypassA (baseAddr, TRUE); + Qspi_Ip_DLLSlaveAutoUpdateA(baseAddr, FALSE); + Qspi_Ip_DLLSetDelayCoarseA (baseAddr, userConfigPtr->dllSettingsA.coarseDelay); + Qspi_Ip_DLLSetFineOffsetA (baseAddr, userConfigPtr->dllSettingsA.fineDelay); + Qspi_Ip_DLLFreqEnA (baseAddr, userConfigPtr->dllSettingsA.freqEnable); + + /* Trigger slave chain update */ + Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE); + + /* Wait for slave delay chain update */ + status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, TRUE); + /* Disable slave chain update */ + Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLASetup + * Description : Setup DLL side A before update + */ +static void Qspi_Ip_ConfigureDLLASetup(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + /* Set DLL in auto update mode and configure coarse and fine delays */ + Qspi_Ip_DLLSlaveBypassA (baseAddr, FALSE); + Qspi_Ip_DLLSlaveAutoUpdateA (baseAddr, (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsA.dllMode)); +#ifdef QuadSPI_DLLCRA_DLL_REFCNTR_MASK + Qspi_Ip_DLLSetReferenceCounterA(baseAddr, userConfigPtr->dllSettingsA.referenceCounter); +#endif /* QuadSPI_DLLCRA_DLL_REFCNTR_MASK */ +#ifdef QuadSPI_DLLCRA_DLLRES_MASK + Qspi_Ip_DLLSetResolutionA (baseAddr, userConfigPtr->dllSettingsA.resolution); +#endif /* QuadSPI_DLLCRA_DLLRES_MASK */ + Qspi_Ip_DLLSetDelayOffsetA (baseAddr, userConfigPtr->dllSettingsA.coarseDelay); + Qspi_Ip_DLLSetFineOffsetA (baseAddr, userConfigPtr->dllSettingsA.fineDelay); + Qspi_Ip_DLLFreqEnA (baseAddr, userConfigPtr->dllSettingsA.freqEnable); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLAUpdate + * Description : Configures DLL - Side A (manual update or auto update mode) + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLAUpdate(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Setup DLL side A before update */ + Qspi_Ip_ConfigureDLLASetup(baseAddr, userConfigPtr); + + if (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsA.dllMode) + { + /* For auto update mode, trigger slave chain update */ + Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE); + } + /* Enable DLL */ + Qspi_Ip_DLLEnableA(baseAddr, TRUE); + + if (QSPI_IP_DLL_MANUAL_UPDATE == userConfigPtr->dllSettingsA.dllMode) + { + /* For manual update mode, wait for DLL lock before triggering slave chain update */ + status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)FALSE); + + Qspi_Ip_DLLSlaveUpdateA(baseAddr, TRUE); + } + + /* Wait for slave delay chain update */ + if (STATUS_QSPI_IP_SUCCESS == status) + { + status = Qspi_Ip_WaitDLLASlaveLock(baseAddr, (boolean)TRUE); + } + + /* Disable slave chain update */ + Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLA + * Description : Configures DLL - Side A + * Qspi_Ip_ConfigureDLLA_Activity + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLA(uint32 instance, + QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + (void)instance; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Ensure DLL and slave chain update are off */ + Qspi_Ip_DLLSlaveUpdateA(baseAddr, FALSE); + Qspi_Ip_DLLEnableA (baseAddr, FALSE); + + /* Enable DQS slave delay chain before any settings take place */ + Qspi_Ip_DLLSlaveEnA(baseAddr, TRUE); + + if (QSPI_IP_DLL_BYPASSED == userConfigPtr->dllSettingsA.dllMode) + { + status = Qspi_Ip_ConfigureDLLAByPass(baseAddr, userConfigPtr); + } + else /* QSPI_DLL_MANUAL_UPDATE or QSPI_DLL_AUTO_UPDATE */ + { + status = Qspi_Ip_ConfigureDLLAUpdate(baseAddr, userConfigPtr); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_WaitDLLBSlaveLock + * Description : DLL side B - Wait for slave high lock status or DLL lock status + */ +static Qspi_Ip_StatusType Qspi_Ip_WaitDLLBSlaveLock(const QuadSPI_Type *baseAddr, + boolean waitSlaveLock + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + boolean LockStatus; + + /* Prepare timeout counter */ + uint32 u32ElapsedTicks = 0UL; + uint32 u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_DLL_LOCK_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + uint32 u32CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + + do + { + /* Wait for slave high lock status or DLL lock status */ + LockStatus = (waitSlaveLock) ? Qspi_Ip_DLLGetSlaveLockStatusB(baseAddr) : Qspi_Ip_DLLGetLockStatusB(baseAddr); + + /* Check for errors reported by DLL */ + if (Qspi_Ip_DLLGetErrorStatusB(baseAddr)) + { + status = STATUS_QSPI_IP_ERROR; + } + else + { + /* Check for timeout */ + u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + if (u32ElapsedTicks >= u32TimeoutTicks) + { + status = STATUS_QSPI_IP_TIMEOUT; + } + } + + if (STATUS_QSPI_IP_SUCCESS != status) + { + break; + } + } + while (!LockStatus); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLBByPass + * Description : Configures DLL - Side B (bypass mode) + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLBByPass(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Set DLL in bypass mode and configure coarse and fine delays */ + Qspi_Ip_DLLSlaveBypassB (baseAddr, TRUE); + Qspi_Ip_DLLSlaveAutoUpdateB(baseAddr, FALSE); + Qspi_Ip_DLLSetDelayCoarseB (baseAddr, userConfigPtr->dllSettingsB.coarseDelay); + Qspi_Ip_DLLSetFineOffsetB (baseAddr, userConfigPtr->dllSettingsB.fineDelay); + Qspi_Ip_DLLFreqEnB (baseAddr, userConfigPtr->dllSettingsB.freqEnable); + + /* Trigger slave chain update */ + Qspi_Ip_DLLSlaveUpdateB (baseAddr, TRUE); + + /* Wait for slave delay chain update */ + status = Qspi_Ip_WaitDLLBSlaveLock(baseAddr, TRUE); + /* Disable slave chain update */ + Qspi_Ip_DLLSlaveUpdateB(baseAddr, FALSE); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLBSetup + * Description : Setup DLL side B before update + */ +static void Qspi_Ip_ConfigureDLLBSetup(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + /* Set DLL in auto update mode and configure coarse and fine delays */ + Qspi_Ip_DLLSlaveBypassB (baseAddr, FALSE); + Qspi_Ip_DLLSlaveAutoUpdateB (baseAddr, (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsB.dllMode)); + Qspi_Ip_DLLSetReferenceCounterB(baseAddr, userConfigPtr->dllSettingsB.referenceCounter); + Qspi_Ip_DLLSetResolutionB (baseAddr, userConfigPtr->dllSettingsB.resolution); + Qspi_Ip_DLLSetDelayOffsetB (baseAddr, userConfigPtr->dllSettingsB.coarseDelay); + Qspi_Ip_DLLSetFineOffsetB (baseAddr, userConfigPtr->dllSettingsB.fineDelay); + Qspi_Ip_DLLFreqEnB (baseAddr, userConfigPtr->dllSettingsB.freqEnable); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLBUpdate + * Description : Configures DLL - Side B (manual update or auto update mode) + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLBUpdate(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Setup DLL side B before update */ + Qspi_Ip_ConfigureDLLBSetup(baseAddr, userConfigPtr); + + if (QSPI_IP_DLL_AUTO_UPDATE == userConfigPtr->dllSettingsB.dllMode) + { + /* For auto update mode, trigger slave chain update */ + Qspi_Ip_DLLSlaveUpdateB(baseAddr, TRUE); + } + /* Enable DLL */ + Qspi_Ip_DLLEnableB(baseAddr, TRUE); + + if (QSPI_IP_DLL_MANUAL_UPDATE == userConfigPtr->dllSettingsB.dllMode) + { + /* For manual update mode, wait for DLL lock before triggering slave chain update */ + status = Qspi_Ip_WaitDLLBSlaveLock(baseAddr, (boolean)FALSE); + + Qspi_Ip_DLLSlaveUpdateB(baseAddr, TRUE); + } + + /* Wait for slave delay chain update */ + if (STATUS_QSPI_IP_SUCCESS == status) + { + status = Qspi_Ip_WaitDLLBSlaveLock(baseAddr, (boolean)TRUE); + } + + /* Disable slave chain update */ + Qspi_Ip_DLLSlaveUpdateB(baseAddr, FALSE); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLLB + * Description : Configures DLL - Side B + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLLB(uint32 instance, + QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + (void)instance; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Ensure DLL and slave chain update are off */ + Qspi_Ip_DLLSlaveUpdateB(baseAddr, FALSE); + Qspi_Ip_DLLEnableB (baseAddr, FALSE); + + /* Enable DQS slave delay chain before any settings take place */ + Qspi_Ip_DLLSlaveEnB(baseAddr, TRUE); + + if (QSPI_IP_DLL_BYPASSED == userConfigPtr->dllSettingsB.dllMode) + { + status = Qspi_Ip_ConfigureDLLBByPass(baseAddr, userConfigPtr); + } + else /* QSPI_DLL_MANUAL_UPDATE or QSPI_DLL_AUTO_UPDATE */ + { + status = Qspi_Ip_ConfigureDLLBUpdate(baseAddr, userConfigPtr); + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureDLL + * Description : Configure the DLL chain + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureDLL(uint32 instance, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance]; + + /* Configure DLL */ + if ((userConfigPtr->memSizeA1 + userConfigPtr->memSizeA2) > 0U) + { + status = Qspi_Ip_ConfigureDLLA(instance, baseAddr, userConfigPtr); + } + if ((userConfigPtr->memSizeB1 + userConfigPtr->memSizeB2) > 0U) + { + if (STATUS_QSPI_IP_SUCCESS == status) + { + status = Qspi_Ip_ConfigureDLLB(instance, baseAddr, userConfigPtr); + } + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_IsSideAvailableB + * Description : Check support Side B in user configuration + * + *END**************************************************************************/ +static inline boolean Qspi_Ip_IsSideAvailableB(const Qspi_Ip_ControllerConfigType *userConfigPtr) +{ + boolean Status = FALSE; + + if ((userConfigPtr->memSizeB1 + userConfigPtr->memSizeB2) > 0U) + { + Status = TRUE; + } + + return Status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureChipOptions + * Description : Configures chip-specific settings, e.g. SOCCR + ***********************************************************************/ +#if defined(FEATURE_QSPI_CHIP_OPTIONS_S32K148) +static void Qspi_Ip_ConfigureChipOptions(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + /* always enable pads input buffers */ + uint8 clkOption = QSPI_MCR_SCLKCFG_INPUT_EN; + uint32 chipOption = 0U; + + /* Configure MCR_SCLKCFG options */ + /* Configure module clock selection */ + if (QSPI_IP_CLK_SRC_BUS_CLK == userConfigPtr->clockSrc) + { + clkOption |= QSPI_MCR_SCLKCFG_CLK_MOD; + } + /* Configure internal reference clock selection */ + if (QSPI_IP_CLK_REF_FIRC_DIV1 == userConfigPtr->clockRef) + { + clkOption |= QSPI_MCR_SCLKCFG_CLK_SRC; + } + /* Configure external DQS mode for Flash B (HyperRAM Enabled) */ + if (QSPI_IP_READ_MODE_EXTERNAL_DQS == userConfigPtr->readModeB) + { + clkOption |= QSPI_MCR_SCLKCFG_EXT_DQS; + } + /* Select reference clock for DQS for each side */ + if (QSPI_IP_READ_MODE_LOOPBACK == userConfigPtr->readModeA) + { + clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_SEL_A); + } + if (QSPI_IP_READ_MODE_LOOPBACK == userConfigPtr->readModeB) + { + clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_SEL_B); + } + /* Configure inverted DQS: 0-Inverted / 1-Not Inverted */ + if ((boolean)FALSE == userConfigPtr->dqsInvertA) + { + clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_INV_A); + } + if ((boolean)FALSE == userConfigPtr->dqsInvertB) + { + clkOption |= (uint8)(QSPI_MCR_SCLKCFG_DQS_INV_B); + } + Qspi_Ip_SetClockOptions(baseAddr, clkOption); + + /* Configure SOCCR options */ + /* Disable divider before configuring it */ + Qspi_Ip_SetChipOptions(baseAddr, QuadSPI_SOCCR_PDD_MASK); + chipOption |= QuadSPI_SOCCR_PD((uint32)userConfigPtr->clockRefDiv - 1U); + chipOption |= ((uint32)userConfigPtr->dqsDelayA << QuadSPI_SOCCR_DSQ_DEL_A) + + ((uint32)userConfigPtr->dqsDelayB << QuadSPI_SOCCR_DSQ_DEL_B); + /* Write configuration, keep divider disabled */ + Qspi_Ip_SetChipOptions(baseAddr, chipOption | QuadSPI_SOCCR_PDD_MASK); + /* Enable divider */ + Qspi_Ip_SetChipOptions(baseAddr, chipOption); +} + +#elif defined(FEATURE_QSPI_CHIP_OPTIONS_S32K3) +static void Qspi_Ip_ConfigureChipOptions(QuadSPI_Type *baseAddr, const Qspi_Ip_ControllerConfigType * userConfigPtr) +{ + (void)userConfigPtr; + Qspi_Ip_SetChipOptions(baseAddr, 0x0000000E); /* set ibe=1, obe=1, dse=1 and sre=0 */ +} + +#else +static void Qspi_Ip_ConfigureChipOptions(const QuadSPI_Type *baseAddr, const Qspi_Ip_ControllerConfigType * userConfigPtr) +{ + /* Do nothing */ + (void)userConfigPtr; + (void)baseAddr; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_DdrConfig + * Description : + */ +static void Qspi_Ip_DdrConfig(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + if (QSPI_IP_DATA_RATE_SDR == userConfigPtr->dataRate) + { + QSPI_DDR_Disable(baseAddr); + /* Ignore output data align setting in SDR mode */ + Qspi_Ip_SetDataInHoldTime(baseAddr, QSPI_IP_FLASH_DATA_ALIGN_REFCLK); + } + else /* QSPI_IP_DATA_RATE_DDR */ + { + QSPI_DDR_Enable(baseAddr); + Qspi_Ip_SetDataInHoldTime(baseAddr, userConfigPtr->dataAlign); + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureReadOptions + * Description : Configures data read settings +* @implements Qspi_Ip_ConfigureReadOptions_Activity */ +static void Qspi_Ip_ConfigureReadOptions(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType *userConfigPtr + ) +{ + /* Always enable DQS */ + QSPI_DQS_Enable(baseAddr); + + Qspi_Ip_DdrConfig(baseAddr, userConfigPtr); + + /* select DQS A source (internal/loopback/external) */ + Qspi_Ip_SetDQSSourceA(baseAddr, userConfigPtr->readModeA); + + /* Select DLL tap in SMPR register */ + Qspi_Ip_SetRxDLLTapA(baseAddr, userConfigPtr->dllSettingsA.tapSelect); + + if (TRUE == Qspi_Ip_IsSideAvailableB(userConfigPtr)) + { + /* Select DQS B source (internal/loopback/external) */ + Qspi_Ip_SetDQSSourceB(baseAddr, userConfigPtr->readModeB); + + /* Select DLL tap in SMPR register */ + Qspi_Ip_SetRxDLLTapB(baseAddr, userConfigPtr->dllSettingsB.tapSelect); + } + + (void)userConfigPtr; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetAhbBuf + * Description : Sets up AHB buffer 0 buffer 1 and buffer 2 + */ +static void Qspi_Ip_SetAhbBuf(uint32 instance, + const Qspi_Ip_ControllerAhbConfigType *config + ) +{ + QuadSPI_Type *baseAddr; + /* Get base address of instance */ + baseAddr = Qspi_Ip_BaseAddress[instance]; + /* Set AHB buffer 0 */ + Qspi_Ip_SetAhbBuf0(baseAddr, config->sizes[0U], config->masters[0U]); + /* Set AHB buffer 1 */ + Qspi_Ip_SetAhbBuf1(baseAddr, config->sizes[1U], config->masters[1U]); + /* Set AHB buffer 2 */ + Qspi_Ip_SetAhbBuf2(baseAddr, config->sizes[2U], config->masters[2U]); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_AhbSetup + * Description : Sets up AHB accesses to the serial flash +* @implements Qspi_Ip_AhbSetup_Activity */ +static Qspi_Ip_StatusType Qspi_Ip_AhbSetup(uint32 instance, + const Qspi_Ip_ControllerAhbConfigType *config + ) +{ + QuadSPI_Type *baseAddr; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(0U == (config->sizes[0U] & 7U)); + DEV_ASSERT_QSPI(((uint32)config->sizes[0U] + + (uint32)config->sizes[1U] + + (uint32)config->sizes[2U] + + (uint32)config->sizes[3U]) <= FEATURE_QSPI_AHB_BUF_SIZE); +#endif + + /* Get base address of instance */ + baseAddr = Qspi_Ip_BaseAddress[instance]; + + /* configure AHB transfer sizes to match the buffer sizes */ + /* Sets up AHB buffer 0 buffer 1 and buffer 2 */ + (void)Qspi_Ip_SetAhbBuf(instance, config); + /* Set AHB buffer 3 */ + Qspi_Ip_SetAhbBuf3(baseAddr, config->sizes[3U], config->masters[3U], config->allMasters); + /* Set AHB buffer index 0 */ + Qspi_Ip_SetAhbBuf0Ind(baseAddr, (uint32)config->sizes[0U]); + /* Set AHB buffer index 1 */ + Qspi_Ip_SetAhbBuf1Ind(baseAddr, (uint32)config->sizes[0U] + (uint32)config->sizes[1U]); + /* Set AHB buffer index 2 */ + Qspi_Ip_SetAhbBuf2Ind(baseAddr, (uint32)config->sizes[0U] + (uint32)config->sizes[1U] + (uint32)config->sizes[2U]); + + return STATUS_QSPI_IP_SUCCESS; +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Program the SFAR & IPCR registers. + * + * @param[in] BaseAddress base address of the given QuadSPI instance + * @param[in] Address address to be written into SFAR + * @param[in] DataSize data size to be written into IPCR + * @param[in] SeqId sequence id where the command is stored in the physical lut + * + * @retval STATUS_QSPI_IP_SUCCESS SFAR and IPCR writes passed the MDAD checks + * @retval STATUS_QSPI_IP_ERROR a common or a queue error has occurred + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static void Qspi_Ip_NewIpsTransaction +( + QuadSPI_Type * BaseAddress, + uint32 Address, + uint16 DataSize, + uint8 SeqId) +{ + #if (FEATURE_QSPI_HAS_SFP == 1) + Qspi_Ip_Sfp_ClearLatchedErrors(BaseAddress); + #endif + + Qspi_Ip_SetIpAddr(BaseAddress, Address); + Qspi_Ip_IpTrigger(BaseAddress, SeqId, DataSize); +} + +#if (FEATURE_QSPI_HAS_SFP == 1) + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Clear the errors latched in SFP registers. + * + * Error Status (ERRSTAT): + * - FRADn Access Error (FRADnACC) + * - No FRAD Match Error (FRADMTCH) + * FlashSeq Request (FLSEQREQ): + * - Clear (CLR) + * IPS Error (IPSERROR): + * - Clear (CLR) + * Target Group n SFAR Status (TG0SFARS - TG1SFARS): + * - Clear (CLR) + * Target Group n IPCR Status (TG0IPCRS - TG1IPCRS): + * - Clear (CLR) + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +void Qspi_Ip_Sfp_ClearLatchedErrors_Privileged +( + QuadSPI_Type * BaseAddr) +{ + BaseAddr->ERRSTAT |= 0x1FFUL; + BaseAddr->FLSEQREQ |= QuadSPI_FLSEQREQ_CLR_MASK; + BaseAddr->IPSERROR |= QuadSPI_IPSERROR_CLR_MASK; + + for (uint32 Mdad = 0U; Mdad < QuadSPI_MDAD_COUNT; Mdad++) + { + BaseAddr->MDAD[Mdad].TGSFARS |= QuadSPI_TGSFARS_CLR_MASK; + BaseAddr->MDAD[Mdad].TGIPCRS |= QuadSPI_TGIPCRS_CLR_MASK; + } +} + +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Wait for the current transaction to reach a given state + * + * @param[in] BaseAddress base address of the given QuadSPI instance + * @param[in] State the STATE field value that is to be expected + * + * @retval STATUS_QSPI_IP_SUCCESS + * @retval STATUS_QSPI_IP_TIMEOUT + * @retval STATUS_QSPI_IP_ERROR + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static Qspi_Ip_StatusType Qspi_Ip_Sfp_WaitFsmState +( + QuadSPI_Type const * BaseAddress, + uint32 State) +{ + Qspi_Ip_StatusType Status = STATUS_QSPI_IP_ERROR; + uint32 FsmStat; + uint32 FsmStatValid; + uint32 FsmStatState; + + uint32 ElapsedTicks = 0U; + uint32 TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_QSPI_IDLE_TIMEOUT, QSPI_IP_TIMEOUT_TYPE);; + uint32 CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE);; + + do + { + FsmStat = BaseAddress->FSMSTAT; + FsmStatValid = (FsmStat & QuadSPI_FSMSTAT_VLD_MASK); + FsmStatState = (FsmStat & QuadSPI_FSMSTAT_STATE_MASK) >> QuadSPI_FSMSTAT_STATE_SHIFT; + if ((FsmStatValid != 0U) && (FsmStatState == State)) + { + Status = STATUS_QSPI_IP_SUCCESS; + break; + } + + ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + } while (ElapsedTicks < TimeoutTicks); + + if (ElapsedTicks >= TimeoutTicks) + { + Status = STATUS_QSPI_IP_TIMEOUT; + } + + return Status; +} + +#endif /* FEATURE_QSPI_HAS_SFP */ + +/*! @endcond */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetLut + * Description : Configures a pair of LUT commands in the specified LUT register + * + *END**************************************************************************/ +void Qspi_Ip_SetLut(uint32 instance, + uint8 LutRegister, + Qspi_Ip_InstrOpType operation0, + Qspi_Ip_InstrOpType operation1 + ) +{ + QuadSPI_Type *baseAddr; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(LutRegister < QuadSPI_LUT_COUNT); +#endif + + baseAddr = Qspi_Ip_BaseAddress[instance]; + baseAddr->LUT[LutRegister] = QSPI_IP_PACK_LUT_REG(operation0, operation1); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_WriteLuts_Privileged + * Description : Configures pairs of LUT commands from the specified LUT register + * + *END**************************************************************************/ +void Qspi_Ip_WriteLuts_Privileged(uint32 Instance, + uint8 StartLutRegister, + const uint32 *Data, + uint8 Size + ) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(Instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(StartLutRegister < QuadSPI_LUT_COUNT); + DEV_ASSERT_QSPI(Size <= FEATURE_QSPI_LUT_SEQUENCE_SIZE); + DEV_ASSERT_QSPI((StartLutRegister + Size) <= QuadSPI_LUT_COUNT); +#endif + + QuadSPI_Type *BaseAddr = Qspi_Ip_BaseAddress[Instance]; + uint8 Idx; + + for (Idx = 0U; Idx < Size; Idx++) + { + BaseAddr->LUT[StartLutRegister + Idx] = Data[Idx]; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetAhbSeqId_Privileged + * Description : Sets sequence ID for AHB operations + * + *END**************************************************************************/ +void Qspi_Ip_SetAhbSeqId_Privileged(uint32 instance, + uint8 seqID + ) +{ + QuadSPI_Type *baseAddr; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); +#endif + + baseAddr = Qspi_Ip_BaseAddress[instance]; + baseAddr->BFGENCR = QuadSPI_BFGENCR_SEQID(seqID); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetSerialFlashAddr + * Description : Configure the Serial Flash Memory Address + * + *END**************************************************************************/ +static inline void Qspi_Ip_SetSerialFlashAddress(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ) +{ + Qspi_Ip_SetAddrOptions(baseAddr, userConfigPtr->columnAddr, userConfigPtr->wordAddresable); + + Qspi_Ip_SetByteSwap(baseAddr, userConfigPtr->byteSwap); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SetCsTime + * Description : Configure the CS holdtime and CS setup time + * + *END**************************************************************************/ +static inline void Qspi_Ip_SetCsTime(QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ) +{ + /* Configure the CS holdtime and CS setup time */ + Qspi_Ip_SetCsHoldTime(baseAddr, userConfigPtr->csHoldTime); + Qspi_Ip_SetCsSetupTime(baseAddr, userConfigPtr->csSetupTime); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureBuffers + * Description : Configure the Tx, Rx and AHB buffers + * + *END**************************************************************************/ +static inline void Qspi_Ip_ConfigureBuffers(uint32 instance, + QuadSPI_Type *baseAddr, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ) +{ + Qspi_Ip_SetRxCfg(baseAddr, userConfigPtr->sampleDelay, userConfigPtr->samplePhase); +#ifdef QuadSPI_RBCT_RXBRD_MASK + /* Read Rx buffer through RBDR registers */ + Qspi_Ip_SetRxBufReadout(baseAddr, QSPI_IP_RX_READOUT_IP); +#endif + /* Set watermarks */ + Qspi_Ip_SetTxWatermark(baseAddr, 1U); + Qspi_Ip_SetRxWatermark(baseAddr, 1U); + /* Configure AHB buffers settings */ + (void)Qspi_Ip_AhbSetup(instance, &(userConfigPtr->ahbConfig)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureControllerA + * Description : Configure for side A + * + *END**************************************************************************/ +static inline void Qspi_Ip_ConfigureControllerA(uint32 instance, + const Qspi_Ip_ControllerConfigType *userConfigPtr) +{ + QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance]; + + /* Configure external flash memory map Size A */ + Qspi_Ip_SetMemMapSizeA(instance, baseAddr, userConfigPtr->memSizeA1, userConfigPtr->memSizeA2); + + /* Configure idle line value side A */ + Qspi_Ip_SetIdleLineValuesA(baseAddr, userConfigPtr->io2IdleValueA, userConfigPtr->io3IdleValueA); + + /* Configure the center aligned strobe side A */ + Qspi_Ip_SetCenterAlignedStrobeA(baseAddr, userConfigPtr->centerAlignedStrobeA); + + /* Configure the differential clock side A */ + Qspi_Ip_SetDifferentialClockA(baseAddr, userConfigPtr->differentialClockA); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureControllerB + * Description : Configure for side B + * + *END**************************************************************************/ +static inline void Qspi_Ip_ConfigureControllerB(uint32 instance, + const Qspi_Ip_ControllerConfigType *userConfigPtr) +{ + /* Check Size B is available */ + if (TRUE == Qspi_Ip_IsSideAvailableB(userConfigPtr)) + { + QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance]; + /* Configure external flash memory map Side B, + the end address of side B must be greater than or equal to the end address of side A2 + */ + Qspi_Ip_SetMemMapSizeB(baseAddr, userConfigPtr->memSizeB1, userConfigPtr->memSizeB2); + /* Unused side lines are "no matter" so just repeat idle settings on both sides */ + Qspi_Ip_SetIdleLineValuesB(baseAddr, userConfigPtr->io2IdleValueB, userConfigPtr->io3IdleValueB); + + /* Configure the center aligned strobe Side B */ + Qspi_Ip_SetCenterAlignedStrobeB(baseAddr, userConfigPtr->centerAlignedStrobeB); + + /* Configure the differential clock Side B */ + Qspi_Ip_SetDifferentialClockB(baseAddr, userConfigPtr->differentialClockB); + } +} + + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureControllerRegisters + * Description : Configure the controller A and B registers following user configurations + * + *END**************************************************************************/ +static inline void Qspi_Ip_ConfigureControllerRegisters(uint32 instance, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ) +{ + Qspi_Ip_ConfigureControllerA(instance, userConfigPtr); + + Qspi_Ip_ConfigureControllerB(instance, userConfigPtr); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureController + * Description : Configure the controller register following user configurations + * + *END**************************************************************************/ +static inline void Qspi_Ip_ConfigureController(uint32 instance, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ) +{ + QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance]; + + Qspi_Ip_ConfigureControllerRegisters(instance, userConfigPtr); + /* Configure the Serial Flash Memory Address */ + Qspi_Ip_SetSerialFlashAddress(baseAddr, userConfigPtr); + + /* Configure the CS holdtime and CS setup time */ + Qspi_Ip_SetCsTime(baseAddr, userConfigPtr); + + /* Configure buffers */ + Qspi_Ip_ConfigureBuffers(instance, baseAddr, userConfigPtr); + + /* Configure read options */ + Qspi_Ip_ConfigureReadOptions(baseAddr, userConfigPtr); + + /* Configure chip-specific options */ + Qspi_Ip_ConfigureChipOptions(baseAddr, userConfigPtr); + + #if (FEATURE_QSPI_HAS_SFP == 1) + Qspi_Ip_Sfp_Configure(baseAddr, userConfigPtr); + #endif +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ControllerInit + * Description : Initializes the qspi controller + * @implements Qspi_Ip_ControllerInit_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ControllerInit(uint32 instance, + const Qspi_Ip_ControllerConfigType * userConfigPtr + ) +{ + QuadSPI_Type *baseAddr; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(userConfigPtr != NULL_PTR); +#endif + + /* Initialize driver status structure */ + baseAddr = Qspi_Ip_BaseAddress[instance]; + + /* Ensure module is disabled */ + Qspi_Ip_Disable(baseAddr); + + /* Ensure all registers contain their reset value */ + Qspi_Ip_ResetAllRegisters(baseAddr); + + /* Configure the controller following the user configurations */ + Qspi_Ip_ConfigureController(instance, userConfigPtr); + + /* Enable QuadSPI module */ + Qspi_Ip_Enable(baseAddr); + + /* Reset serial flash and AHB domains */ + Qspi_Ip_SwReset(baseAddr); + + /* Store user configuration for runtime usage */ + Qspi_Ip_ControllerConfig[instance] = userConfigPtr; + /* Configure the DLL */ + status = Qspi_Ip_ConfigureDLL(instance, userConfigPtr); + + /* Workaround to clear CRC and ECC errors flags */ + baseAddr->FR = (uint32)0xFFFFFFFFUL; + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ControllerDeinit + * Description : De-initialize the qspi driver + * @implements Qspi_Ip_ControllerDeinit_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ControllerDeinit(uint32 instance) +{ + QuadSPI_Type *baseAddr; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); +#endif + + baseAddr = Qspi_Ip_BaseAddress[instance]; + + /* Disable QuadSPI module */ + Qspi_Ip_Disable(baseAddr); + + /* Detach the configuration pointer */ + Qspi_Ip_ControllerConfig[instance] = NULL_PTR; + + return STATUS_QSPI_IP_SUCCESS; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Abort + * Description : Force the Qspi controller to cancel any on-going transactions by performing the software reset requence. + * This can be used to recover the hardware controller from being stuck in BUSY state. + * Re-configure DLL is needed to avoid side-effects on the DLL after the S/W reset. + */ +Qspi_Ip_StatusType Qspi_Ip_Abort(uint32 instance) +{ +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); +#endif + + QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance]; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Reset serial flash and AHB domains */ + Qspi_Ip_SwReset(baseAddr); + + /* S/W reset would also loose any Slave-chain upate, therefore re-configure DLL sequence is needed */ + if (Qspi_Ip_ControllerConfig[instance] != NULL_PTR) + { + /* Perform the DLL config only if the user configuration is available. + Because there will be the case when user skip the controller configuration at initialization time. + */ + status = Qspi_Ip_ConfigureDLL(instance, Qspi_Ip_ControllerConfig[instance]); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_GetBaseAdress + * Description : Returns the physical base address of a flash device on the AHB bus. + * The controller must be initialized prior to calling this function. + * @implements Qspi_Ip_GetBaseAdress_Activity */ +uint32 Qspi_Ip_GetBaseAdress(uint32 instance, + Qspi_Ip_ConnectionType connectionType + ) +{ + const QuadSPI_Type *baseAddr; + uint32 address = 0U; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); +#endif + + /* get the base address base on the instance */ + baseAddr = Qspi_Ip_BaseAddress[instance]; + + switch (connectionType) + { + case QSPI_IP_SIDE_A1: + /* get base address of side A1 */ + address = Qspi_Ip_AhbAddress[instance]; + break; + case QSPI_IP_SIDE_A2: + /* get base address of side A2 */ + address = baseAddr->SFA1AD; + break; + case QSPI_IP_SIDE_B1: + /* get base address of side B1 */ + address = baseAddr->SFA2AD; + break; + case QSPI_IP_SIDE_B2: + /* get base address of side B2 */ + address = baseAddr->SFB1AD; + break; + default: + ; /* Not possible */ + break; + } + + return address; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_IpCommand + * Description : Launches a simple IP command + * @implements Qspi_Ip_IpCommand_Activity */ +Qspi_Ip_StatusType Qspi_Ip_IpCommand(uint32 instance, + uint8 SeqId, + uint32 addr + ) +{ + QuadSPI_Type *baseAddr; + Qspi_Ip_StatusType status; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE)); +#endif + + baseAddr = Qspi_Ip_BaseAddress[instance]; + + /* Reset AHB buffers to force re-read from memory after erase operation */ + Qspi_Ip_AhbFlush(baseAddr); + + /* Launch the IP command */ + Qspi_Ip_NewIpsTransaction(baseAddr, addr, 0U, SeqId); + + /* Add Fault Injection point for FR_ILLINE flag */ + MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPCOMMAND); + + status = Qspi_Ip_CmdWaitComplete(instance); + + /* Make sure there is no garbage in Rx fifo in case of triggering a dummy READ instruction. + This clears RBSR[RDBFL] to ensure QuadSPI is idle from SFP point of view and avoid the Master timeout error. + */ + Qspi_Ip_ClearRxBuf(baseAddr); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_CmdWaitComplete + * Description : Wait until Qspi controller is not busy or timeout + */ +static Qspi_Ip_StatusType Qspi_Ip_CmdWaitComplete(uint32 instance) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint32 u32ElapsedTicks = 0UL; + uint32 u32TimeoutTicks; + uint32 u32CurrentTicks; + + /* Prepare timeout counter */ + u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_CMD_COMPLETE_TIMEOUT, QSPI_IP_TIMEOUT_TYPE); + u32CurrentTicks = OsIf_GetCounter(QSPI_IP_TIMEOUT_TYPE); + + MCAL_FAULT_INJECTION_POINT(QSPI_IP_FMEA_WAIT_TRANSACTION_COMPLETE); + + /* Wait for command to be completed */ + do + { + u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, QSPI_IP_TIMEOUT_TYPE); + status = Qspi_Ip_ControllerGetStatus(instance); + } + while ((u32ElapsedTicks < u32TimeoutTicks) && (STATUS_QSPI_IP_BUSY == status)); + + if (STATUS_QSPI_IP_BUSY == status) + { + status = STATUS_QSPI_IP_TIMEOUT; + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_IpRead + * Description : Launches an IP read command + * @implements Qspi_Ip_IpRead_Activity */ +Qspi_Ip_StatusType Qspi_Ip_IpRead(uint32 instance, + uint8 SeqId, + uint32 addr, + uint8 * dataRead, + const uint8 * dataCmp, + uint32 size + ) +{ + Qspi_Ip_StatusType status; + QuadSPI_Type *baseAddr; + uint32 padding; + uint16 Idatsz = 0U; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE)); + DEV_ASSERT_QSPI(size <= FEATURE_QSPI_RX_BUF_SIZE); +#endif + + baseAddr = Qspi_Ip_BaseAddress[instance]; + padding = (uint32)(Qspi_Ip_MemoryPadding[instance]); + + /* If size is odd, round up to even size; this is needed in octal DDR mode */ + Idatsz = (uint16)((size + 1U) & (~1U)); + + /* Make sure there is no garbage in Rx fifo */ + Qspi_Ip_ClearRxBuf(baseAddr); + + Qspi_Ip_NewIpsTransaction(baseAddr, addr, Idatsz, SeqId); + + /* Add Fault Injection point for FR_ILLINE flag */ + MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPREAD); + + /* Wait until the command is sent */ + status = Qspi_Ip_CmdWaitComplete(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Process received data */ + if (dataRead != NULL_PTR) + { + /* Normal read */ + status = Qspi_Ip_ProcessDataRead(dataRead, size, baseAddr, padding); + } + else if (dataCmp != NULL_PTR) + { + /* Verify */ + status = Qspi_Ip_ProcessDataVerify(dataCmp, size, baseAddr, padding); + } + else + { + /* Blank check */ + status = Qspi_Ip_ProcessDataBlankCheck(size, baseAddr, padding); + } + } + + /* Reset Rx fifo */ + Qspi_Ip_ClearRxBuf(baseAddr); + + /* Clear padding, only needed for the first read */ + Qspi_Ip_MemoryPadding[instance] = 0U; + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_InvalidateTxBuf + * Description : Invalidates the TX buffer content and wait until it is completed or timed out + * @implements Qspi_Ip_InvalidateTxBuf_Activity */ +static inline void Qspi_Ip_InvalidateTxBuf(uint32 instance) +{ + QuadSPI_Type *baseAddr = Qspi_Ip_BaseAddress[instance]; + volatile uint32 u32CurrentTicks; + + /* Start TX FIFO reset */ + Qspi_Ip_ClearTxBuf(baseAddr); + + /* Prepare timeout counter */ + u32CurrentTicks = QSPI_IP_TX_BUFFER_RESET_DELAY; + /* Insert delay to ensure TX FIFO reset is complete */ + while (u32CurrentTicks > 0U) + { + u32CurrentTicks--; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_PadTxBuf + * Description : Pad Tx buffer up to a minimum number of entries required + * by the device for transmission to start + * + *END**************************************************************************/ +#if (FEATURE_QSPI_TX_MIN_BUF_FILL > 1) +static void Qspi_Ip_PadTxBuf(QuadSPI_Type *baseAddr) +{ + uint32 bufFill = Qspi_Ip_GetTxBufFill(baseAddr); + /* Pad buffer will blank data */ + while ((bufFill < FEATURE_QSPI_TX_MIN_BUF_FILL) || ((bufFill & 3U) != 0U)) + { + Qspi_Ip_WriteTxData(baseAddr, 0xFFFFFFFFU); + bufFill++; + } +} +#else +static void Qspi_Ip_PadTxBuf(const QuadSPI_Type *baseAddr) +{ + /* Remove unused variable */ + (void)baseAddr; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_IpWritePrepare + * Description : Reset AHB buffers and check no garbage in Tx + */ +static void Qspi_Ip_IpWritePrepare(uint32 instance) +{ + QuadSPI_Type *baseAddr; + baseAddr = Qspi_Ip_BaseAddress[instance]; + /* Reset AHB buffers to force re-read from memory after write operation */ + Qspi_Ip_AhbFlush(baseAddr); + + /* Ensure there is no garbage in Tx FIFO */ + Qspi_Ip_InvalidateTxBuf(instance); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_TxBufPrepare + * Description : Fill Tx buffer and Pad Tx buffer up to the minimum number of entries required by the device. + */ +static void Qspi_Ip_TxBufPrepare(QuadSPI_Type *baseAddr, + const uint8 *data, + uint32 size, + uint32 padding + ) +{ + /* Fill Tx buffer */ + Qspi_Ip_FillTxBuf(baseAddr, data, size, padding); + + /* Pad Tx buffer up to the minimum number of entries required by the device */ + Qspi_Ip_PadTxBuf(baseAddr); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_IpWriteSfp + * Description : Launches an IP write command with sfp + */ +static Qspi_Ip_StatusType Qspi_Ip_IpWriteSfp(uint32 instance, + uint8 SeqId, + uint32 addr, + const uint8 * data, + uint32 size + ) +{ + QuadSPI_Type *baseAddr; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_ERROR; + uint32 padding; + uint16 TotalSize = 0U; + + baseAddr = Qspi_Ip_BaseAddress[instance]; + /* Reset AHB buffers and check no garbage in Tx */ + Qspi_Ip_IpWritePrepare(instance); + + padding = Qspi_Ip_MemoryPadding[instance]; + TotalSize = (uint16)(size + (padding >> 4U) + (padding & 0x0FU)); + /* Check total data size need to be written is aligned with 4-bytes to avoid invalid value when setup watermark */ + if (((TotalSize % 4U) != 0U) && (TotalSize > 4U)) + { + TotalSize += (4U - (TotalSize % 4U)); + } + Qspi_Ip_MemoryPadding[instance] = 0U; /* Clear padding */ + + /* Setup water mark according to the transfer size to avoid underrun issue. */ + Qspi_Ip_SetTxWatermark(baseAddr, (uint8)((FEATURE_QSPI_TX_BUF_SIZE / 4U) - ((TotalSize / 4U) - 1U))); + + Qspi_Ip_NewIpsTransaction(baseAddr, addr, TotalSize, SeqId); + + /* 01 - TBDR lock is open. QuadSPI considers IPS transfer. Master counter is started. */ + if (STATUS_QSPI_IP_SUCCESS == Qspi_Ip_Sfp_WaitFsmState(baseAddr, 1U)) + { + /* Fill Tx buffer and Pad Tx buffer up to the minimum number of entries required by the device. */ + Qspi_Ip_TxBufPrepare(baseAddr, data, size, padding); + + MCAL_DATA_SYNC_BARRIER(); + MCAL_INSTRUCTION_SYNC_BARRIER(); + /* 10 - TX buffer filled above threshold. Write transfer is triggered. SEQID is written. */ + if (((baseAddr->FSMSTAT & QuadSPI_FSMSTAT_STATE_MASK) >> QuadSPI_FSMSTAT_STATE_SHIFT) == 2U) + { + /* Add Fault Injection point for FR_TBUF flag */ + MCAL_FAULT_INJECTION_POINT(FLS_FIP_FR_ERROR_IPWRITE); + + /* Wait until the command is sent */ + status = Qspi_Ip_CmdWaitComplete(instance); + } + } + return status; +} + + + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_IpWrite + * Description : Launches an IP write command + * @implements Qspi_Ip_IpWrite_Activity */ +Qspi_Ip_StatusType Qspi_Ip_IpWrite(uint32 instance, + uint8 SeqId, + uint32 addr, + const uint8 * data, + uint32 size + ) +{ + Qspi_Ip_StatusType status; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI(instance < QuadSPI_INSTANCE_COUNT); + DEV_ASSERT_QSPI(size <= (uint16)FEATURE_QSPI_TX_BUF_SIZE); + DEV_ASSERT_QSPI(SeqId < (QuadSPI_LUT_COUNT / FEATURE_QSPI_LUT_SEQUENCE_SIZE)); + DEV_ASSERT_QSPI(data != NULL_PTR); +#endif + + /* Launches an IP write command with sfp */ + status = Qspi_Ip_IpWriteSfp(instance, SeqId, addr, data, size); + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ControllerGetStatus + * Description : Checks the status of the currently running IP command + * @implements Qspi_Ip_ControllerGetStatus_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ControllerGetStatus(uint32 instance) +{ + QuadSPI_Type *baseAddr; + Qspi_Ip_StatusType status; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + DEV_ASSERT_QSPI((instance < QuadSPI_INSTANCE_COUNT)); +#endif + + baseAddr = Qspi_Ip_BaseAddress[instance]; + + MCAL_FAULT_INJECTION_POINT(QSPI_IP_FMEA_CONTROLLER_GET_STATUS); + /* Check device for busy status */ + if (Qspi_Ip_GetBusyStatus(baseAddr)) + { + status = STATUS_QSPI_IP_BUSY; + } + else + { + /* Check for errors reported by the QuadSPI */ + status = Qspi_Ip_ErrorCheck(baseAddr); + } + return status; +} + +#if (FEATURE_QSPI_HAS_SFP == 1) + +#if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON) +#if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON) +static void Qspi_Ip_Sfp_SetMdadConfig(QuadSPI_Type * baseAddr, + uint8 MdadInstance, + Qspi_Ip_ControllerConfigType const * userConfigPtr) +{ + /* Set Mdad config */ + Qspi_Ip_Sfp_SetTgSecureAttribute(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Tg[MdadInstance].SecureAttribute); + Qspi_Ip_Sfp_SetTgMaskType(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Tg[MdadInstance].MaskType); + Qspi_Ip_Sfp_SetTgMask(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Tg[MdadInstance].Mask); + Qspi_Ip_Sfp_SetTgDomainIdMatch(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Tg[MdadInstance].DomainId); + Qspi_Ip_Sfp_SetTgValid(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Tg[MdadInstance].Valid); +} + +#endif /* QSPI_IP_SFP_ENABLE_MDAD */ +#if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON) +static void Qspi_Ip_Sfp_SetFradConfig(QuadSPI_Type * baseAddr, + uint8 MdadInstance, + Qspi_Ip_ControllerConfigType const * userConfigPtr) +{ + /* Set Frad config */ + Qspi_Ip_Sfp_SetFradStartAddress(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Frad[MdadInstance].StartAddress); + Qspi_Ip_Sfp_SetFradEndAddress(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Frad[MdadInstance].EndAddress); + Qspi_Ip_Sfp_SetFradMd0Acp(baseAddr, MdadInstance, (uint8)userConfigPtr->SfpCfg.Frad[MdadInstance].Md0Acp); + Qspi_Ip_Sfp_SetFradMd1Acp(baseAddr, MdadInstance, (uint8)userConfigPtr->SfpCfg.Frad[MdadInstance].Md1Acp); + Qspi_Ip_Sfp_SetFradEaLock(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Frad[MdadInstance].ExclusiveAccessLock); + Qspi_Ip_Sfp_SetFradEaOwner(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Frad[MdadInstance].ExclusiveAccessOwner); + Qspi_Ip_Sfp_SetFradValid(baseAddr, MdadInstance, userConfigPtr->SfpCfg.Frad[MdadInstance].Valid); +} +#endif /* QSPI_IP_SFP_ENABLE_FRAD */ +#endif /* QSPI_IP_SFP_ENABLE_GLOBAL */ +/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * @brief Configure the SFP registers. + * + * @param[in] BaseAddr base address of the given QuadSPI instance + * @param[in] userConfigPtr QSPI controller configuration structure + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +void Qspi_Ip_Sfp_Configure_Privileged(QuadSPI_Type * baseAddr, + Qspi_Ip_ControllerConfigType const * userConfigPtr) +{ + /* Workaround for K396: QSPI must be enabled in order to write into SFP registers */ + /* Enable QuadSPI module */ + Qspi_Ip_Enable(baseAddr); + + Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_ALL, QSPI_IP_SFP_ENABLE_GLOBAL); + Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_MDAD, QSPI_IP_SFP_ENABLE_MDAD); + Qspi_Ip_Sfp_SetAccessControls(baseAddr, QSPI_IP_SFP_FRAD, QSPI_IP_SFP_ENABLE_FRAD); + +#if (QSPI_IP_SFP_ENABLE_GLOBAL == STD_ON) + +#if (QSPI_IP_SFP_ENABLE_MDAD == STD_ON) + for (uint8 Index = 0U; Index < QuadSPI_MDAD_COUNT; ++Index) + { + if (TRUE == userConfigPtr->SfpCfg.Tg[Index].Valid) + { + Qspi_Ip_Sfp_SetMdadConfig(baseAddr, Index, userConfigPtr); + } + } +#endif /* QSPI_IP_SFP_ENABLE_MDAD */ + +#if (QSPI_IP_SFP_ENABLE_FRAD == STD_ON) + for (uint8 Index = 0U; Index < QuadSPI_FRAD_COUNT; ++Index) + { + if (TRUE == userConfigPtr->SfpCfg.Frad[Index].Valid) + { + Qspi_Ip_Sfp_SetFradConfig(baseAddr, Index, userConfigPtr); + } + } +#endif /* QSPI_IP_SFP_ENABLE_FRAD */ + + Qspi_Ip_Sfp_SetMasterTimeout(baseAddr, userConfigPtr->SfpCfg.MasterTimeout); + +#else + (void)userConfigPtr; +#endif /* QSPI_IP_SFP_ENABLE_GLOBAL */ + +} + +/** + * Reset the registers the require privilege access for programming. + */ +void Qspi_Ip_ResetPrivilegedRegisters_Privileged(QuadSPI_Type *BaseAddr) +{ + uint8 cnt; + + /* reset BFGENCR register */ + BaseAddr->BFGENCR = (uint32)0x00000000UL; + + /* reset LUT0 register */ + BaseAddr->LUT[0] = (uint32)0x08180403UL; + /* reset LUT1 register */ + BaseAddr->LUT[1] = (uint32)0x24001C08UL; + for (cnt = 2U; cnt < QuadSPI_LUT_COUNT; cnt++) + { + BaseAddr->LUT[cnt] = (uint32)0x00000000UL; + } + + /* reset Secure Flash Protection registers */ + for (cnt = 0U; cnt < QuadSPI_FRAD_COUNT; ++cnt) + { + BaseAddr->FRAD[cnt].WORD0 = 0x00000000UL; + BaseAddr->FRAD[cnt].WORD1 = 0x0000FFFFUL; + BaseAddr->FRAD[cnt].WORD2 = 0x00000000UL; + BaseAddr->FRAD[cnt].WORD3 = 0x00000000UL; + } + for (cnt = 0U; cnt < QuadSPI_MDAD_COUNT; ++cnt) + { + BaseAddr->MDAD[cnt].TGMDAD = 0x00000000UL; + BaseAddr->MDAD[cnt].TGSFARS = 0x00000000UL; + BaseAddr->MDAD[cnt].TGIPCRS = 0x00000000UL; + } + BaseAddr->MGC = 0xA8000000UL; + BaseAddr->MRC = 0x00000E07UL; + BaseAddr->MTO = 0x0000FFFFUL; + BaseAddr->FLSEQREQ = 0x20000000UL; + BaseAddr->IPSERROR = 0x20000000UL; + BaseAddr->ERRSTAT = 0x000001FFUL; + BaseAddr->INT_EN = 0x00000000UL; +} + +#endif /* FEATURE_QSPI_HAS_SFP */ + +/* + * Set all hardware registers to their reset value + */ +static inline void Qspi_Ip_ResetAllRegisters(QuadSPI_Type *BaseAddr) +{ + uint8 cnt = 0U; + + /* reset MCR register */ + BaseAddr->MCR = (uint32)0x000F404CUL; + /* reset FLSHCR register */ + BaseAddr->FLSHCR = (uint32)0x00000303UL; + /* reset BUF0CR register */ + BaseAddr->BUF0CR = (uint32)0x00000000UL; + /* reset BUF1CR register */ + BaseAddr->BUF1CR = (uint32)0x00000001UL; + /* reset BUF2CR register */ + BaseAddr->BUF2CR = (uint32)0x00000002UL; + /* reset BUF3CR register */ + BaseAddr->BUF3CR = (uint32)0x80000003UL; + /* reset BUF0IND register */ + BaseAddr->BUF0IND = (uint32)0x00000000UL; + /* reset BUF1IND register */ + BaseAddr->BUF1IND = (uint32)0x00000000UL; + /* reset BUF2IND register */ + BaseAddr->BUF2IND = (uint32)0x00000000UL; + /* reset AWRCR register */ + BaseAddr->AWRCR = (uint32)0x00000000UL; + /* reset DLLCRA register */ + BaseAddr->DLLCRA = (uint32)0x01200000UL; + /* reset DLLCRB register */ + BaseAddr->DLLCRB = (uint32)0x01200000UL; + /* reset PARITYCR register */ + BaseAddr->PARITYCR = (uint32)0x00000000UL; + /* reset SFACR register */ + BaseAddr->SFACR = (uint32)0x00000800UL; + /* reset SMPR register */ + BaseAddr->SMPR = (uint32)0x00000000UL; + /* reset RBCT register */ + BaseAddr->RBCT = (uint32)0x00000000UL; + /* reset DLCR register */ + BaseAddr->DLCR = (uint32)0x40FF40FFUL; + /* reset TBCT register */ + BaseAddr->TBCT = (uint32)0x00000000UL; + /* reset FR register, Write 1 to clear */ + BaseAddr->FR = (uint32)0x9D83FF41UL; + /* reset RSER register */ + BaseAddr->RSER = (uint32)0x00000000UL; + /* reset SPTRCLR register and clear both IP and AHB sequence pointers */ + BaseAddr->SPTRCLR = (uint32)0x01000000UL | (uint32)QuadSPI_SPTRCLR_BFPTRC_MASK | (uint32)QuadSPI_SPTRCLR_IPPTRC_MASK; + /* reset SFA1AD register */ + BaseAddr->SFA1AD = (IP_QUADSPI_0 == BaseAddr) ? ((uint32)0x08000000UL) : ((uint32)0x14000000UL); + /* reset SFA2AD register */ + BaseAddr->SFA2AD = (IP_QUADSPI_0 == BaseAddr) ? ((uint32)0x08000000UL) : ((uint32)0x14000000UL); + /* On ZSE, QSPI_0 does not have side B */ + if (IP_QUADSPI_0 != BaseAddr) + { + /* reset SFB1AD register */ + BaseAddr->SFB1AD = (uint32)0x18000000UL; + /* reset SFB2AD register */ + BaseAddr->SFB2AD = (uint32)0x18000000UL; + } + /* reset DLPR register */ + BaseAddr->DLPR = (uint32)0xAA553443UL; + /* reset LUTKEY register */ + BaseAddr->LUTKEY = (uint32)0x5AF05AF0UL; + /* reset LCKCR register */ + BaseAddr->LCKCR = (uint32)0x00000002UL; + + Qspi_Ip_ResetPrivilegedRegisters(BaseAddr); + + /* avoid warning unused variable */ + (void)cnt; +} + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +#endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */ + + +#ifdef __cplusplus +} +#endif + +/** @} */ + diff --git a/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Hyperflash.c b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Hyperflash.c new file mode 100644 index 000000000..18c6e7da1 --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Hyperflash.c @@ -0,0 +1,1170 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** +* @file Qspi_Ip_Hyperflash.c +* +* @addtogroup IPV_QSPI +* @{ +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + + +/*================================================================================================== + * INCLUDE FILES +==================================================================================================*/ +#include "OsIf.h" +#include "Qspi_Ip.h" +#include "Qspi_Ip_Common.h" +#include "Qspi_Ip_Controller.h" +#include "Qspi_Ip_HyperflashRegs.h" +#include "Qspi_Ip_Hyperflash.h" + + +/*================================================================================================== + * SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_HYPERFLASH_VENDOR_ID_C 43 +#define QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_C 4 +#define QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_C 7 +#define QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_C 0 +#define QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_C 2 +#define QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_C 0 +#define QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_C 0 + +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/*================================================================================================== + * FILE VERSION CHECKS +==================================================================================================*/ +#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK + /* Check if current file and OsIf.h header file are of the same Autosar version */ + #if ((QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Hyperflash.c and OsIf.h are different" + #endif +#endif + +/* Check if current file and Qspi_Ip header file are of the same vendor */ +#if (QSPI_IP_HYPERFLASH_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H) + #error "Qspi_Ip_Hyperflash.c and Qspi_Ip.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip header file are of the same Autosar version */ +#if ((QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip.h are different" +#endif +/* Check if current file and Qspi_Ip header file are of the same Software version */ +#if ((QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip.h are different" +#endif + +/* Check if current file and Qspi_Ip_Common header file are of the same vendor */ +#if (QSPI_IP_HYPERFLASH_VENDOR_ID_C != QSPI_IP_COMMON_VENDOR_ID_H) + #error "Qspi_Ip_Hyperflash.c and Qspi_Ip_Common.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Common header file are of the same Autosar version */ +#if ((QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_Common.h are different" +#endif +/* Check if current file and Qspi_Ip_Common header file are of the same Software version */ +#if ((QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_C != QSPI_IP_COMMON_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_C != QSPI_IP_COMMON_SW_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_C != QSPI_IP_COMMON_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_Common.h are different" +#endif + +/* Check if current file and Qspi_Ip_Controller header file are of the same vendor */ +#if (QSPI_IP_HYPERFLASH_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H) + #error "Qspi_Ip_Hyperflash.c and Qspi_Ip_Controller.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */ +#if ((QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_Controller.h are different" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Software version */ +#if ((QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_Controller.h are different" +#endif + +/* Check if current file and Qspi_Ip_HyperflashRegs header file are of the same vendor */ +#if (QSPI_IP_HYPERFLASH_VENDOR_ID_C != QSPI_IP_HYPERFLASHREGS_VENDOR_ID_H) + #error "Qspi_Ip_Hyperflash.c and Qspi_Ip_HyperflashRegs.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_HyperflashRegs header file are of the same Autosar version */ +#if ((QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_HYPERFLASHREGS_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_HYPERFLASHREGS_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_HYPERFLASHREGS_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_HyperflashRegs.h are different" +#endif +/* Check if current file and Qspi_Ip_HyperflashRegs header file are of the same Software version */ +#if ((QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_C != QSPI_IP_HYPERFLASHREGS_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_C != QSPI_IP_HYPERFLASHREGS_SW_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_C != QSPI_IP_HYPERFLASHREGS_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_HyperflashRegs.h are different" +#endif + +/* Check if current file and Qspi_Ip_Hyperflash header file are of the same vendor */ +#if (QSPI_IP_HYPERFLASH_VENDOR_ID_C != QSPI_IP_HYPERFLASH_VENDOR_ID_H) + #error "Qspi_Ip_Hyperflash.c and Qspi_Ip_Hyperflash.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Hyperflash header file are of the same Autosar version */ +#if ((QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_HYPERFLASH_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_Hyperflash.h are different" +#endif +/* Check if current file and Qspi_Ip_Hyperflash header file are of the same Software version */ +#if ((QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_C != QSPI_IP_HYPERFLASH_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_C != QSPI_IP_HYPERFLASH_SW_MINOR_VERSION_H) || \ + (QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_C != QSPI_IP_HYPERFLASH_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Hyperflash.c and Qspi_Ip_Hyperflash.h are different" +#endif + + /******************************************************************************* + * Variables + ******************************************************************************/ + +/* HyperFlash commands */ +typedef enum +{ + QSPI_IP_HF_READ = 0xA0, /* Read command with continuous burst type */ + QSPI_IP_HF_WRITE = 0x00, /* Write command with continuous burst type */ + QSPI_IP_HF_RDSR = 0x70, /* Status register read */ + QSPI_IP_HF_SRC = 0x71, /* Status register clear */ + QSPI_IP_HF_EDPD = 0xB9, /* Enter Deep Power-Down */ + QSPI_IP_HF_PPORTR = 0x34, /* Program Power-On Reset Timer Register */ + QSPI_IP_HF_RPORTR = 0x3C, /* Read Power-On Reset Timer Register */ + QSPI_IP_HF_LDICR = 0x36, /* Load Interrupt Configuration Register */ + QSPI_IP_HF_RDICR = 0xC4, /* Read Interrupt Configuration Register */ + QSPI_IP_HF_LDISR = 0x37, /* Load Interrupt Status Register */ + QSPI_IP_HF_RDISR = 0xC5, /* Read Interrupt Status Register */ + QSPI_IP_HF_LDVCR = 0x38, /* Load Volatile Configuration Register */ + QSPI_IP_HF_RDVCR = 0xC7, /* Read Volatile Configuration Register */ + QSPI_IP_HF_PNVCR = 0x39, /* Program Non-Volatile Configuration Register */ + QSPI_IP_HF_ENVCR = 0xC8, /* Erase Non-Volatile Configuration Register */ + QSPI_IP_HF_RDNVCR = 0xC6, /* Read Non-Volatile Configuration Register */ + QSPI_IP_HF_WP = 0xA0, /* Word Program */ + QSPI_IP_HF_WB = 0x25, /* Write to Buffer */ + QSPI_IP_HF_PBF = 0x29, /* Program Buffer to Flash */ + QSPI_IP_HF_WBAR = 0xF0, /* Write to Buffer Abort Reset */ + QSPI_IP_HF_CE = 0x10, /* Chip erase */ + QSPI_IP_HF_SE = 0x30, /* Sector Erase */ + QSPI_IP_HF_BC = 0x33, /* Blank check */ + QSPI_IP_HF_EES = 0xD0, /* Evaluate Erase Status */ + QSPI_IP_HF_ES = 0xB0, /* Erase Suspend */ + QSPI_IP_HF_ER = 0x30, /* Erase Resume */ + QSPI_IP_HF_PS = 0x51, /* Program Suspend */ + QSPI_IP_HF_PR = 0x50, /* Program Resume */ + QSPI_IP_HF_RESET = 0xF0, /* Software reset */ + QSPI_IP_HF_CFIE = 0x98, /* CIF enter */ +} Qspi_Ip_HyperFlashCommandsType; + + +#define MEM_43_EXFLS_START_SEC_VAR_INIT_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + + +/* Hyperflash virtual LUT */ +Qspi_Ip_InstrOpType Qspi_Ip_HyperflashLutTable[QSPI_IP_HF_LUT_SIZE] = +{ + /* 0: QSPI_IP_HF_LUT_COMMON_555_AA: pre-read with operand AA */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0xAA), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 6: QSPI_IP_HF_LUT_COMMON_2AA_55: pre-read with operand 55 */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x55), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 12: QSPI_IP_HF_LUT_READ: Read command */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_READ), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)16U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_DUMMY | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x4), /* dummy cycles to be patched in before use*/ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_READ_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x4), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 18: QSPI_IP_HF_LUT_WRITE: write command */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)16U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_WRITE_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x2), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 23: QSPI_IP_HF_LUT_RDSR: Read status register */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_RDSR), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 29: QSPI_IP_HF_LUT_RDSR_SEQ2 */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_READ), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)16U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_DUMMY | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x4), /* dummy cycles to be patched in before use*/ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_READ_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x4), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 35: QSPI_IP_HF_LUT_WP: Word Program */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WP), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 41: QSPI_IP_HF_LUT_WP_SEQ1: Last sequence word program */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x18), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_WRITE_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x2), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 46: QSPI_IP_HF_LUT_CMD_80: pre-read with operand 0x80 */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x80), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 52: QSPI_IP_HF_LUT_CMD_AA: pre-command with operand 0xAA */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0xAA), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 58: QSPI_IP_HF_LUT_CMD_55: pre-command with operand 0x55 */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x55), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 64: QSPI_IP_HF_LUT_SE: sector erase */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_SE), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 70: QSPI_IP_HF_LUT_CE: chip erase */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_CE), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 76: QSPI_IP_HF_LUT_RST: reset */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_RESET), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 82: QSPI_IP_HF_LUT_SRC: Clear Status Register Command */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_SRC), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 88: QSPI_IP_HF_LUT_BC: blank check command */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_BC), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 94: QSPI_IP_HF_LUT_CMD_25: pre-read with operand 0x25 */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8) QSPI_IP_HF_WB), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 100: QSPI_IP_HF_LUT_WC: sector address and word count */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)(1U - 1U)), /* wordCount to be patched in before use */ + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 106: QSPI_IP_HF_LUT_WB: Write to buffer */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x18), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_WRITE_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x2), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 111: QSPI_IP_HF_LUT_PBF: Write to buffer */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_PBF), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 117: QSPI_IP_HF_LUT_PS: Program suspend */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_PS), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 123: QSPI_IP_HF_LUT_PR: Program resume */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_PR), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 129: QSPI_IP_HF_LUT_ES: Erase suspend */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_ES), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 135: QSPI_IP_HF_LUT_ER: Erase resume */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_ER), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 141:QSPI_IP_HF_LUT_RDNVCR: Read Non-Volatile Configuration Register */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8) QSPI_IP_HF_RDNVCR), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 147: QSPI_IP_HF_LUT_ENVCR: Erase Non-Volatile Configuration Register LUT */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_ENVCR), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 153: QSPI_IP_HF_LUT_PNVCR: Program Non-Volatile Configuration Register LUT */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_PNVCR), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 159: QSPI_IP_HF_LUT_LDVCR: Load Volatile Configuration Register LUT */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)(uint8)QSPI_IP_HF_LDVCR), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP), + /* 165: QSPI_IP_HF_LUT_CMD_98: pre-command with operand 0x98 (Enter CFI) */ + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_WRITE), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_ADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)24U), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CADDR_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x10), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)0x00), + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | (Qspi_Ip_InstrOpType)QSPI_IP_HF_CFIE), + (Qspi_Ip_InstrOpType)(QSPI_IP_LUT_INSTR_STOP) + /* Total LUT size: 171 */ +}; + +#define MEM_43_EXFLS_STOP_SEC_VAR_INIT_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + + +/******************************************************************************* + * Functions + ******************************************************************************/ + +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashUnlockCycles12 + * Description : Sends the unlock cycles 1 and 2 before erase and write commands + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashSendUnlockCycles12(uint32 instance) +{ + Qspi_Ip_StatusType status; + + /* Send unlock cycle 1 */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_COMMON_555_AA, 0xAAA); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Send unlock cycle 2 */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_COMMON_2AA_55, 0x554); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashPatchReadCommand + * Description : Patch a read command with the configured dummy cycles count + * + *END**************************************************************************/ +void Qspi_Ip_HyperflashPatchReadCommand(uint32 instance, + uint16 lut + ) +{ + const Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + uint8 dummyCycles; + + /* Get dummy cycles */ + dummyCycles = (uint8)state->configuration->hfConfig->readLatency + 4U; + /* Patch command - set dummy cycles */ + Qspi_Ip_HyperflashLutTable[lut + 3U] = (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_DUMMY | + (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | + (Qspi_Ip_InstrOpType)dummyCycles); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashPatchRunReadCommand + * Description : Runs a read command after fixing the dummy cycles count + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashPatchRunReadCommand(uint32 instance, + uint16 lut, + uint32 addr, + uint8 * data, + uint32 size + ) +{ + /* Patch command - set dummy cycles */ + Qspi_Ip_HyperflashPatchReadCommand(instance, lut); + + /* Launch read command */ + return Qspi_Ip_RunReadCommand(instance, lut, addr, data, NULL_PTR, size); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashInitConfigRegister + * Description : Initializes configuration register + * + *END**************************************************************************/ +static uint16 Qspi_Ip_HyperflashGetConfigurationValue(const Qspi_Ip_HyperFlashConfigType *config) +{ + uint16 regVal; + + const uint8 RWDSLowOnDualError = (config->RWDSLowOnDualError) ? 1U : 0U; + const uint8 secureRegionUnlocked = (config->secureRegionUnlocked)? 1U : 0U; + + regVal = (uint16)((uint16)QSPI_IP_HF_xVCR_BL((uint8)0x3U) | + (uint16)QSPI_IP_HF_xVCR_RWDS(RWDSLowOnDualError) | + (uint16)QSPI_IP_HF_xVCR_RL((uint8)config->readLatency) | + (uint16)QSPI_IP_HF_xVCR_PSM((uint8)config->paramSectorMap) | + (uint16)QSPI_IP_HF_xVCR_SSR(secureRegionUnlocked) | + (uint16)QSPI_IP_HF_xVCR_FRZ(1U) | + (uint16)QSPI_IP_HF_xVCR_DS((uint8)config->outputDriverStrength) | + ((uint16)QSPI_IP_HF_xVCR_RESERVED_BIT_3) | + ((uint16)QSPI_IP_HF_xVCR_RESERVED_BIT_16)); + + return regVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashGetStatusRegister + * Description : Reads status register of the flash device. + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashGetStatusRegister(uint32 instance, + uint16 * readValue + ) +{ + Qspi_Ip_StatusType status; + + /* Trigger pre-read command */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_RDSR, 0xAAA); + if (STATUS_QSPI_IP_SUCCESS == status) + { + status = Qspi_Ip_HyperflashPatchRunReadCommand(instance, QSPI_IP_HF_LUT_RDSR_SEQ2, 0U, (uint8 *)readValue, 2U); + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashWaitDeviceReady + * Description : Waits device to be ready + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashWaitDeviceReady(uint32 instance) +{ + uint16 readValue = 0U; /* Initilize with busy state */ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint32 u32ElapsedTicks = 0U; + uint32 u32TimeoutTicks; + uint32 u32CurrentTicks; + + /* Prepare timeout counter */ + u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_FLS_INIT_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE); + u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE); + + do + { + status = Qspi_Ip_HyperflashGetStatusRegister(instance, &readValue); + u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE); + + if ((status == STATUS_QSPI_IP_ERROR) || ((readValue & QSPI_IP_HF_SR_DRB_MASK) != 0U)) + { + /* status == STATUS_QSPI_IP_ERROR or hardware is ready */ + break; + } + } + while (u32ElapsedTicks < u32TimeoutTicks); + + if (((readValue & QSPI_IP_HF_SR_DRB_MASK) == 0U) && (STATUS_QSPI_IP_SUCCESS == status)) + { + status = STATUS_QSPI_IP_BUSY; + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashStatusRegisterClear + * Description : Clears the Status Register. This function clears the error status of an + * embedded operation. It is necessary to clear the error status in order to + * return to normal operation, ready for a new read or command write. + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashStatusRegisterClear(uint32 instance) +{ + Qspi_Ip_StatusType status; + + /* Send Clear Status Register command */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_SRC, 0xAAA); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashStatusRegisterDecode + * Description : Decodes the device status according to the last command executed + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashStatusRegisterDecode(uint16 SRValue, + Qspi_Ip_LastCommandType lastCommand + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint16 checkValue = 0U; + + switch (lastCommand) + { + case QSPI_IP_LAST_COMMAND_ERASE: + /* If ESB is set, last erase operation failed. Used also for blank check command */ + checkValue = SRValue & QSPI_IP_HF_SR_ESB_MASK; + break; + + case QSPI_IP_LAST_COMMAND_WRITE: + /* If PSB is set, last programming operation failed */ + checkValue = SRValue & QSPI_IP_HF_SR_PSB_MASK; + break; + + case QSPI_IP_LAST_COMMAND_WRITE_BUFFER_ABORT: + /* If WBASB 0, programming operation was not aborted */ + checkValue = (~SRValue) & QSPI_IP_HF_SR_WBASB_MASK; + break; + + case QSPI_IP_LAST_COMMAND_WRITE_SUSPEND: + /* If PSSB 0, no programming operation is suspended */ + checkValue = (~SRValue) & QSPI_IP_HF_SR_PSSB_MASK; + break; + + case QSPI_IP_LAST_COMMAND_ERASE_SUSPEND: + /* If ESSB 0, no erase operation is suspended */ + checkValue = (~SRValue) & QSPI_IP_HF_SR_ESSB_MASK; + break; + + case QSPI_IP_LAST_COMMAND_CRC_SUSPEND: + /* If CRCSSB 0, CRC operation is not suspended */ + checkValue = (~SRValue) & QSPI_IP_HF_SR_CRCSSB_MASK; + break; + + case QSPI_IP_LAST_COMMAND_SECTOR_ERASE_STATUS: + /* If ESTAT 0, previous erase did not complete successfully */ + checkValue = (~SRValue) & QSPI_IP_HF_SR_ESTAT_MASK; + break; + + default: /* QSPI_IP_LAST_COMMAND_NONE */ + /* Do nothing */ + break; + } + + /* If the check different than zero, there is an error */ + if (checkValue != 0U) + { + status = STATUS_QSPI_IP_ERROR; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashGetMemoryStatus + * Description : Get the flash device status according to the last command executed + * + *END**************************************************************************/ +Qspi_Ip_StatusType Qspi_Ip_HyperflashGetMemoryStatus(uint32 instance) +{ + const Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + Qspi_Ip_StatusType status; + uint16 SRValue = 0U; + + /* Read status register */ + status = Qspi_Ip_HyperflashGetStatusRegister(instance, &SRValue); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Check if device is busy */ + if ((SRValue & QSPI_IP_HF_SR_DRB_MASK) == 0U) + { + status = STATUS_QSPI_IP_BUSY; + } + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Clear Status Register */ + status = Qspi_Ip_HyperflashStatusRegisterClear(instance); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Decode Status Register */ + status = Qspi_Ip_HyperflashStatusRegisterDecode(SRValue, state->lastCommand); + } + + return status; +} + +/*FUNCTION****************************************************************************** + * + * Function Name : Qspi_Ip_HyperflashEraseNonVolatileConfigurationRegister + * Description : Erases the non-volatile configuration register. + * + *END***********************************************************************************/ + static Qspi_Ip_StatusType Qspi_Ip_HyperflashEraseNonVolatileConfigurationRegister(uint32 instance) +{ + Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + Qspi_Ip_StatusType status; + + /* Send unclock cycles 1 & 2 */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Erase Nonvolatile Configuration Registers */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_ENVCR, 0xAAA); + state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE; + } + + return status; +} + + +/*FUNCTION****************************************************************************** + * + * Function Name : Qspi_Ip_HyperflashProgramNonVolatileConfigurationRegister + * Description : Programs the Non-volatile configuration register of the flash device. + * + *END***********************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashProgramNonVolatileConfigurationRegister(uint32 instance, + const uint16 *data + ) +{ + Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + Qspi_Ip_StatusType status; + + /* Send unclock cycles 1 & 2 */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Third cycle */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_PNVCR, 0xAAA); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Fourth cycle */ + status = Qspi_Ip_RunWriteCommand(instance, QSPI_IP_HF_LUT_WRITE, 0U, (const uint8 *)data, 2U); + state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE; + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashGetNonVolatileConfigurationRegister + * Description : Reads the non-volatile configuration register + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashGetNonVolatileConfigurationRegister(uint32 instance, + uint16 * dataRead + ) +{ + Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + Qspi_Ip_StatusType status; + + /* Send unclock cycles 1 & 2 */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_RDNVCR, 0xAAA); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + status = Qspi_Ip_HyperflashPatchRunReadCommand(instance, QSPI_IP_HF_LUT_READ, 0U, (uint8 *)dataRead, 2U); + state->lastCommand = QSPI_IP_LAST_COMMAND_NONE; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashLoadVolatileConfigurationRegister + * Description : Loads volatile configuration register with the data provided + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashLoadVolatileConfigurationRegister(uint32 instance, + const uint16 * data + ) +{ + Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + Qspi_Ip_StatusType status; + + /* Send unclock cycles 1 & 2 */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Third cycle */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_LDVCR, 0xAAA); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Fourth cycle */ + status = Qspi_Ip_RunWriteCommand(instance, QSPI_IP_HF_LUT_WRITE, 0U, (const uint8 *)data, 2U); + state->lastCommand = QSPI_IP_LAST_COMMAND_WRITE; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashSectorBlankCheck + * Description : Checks if a specified sector is erased + * + *END**************************************************************************/ +Qspi_Ip_StatusType Qspi_Ip_HyperflashSectorBlankCheck(uint32 instance, + uint32 sectorAddress + ) +{ + Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + Qspi_Ip_StatusType status; + uint32 startAddr; + + /* Calculate starting address of the address provided */ + startAddr = (uint32)(sectorAddress & ~(QSPI_IP_HYPERFLASH_SECTOR_SIZE - 1U)); + + /* Write at address 0x555 of the sector specified */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_BC, (startAddr + (uint32)0xAAA)); + if (STATUS_QSPI_IP_SUCCESS == status) + { + state->lastCommand = QSPI_IP_LAST_COMMAND_ERASE; + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashSectorErase + * Description : Erase a specified sector (4KB or 256KB) in hyperflash. + * + *END**************************************************************************/ +Qspi_Ip_StatusType Qspi_Ip_HyperflashSectorErase(uint32 instance, + uint32 sectorAddress + ) +{ + Qspi_Ip_StatusType status; + + /* Send unclock cycles 1 & 2 */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Command Cycle 1 */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_CMD_80, 0xAAA); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Command Cycle 2 */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_CMD_AA, 0xAAA); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Command Cycle 3 */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_CMD_55, 0x554); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Specify the address for erasure */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_SE, sectorAddress); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashProgramBufferToFlashConfirm + * Description : Program buffer to flash confirm command + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashProgramBufferToFlashConfirm(uint32 instance, + uint32 sectorAddr + ) +{ + Qspi_Ip_StateType *state = &Qspi_Ip_MemoryStateStructure[instance]; + Qspi_Ip_StatusType status; + + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_PBF, sectorAddr); + state->lastCommand = QSPI_IP_LAST_COMMAND_NONE; + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashChipErase + * Description : Erases the entire chip + * + *END**************************************************************************/ +Qspi_Ip_StatusType Qspi_Ip_HyperflashChipErase(uint32 instance) +{ + Qspi_Ip_StatusType status; + + /* Send unclock cycles 1 & 2 */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Send set-up command */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_CMD_80, 0xAAA); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Two additional unlock write cycles */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Send Chip Erase command */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_CE, 0xAAA); + } + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashProgram + * Description : Writes from 1 up to 512 bytes to write buffer. + * The address provided should be in the same line buffer. + * + *END**************************************************************************/ +Qspi_Ip_StatusType Qspi_Ip_HyperflashProgram(uint32 instance, + uint32 address, + const uint8 * data, + uint32 size + ) +{ + Qspi_Ip_StatusType status; + const uint32 sectorAddress = address & ~(QSPI_IP_HYPERFLASH_SECTOR_SIZE - 1U); + uint32 selectAddress = address; + const uint8 * dataPtr = data; + + /* Get the padding information */ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + const uint32 qspiInstance = state->connection->qspiInstance; + const uint32 padding = (uint32)Qspi_Ip_MemoryPadding[qspiInstance]; + const uint32 prePadding = padding >> 4U; + const uint32 postPadding = padding & 0x0FU; + Qspi_Ip_MemoryPadding[qspiInstance] = 0U; /* Clear all padding*/ + + /* Calculate the word count to program */ + uint32 byteCnt = size; + const uint32 byteTotal = byteCnt + prePadding + postPadding; + const uint32 wordCnt = (byteTotal >> 1U) - 1U; /* minus 1 */ + + /* Send unclock cycles 1 & 2 */ + status = Qspi_Ip_HyperflashSendUnlockCycles12(instance); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Send pre-read with operand 0x25, third cycle */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_CMD_25, sectorAddress); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Patch LUT sequence with number of words to program minus 1 */ + Qspi_Ip_HyperflashLutTable[QSPI_IP_HF_LUT_WC + 4U] = + (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)QSPI_IP_LUT_INSTR_CMD_DDR | + (Qspi_Ip_InstrOpType)QSPI_IP_LUT_PADS_8 | + (Qspi_Ip_InstrOpType)wordCnt); + + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_WC, sectorAddress); + } + + /* Load each Address/Data pair */ + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* The start address is unaligned */ + if (prePadding != 0U) + { + /* Set prePadding */ + Qspi_Ip_MemoryPadding[qspiInstance] = (uint8)(prePadding << 4UL); + /* Load the first data byte */ + status = Qspi_Ip_RunWriteCommand(instance, QSPI_IP_HF_LUT_WB, selectAddress, dataPtr, 1U); + /* Move to the next data */ + selectAddress += 2U; + dataPtr = &dataPtr[1U]; + byteCnt -= 1U; + } + + /* Loop for aligned cases */ + while ((byteCnt >= 2U) && (STATUS_QSPI_IP_SUCCESS == status)) + { + /* Load each word */ + status = Qspi_Ip_RunWriteCommand(instance, QSPI_IP_HF_LUT_WB, selectAddress, dataPtr, 2U); + /* Move to the next data */ + selectAddress += 2U; + dataPtr = &dataPtr[2U]; + byteCnt -= 2U; + } + + /* The end address is unaligned */ + if ((postPadding != 0U) && (STATUS_QSPI_IP_SUCCESS == status)) + { + /* Set postPadding */ + Qspi_Ip_MemoryPadding[qspiInstance] = (uint8)postPadding; + /* Load the last data byte */ + status = Qspi_Ip_RunWriteCommand(instance, QSPI_IP_HF_LUT_WB, selectAddress, dataPtr, 1U); + } + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Write Program Buffer to Flash Confirm */ + status = Qspi_Ip_HyperflashProgramBufferToFlashConfirm(instance, sectorAddress); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashReadId + * Description : Read manufacturer ID from hyper flash. + * + *END**************************************************************************/ +Qspi_Ip_StatusType Qspi_Ip_HyperflashReadId(uint32 instance, + uint32 wordAddress, + uint8 * data, + uint32 size + ) +{ + Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + + /* CFI enter */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_CMD_98, 0xAAA); + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Read the ID at the designated word location (convert to byte address) */ + status = Qspi_Ip_HyperflashPatchRunReadCommand(instance, + QSPI_IP_HF_LUT_READ, + wordAddress << 1U, + data, + size); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* ASO Exit: back to flash memory array */ + status = Qspi_Ip_RunCommand(instance, QSPI_IP_HF_LUT_RST, 0U); + state->lastCommand = QSPI_IP_LAST_COMMAND_NONE; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashInitConfigurationRegister + * Description : Sets up Volatile and Non-Volatile configuration registers + * + *END**************************************************************************/ +static Qspi_Ip_StatusType Qspi_Ip_HyperflashInitConfigurationRegister(uint32 instance) +{ + const Qspi_Ip_StateType * state = &(Qspi_Ip_MemoryStateStructure[instance]); + Qspi_Ip_StatusType status; + uint16 readValue; + uint16 writeVCR; + + /* Compute new configuration value */ + writeVCR = Qspi_Ip_HyperflashGetConfigurationValue(state->configuration->hfConfig); + + /* Read Non-Volatile Configuration Register */ + status = Qspi_Ip_HyperflashGetNonVolatileConfigurationRegister(instance, &readValue); + + if ((STATUS_QSPI_IP_SUCCESS == status) && (writeVCR != readValue)) + { + /* Write the Non-Volatile register only if current configuration is different from the previous one */ + + /* Erase the NVCR */ + status = Qspi_Ip_HyperflashEraseNonVolatileConfigurationRegister(instance); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Wait until Configuration register is erased */ + status = Qspi_Ip_HyperflashWaitDeviceReady(instance); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Loads value into non-volatile configuration register */ + status = Qspi_Ip_HyperflashProgramNonVolatileConfigurationRegister(instance, &writeVCR); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Wait until Configuration register is programmed */ + status = Qspi_Ip_HyperflashWaitDeviceReady(instance); + } + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Load values into volatile configuration register */ + status = Qspi_Ip_HyperflashLoadVolatileConfigurationRegister(instance, &writeVCR); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Wait until Configuration register is updated */ + status = Qspi_Ip_HyperflashWaitDeviceReady(instance); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_HyperflashInit + * Description : Initializes the hyper flash memory + * + *END**************************************************************************/ +Qspi_Ip_StatusType Qspi_Ip_HyperflashInit(uint32 instance) +{ + Qspi_Ip_StatusType status; + uint16 readValue; + + /* Check status register */ + status = Qspi_Ip_HyperflashGetStatusRegister(instance, &readValue); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Check if device is ready */ + if ((readValue & QSPI_IP_HF_SR_DRB_MASK) == 0U) + { + status = STATUS_QSPI_IP_BUSY; + } + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Set up Volatile and Non-Volatile Configuration Registers */ + status = Qspi_Ip_HyperflashInitConfigurationRegister(instance); + } + + return status; +} + + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +#endif /* QSPI_IP_MEM_INSTANCE_COUNT */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + + diff --git a/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Sfdp.c b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Sfdp.c new file mode 100644 index 000000000..3c12a1814 --- /dev/null +++ b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip_Sfdp.c @@ -0,0 +1,4077 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** +* @file Qspi_Ip_Sfdp.c +* +* @addtogroup IPV_QSPI +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "OsIf.h" +#include "Qspi_Ip_Controller.h" +#include "Qspi_Ip.h" +#include "Qspi_Ip_Common.h" + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_VENDOR_ID_C 43 +#define QSPI_IP_AR_RELEASE_MAJOR_VERSION_C 4 +#define QSPI_IP_AR_RELEASE_MINOR_VERSION_C 7 +#define QSPI_IP_AR_RELEASE_REVISION_VERSION_C 0 +#define QSPI_IP_SW_MAJOR_VERSION_C 2 +#define QSPI_IP_SW_MINOR_VERSION_C 0 +#define QSPI_IP_SW_PATCH_VERSION_C 0 +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ +#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK + /* Check if current file and OsIf.h header file are of the same Autosar version */ + #if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and OsIf.h are different" + #endif +#endif + +/* Check if current file and Qspi_Ip_Controller header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_C != QSPI_IP_CONTROLLER_VENDOR_ID_H) + #error "Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_CONTROLLER_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h are different" +#endif +/* Check if current file and Qspi_Ip_Controller header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_CONTROLLER_SW_MINOR_VERSION_H) || \ + (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_CONTROLLER_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Controller.h are different" +#endif + +/* Check if current file and Qspi_Ip_Common header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_C != QSPI_IP_COMMON_VENDOR_ID_H) + #error "Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip_Common header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_COMMON_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h are different" +#endif +/* Check if current file and Qspi_Ip_Common header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_COMMON_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_COMMON_SW_MINOR_VERSION_H) || \ + (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_COMMON_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip_Common.h are different" +#endif + +/* Check if current file and Qspi_Ip header file are of the same vendor */ +#if (QSPI_IP_VENDOR_ID_C != QSPI_IP_VENDOR_ID_H) + #error "Qspi_Ip_Sfdp.c and Qspi_Ip.h have different vendor ids" +#endif +/* Check if current file and Qspi_Ip header file are of the same Autosar version */ +#if ((QSPI_IP_AR_RELEASE_MAJOR_VERSION_C != QSPI_IP_AR_RELEASE_MAJOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_MINOR_VERSION_C != QSPI_IP_AR_RELEASE_MINOR_VERSION_H) || \ + (QSPI_IP_AR_RELEASE_REVISION_VERSION_C != QSPI_IP_AR_RELEASE_REVISION_VERSION_H) \ + ) + #error "AutoSar Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip.h are different" +#endif +/* Check if current file and Qspi_Ip header file are of the same Software version */ +#if ((QSPI_IP_SW_MAJOR_VERSION_C != QSPI_IP_SW_MAJOR_VERSION_H) || \ + (QSPI_IP_SW_MINOR_VERSION_C != QSPI_IP_SW_MINOR_VERSION_H) || \ + (QSPI_IP_SW_PATCH_VERSION_C != QSPI_IP_SW_PATCH_VERSION_H) \ + ) + #error "Software Version Numbers of Qspi_Ip_Sfdp.c and Qspi_Ip.h are different" +#endif + +/******************************************************************************* + * Definitions. + ******************************************************************************/ + +#define QSPI_IP_CMD_SFDP_READ 0x5AU /* Instruction for Read SFDP command */ +#define QSPI_IP_CMD_BASIC_READ 0x03U /* Basic read instruction */ +#define QSPI_IP_CMD_BASIC_READ_4B 0x13U /* Basic read instruction - 4 bytes address */ +#define QSPI_IP_CMD_BASIC_WRITE 0x02U /* Basic write (page program) instruction */ +#define QSPI_IP_CMD_BASIC_READ_SR 0x05U /* Basic instruction for read status reg. command */ +#define QSPI_IP_CMD_BASIC_WRITE_SR 0x01U /* Basic instruction for write status reg. command */ +#define QSPI_IP_CMD_BASIC_WRITE_ENABLE 0x06U /* Basic instruction for write enable command */ +#define QSPI_IP_CMD_BASIC_CHIP_ERASE 0x60U /* Basic instruction for chip erase command */ +#define QSPI_IP_CMD_XSPI_WRITE 0x12U /* XSPI profile 1.0 Instruction for Program command */ +#define QSPI_IP_CMD_XSPI_CHIP_ERASE 0xC7U /* XSPI profile 1.0 Instruction for Chip Erase command */ +#define QSPI_IP_CMD_XSPI_READ_SR 0x05U /* XSPI profile 1.0 Instruction for read status reg. command */ +#define QSPI_IP_CMD_XSPI_WRITE_SR 0x01U /* XSPI profile 1.0 Instruction for write status reg. command */ +#define QSPI_IP_CMD_XSPI_WRITE_ENABLE 0x06U /* XSPI profile 1.0 Instruction for write enable command */ +#define QSPI_IP_CMD_XSPI_RESET 0xF0U /* XSPI profile 1.0 Instruction for soft reset command */ +#define QSPI_IP_CMD_XSPI_RESET_ENABLE 0x66U /* XSPI profile 1.0 Instruction for reset enable command */ +#define QSPI_IP_CMD_XSPI_RESET_DEF 0x99U /* XSPI profile 1.0 Instruction for soft reset and enter default protocol mode command */ + +#define QSPI_IP_TABLE_SIZE_BASIC 20U /* Max basic flash parameter table length */ +#define QSPI_IP_TABLE_SIZE_4BADD 2U /* Max 4-byte address instruction table length */ +#define QSPI_IP_TABLE_SIZE_XSPI1 5U /* Max extended serial peripheral interface table length */ +#define QSPI_IP_TABLE_SIZE_SRMAP 28U /* Max status, control and configuration register map length */ +#define QSPI_IP_TABLE_SIZE_2DOPI 8U /* Max command sequence to change to octal ddr length */ + +#define QSPI_IP_SFDP_MAJOR_REVISION 1U +#define QSPI_IP_SFDP_MINOR_REVISION_REV_0 0U +#define QSPI_IP_SFDP_MINOR_REVISION_REV_A 5U + +#define QSPI_IP_SFDP_ACCESS_PROTOCOL_HYPERBUS 0xFAU /* xSPI NOR Profile 2 HYPERBUS, (8D, 8D, 8D) operation */ +#define QSPI_IP_SFDP_ACCESS_PROTOCOL_LEGACY 0xFFU /* Legacy option (1S-1S-1S), (2S-2S-2S) or (4S-4S-4S) operation, 3-byte addressing for SFDP */ + + /**** Constants for retrieving SFDP parameters - Basic flash parameters table *****/ + + /* Flash Size */ +#define QSPI_IP_SFDP_BASIC_MEM_SIZE_DWORD 2U +#define QSPI_IP_SFDP_BASIC_MEM_SIZE_SHIFT 0U +#define QSPI_IP_SFDP_BASIC_MEM_SIZE_WIDTH 32U + /* Page Size */ +#define QSPI_IP_SFDP_BASIC_PAGE_SIZE_DWORD 11U +#define QSPI_IP_SFDP_BASIC_PAGE_SIZE_SHIFT 4U +#define QSPI_IP_SFDP_BASIC_PAGE_SIZE_WIDTH 4U + /* Octal DTR (8D-8D-8D) Command and Command Extension */ +#define QSPI_IP_SFDP_BASIC_CMD_EXT_DWORD 18U +#define QSPI_IP_SFDP_BASIC_CMD_EXT_SHIFT 29U +#define QSPI_IP_SFDP_BASIC_CMD_EXT_WIDTH 2U + /* Erase type 1 - instruction and size */ +#define QSPI_IP_SFDP_BASIC_ERASE1_INST_DWORD 8U +#define QSPI_IP_SFDP_BASIC_ERASE1_INST_SHIFT 8U +#define QSPI_IP_SFDP_BASIC_ERASE1_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_DWORD 8U +#define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_SHIFT 0U +#define QSPI_IP_SFDP_BASIC_ERASE1_SIZE_WIDTH 8U + /* Erase type 2 - instruction and size */ +#define QSPI_IP_SFDP_BASIC_ERASE2_INST_DWORD 8U +#define QSPI_IP_SFDP_BASIC_ERASE2_INST_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_ERASE2_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_DWORD 8U +#define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_ERASE2_SIZE_WIDTH 8U + /* Erase type 3 - instruction and size */ +#define QSPI_IP_SFDP_BASIC_ERASE3_INST_DWORD 9U +#define QSPI_IP_SFDP_BASIC_ERASE3_INST_SHIFT 8U +#define QSPI_IP_SFDP_BASIC_ERASE3_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_DWORD 9U +#define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_SHIFT 0U +#define QSPI_IP_SFDP_BASIC_ERASE3_SIZE_WIDTH 8U + /* Erase type 4 - instruction and size */ +#define QSPI_IP_SFDP_BASIC_ERASE4_INST_DWORD 9U +#define QSPI_IP_SFDP_BASIC_ERASE4_INST_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_ERASE4_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_DWORD 9U +#define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_ERASE4_SIZE_WIDTH 8U + /* Erase suspend instruction */ +#define QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD 13U +#define QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH 8U + /* Erase resume instruction */ +#define QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD 13U +#define QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH 8U + /* Program suspend instruction */ +#define QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD 13U +#define QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT 8U +#define QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH 8U + /* Program resume instruction */ +#define QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD 13U +#define QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT 0U +#define QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH 8U + /* Quad Enable Requirements */ +#define QSPI_IP_SFDP_BASIC_QE_REQ_DWORD 15U +#define QSPI_IP_SFDP_BASIC_QE_REQ_SHIFT 20U +#define QSPI_IP_SFDP_BASIC_QE_REQ_WIDTH 3U + /* Soft Reset */ +#define QSPI_IP_SFDP_BASIC_SW_RESET_DWORD 16U +#define QSPI_IP_SFDP_BASIC_SW_RESET_SHIFT 8U +#define QSPI_IP_SFDP_BASIC_SW_RESET_WIDTH 6U + /* Write Enable Instruction Select for Writing to Volatile Status Register */ +#define QSPI_IP_SFDP_BASIC_WREN_SR_DWORD 1U +#define QSPI_IP_SFDP_BASIC_WREN_SR_SHIFT 3U +#define QSPI_IP_SFDP_BASIC_WREN_SR_WIDTH 2U + /* 4-4-4 mode enable sequences */ +#define QSPI_IP_SFDP_BASIC_444_SWITCH_DWORD 15U +#define QSPI_IP_SFDP_BASIC_444_SWITCH_SHIFT 4U +#define QSPI_IP_SFDP_BASIC_444_SWITCH_WIDTH 5U + + /* Fast read instructions/mode bits/dummy bits */ +#define QSPI_IP_SFDP_BASIC_READ112_SUP_DWORD 1U +#define QSPI_IP_SFDP_BASIC_READ122_SUP_DWORD 1U +#define QSPI_IP_SFDP_BASIC_READ114_SUP_DWORD 1U +#define QSPI_IP_SFDP_BASIC_READ144_SUP_DWORD 1U +#define QSPI_IP_SFDP_BASIC_READ444_SUP_DWORD 5U +#define QSPI_IP_SFDP_BASIC_READ118_SUP_DWORD 17U +#define QSPI_IP_SFDP_BASIC_READ188_SUP_DWORD 17U + +#define QSPI_IP_SFDP_BASIC_READ112_SUP_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_READ122_SUP_SHIFT 20U +#define QSPI_IP_SFDP_BASIC_READ114_SUP_SHIFT 22U +#define QSPI_IP_SFDP_BASIC_READ144_SUP_SHIFT 21U +#define QSPI_IP_SFDP_BASIC_READ444_SUP_SHIFT 4U +#define QSPI_IP_SFDP_BASIC_READ118_SUP_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_READ188_SUP_SHIFT 8U + +#define QSPI_IP_SFDP_BASIC_READ112_SUP_WIDTH 1U +#define QSPI_IP_SFDP_BASIC_READ122_SUP_WIDTH 1U +#define QSPI_IP_SFDP_BASIC_READ114_SUP_WIDTH 1U +#define QSPI_IP_SFDP_BASIC_READ144_SUP_WIDTH 1U +#define QSPI_IP_SFDP_BASIC_READ444_SUP_WIDTH 1U +#define QSPI_IP_SFDP_BASIC_READ118_SUP_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_READ188_SUP_WIDTH 8U + +#define QSPI_IP_SFDP_BASIC_READ112_INST_DWORD 4U +#define QSPI_IP_SFDP_BASIC_READ122_INST_DWORD 4U +#define QSPI_IP_SFDP_BASIC_READ114_INST_DWORD 3U +#define QSPI_IP_SFDP_BASIC_READ144_INST_DWORD 3U +#define QSPI_IP_SFDP_BASIC_READ444_INST_DWORD 7U +#define QSPI_IP_SFDP_BASIC_READ118_INST_DWORD 17U +#define QSPI_IP_SFDP_BASIC_READ188_INST_DWORD 17U + +#define QSPI_IP_SFDP_BASIC_READ112_INST_SHIFT 8U +#define QSPI_IP_SFDP_BASIC_READ122_INST_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_READ114_INST_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_READ144_INST_SHIFT 8U +#define QSPI_IP_SFDP_BASIC_READ444_INST_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_READ118_INST_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_READ188_INST_SHIFT 8U + +#define QSPI_IP_SFDP_BASIC_READ112_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_READ122_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_READ114_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_READ144_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_READ444_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_READ118_INST_WIDTH 8U +#define QSPI_IP_SFDP_BASIC_READ188_INST_WIDTH 8U + +#define QSPI_IP_SFDP_BASIC_READ112_MODE_DWORD 4U +#define QSPI_IP_SFDP_BASIC_READ122_MODE_DWORD 4U +#define QSPI_IP_SFDP_BASIC_READ114_MODE_DWORD 3U +#define QSPI_IP_SFDP_BASIC_READ144_MODE_DWORD 3U +#define QSPI_IP_SFDP_BASIC_READ444_MODE_DWORD 7U +#define QSPI_IP_SFDP_BASIC_READ118_MODE_DWORD 17U +#define QSPI_IP_SFDP_BASIC_READ188_MODE_DWORD 17U + +#define QSPI_IP_SFDP_BASIC_READ112_MODE_SHIFT 5U +#define QSPI_IP_SFDP_BASIC_READ122_MODE_SHIFT 21U +#define QSPI_IP_SFDP_BASIC_READ114_MODE_SHIFT 21U +#define QSPI_IP_SFDP_BASIC_READ144_MODE_SHIFT 5U +#define QSPI_IP_SFDP_BASIC_READ444_MODE_SHIFT 21U +#define QSPI_IP_SFDP_BASIC_READ118_MODE_SHIFT 21U +#define QSPI_IP_SFDP_BASIC_READ188_MODE_SHIFT 5U + +#define QSPI_IP_SFDP_BASIC_READ112_MODE_WIDTH 3U +#define QSPI_IP_SFDP_BASIC_READ122_MODE_WIDTH 3U +#define QSPI_IP_SFDP_BASIC_READ114_MODE_WIDTH 3U +#define QSPI_IP_SFDP_BASIC_READ144_MODE_WIDTH 3U +#define QSPI_IP_SFDP_BASIC_READ444_MODE_WIDTH 3U +#define QSPI_IP_SFDP_BASIC_READ118_MODE_WIDTH 3U +#define QSPI_IP_SFDP_BASIC_READ188_MODE_WIDTH 3U + +#define QSPI_IP_SFDP_BASIC_READ112_DUMMY_DWORD 4U +#define QSPI_IP_SFDP_BASIC_READ122_DUMMY_DWORD 4U +#define QSPI_IP_SFDP_BASIC_READ114_DUMMY_DWORD 3U +#define QSPI_IP_SFDP_BASIC_READ144_DUMMY_DWORD 3U +#define QSPI_IP_SFDP_BASIC_READ444_DUMMY_DWORD 7U +#define QSPI_IP_SFDP_BASIC_READ118_DUMMY_DWORD 17U +#define QSPI_IP_SFDP_BASIC_READ188_DUMMY_DWORD 17U + +#define QSPI_IP_SFDP_BASIC_READ112_DUMMY_SHIFT 0U +#define QSPI_IP_SFDP_BASIC_READ122_DUMMY_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_READ114_DUMMY_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_READ144_DUMMY_SHIFT 0U +#define QSPI_IP_SFDP_BASIC_READ444_DUMMY_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_READ118_DUMMY_SHIFT 16U +#define QSPI_IP_SFDP_BASIC_READ188_DUMMY_SHIFT 0U + +#define QSPI_IP_SFDP_BASIC_READ112_DUMMY_WIDTH 5U +#define QSPI_IP_SFDP_BASIC_READ122_DUMMY_WIDTH 5U +#define QSPI_IP_SFDP_BASIC_READ114_DUMMY_WIDTH 5U +#define QSPI_IP_SFDP_BASIC_READ144_DUMMY_WIDTH 5U +#define QSPI_IP_SFDP_BASIC_READ444_DUMMY_WIDTH 5U +#define QSPI_IP_SFDP_BASIC_READ118_DUMMY_WIDTH 5U +#define QSPI_IP_SFDP_BASIC_READ188_DUMMY_WIDTH 5U + +#define QSPI_IP_SFDP_BASIC_ADDR_BYTES_DWORD 1U +#define QSPI_IP_SFDP_BASIC_ADDR_BYTES_SHIFT 17U +#define QSPI_IP_SFDP_BASIC_ADDR_BYTES_WIDTH 2U + +#define QSPI_IP_SFDP_BASIC_ADDR_SWITCH_DWORD 16U +#define QSPI_IP_SFDP_BASIC_ADDR_SWITCH_SHIFT 24U +#define QSPI_IP_SFDP_BASIC_ADDR_SWITCH_WIDTH 8U + + + /**** Constants for retrieving SFDP parameters - xSPI 1.0 table *****/ + + /* Read fast command */ +#define QSPI_IP_SFDP_XSPI1_READ_FAST_DWORD 1U +#define QSPI_IP_SFDP_XSPI1_READ_FAST_SHIFT 8U +#define QSPI_IP_SFDP_XSPI1_READ_FAST_WIDTH 8U + /* Max. number of dummy cycles */ +#define QSPI_IP_SFDP_XSPI1_DUMMY_DWORD 4U +#define QSPI_IP_SFDP_XSPI1_DUMMY_SHIFT 7U +#define QSPI_IP_SFDP_XSPI1_DUMMY_WIDTH 5U + /* Chip erase support */ +#define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_DWORD 3U +#define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_SHIFT 26U +#define QSPI_IP_SFDP_XSPI1_CHIP_ERASE_WIDTH 1U + /* Soft Reset support */ +#define QSPI_IP_SFDP_XSPI1_RESET_DWORD 3U +#define QSPI_IP_SFDP_XSPI1_RESET_SHIFT 13U +#define QSPI_IP_SFDP_XSPI1_RESET_WIDTH 1U + /* Reset Enable support */ +#define QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD 3U +#define QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT 12U +#define QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH 1U + /* Soft Reset and Enter default protocol mode support */ +#define QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD 3U +#define QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT 11U +#define QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH 1U + + /**** Constants for retrieving SFDP parameters - Status, Control and Configuration Register Map *****/ + + /* Busy (WIP) flag offset */ +#define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_DWORD 5U +#define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_SHIFT 24U +#define QSPI_IP_SFDP_SRMAP_WIP_OFFSET_WIDTH 3U + /* Busy (WIP) flag value */ +#define QSPI_IP_SFDP_SRMAP_WIP_VALUE_DWORD 5U +#define QSPI_IP_SFDP_SRMAP_WIP_VALUE_SHIFT 30U +#define QSPI_IP_SFDP_SRMAP_WIP_VALUE_WIDTH 1U + /* Write Enable (WEL) flag offset */ +#define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_DWORD 6U +#define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_SHIFT 24U +#define QSPI_IP_SFDP_SRMAP_WEL_OFFSET_WIDTH 3U + /* Dummy cycles in 8D-8D-8D mode */ +#define QSPI_IP_SFDP_SRMAP_DUMMY_8D_DWORD 3U +#define QSPI_IP_SFDP_SRMAP_DUMMY_8D_SHIFT 6U +#define QSPI_IP_SFDP_SRMAP_DUMMY_8D_WIDTH 4U + /* SR read is direct command (not using address) */ +#define QSPI_IP_SFDP_SRMAP_USE_ADDR_DWORD 5U +#define QSPI_IP_SFDP_SRMAP_USE_ADDR_SHIFT 28U +#define QSPI_IP_SFDP_SRMAP_USE_ADDR_WIDTH 1U + /* Address offset for volatile registers */ +#define QSPI_IP_SFDP_SRMAP_OFFSET_DWORD 1U +#define QSPI_IP_SFDP_SRMAP_OFFSET_SHIFT 0U +#define QSPI_IP_SFDP_SRMAP_OFFSET_WIDTH 32U + /* Number of address bytes used for Generic Addressable Read/Write Status/Control register commands for volatile registers */ +#define QSPI_IP_SFDP_SRMAP_NBYTES_DWORD 3U +#define QSPI_IP_SFDP_SRMAP_NBYTES_SHIFT 28U +#define QSPI_IP_SFDP_SRMAP_NBYTES_WIDTH 2U + /* SR local address */ +#define QSPI_IP_SFDP_SRMAP_SR_ADDR_DWORD 5U +#define QSPI_IP_SFDP_SRMAP_SR_ADDR_SHIFT 16U +#define QSPI_IP_SFDP_SRMAP_SR_ADDR_WIDTH 8U + /* SR address shift (before adding to the offset) */ +#define QSPI_IP_SFDP_SRMAP_SR_SHIFT_DWORD 5U +#define QSPI_IP_SFDP_SRMAP_SR_SHIFT_SHIFT 27U +#define QSPI_IP_SFDP_SRMAP_SR_SHIFT_WIDTH 1U + + /**** Constants for retrieving SFDP parameters - Command Sequences to Change to Octal DDR (8D-8D-8D) mode *****/ + + /* Length of command sequence */ +#define QSPI_IP_SFDP_2DOPI_CMD_LEN_SHIFT 24U +#define QSPI_IP_SFDP_2DOPI_CMD_LEN_WIDTH 8U + /* Bytes of command sequence */ +#define QSPI_IP_SFDP_2DOPI_CMD_BYTE1_SHIFT 16U +#define QSPI_IP_SFDP_2DOPI_CMD_BYTE2_SHIFT 8U +#define QSPI_IP_SFDP_2DOPI_CMD_BYTE3_SHIFT 0U +#define QSPI_IP_SFDP_2DOPI_CMD_BYTE4_SHIFT 24U +#define QSPI_IP_SFDP_2DOPI_CMD_BYTE5_SHIFT 16U +#define QSPI_IP_SFDP_2DOPI_CMD_BYTE6_SHIFT 8U +#define QSPI_IP_SFDP_2DOPI_CMD_BYTE7_SHIFT 0U + + /**** Constants for retrieving SFDP parameters - 4-byte Address Instructions *****/ + +#define QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH 1U +#define QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD 2U +#define QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH 8U +#define QSPI_IP_SFDP_4BADD_ERASE1_SUP_SHIFT 9U +#define QSPI_IP_SFDP_4BADD_ERASE2_SUP_SHIFT 10U +#define QSPI_IP_SFDP_4BADD_ERASE3_SUP_SHIFT 11U +#define QSPI_IP_SFDP_4BADD_ERASE4_SUP_SHIFT 12U +#define QSPI_IP_SFDP_4BADD_ERASE1_INST_SHIFT 0U +#define QSPI_IP_SFDP_4BADD_ERASE2_INST_SHIFT 8U +#define QSPI_IP_SFDP_4BADD_ERASE3_INST_SHIFT 16U +#define QSPI_IP_SFDP_4BADD_ERASE4_INST_SHIFT 24U + +#define QSPI_IP_SFDP_4BADD_READ112_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_READ122_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_READ114_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_READ144_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_READ444_SUP_DWORD 0xFFU /* invalid */ +#define QSPI_IP_SFDP_4BADD_READ118_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_READ188_SUP_DWORD 1U + +#define QSPI_IP_SFDP_4BADD_READ111_SUP_SHIFT 0U +#define QSPI_IP_SFDP_4BADD_READ112_SUP_SHIFT 2U +#define QSPI_IP_SFDP_4BADD_READ122_SUP_SHIFT 3U +#define QSPI_IP_SFDP_4BADD_READ114_SUP_SHIFT 4U +#define QSPI_IP_SFDP_4BADD_READ144_SUP_SHIFT 5U +#define QSPI_IP_SFDP_4BADD_READ444_SUP_SHIFT 1U /* use 1-1-1 fast read */ +#define QSPI_IP_SFDP_4BADD_READ118_SUP_SHIFT 20U +#define QSPI_IP_SFDP_4BADD_READ188_SUP_SHIFT 21U + + +#define QSPI_IP_SFDP_4BADD_WRITE112_SUP_DWORD 0xFFU /* invalid */ +#define QSPI_IP_SFDP_4BADD_WRITE122_SUP_DWORD 0xFFU /* invalid */ +#define QSPI_IP_SFDP_4BADD_WRITE114_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_WRITE144_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_WRITE444_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_WRITE118_SUP_DWORD 1U +#define QSPI_IP_SFDP_4BADD_WRITE188_SUP_DWORD 1U + +#define QSPI_IP_SFDP_4BADD_WRITE112_SUP_SHIFT 0U +#define QSPI_IP_SFDP_4BADD_WRITE122_SUP_SHIFT 0U +#define QSPI_IP_SFDP_4BADD_WRITE114_SUP_SHIFT 7U +#define QSPI_IP_SFDP_4BADD_WRITE144_SUP_SHIFT 8U +#define QSPI_IP_SFDP_4BADD_WRITE444_SUP_SHIFT 6U /* use 1-1-1 write */ +#define QSPI_IP_SFDP_4BADD_WRITE118_SUP_SHIFT 23U +#define QSPI_IP_SFDP_4BADD_WRITE188_SUP_SHIFT 24U + +/* fast read modes */ +#define QSPI_IP_SFDP_READ_MODE_112 0x00U /* 1-1-2 fast read mode */ +#define QSPI_IP_SFDP_READ_MODE_122 0x01U /* 1-2-2 fast read mode */ +#define QSPI_IP_SFDP_READ_MODE_114 0x02U /* 1-1-4 fast read mode */ +#define QSPI_IP_SFDP_READ_MODE_144 0x03U /* 1-4-4 fast read mode */ +#define QSPI_IP_SFDP_READ_MODE_444 0x04U /* 4-4-4 fast read mode */ +#define QSPI_IP_SFDP_READ_MODE_118 0x05U /* 1-1-8 fast read mode */ +#define QSPI_IP_SFDP_READ_MODE_188 0x06U /* 1-8-8 fast read mode */ +#define QSPI_IP_SFDP_READ_MODE_MAX 0x07U /* Number of read modes */ + + +/******************************************************************************* + * Enumerations. + ******************************************************************************/ + +#if (QSPI_IP_MEM_INSTANCE_COUNT > 0) + +/* sfdp modes */ +typedef enum +{ + QSPI_IP_SFDP_1S_1S_1S = 0x00U, /*!< 1S-1S-1S mode */ + QSPI_IP_SFDP_2S_2S_2S = 0x01U, /*!< 2S-2S-2S mode */ + QSPI_IP_SFDP_4S_4S_4S = 0x02U, /*!< 4S-4S-4S mode */ + QSPI_IP_SFDP_4S_4D_4D = 0x03U, /*!< 4S-4D-4D mode */ + QSPI_IP_SFDP_8D_8D_8D = 0x04U, /*!< 8D-8D-8D mode */ +} Qspi_Ip_SfdpModes; + +/* sfdp table types */ +typedef enum +{ + QSPI_IP_SFDP_TABLE_BASIC = 0x00U, /*!< Basic flash parameter table */ + QSPI_IP_SFDP_TABLE_4BADD = 0x84U, /*!< 4-byte Address Instruction Table */ + QSPI_IP_SFDP_TABLE_XSPI1 = 0x05U, /*!< eXtended Serial Peripheral Interface (xSPI) Profile 1.0 */ + QSPI_IP_SFDP_TABLE_SRMAP = 0x87U, /*!< Status, Control and Configuration Register Map */ + QSPI_IP_SFDP_TABLE_2DOPI = 0x0AU, /*!< Command Sequences to change to DOPI (8D-8D-8D) mode */ +} Qspi_Ip_SfdpTables; + +/* structure containing sfdp tables */ +typedef struct +{ + uint32 paramTable_basic[QSPI_IP_TABLE_SIZE_BASIC]; + uint32 paramTable_4badd[QSPI_IP_TABLE_SIZE_4BADD]; + uint32 paramTable_xspi1[QSPI_IP_TABLE_SIZE_XSPI1]; + uint32 paramTable_srmap[QSPI_IP_TABLE_SIZE_SRMAP]; + uint32 paramTable_2dopi[QSPI_IP_TABLE_SIZE_2DOPI]; + uint8 paramTableLength_basic; + uint8 paramTableLength_4badd; + uint8 paramTableLength_xspi1; + uint8 paramTableLength_srmap; + uint8 paramTableLength_2dopi; +} Qspi_Ip_SfdpTablesContainer; + +/******************************************************************************* + * Local Variables + ******************************************************************************/ + +#define MEM_43_EXFLS_START_SEC_VAR_CLEARED_16 +#include "Mem_43_EXFLS_MemMap.h" + +static uint16 lutCount; /* Current number of operations in the LUT table */ + +#define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_16 +#include "Mem_43_EXFLS_MemMap.h" + + +#define MEM_43_EXFLS_START_SEC_VAR_CLEARED_8 +#include "Mem_43_EXFLS_MemMap.h" + +static uint8 initOpCount; /* Current number of operations in the initial operations list */ +static uint8 basicAddrBits; /* Current number of operations in the initial operations list */ +static uint8 modeIndex; /* Index of the selected read mode */ + +#define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_8 +#include "Mem_43_EXFLS_MemMap.h" + + +#define MEM_43_EXFLS_START_SEC_VAR_CLEARED_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + +static Qspi_Ip_LutPadsType cmdPads; /* Pads to use for commands (e.g. 4 if the selected operation mode is 4-4-4) */ +static Qspi_Ip_LutPadsType cmdPadsInit; /* Number of pads used for commands in the initial state */ + +#define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + + +#define MEM_43_EXFLS_START_SEC_VAR_CLEARED_BOOLEAN +#include "Mem_43_EXFLS_MemMap.h" + +static boolean overflow; /* Either LUT or initial operations list was not big enough */ +static boolean quadAvailable; /* Quad mode can be used */ + +#define MEM_43_EXFLS_STOP_SEC_VAR_CLEARED_BOOLEAN +#include "Mem_43_EXFLS_MemMap.h" + + +#define MEM_43_EXFLS_START_SEC_VAR_INIT_BOOLEAN +#include "Mem_43_EXFLS_MemMap.h" + +static boolean bootModeLegacyXPI = (boolean)TRUE; /* Memory device boots up in xSPI or HyperBus mode (default is XPI) */ + +#define MEM_43_EXFLS_STOP_SEC_VAR_INIT_BOOLEAN +#include "Mem_43_EXFLS_MemMap.h" + +/* tables for extracting parameters from SFDP table */ + +#define MEM_43_EXFLS_START_SEC_VAR_INIT_8 +#include "Mem_43_EXFLS_MemMap.h" + +static uint8 eraseInstDword[4U] = { + QSPI_IP_SFDP_BASIC_ERASE1_INST_DWORD, + QSPI_IP_SFDP_BASIC_ERASE2_INST_DWORD, + QSPI_IP_SFDP_BASIC_ERASE3_INST_DWORD, + QSPI_IP_SFDP_BASIC_ERASE4_INST_DWORD +}; +static uint8 eraseInstShift[4U] = { + QSPI_IP_SFDP_BASIC_ERASE1_INST_SHIFT, + QSPI_IP_SFDP_BASIC_ERASE2_INST_SHIFT, + QSPI_IP_SFDP_BASIC_ERASE3_INST_SHIFT, + QSPI_IP_SFDP_BASIC_ERASE4_INST_SHIFT +}; +static uint8 eraseInstWidth[4U] = { + QSPI_IP_SFDP_BASIC_ERASE1_INST_WIDTH, + QSPI_IP_SFDP_BASIC_ERASE2_INST_WIDTH, + QSPI_IP_SFDP_BASIC_ERASE3_INST_WIDTH, + QSPI_IP_SFDP_BASIC_ERASE4_INST_WIDTH +}; +static uint8 eraseSizeDword[4U] = { + QSPI_IP_SFDP_BASIC_ERASE1_SIZE_DWORD, + QSPI_IP_SFDP_BASIC_ERASE2_SIZE_DWORD, + QSPI_IP_SFDP_BASIC_ERASE3_SIZE_DWORD, + QSPI_IP_SFDP_BASIC_ERASE4_SIZE_DWORD +}; +static uint8 eraseSizeShift[4U] = { + QSPI_IP_SFDP_BASIC_ERASE1_SIZE_SHIFT, + QSPI_IP_SFDP_BASIC_ERASE2_SIZE_SHIFT, + QSPI_IP_SFDP_BASIC_ERASE3_SIZE_SHIFT, + QSPI_IP_SFDP_BASIC_ERASE4_SIZE_SHIFT +}; +static uint8 eraseSizeWidth[4U] = { + QSPI_IP_SFDP_BASIC_ERASE1_SIZE_WIDTH, + QSPI_IP_SFDP_BASIC_ERASE2_SIZE_WIDTH, + QSPI_IP_SFDP_BASIC_ERASE3_SIZE_WIDTH, + QSPI_IP_SFDP_BASIC_ERASE4_SIZE_WIDTH +}; + +static uint8 erase4ByteSupShift[4U] = { + QSPI_IP_SFDP_4BADD_ERASE1_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_ERASE2_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_ERASE3_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_ERASE4_SUP_SHIFT +}; + +static uint8 erase4ByteInstShift[4U] = { + QSPI_IP_SFDP_4BADD_ERASE1_INST_SHIFT, + QSPI_IP_SFDP_4BADD_ERASE2_INST_SHIFT, + QSPI_IP_SFDP_4BADD_ERASE3_INST_SHIFT, + QSPI_IP_SFDP_4BADD_ERASE4_INST_SHIFT +}; + +/* Erase instruction with 4-Byte Address, specified by JESD216D */ +static uint8 erase4ByteInst[4U] = { + 0x21U, /* 4-KB erase */ + 0x5CU, /* 32-KB erase */ + 0xDCU, /* 64-KB erase */ + 0xDCU /* 256-KB erase */ +}; + +static uint8 dopiSwitchShift[7U] = { + QSPI_IP_SFDP_2DOPI_CMD_BYTE1_SHIFT, + QSPI_IP_SFDP_2DOPI_CMD_BYTE2_SHIFT, + QSPI_IP_SFDP_2DOPI_CMD_BYTE3_SHIFT, + QSPI_IP_SFDP_2DOPI_CMD_BYTE4_SHIFT, + QSPI_IP_SFDP_2DOPI_CMD_BYTE5_SHIFT, + QSPI_IP_SFDP_2DOPI_CMD_BYTE6_SHIFT, + QSPI_IP_SFDP_2DOPI_CMD_BYTE7_SHIFT, +}; +static uint8 dopiSwitchWord[7U] = { + 0U, + 0U, + 0U, + 1U, + 1U, + 1U, + 1U, +}; + +static uint8 readSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_SUP_DWORD, + QSPI_IP_SFDP_BASIC_READ122_SUP_DWORD, + QSPI_IP_SFDP_BASIC_READ114_SUP_DWORD, + QSPI_IP_SFDP_BASIC_READ144_SUP_DWORD, + QSPI_IP_SFDP_BASIC_READ444_SUP_DWORD, + QSPI_IP_SFDP_BASIC_READ118_SUP_DWORD, + QSPI_IP_SFDP_BASIC_READ188_SUP_DWORD +}; + +static uint8 readSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_SUP_SHIFT, + QSPI_IP_SFDP_BASIC_READ122_SUP_SHIFT, + QSPI_IP_SFDP_BASIC_READ114_SUP_SHIFT, + QSPI_IP_SFDP_BASIC_READ144_SUP_SHIFT, + QSPI_IP_SFDP_BASIC_READ444_SUP_SHIFT, + QSPI_IP_SFDP_BASIC_READ118_SUP_SHIFT, + QSPI_IP_SFDP_BASIC_READ188_SUP_SHIFT +}; + +static uint8 readSupWitdh[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_SUP_WIDTH, + QSPI_IP_SFDP_BASIC_READ122_SUP_WIDTH, + QSPI_IP_SFDP_BASIC_READ114_SUP_WIDTH, + QSPI_IP_SFDP_BASIC_READ144_SUP_WIDTH, + QSPI_IP_SFDP_BASIC_READ444_SUP_WIDTH, + QSPI_IP_SFDP_BASIC_READ118_SUP_WIDTH, + QSPI_IP_SFDP_BASIC_READ188_SUP_WIDTH +}; + +static uint8 read4ByteSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_4BADD_READ112_SUP_DWORD, + QSPI_IP_SFDP_4BADD_READ122_SUP_DWORD, + QSPI_IP_SFDP_4BADD_READ114_SUP_DWORD, + QSPI_IP_SFDP_4BADD_READ144_SUP_DWORD, + QSPI_IP_SFDP_4BADD_READ444_SUP_DWORD, + QSPI_IP_SFDP_4BADD_READ118_SUP_DWORD, + QSPI_IP_SFDP_4BADD_READ188_SUP_DWORD +}; + +static uint8 read4ByteSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_4BADD_READ112_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_READ122_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_READ114_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_READ144_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_READ444_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_READ118_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_READ188_SUP_SHIFT +}; + +static uint8 write4ByteSupDword[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_4BADD_WRITE112_SUP_DWORD, + QSPI_IP_SFDP_4BADD_WRITE122_SUP_DWORD, + QSPI_IP_SFDP_4BADD_WRITE114_SUP_DWORD, + QSPI_IP_SFDP_4BADD_WRITE144_SUP_DWORD, + QSPI_IP_SFDP_4BADD_WRITE444_SUP_DWORD, + QSPI_IP_SFDP_4BADD_WRITE118_SUP_DWORD, + QSPI_IP_SFDP_4BADD_WRITE188_SUP_DWORD +}; + +static uint8 write4ByteSupShift[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_4BADD_WRITE112_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_WRITE122_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_WRITE114_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_WRITE144_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_WRITE444_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_WRITE118_SUP_SHIFT, + QSPI_IP_SFDP_4BADD_WRITE188_SUP_SHIFT +}; + +static uint8 read4ByteInst[QSPI_IP_SFDP_READ_MODE_MAX] = { + 0x3CU, + 0xBCU, + 0x6CU, + 0xECU, + 0x13U, + 0x7CU, + 0xCCU +}; + +static uint8 write4ByteInst[QSPI_IP_SFDP_READ_MODE_MAX] = { + 0x00U, + 0x00U, + 0x34U, + 0x3EU, + 0x12U, + 0x84U, + 0x8EU +}; + +static uint8 readInstDword[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_INST_DWORD, + QSPI_IP_SFDP_BASIC_READ122_INST_DWORD, + QSPI_IP_SFDP_BASIC_READ114_INST_DWORD, + QSPI_IP_SFDP_BASIC_READ144_INST_DWORD, + QSPI_IP_SFDP_BASIC_READ444_INST_DWORD, + QSPI_IP_SFDP_BASIC_READ118_INST_DWORD, + QSPI_IP_SFDP_BASIC_READ188_INST_DWORD +}; + +static uint8 readInstShift[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_INST_SHIFT, + QSPI_IP_SFDP_BASIC_READ122_INST_SHIFT, + QSPI_IP_SFDP_BASIC_READ114_INST_SHIFT, + QSPI_IP_SFDP_BASIC_READ144_INST_SHIFT, + QSPI_IP_SFDP_BASIC_READ444_INST_SHIFT, + QSPI_IP_SFDP_BASIC_READ118_INST_SHIFT, + QSPI_IP_SFDP_BASIC_READ188_INST_SHIFT +}; + +static uint8 readInstWidth[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_INST_WIDTH, + QSPI_IP_SFDP_BASIC_READ122_INST_WIDTH, + QSPI_IP_SFDP_BASIC_READ114_INST_WIDTH, + QSPI_IP_SFDP_BASIC_READ144_INST_WIDTH, + QSPI_IP_SFDP_BASIC_READ444_INST_WIDTH, + QSPI_IP_SFDP_BASIC_READ118_INST_WIDTH, + QSPI_IP_SFDP_BASIC_READ188_INST_WIDTH +}; + +static uint8 readModeDword[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_MODE_DWORD, + QSPI_IP_SFDP_BASIC_READ122_MODE_DWORD, + QSPI_IP_SFDP_BASIC_READ114_MODE_DWORD, + QSPI_IP_SFDP_BASIC_READ144_MODE_DWORD, + QSPI_IP_SFDP_BASIC_READ444_MODE_DWORD, + QSPI_IP_SFDP_BASIC_READ118_MODE_DWORD, + QSPI_IP_SFDP_BASIC_READ188_MODE_DWORD +}; + +static uint8 readModeShift[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_MODE_SHIFT, + QSPI_IP_SFDP_BASIC_READ122_MODE_SHIFT, + QSPI_IP_SFDP_BASIC_READ114_MODE_SHIFT, + QSPI_IP_SFDP_BASIC_READ144_MODE_SHIFT, + QSPI_IP_SFDP_BASIC_READ444_MODE_SHIFT, + QSPI_IP_SFDP_BASIC_READ118_MODE_SHIFT, + QSPI_IP_SFDP_BASIC_READ188_MODE_SHIFT +}; + +static uint8 readModeWidth[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_MODE_WIDTH, + QSPI_IP_SFDP_BASIC_READ122_MODE_WIDTH, + QSPI_IP_SFDP_BASIC_READ114_MODE_WIDTH, + QSPI_IP_SFDP_BASIC_READ144_MODE_WIDTH, + QSPI_IP_SFDP_BASIC_READ444_MODE_WIDTH, + QSPI_IP_SFDP_BASIC_READ118_MODE_WIDTH, + QSPI_IP_SFDP_BASIC_READ188_MODE_WIDTH +}; + +static uint8 readDummyDword[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_DUMMY_DWORD, + QSPI_IP_SFDP_BASIC_READ122_DUMMY_DWORD, + QSPI_IP_SFDP_BASIC_READ114_DUMMY_DWORD, + QSPI_IP_SFDP_BASIC_READ144_DUMMY_DWORD, + QSPI_IP_SFDP_BASIC_READ444_DUMMY_DWORD, + QSPI_IP_SFDP_BASIC_READ118_DUMMY_DWORD, + QSPI_IP_SFDP_BASIC_READ188_DUMMY_DWORD +}; + +static uint8 readDummyShift[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_DUMMY_SHIFT, + QSPI_IP_SFDP_BASIC_READ122_DUMMY_SHIFT, + QSPI_IP_SFDP_BASIC_READ114_DUMMY_SHIFT, + QSPI_IP_SFDP_BASIC_READ144_DUMMY_SHIFT, + QSPI_IP_SFDP_BASIC_READ444_DUMMY_SHIFT, + QSPI_IP_SFDP_BASIC_READ118_DUMMY_SHIFT, + QSPI_IP_SFDP_BASIC_READ188_DUMMY_SHIFT +}; + +static uint8 readDummyWidth[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_SFDP_BASIC_READ112_DUMMY_WIDTH, + QSPI_IP_SFDP_BASIC_READ122_DUMMY_WIDTH, + QSPI_IP_SFDP_BASIC_READ114_DUMMY_WIDTH, + QSPI_IP_SFDP_BASIC_READ144_DUMMY_WIDTH, + QSPI_IP_SFDP_BASIC_READ444_DUMMY_WIDTH, + QSPI_IP_SFDP_BASIC_READ118_DUMMY_WIDTH, + QSPI_IP_SFDP_BASIC_READ188_DUMMY_WIDTH +}; + +#define MEM_43_EXFLS_STOP_SEC_VAR_INIT_8 +#include "Mem_43_EXFLS_MemMap.h" + + +#define MEM_43_EXFLS_START_SEC_VAR_INIT_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + +static Qspi_Ip_LutPadsType readModeInstPads[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_4, + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_1 +}; + +static Qspi_Ip_LutPadsType readModeAddrPads[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_2, + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_4, + QSPI_IP_LUT_PADS_4, + QSPI_IP_LUT_PADS_1, + QSPI_IP_LUT_PADS_8 +}; + +static Qspi_Ip_LutPadsType readModeDataPads[QSPI_IP_SFDP_READ_MODE_MAX] = { + QSPI_IP_LUT_PADS_2, + QSPI_IP_LUT_PADS_2, + QSPI_IP_LUT_PADS_4, + QSPI_IP_LUT_PADS_4, + QSPI_IP_LUT_PADS_4, + QSPI_IP_LUT_PADS_8, + QSPI_IP_LUT_PADS_8 +}; + +#define MEM_43_EXFLS_STOP_SEC_VAR_INIT_UNSPECIFIED +#include "Mem_43_EXFLS_MemMap.h" + + +/*================================================================================================== + *LOCAL FUNCTION PROTOTYPES +==================================================================================================*/ +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +static inline Qspi_Ip_InstrOpType Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd, + Qspi_Ip_LutPadsType pad, + uint8 op + ); + +static inline void Qspi_Ip_SfdpLutInit(void); + +static inline void Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType *lutSequences, + Qspi_Ip_InstrOpType instr + ); + +static inline uint32 Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ); + +static inline uint32 Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ); + +static inline uint32 Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ); + +static inline uint32 Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ); + +static inline uint32 Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ); + +static void Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType *lutSequences, + const Qspi_Ip_SfdpTablesContainer *sfdpTables + ); + +static inline boolean Qspi_Ip_SfdpSignatureCheck(const uint8 *data); + +static inline void Qspi_Ip_SfdpInitLut(uint32 instance, + Qspi_Ip_SfdpModes mode + ); + +static void Qspi_Ip_WaitAfterReset(void); + +static void Qspi_Ip_SfdpInitReset(uint32 instance, + uint32 baseAddress + ); + +static void Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance, + uint32 baseAddress + ); + +static void Qspi_Ip_SfdpExitQPI(uint32 instance, + uint32 baseAddress + ); + + +static void Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance, + uint32 baseAddress + ); + +static void Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex, + uint32 *lutData + ); + +static void Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const *pConfig); + +static void Qspi_Ip_SfdpEnterLegacySPI(uint32 instance, + uint32 baseAddress + ); + +static void Qspi_Ip_SfdpExitDOPI(uint32 instance, + uint32 baseAddress + ); + +static Qspi_Ip_StatusType Qspi_Ip_SfdpCheck(uint32 instance, + uint32 baseAddress + ); + +static Qspi_Ip_StatusType Qspi_Ip_SfdpFindWorkingMode(uint32 instance, + uint32 baseAddress + ); + +static inline boolean Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision); + +static inline uint8 Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 instruction + ); + +static inline uint32 Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader, + uint8 accessProtocol + ); + +static inline boolean Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB, + uint8 tableType, + uint8 majorRevision, + uint8 minorRevision, + sint16 minorRevisionMax + ); + +static Qspi_Ip_StatusType Qspi_Ip_SfdpFindTable(uint32 instance, + uint32 baseAddress, + Qspi_Ip_SfdpTables tableType, + uint32 * paramTable, + uint8 * paramTableLength + ); + +static Qspi_Ip_StatusType Qspi_Ip_SfdpReadTables(uint32 instance, + uint32 baseAddress, + Qspi_Ip_SfdpTablesContainer *sfdpTables + ); + +static void Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd, + const Qspi_Ip_MemoryConfigType *pConfig + ); + +static uint8 Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables); + +static void Qspi_Ip_SfdpInitWriteReg(uint8 cmd, + uint8 wrenCmd, + uint8 size, + uint32 value, + const Qspi_Ip_MemoryConfigType *pConfig + ); + +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig); +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig); +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig); +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig); + +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType *pConfig + ); + +static Qspi_Ip_LutCommandsType Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks, + Qspi_Ip_LutPadsType addrPads + ); + +static void Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 cnt, + uint8 *instruction, + uint8 *addrBits + ); + +static void Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig); +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig); +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig); +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig); + +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ); + +static void Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static uint8 Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 cnt, + uint8 *addrbits + ); + +static uint8 Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 cnt); + +static void Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig, + uint8 instruction + ); + +static void Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType *pConfig, + const Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ); + +static void Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType *pConfig, + const Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ); + +static void Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType *pConfig, + const Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ); + +static void Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType *pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ); + +static void Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType *pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ); + +static void Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption, + const Qspi_Ip_MemoryConfigType * pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ); + +static void Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType *pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ); + +static void Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType *pConfig, + uint8 seqSize, + const uint32 *words + ); + +static void Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType *pConfig); + +static void Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType *pConfig); + +static void Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static void Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType *pConfig); + +static void Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static Qspi_Ip_StatusType Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static Qspi_Ip_StatusType Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static inline void Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +static inline void Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ); + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +/******************************************************************************* + * Private Functions + ******************************************************************************/ + +#define MEM_43_EXFLS_START_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_PackLut + * Description : Packs command, pads count and operand in a LUT entry + */ +static inline Qspi_Ip_InstrOpType Qspi_Ip_PackLut(Qspi_Ip_LutCommandsType cmd, + Qspi_Ip_LutPadsType pad, + uint8 op + ) +{ + return (Qspi_Ip_InstrOpType)((Qspi_Ip_InstrOpType)cmd | (Qspi_Ip_InstrOpType)pad | (Qspi_Ip_InstrOpType)op); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpLutInit + * Description : Initializes LUT and init operations counters + */ +static inline void Qspi_Ip_SfdpLutInit(void) +{ + lutCount = 0U; + initOpCount = 0U; + overflow = FALSE; + quadAvailable = TRUE; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpLutAdd + * Description : Initializes LUT and init operations counters + */ +static inline void Qspi_Ip_SfdpLutAdd(const Qspi_Ip_LutConfigType *lutSequences, + Qspi_Ip_InstrOpType instr + ) +{ + if (lutCount < lutSequences->opCount) + { + lutSequences->lutOps[lutCount] = instr; + lutCount++; + } + else + { + overflow = TRUE; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicParam + * Description : Returns a bitfield from the SFDP tables + */ +static inline uint32 Qspi_Ip_SfdpGetBasicParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ) +{ + const uint32* tablePtr = NULL_PTR; + uint8 tableSize = 0U; + volatile uint32 mask = 0UL; + volatile uint32 result = 0UL; + + tablePtr = sfdpTables->paramTable_basic; + tableSize = sfdpTables->paramTableLength_basic; + + if ((NULL_PTR != tablePtr) && (dword <= tableSize) ) + { + /* get required field */ + mask = (1UL << (uint32)(width)) - 1UL; + result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask; + } + else + { + /* table too short, use default */ + result = defaultValue; + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGet4BAddParam + * Description : Returns a bitfield from the SFDP tables + */ +static inline uint32 Qspi_Ip_SfdpGet4BAddParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ) +{ + const uint32* tablePtr = NULL_PTR; + uint8 tableSize = 0U; + volatile uint32 mask = 0UL; + volatile uint32 result = 0UL; + + tablePtr = sfdpTables->paramTable_4badd; + tableSize = sfdpTables->paramTableLength_4badd; + + if ((NULL_PTR != tablePtr) && (dword <= tableSize) ) + { + /* get required field */ + mask = (1UL << (uint32)(width)) - 1UL; + result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask; + } + else + { + /* table too short, use default */ + result = defaultValue; + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1Param + * Description : Returns a bitfield from the SFDP tables + */ +static inline uint32 Qspi_Ip_SfdpGetXspi1Param(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ) +{ + const uint32* tablePtr = NULL_PTR; + uint8 tableSize = 0U; + volatile uint32 mask = 0UL; + volatile uint32 result = 0UL; + + tablePtr = sfdpTables->paramTable_xspi1; + tableSize = sfdpTables->paramTableLength_xspi1; + + if ((NULL_PTR != tablePtr) && (dword <= tableSize) ) + { + /* get required field */ + mask = (1UL << (uint32)(width)) - 1UL; + result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask; + } + else + { + /* table too short, use default */ + result = defaultValue; + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetSRMapParam + * Description : Returns a bitfield from the SFDP tables + */ +static inline uint32 Qspi_Ip_SfdpGetSRMapParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ) +{ + const uint32* tablePtr = NULL_PTR; + uint8 tableSize = 0U; + volatile uint32 mask = 0UL; + volatile uint32 result = 0UL; + + tablePtr = sfdpTables->paramTable_srmap; + tableSize = sfdpTables->paramTableLength_srmap; + + if ((NULL_PTR != tablePtr) && (dword <= tableSize) ) + { + /* get required field */ + mask = (1UL << (uint32)(width)) - 1UL; + result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask; + } + else + { + /* table too short, use default */ + result = defaultValue; + } + + return result; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGet2DopiParam + * Description : Returns a bitfield from the SFDP tables + */ +static inline uint32 Qspi_Ip_SfdpGet2DopiParam(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 dword, + uint8 shift, + uint8 width, + uint32 defaultValue + ) +{ + const uint32* tablePtr = NULL_PTR; + uint8 tableSize = 0U; + volatile uint32 mask = 0UL; + volatile uint32 result = 0UL; + + tablePtr = sfdpTables->paramTable_2dopi; + tableSize = sfdpTables->paramTableLength_2dopi; + + if ((NULL_PTR != tablePtr) && (dword <= tableSize) ) + { + /* get required field */ + mask = (1UL << (uint32)(width)) - 1UL; + result = ((uint32)(tablePtr[dword - 1U] >> shift)) & mask; + } + else + { + /* table too short, use default */ + result = defaultValue; + } + + return result; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpLutAddSrAddr + * Description : Initializes LUT and init operations counters + */ +static void Qspi_Ip_SfdpLutAddSrAddr(const Qspi_Ip_LutConfigType *lutSequences, + const Qspi_Ip_SfdpTablesContainer *sfdpTables + ) +{ + uint32 addrOffset; + uint8 srAddr; + uint8 srShift; + uint8 nBytes; + sint8 cnt; + uint8 directCmd; + + /* SR read is direct command (not using address */ + directCmd = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_USE_ADDR_DWORD, + QSPI_IP_SFDP_SRMAP_USE_ADDR_SHIFT, QSPI_IP_SFDP_SRMAP_USE_ADDR_WIDTH, 0x0U); + if (directCmd == 0U) + { + /* direct command - nothing to do */ + } + else + { + /* Address offset for volatile registers */ + addrOffset = (uint32)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_OFFSET_DWORD, + QSPI_IP_SFDP_SRMAP_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_OFFSET_WIDTH, 0x0U); + /* Number of address bytes used for Generic Addressable Read/Write Status/Control register commands for volatile registers */ + nBytes = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_NBYTES_DWORD, + QSPI_IP_SFDP_SRMAP_NBYTES_SHIFT, QSPI_IP_SFDP_SRMAP_NBYTES_WIDTH, 0x0U); + /* SR local address */ + srAddr = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_SR_ADDR_DWORD, + QSPI_IP_SFDP_SRMAP_SR_ADDR_SHIFT, QSPI_IP_SFDP_SRMAP_SR_ADDR_WIDTH, 0x0U); + /* SR address shift (before adding to the offset) */ + srShift = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_SR_SHIFT_DWORD, + QSPI_IP_SFDP_SRMAP_SR_SHIFT_SHIFT, QSPI_IP_SFDP_SRMAP_SR_SHIFT_WIDTH, 0x0U); + + /* compute SR address */ + addrOffset = addrOffset + ((uint32)srAddr << (srShift * 8U)); + /* add address to LUT sequence. Use CMD in case addr is out of range */ + for (cnt = (sint8)nBytes; cnt >= 0; cnt--) + { + srAddr = (uint8)((addrOffset >> ((uint8)cnt * 8U)) & 0xFFU); + Qspi_Ip_SfdpLutAdd(lutSequences, Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, srAddr)); + } + } + + return; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpSignatureCheck + * Description : Checks SFDP signature + */ +static inline boolean Qspi_Ip_SfdpSignatureCheck(const uint8 *data) +{ + boolean retCode = FALSE; + + if ((data[0] == 0x53U) && (data[1] == 0x46U) && (data[2] == 0x44U) && (data[3] == 0x50U)) + { + retCode = TRUE; + } + + return retCode; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpInitLut + * Description : Initializes LUT table for reading SFDP information, using the specified format + */ +static inline void Qspi_Ip_SfdpInitLut(uint32 instance, + Qspi_Ip_SfdpModes mode + ) +{ + Qspi_Ip_LutCommandsType instCmd; + Qspi_Ip_LutCommandsType addrCmd; + Qspi_Ip_LutCommandsType dataCmd; + Qspi_Ip_LutPadsType pads; + uint32 lutData[3U]; /* Data to be written to the physical LUTs */ + + /* Set command parameters according to mode */ + instCmd = QSPI_IP_LUT_INSTR_CMD; + addrCmd = QSPI_IP_LUT_INSTR_ADDR; + dataCmd = QSPI_IP_LUT_INSTR_READ; + if (QSPI_IP_SFDP_8D_8D_8D == mode) + { + pads = QSPI_IP_LUT_PADS_8; + instCmd = QSPI_IP_LUT_INSTR_CMD_DDR; + addrCmd = QSPI_IP_LUT_INSTR_ADDR_DDR; + dataCmd = QSPI_IP_LUT_INSTR_READ_DDR; + } + else if (QSPI_IP_SFDP_4S_4D_4D == mode) + { + pads = QSPI_IP_LUT_PADS_4; + addrCmd = QSPI_IP_LUT_INSTR_ADDR_DDR; + dataCmd = QSPI_IP_LUT_INSTR_READ_DDR; + } + else if (QSPI_IP_SFDP_4S_4S_4S == mode) + { + pads = QSPI_IP_LUT_PADS_4; + } + else if (QSPI_IP_SFDP_2S_2S_2S == mode) + { + pads = QSPI_IP_LUT_PADS_2; + } + else + { + pads = QSPI_IP_LUT_PADS_1; + } + + /* Build SFDP Read Sequence */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(instCmd, pads, QSPI_IP_CMD_SFDP_READ), /* READ SFDP command on 1 data line */ + Qspi_Ip_PackLut(addrCmd, pads, 24U)); /* 24-bit address on 1 data line */ + + lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, pads, 8U), /* 8 Dummy cycles */ + Qspi_Ip_PackLut(dataCmd, pads, 0x10U)); /* Read data on "pads" data lines */ + + lutData[2] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END); /* End of sequence */ + + /* Write the SFDP Read Sequence into physical LUT registers */ + Qspi_Ip_WriteLuts(instance, QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE, lutData, 3U); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_WaitAfterReset + * Description : Wait until external memory is available for operation after a reset + */ +static void Qspi_Ip_WaitAfterReset(void) +{ + uint32 u32ElapsedTicks = 0U; + uint32 u32TimeoutTicks; + uint32 u32CurrentTicks; + + /* Prepare timeout counter */ + u32TimeoutTicks = OsIf_MicrosToTicks(QSPI_IP_RESET_TIMEOUT, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE); + u32CurrentTicks = OsIf_GetCounter((OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE); + /* Wait for the specified time */ + do + { + u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, (OsIf_CounterType)QSPI_IP_TIMEOUT_TYPE); + } + while (u32ElapsedTicks < u32TimeoutTicks); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpInitReset_4S4S4S + * Description : Sends 4S-4S-4S reset commands to force device to exit the QPI mode. + */ +static void Qspi_Ip_SfdpInitReset_4S4S4S(uint32 instance, + uint32 baseAddress + ) +{ + /* Data to be written to the physical LUTs */ + uint32 lutData; + + const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE; + + const Qspi_Ip_LutCommandsType cmd = QSPI_IP_LUT_INSTR_CMD; + const Qspi_Ip_LutPadsType pad = QSPI_IP_LUT_PADS_4; + + /* Send Reset Enable Command */ + lutData = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE), + QSPI_IP_LUT_SEQ_END); + Qspi_Ip_WriteLuts(instance, lutRegister, &lutData, 1U); + (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); + + /* Send Reset Command */ + lutData = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF), + QSPI_IP_LUT_SEQ_END); + Qspi_Ip_WriteLuts(instance, lutRegister, &lutData, 1U); + (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); + + /* Wait for reset to complete */ + Qspi_Ip_WaitAfterReset(); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpExitQPI + * Description : Attempt to exit the memory device from QPI (4-4-4) mode. + */ +static void Qspi_Ip_SfdpExitQPI(uint32 instance, + uint32 baseAddress + ) +{ + /* Workaround: send 4S-4S-4S reset command */ + Qspi_Ip_SfdpInitReset_4S4S4S(instance, baseAddress); +} + + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpInitReset_8D8D8D + * Description : Sends 8D-8D-8D reset commands to force device to enter SPI mode. + */ +static void Qspi_Ip_SfdpInitReset_8D8D8D(uint32 instance, + uint32 baseAddress + ) +{ + /* Data to be written to the physical LUTs */ + uint32 lutData[2U] = + { + QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END), + QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END) + }; + + const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE; + + const Qspi_Ip_LutCommandsType cmd = QSPI_IP_LUT_INSTR_CMD_DDR; + const Qspi_Ip_LutPadsType pad = QSPI_IP_LUT_PADS_8; + + /* As we don't know yet the command extension convention of the device, try both ways */ + /* 1. Command Extension is the inverse of the Command */ + /* Send Reset Enable Command */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE), /* Reset Enable command in DOPI Mode */ + Qspi_Ip_PackLut(cmd, pad, (uint8)~QSPI_IP_CMD_XSPI_RESET_ENABLE)); /* command extension */ + Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U); + (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); + + /* Send Reset Command */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF), /* Reset command in DOPI Mode */ + Qspi_Ip_PackLut(cmd, pad, (uint8)~QSPI_IP_CMD_XSPI_RESET_DEF)); /* command extension */ + Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U); + (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); + + /* 2. Command Extension is the same as the Command */ + /* Send Reset Enable Command */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE), /* Reset Enable command in DOPI Mode */ + Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_ENABLE)); /* command extension */ + Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U); + (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); + + /* Send Reset Command */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF), /* Reset command in DOPI Mode */ + Qspi_Ip_PackLut(cmd, pad, (uint8)QSPI_IP_CMD_XSPI_RESET_DEF)); /* command extension */ + Qspi_Ip_WriteLuts(instance, lutRegister, lutData, 2U); + (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); + + /* Wait for reset to complete */ + Qspi_Ip_WaitAfterReset(); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpPackLutEnterLegacySPI + * Description : Pack the Enter Default Protocol Mode command is a sequence of three Write Register Linear commands. + */ +static void Qspi_Ip_SfdpPackLutEnterLegacySPI(uint32 sequenceIndex, uint32 *lutData) +{ + /* - Hyperbus Write Transaction: 6-byte Command/Address + 2-byte Data + - The address is split into 2 parts: half-page address and word address + - With DDR timing, using four clock cycles (eight clock edges) to send 8-byte + + ____ Address=555h, Data=00AAh ___ + CS# \_______________________________/ + + ___ ___ ___ ___ + CK ______/ 1 \___/ 2 \___/ 3 \___/ 4 \_____ + + __ __ __ __ __ __ __ __ + DQ[7-0] ____/00\/00\/00\/AA\/00\/05\/00\/AA\____ + \__/\__/\__/\__/\__/\__/\__/\__/ + */ + + if (0U == sequenceIndex) + { + /* First command: Write Register Linear with Address=555h, Data=00AAh */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U)); + + lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU)); + + lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x05U)); + + lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU)); + } + else if (1U == sequenceIndex) + { + /* Second command: Write Register Linear with Address=2AAh, Data=0055h */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U)); + + lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x55U)); + + lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x02U)); + + lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x55U)); + } + else /* sequenceIndex is 2U */ + { + /* Third command: Write Register Linear with Address=555h, Data=00F5h */ + lutData[0] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U)); + + lutData[1] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xAAU)); + + lutData[2] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x05U)); + + lutData[3] = QSPI_IP_PACK_LUT_REG(Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0x00U), + Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, 0xF5U)); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpLutInitEnterLegacySPI + * Description : Builds the enter XPI protocol initial operations (needed for devices booting-up in Hyperbus mode) + */ +static void Qspi_Ip_SfdpLutInitEnterLegacySPI(Qspi_Ip_MemoryConfigType const *pConfig) +{ + Qspi_Ip_InitOperationType *operation; + uint32 lutData[4U]; /* Data to be written to the physical LUTs */ + uint32 sequenceIndex; + + /* Only needed for devices do not boot in legacy XPI mode */ + if ((boolean)FALSE == bootModeLegacyXPI) + { + for (sequenceIndex = 0U; sequenceIndex < 3U; sequenceIndex++) + { + operation = &(pConfig->initConfiguration.operations[initOpCount]); + initOpCount++; + + /* Build operation */ + operation->opType = QSPI_IP_OP_TYPE_CMD; + operation->command1Lut = lutCount; + operation->addr = 0U; + + /* Pack the command sequence */ + Qspi_Ip_SfdpPackLutEnterLegacySPI(sequenceIndex, lutData); + + /* Build LUT sequence (copy into the virtual LUT table of the configuration) */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[0] >> 0U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[0] >> 16U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[1] >> 0U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[1] >> 16U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[2] >> 0U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[2] >> 16U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[3] >> 0U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), (uint16)(lutData[3] >> 16U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), QSPI_IP_LUT_SEQ_END); /* End of sequence */ + + /* Other operation fields are unused */ + operation->command2Lut = QSPI_IP_LUT_INVALID; + operation->weLut = QSPI_IP_LUT_INVALID; + operation->size = 0U; + operation->shift = 0U; + operation->width = 0U; + operation->value = 0U; + operation->ctrlCfgPtr = NULL_PTR; + } + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpEnterLegacySPI + * Description : The Enter Default Protocol Mode command is a sequence of three Write Register Linear commands. + */ +static void Qspi_Ip_SfdpEnterLegacySPI(uint32 instance, + uint32 baseAddress + ) +{ + uint32 sequenceIndex; + uint32 lutData[5U]; /* Data to be written to the physical LUTs */ + lutData[4] = QSPI_IP_PACK_LUT_REG(QSPI_IP_LUT_SEQ_END, QSPI_IP_LUT_SEQ_END); /* End of sequence */ + + const uint8 lutRegister = QSPI_IP_COMMAND_LUT * FEATURE_QSPI_LUT_SEQUENCE_SIZE; + + /* We need 5 LUT registers: 4 for the command sequence, plus 1 for the end of sequence. + - For platforms that have 4 LUT registers that make up a LUT sequence: + only the first 4 LUT registers will be written to avoid overwriting the next sequence + + - For platforms that have 5 LUT registers that make up a LUT sequence: + all 5 LUT registers will be written + + Because: The instructions are executed sequentially until the last instruction or the STOP instruction is encountered. + + Note: + - This will not work if FEATURE_QSPI_LUT_SEQUENCE_SIZE is less than 4 + - In that case, QSPI_IP_LUT_INSTR_WRITE_DDR must be used (data will be placed in the TBDR to save the number of LUTs) + */ + uint8 lutSize = 5U; + + #if (FEATURE_QSPI_LUT_SEQUENCE_SIZE == 4) + lutSize = 4U; + #elif (FEATURE_QSPI_LUT_SEQUENCE_SIZE < 4) + /* Note for future platforms */ + #error LUT sequence is not big enough. + #endif + + /* Issue the three command sequences */ + for (sequenceIndex = 0U; sequenceIndex < 3U; sequenceIndex++) + { + Qspi_Ip_SfdpPackLutEnterLegacySPI(sequenceIndex, lutData); /* Pack the command sequence */ + Qspi_Ip_WriteLuts(instance, lutRegister, lutData, lutSize); /* Write them to physical hardware LUT registers */ + (void)Qspi_Ip_IpCommand(instance, QSPI_IP_COMMAND_LUT, baseAddress); /* Issue the command sequence */ + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpExitDOPI + * Description : Attempt to exit the memory device from DTR-Octal (8D-8D-8D) mode. + */ +static void Qspi_Ip_SfdpExitDOPI(uint32 instance, + uint32 baseAddress + ) +{ + /* Workaround 1: send 8D-8D-8D reset commands as specified by xSPI Profile 1.0 */ + Qspi_Ip_SfdpInitReset_8D8D8D(instance, baseAddress); + + /* Workaround 2: send Enter Default Protocol Mode command sequence (1S-1S-1S) as specified by xSPI Profile 2.0 */ + Qspi_Ip_SfdpEnterLegacySPI(instance, baseAddress); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpInitReset + * Description : Sends reset commands to force device to enter SPI mode. + */ +static void Qspi_Ip_SfdpInitReset(uint32 instance, + uint32 baseAddress + ) +{ + /* Attempt to read SFDP in DOPI mode */ + Qspi_Ip_SfdpExitDOPI(instance, baseAddress); + + /* Attempt to read SFDP in QPI mode */ + Qspi_Ip_SfdpExitQPI(instance, baseAddress); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpFindWorkingMode + * Description : Tries each mode to find the mode in which the flash device is working. + */ +static Qspi_Ip_StatusType Qspi_Ip_SfdpFindWorkingMode(uint32 instance, + uint32 baseAddress + ) +{ + /* List of sfdp modes attempt to read and the corresponding pad return values */ + const Qspi_Ip_SfdpModes modes[4U] = {QSPI_IP_SFDP_4S_4D_4D, QSPI_IP_SFDP_4S_4S_4S, QSPI_IP_SFDP_2S_2S_2S, QSPI_IP_SFDP_1S_1S_1S}; + const Qspi_Ip_LutPadsType pads[4U] = {QSPI_IP_LUT_PADS_4, QSPI_IP_LUT_PADS_4, QSPI_IP_LUT_PADS_2, QSPI_IP_LUT_PADS_1 }; + const uint32 maxAttempts = 4U; + Qspi_Ip_StatusType status; + uint8 data[4U]; + uint32 idx; + + /* Attempt to read SFDP modes */ + for (idx = 0U; idx < maxAttempts; idx++) + { + Qspi_Ip_SfdpInitLut(instance, modes[idx]); + status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress, data, NULL_PTR, 4U); + if ((STATUS_QSPI_IP_SUCCESS == status) && Qspi_Ip_SfdpSignatureCheck(data)) + { + /* Found a supported mode */ + cmdPadsInit = pads[idx]; + break; + } + } + + /* All read attempts failed, device does not support SFDP */ + if (idx >= maxAttempts) + { + status = STATUS_QSPI_IP_ERROR; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpCheck + * Description : Checks the existence of SFDP support. + */ +static Qspi_Ip_StatusType Qspi_Ip_SfdpCheck(uint32 instance, + uint32 baseAddress + ) +{ + Qspi_Ip_StatusType status; + + /* First attempt to check if SFDP is supported or not */ + status = Qspi_Ip_SfdpFindWorkingMode(instance, baseAddress); + if (STATUS_QSPI_IP_SUCCESS != status) + { + /* The first check has failed, try to issue reset commands in various modes */ + Qspi_Ip_SfdpInitReset(instance, baseAddress); + /* Then try for the second attempt */ + status = Qspi_Ip_SfdpFindWorkingMode(instance, baseAddress); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpCheckMinorRevision + * Description : Verifies validity of sfdp minor revision + * + *END**************************************************************************/ +static inline boolean Qspi_Ip_SfdpCheckMinorRevision(uint8 minorRevision) +{ + /* Revision and size must match the specifications of JESD216, JESD216A or JESD216B; also accept newer revisions */ + return ((QSPI_IP_SFDP_MINOR_REVISION_REV_0 == minorRevision) || + (minorRevision >= QSPI_IP_SFDP_MINOR_REVISION_REV_A)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetCmdExt + * Description : Builds configuration for octal DDR (DOPI) mode. + */ +static inline uint8 Qspi_Ip_SfdpGetCmdExt(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 instruction + ) +{ + uint8 cmdExt; + + /* Get Command Extension */ + cmdExt = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_CMD_EXT_DWORD, + QSPI_IP_SFDP_BASIC_CMD_EXT_SHIFT, QSPI_IP_SFDP_BASIC_CMD_EXT_WIDTH, 0x1U); + if (cmdExt == 0U) + { + cmdExt = instruction; + } + else + { + cmdExt = ~instruction; + } + return cmdExt; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpClearTable + * Description : Clears parameter table before reading it. This is to avoid MISRA non-initialized value errors. + */ +static void Qspi_Ip_SfdpClearTable(uint32 * paramTable, + uint8 paramTableLength + ) +{ + uint8 count; + for (count = 0U; count < paramTableLength; count++) + { + paramTable[count] = 0U; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpCheckNewerRevision + * Description : Check SFDP Parameter Table revision is newer or not + */ +static inline boolean Qspi_Ip_SfdpCheckNewerRevision(uint8 paramIdLSB, + uint8 tableType, + uint8 majorRevision, + uint8 minorRevision, + sint16 minorRevisionMax + ) +{ + boolean retVal; + + if ((paramIdLSB == (uint8)tableType) && + (QSPI_IP_SFDP_MAJOR_REVISION == majorRevision) && + ((sint16)minorRevision > minorRevisionMax)) + { + retVal = TRUE; + } + else + { + retVal = FALSE; + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetParamTableAddress + * Description : Gets the address of parameter table from the parameter header. + * Converts to byte address if the device is hyperbus. + */ +static inline uint32 Qspi_Ip_SfdpGetParamTableAddress(const uint8 * paramHeader, + uint8 accessProtocol + ) +{ + /* Get the table address from pointer byte 2, 1 and 0 */ + uint32 paramTableAddress = ((uint32)paramHeader[6U] << 16U) | ((uint32)paramHeader[5U] << 8U) | (uint32)paramHeader[4U]; + + /* The memory is a hyperbus device, convert from word address to byte address */ + if (accessProtocol == QSPI_IP_SFDP_ACCESS_PROTOCOL_HYPERBUS) + { + bootModeLegacyXPI = (boolean)FALSE; /* The memory device booting up in xSPI NOR Profile 2 HYPERBUS */ + paramTableAddress <<= 1U; + } + + return paramTableAddress; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpFindTable + * Description : Finds requested parameters table in SFDP table, if it exists. + */ +static Qspi_Ip_StatusType Qspi_Ip_SfdpFindTable(uint32 instance, + uint32 baseAddress, + Qspi_Ip_SfdpTables tableType, + uint32 * paramTable, + uint8 * paramTableLength + ) +{ + Qspi_Ip_StatusType status; + uint8 data[8U]; + uint8 paramHeaders = 0U; + uint8 majorRevision; + uint8 minorRevision; + sint16 minorRevisionMax = -1; + uint8 paramIdLSB; + uint32 currAddr; + uint32 paramTableBaseAddr = 0U; + uint8 tableLength; + uint8 tableLengthMax = 0U; + boolean minorVerFlag = FALSE; + uint8 accessProtocol = QSPI_IP_SFDP_ACCESS_PROTOCOL_LEGACY; /* default value as Legacy option */ + + Qspi_Ip_SfdpClearTable(paramTable, *paramTableLength); + /* read second part of SFDP header to check version and get number of parameter headers */ + status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + 4U, data, NULL_PTR, 4U); + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* check SFDP revision; minor revision can be greater than expected, because backward compatibility is guaranteed */ + majorRevision = data[1]; + minorRevision = data[0]; + paramHeaders = (uint8)(data[2] + 1U); + accessProtocol = data[3]; /* [31:24] SFDP Access Protocol field */ + minorVerFlag = Qspi_Ip_SfdpCheckMinorRevision(minorRevision); + if ((QSPI_IP_SFDP_MAJOR_REVISION != majorRevision) || (TRUE != minorVerFlag)) + { + paramHeaders = 0U; + status = STATUS_QSPI_IP_ERROR; + } + } + + /* If paramHeaders is greater than zero means the SFDP revision is correct */ + /* iterate through parameter headers */ + currAddr = 8U; + for (; paramHeaders > (uint8)0U; paramHeaders--) + { + /* read current parameter header */ + status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + currAddr, data, NULL_PTR, 8U); + if (status != STATUS_QSPI_IP_SUCCESS) + { + break; + } + majorRevision = data[2]; + minorRevision = data[1]; + paramIdLSB = data[0]; + tableLength = data[3]; + if (TRUE == Qspi_Ip_SfdpCheckNewerRevision(paramIdLSB, (uint8)tableType, majorRevision, minorRevision, minorRevisionMax)) + { + /* Found SFDP Basic Parameter Table with newer revision */ + paramTableBaseAddr = Qspi_Ip_SfdpGetParamTableAddress(data, accessProtocol); + minorRevisionMax = (sint16)minorRevision; + tableLengthMax = tableLength; + } + currAddr += 8U; + } + + /* If minorRevisionMax is not negative, it means that a SFDP table was found */ + if (minorRevisionMax >= 0) + { + /* Adjust table length in case of newer revisions */ + if (tableLengthMax > *paramTableLength) + { + tableLengthMax = *paramTableLength; + } + /* Read parameter table */ + status = Qspi_Ip_IpRead(instance, QSPI_IP_COMMAND_LUT, baseAddress + paramTableBaseAddr, (uint8 *)paramTable, NULL_PTR, (uint32)tableLengthMax * 4U); + if (STATUS_QSPI_IP_SUCCESS == status) + { + *paramTableLength = tableLengthMax; + } + } + else + { + /* Could not find a table of the requested kind */ + *paramTableLength = 0U; + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpReadTables + * Description : Finds requested parameters table in SFDP table, if it exists. + */ +static Qspi_Ip_StatusType Qspi_Ip_SfdpReadTables(uint32 instance, + uint32 baseAddress, + Qspi_Ip_SfdpTablesContainer *sfdpTables + ) +{ + Qspi_Ip_StatusType status; + + /* Initialize each table length to max specified by JESD216 rev. D */ + sfdpTables->paramTableLength_basic = QSPI_IP_TABLE_SIZE_BASIC; + sfdpTables->paramTableLength_4badd = QSPI_IP_TABLE_SIZE_4BADD; + sfdpTables->paramTableLength_xspi1 = QSPI_IP_TABLE_SIZE_XSPI1; + sfdpTables->paramTableLength_srmap = QSPI_IP_TABLE_SIZE_SRMAP; + sfdpTables->paramTableLength_2dopi = QSPI_IP_TABLE_SIZE_2DOPI; + + /* Search Basic Flash Parameter Table */ + status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_BASIC, + sfdpTables->paramTable_basic, &(sfdpTables->paramTableLength_basic)); + if ((status != STATUS_QSPI_IP_SUCCESS) || (sfdpTables->paramTableLength_basic == 0U)) + { + status = STATUS_QSPI_IP_ERROR; + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Search 4-byte Address Instruction Table */ + status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_4BADD, + sfdpTables->paramTable_4badd, &(sfdpTables->paramTableLength_4badd)); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Search eXtended Serial Peripheral Interface (xSPI) Profile 1.0 Table */ + status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_XSPI1, + sfdpTables->paramTable_xspi1, &(sfdpTables->paramTableLength_xspi1)); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Search Status, Control and Configuration Register Map Table */ + status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_SRMAP, + sfdpTables->paramTable_srmap, &(sfdpTables->paramTableLength_srmap)); + } + + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Command Sequences to change to DOPI (8D-8D-8D) mode */ + status = Qspi_Ip_SfdpFindTable(instance, baseAddress, QSPI_IP_SFDP_TABLE_2DOPI, + sfdpTables->paramTable_2dopi, &(sfdpTables->paramTableLength_2dopi)); + } + + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpInitSimpleCmd + * Description : Builds an initial operation containing a simple command. + */ +static void Qspi_Ip_SfdpInitSimpleCmd(uint8 cmd, + const Qspi_Ip_MemoryConfigType *pConfig + ) +{ + Qspi_Ip_InitOperationType *operation; + + if (initOpCount >= pConfig->initConfiguration.opCount) + { + /* operations list not big enough */ + overflow = TRUE; + } + else + { + operation = &(pConfig->initConfiguration.operations[initOpCount]); + initOpCount++; + /* Build operation */ + operation->opType = QSPI_IP_OP_TYPE_CMD; + operation->command1Lut = lutCount; + operation->addr = 0U; + /* Build LUT sequence */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, cmd)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* Other operation fields are unused */ + operation->command2Lut = QSPI_IP_LUT_INVALID; + operation->weLut = QSPI_IP_LUT_INVALID; + operation->size = 0U; + operation->shift = 0U; + operation->width = 0U; + operation->value = 0U; + operation->ctrlCfgPtr = NULL_PTR; + } + + return; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetWeSrInstr + * Description : Returns instruction for write enable on SR register. + */ +static uint8 Qspi_Ip_SfdpGetWeSrInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables) +{ + uint8 wrEnSr; + + /* Check "Write Enable Instruction Select for Writing to Volatile Status Register" bitfield */ + wrEnSr = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_WREN_SR_DWORD, + QSPI_IP_SFDP_BASIC_WREN_SR_SHIFT, QSPI_IP_SFDP_BASIC_WREN_SR_WIDTH, 0x1U); + if (wrEnSr == 1U) + { + wrEnSr = 0x50U; + } + else + { + wrEnSr = 0x06U; + } + return wrEnSr; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpInitWriteReg + * Description : Builds an initial operation containing a register write command. + */ +static void Qspi_Ip_SfdpInitWriteReg(uint8 cmd, + uint8 wrenCmd, + uint8 size, + uint32 value, + const Qspi_Ip_MemoryConfigType *pConfig + ) +{ + Qspi_Ip_InitOperationType *operation; + + if (initOpCount >= pConfig->initConfiguration.opCount) + { + /* operations list not big enough */ + overflow = TRUE; + } + else + { + operation = &(pConfig->initConfiguration.operations[initOpCount]); + initOpCount++; + /* Build operation */ + operation->opType = QSPI_IP_OP_TYPE_WRITE_REG; + operation->addr = 0U; + operation->weLut = lutCount; + operation->size = size; + operation->value = value; + /* Build WE LUT sequence */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, wrenCmd)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + operation->command1Lut = lutCount; + /* Build write SR LUT sequence */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, cmd)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, QSPI_IP_LUT_PADS_1, 0x1U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + + /* Other operation fields are unused */ + operation->command2Lut = QSPI_IP_LUT_INVALID; + operation->shift = 0U; + operation->width = 0U; + operation->ctrlCfgPtr = NULL_PTR; + } + + return; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_01 + * Description : Switch to 4-byte addressing mode. + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_01(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* issue instruction B7h (preceding write enable not required) */ + Qspi_Ip_SfdpInitSimpleCmd(0xB7U, pConfig); + return STATUS_QSPI_IP_SUCCESS; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_02 + * Description : Switch to 4-byte addressing mode. + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_02(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* issue write enable instruction 06h, then issue instruction B7h */ + Qspi_Ip_SfdpInitSimpleCmd(0x06U, pConfig); + Qspi_Ip_SfdpInitSimpleCmd(0xB7U, pConfig); + return STATUS_QSPI_IP_SUCCESS; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_08 + * Description : Switch to 4-byte addressing mode. + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_08(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used to enable/disable 4-byte address mode. + When MSB is set to ‘1’, 4-byte address mode is active and A[30:24] bits are don’t care. Read with instruction 16h. + Write instruction is 17h with 1 byte of data. When MSB is cleared to ‘0’, select the active 128 Mbit segment by setting + the appropriate A[30:24] bits and use 3-Byte addressing */ + /* Not implemented */ + (void)pConfig; + return STATUS_QSPI_IP_ERROR; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch_16 + * Description : Switch to 4-byte addressing mode. + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch_16(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. Read instruction is B5h. + Bit[0] controls address mode [0=3-Byte; 1=4-Byte]. Write configuration register instruction is B1h, data length is 2 bytes */ + /* Not implemented */ + (void)pConfig; + return STATUS_QSPI_IP_ERROR; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp4byteAddrSwitch + * Description : Switch to 4-byte addressing mode. + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp4byteAddrSwitch(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType * pConfig + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint8 addrSwitch; + + /* Check 4-byte addr enable mode */ + addrSwitch = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ADDR_SWITCH_DWORD, + QSPI_IP_SFDP_BASIC_ADDR_SWITCH_SHIFT, QSPI_IP_SFDP_BASIC_ADDR_SWITCH_WIDTH, 0x0U); + if ((addrSwitch & 0x01U) != 0U) + { + /* issue instruction B7h (preceding write enable not required) */ + status = Qspi_Ip_Sfdp4byteAddrSwitch_01(pConfig); + } + else if ((addrSwitch & 0x02U) != 0U) + { + /* issue write enable instruction 06h, then issue instruction B7h */ + status = Qspi_Ip_Sfdp4byteAddrSwitch_02(pConfig); + } + else if ((addrSwitch & 0x08U) != 0U) + { + /* 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used to enable/disable 4-byte address mode */ + status = Qspi_Ip_Sfdp4byteAddrSwitch_08(pConfig); + } + else if ((addrSwitch & 0x10U) != 0U) + { + /* A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. */ + status = Qspi_Ip_Sfdp4byteAddrSwitch_16(pConfig); + } + else + { + /* Can't switch to 4-byte addr. mode */ + status = STATUS_QSPI_IP_ERROR; + } + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicAddrBits + * Description : Returns number of address bits. + */ +static void Qspi_Ip_SfdpGetBasicAddrBits(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType * pConfig + ) +{ + uint8 addrBytes; + Qspi_Ip_StatusType status; + + /* Check number of address bytes */ + addrBytes = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ADDR_BYTES_DWORD, + QSPI_IP_SFDP_BASIC_ADDR_BYTES_SHIFT, QSPI_IP_SFDP_BASIC_ADDR_BYTES_WIDTH, 0x0U); + switch (addrBytes) + { + case 0U: + /* 3-Byte only addressing */ + basicAddrBits = 24U; + break; + case 1U: + /* 3 or 4 byte addressing, try to switch to 4 */ + status = Qspi_Ip_Sfdp4byteAddrSwitch(sfdpTables, pConfig); + if (STATUS_QSPI_IP_SUCCESS == status) + { + basicAddrBits = 32U; + } + else + { + basicAddrBits = 24U; + } + break; + case 2U: + /* 4-Byte only addressing */ + basicAddrBits = 32U; + break; + default: + /* reseved, should not happen, default to 3-byte */ + basicAddrBits = 24U; + break; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigureQE + * Description : Adds initial operation to set QE bit, if required. + */ +static void Qspi_Ip_SfdpConfigureQE(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 qeReq; + uint8 wrenCmd; + boolean qeBit = TRUE; + + /* Check "Quad Enable Requirements (QER)" field */ + qeReq = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_QE_REQ_DWORD, + QSPI_IP_SFDP_BASIC_QE_REQ_SHIFT, QSPI_IP_SFDP_BASIC_QE_REQ_WIDTH, 0x7U); + wrenCmd = Qspi_Ip_SfdpGetWeSrInstr(sfdpTables); + switch (qeReq) + { + case 0U: + /* Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 reads based on instruction. + (the quad commands are available without setting any bits) */ + qeBit = FALSE; + break; + case 1U: + /* QE is bit 1 of status register 2. It is set via Write Status with two data bytes where bit 1 of the second byte is one. It is cleared via + Write Status with two data bytes where bit 1 of the second byte is zero. Writing only one byte to the status register has the side-effect + of clearing status register 2, including the QE bit */ + Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig); + break; + case 2U: + /* QE is bit 6 of status register 1. It is set via Write Status with one data byte where bit 6 is one. + It is cleared via Write Status with one data byte where bit 6 is zero. */ + Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 1U, 0x40U, pConfig); + break; + case 3U: + /* QE is bit 7 of status register 2. It is set via Write status register 2 instruction 3Eh with one data byte where bit 7 is one. + It is cleared via Write status register 2 instruction 3Eh with one data byte where bit 7 is zero. The status register 2 is read using instruction 3Fh. */ + Qspi_Ip_SfdpInitWriteReg(0x3EU, wrenCmd, 1U, 0x80U, pConfig); + break; + case 4U: + /* QE is bit 1 of status register 2. It is set via Write Status with two data bytes where bit 1 of the second byte is one. It is cleared via + Write Status with two data bytes where bit 1 of the second byte is zero. In contrast to the 001b code, writing one byte to the status + register does not modify status register 2. */ + Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig); + break; + case 5U: + /* QE is bit 1 of the status register 2. Status register 1 is read using Read Status instruction 05h. Status register 2 is read using instruction 35h. + QE is set via Write Status instruction 01h with two data bytes where bit 1 of the second byte is one. It is cleared via Write Status with + two data bytes where bit 1 of the second byte is zero. */ + Qspi_Ip_SfdpInitWriteReg(0x01U, wrenCmd, 2U, 0x0002U, pConfig); + break; + case 6U: + /* QE is bit 1 of the status register 2. Status register 1 is read using Read Status instruction 05h. Status register 2 is read using instruction + 35h, and status register 3 is read using instruction 15h. QE is set via Write Status Register instruction 31h with one data byte where + bit 1 is one. It is cleared via Write Status Register instruction 31h with one data byte where bit 1 is zero. */ + Qspi_Ip_SfdpInitWriteReg(0x31U, wrenCmd, 1U, 0x02U, pConfig); + break; + default: + /* Unknown QE bit setting procedure or table too short, disable quad commands */ + quadAvailable = FALSE; + qeBit = FALSE; + break; + } + + if (TRUE == qeBit) + { + /* Add a wait operation to ensure the write to non-volatile QE bit is completed */ + Qspi_Ip_SfdpAddCheckBusyOperation(pConfig); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetModeInstr + * Description : Returns MODE instructions to use for read commands. + */ +static Qspi_Ip_LutCommandsType Qspi_Ip_SfdpGetModeInstr(uint8 modeClocks, + Qspi_Ip_LutPadsType addrPads + ) +{ + uint8 modeBits; + Qspi_Ip_LutCommandsType mode = QSPI_IP_LUT_INSTR_MODE; + + /* compute the number of mode bits from pads and mode clocks */ + modeBits = modeClocks * (1U << (uint8)((uint32)addrPads >> 8U)); + switch (modeBits) + { + case 2U: + mode = QSPI_IP_LUT_INSTR_MODE2; + break; + case 4U: + mode = QSPI_IP_LUT_INSTR_MODE4; + break; + case 8U: + mode = QSPI_IP_LUT_INSTR_MODE; + break; + default: + /* unsupported mode */ + break; + } + return mode; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetSpiReadInstr + * Description : Returns instructions for read type . + */ +static void Qspi_Ip_SfdpGetSpiReadInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 cnt, + uint8 *instruction, + uint8 *addrBits + ) +{ + uint8 sup4badd; + + /* Check 4-byte instr. support */ + sup4badd = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, read4ByteSupDword[cnt], + read4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U); + if (sup4badd == 1U) + { + /* Use 4-byte address instruction specified in SFDP standard */ + *instruction = read4ByteInst[cnt]; + *addrBits = 32U; + } + else + { + /* Get instruction from basic parameters table */ + *instruction = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readInstDword[cnt], + readInstShift[cnt], readInstWidth[cnt], 0x0U); + *addrBits = basicAddrBits; + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigBasicRead + * Description : Configures basic 1-1-1 read. + */ +static void Qspi_Ip_SfdpConfigBasicRead(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 addrBits; + uint8 instruction; + + /* Check 4-byte instr. support */ + addrBits = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD, + QSPI_IP_SFDP_4BADD_READ111_SUP_SHIFT, QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U); + if (addrBits == 0U) + { + instruction = QSPI_IP_CMD_BASIC_READ; + addrBits = basicAddrBits; + } + else + { + instruction = QSPI_IP_CMD_BASIC_READ_4B; + addrBits = 32U; + } + /* Get LUT index */ + pConfig->readLut = lutCount; + /* Build LUT */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, QSPI_IP_LUT_PADS_1, addrBits)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, QSPI_IP_LUT_PADS_1, 0x10U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp444Switch + * Description : Add commands to switch to 4-4-4 mode in operations list + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_01(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* 01: set QE per QER description above, then issue instruction 38h */ + /* 02: issue instruction 38h */ + Qspi_Ip_SfdpInitSimpleCmd(0x38U, pConfig); + return STATUS_QSPI_IP_SUCCESS; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp444Switch + * Description : Add commands to switch to 4-4-4 mode in operations list + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_04(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* issue instruction 35h */ + Qspi_Ip_SfdpInitSimpleCmd(0x35U, pConfig); + return STATUS_QSPI_IP_SUCCESS; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp444Switch + * Description : Add commands to switch to 4-4-4 mode in operations list + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_08(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* device uses a read-modify-write sequence of operations: read configuration using instruction 65h followed by address 800003h, set bit 6, + write configuration using instruction 71h followed by address 800003h. This configuration is volatile. */ + /* Not implemented */ + (void)pConfig; + return STATUS_QSPI_IP_ERROR; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp444Switch + * Description : Add commands to switch to 4-4-4 mode in operations list + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch_16(const Qspi_Ip_MemoryConfigType * pConfig) +{ + /* Device uses a read-modify-write sequence of operations: Read Volatile Enhanced Configuration Register using instruction 65h, + no address is required, reset bit 7 to 0. Write Volatile Enhanced Configuration Register using instruction 61h, + no address is required. This configuration is volatile. */ + /* Not implemented */ + (void)pConfig; + return STATUS_QSPI_IP_ERROR; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_Sfdp444Switch + * Description : Add commands to switch to 4-4-4 mode in operations list + */ +static Qspi_Ip_StatusType Qspi_Ip_Sfdp444Switch(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType * pConfig + ) +{ + uint8 quadSwitch; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Check 4-4-4 mode enable sequences */ + quadSwitch = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_444_SWITCH_DWORD, + QSPI_IP_SFDP_BASIC_444_SWITCH_SHIFT, QSPI_IP_SFDP_BASIC_444_SWITCH_WIDTH, 0x0U); + if ((quadSwitch & 0x3U) != 0U) + { + /* 01: set QE per QER description above, then issue instruction 38h */ + /* 02: issue instruction 38h */ + status = Qspi_Ip_Sfdp444Switch_01(pConfig); + } + else if ((quadSwitch & 0x4U) != 0U) + { + /* issue instruction 35h */ + status = Qspi_Ip_Sfdp444Switch_04(pConfig); + } + else if ((quadSwitch & 0x8U) != 0U) + { /* device uses a read-modify-write sequence of operations */ + status = Qspi_Ip_Sfdp444Switch_08(pConfig); + } + else if ((quadSwitch & 0x16U) != 0U) + { /* device uses a read-modify-write sequence of operations */ + status = Qspi_Ip_Sfdp444Switch_16(pConfig); + } + else + { + /* can't do the switch to 4-4-4 mode */ + status = STATUS_QSPI_IP_ERROR; + } + return status; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicReadInfo + * Description : Builds configuration for basic (SPI) read. + */ +static void Qspi_Ip_SfdpGetBasicReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + uint8 supported = 0U; + uint8 crtMode; + uint8 modeClocks; + uint8 dummyClocks; + Qspi_Ip_LutPadsType instPads; + Qspi_Ip_LutPadsType addrPads; + Qspi_Ip_LutPadsType dataPads; + uint8 addrBits; + uint8 instruction; + Qspi_Ip_LutCommandsType modeInstr; + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Find the best supported fast read mode */ + /* Check if read mode is supported */ + for (crtMode = (uint8)QSPI_IP_SFDP_READ_MODE_MAX; crtMode > 0U; crtMode-- ) + { + modeIndex = (uint8)(crtMode - 1U); + if ((QSPI_IP_LUT_PADS_4 == readModeDataPads[modeIndex]) && (FALSE == quadAvailable)) + { + /* Quad mode not available ignore quad commands */ + continue; + } + supported = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readSupDword[modeIndex], + readSupShift[modeIndex], readSupWitdh[modeIndex], 0x0U); + if (supported != 0U) + { + if ((uint8)QSPI_IP_SFDP_READ_MODE_444 == modeIndex) + { + /* 4-4-4 read mode, add commands to switch to this mode in operation list */ + status = Qspi_Ip_Sfdp444Switch(sfdpTables, pConfig); + /* Will use 4 cmd pads for all commands */ + cmdPads = QSPI_IP_LUT_PADS_4; + } + else + { + status = STATUS_QSPI_IP_SUCCESS; + cmdPads = QSPI_IP_LUT_PADS_1; + } + if (STATUS_QSPI_IP_SUCCESS == status) + { + /* Get read instruction */ + Qspi_Ip_SfdpGetSpiReadInstr(sfdpTables, modeIndex, &instruction, &addrBits); + /* Get mode and dummy clocks */ + modeClocks = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readModeDword[modeIndex], + readModeShift[modeIndex], readModeWidth[modeIndex], 0x0U); + dummyClocks = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, readDummyDword[modeIndex], + readDummyShift[modeIndex], readDummyWidth[modeIndex], 0x0U); + /* Get other command parameters */ + instPads = readModeInstPads[modeIndex]; + addrPads = readModeAddrPads[modeIndex]; + dataPads = readModeDataPads[modeIndex]; + /* Build LUT */ + pConfig->readLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, instPads, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, addrPads, addrBits)); + if (modeClocks > 0U) + { + modeInstr = Qspi_Ip_SfdpGetModeInstr(modeClocks, addrPads); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(modeInstr, addrPads, 0x0U)); + } + if (dummyClocks > 0U) + { + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, addrPads, dummyClocks)); + } + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, dataPads, 0x10U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* Found read command, exit loop */ + break; + } + } + } + + if (supported == 0U) + { + /* No supported fast read mode found, use default */ + Qspi_Ip_SfdpConfigBasicRead(sfdpTables, pConfig); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicWriteInfo + * Description : Builds configuration for basic (SPI) write + */ +static void Qspi_Ip_SfdpGetBasicWriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + uint8 supported; + Qspi_Ip_LutPadsType instPads; + Qspi_Ip_LutPadsType addrPads; + Qspi_Ip_LutPadsType dataPads; + uint8 addrBits; + uint8 instruction; + + /* check if 4-byte write corresponding to the current read mode is supported */ + supported = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, write4ByteSupDword[modeIndex], + write4ByteSupShift[modeIndex], QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD, 0x0); + if (supported == 1U) + { + addrBits = 32U; + instruction = write4ByteInst[modeIndex]; + instPads = readModeInstPads[modeIndex]; + addrPads = readModeAddrPads[modeIndex]; + dataPads = readModeDataPads[modeIndex]; + } + else + { + /* No 4-byte write support, use basic write since SFDP does not specify other write modes */ + addrBits = basicAddrBits; + instruction = QSPI_IP_CMD_BASIC_WRITE; + instPads = cmdPads; + addrPads = cmdPads; + dataPads = cmdPads; + } + /* Get LUT index */ + pConfig->writeLut = lutCount; + /* Build LUT */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, instPads, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, addrPads, addrBits)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, dataPads, 0x10U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1ReadInfo + * Description : Builds configuration for octal DDR (DOPI) mode. + */ +static void Qspi_Ip_SfdpGetXspi1ReadInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 readInst; + uint8 cmdExt; + uint8 dummy; + + /* Get fast read instruction */ + readInst = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_READ_FAST_DWORD, + QSPI_IP_SFDP_XSPI1_READ_FAST_SHIFT, QSPI_IP_SFDP_XSPI1_READ_FAST_WIDTH, 0xEEU); + /* Get Command Extension */ + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, readInst); + /* Get Dummy cycles */ + dummy = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_DUMMY_DWORD, + QSPI_IP_SFDP_XSPI1_DUMMY_SHIFT, QSPI_IP_SFDP_XSPI1_DUMMY_WIDTH, 20U); + + /* Get LUT index */ + pConfig->readLut = lutCount; + /* Build LUT command */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, readInst)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, QSPI_IP_LUT_PADS_8, dummy)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ_DDR, QSPI_IP_LUT_PADS_8, 0x10U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1WriteInfo + * Description : Builds configuration for octal DDR (DOPI) mode. + */ +static void Qspi_Ip_SfdpGetXspi1WriteInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 writeInst; + uint8 cmdExt; + + /* Page program instruction - not in SFDP table */ + writeInst = QSPI_IP_CMD_XSPI_WRITE; + /* Get Command Extension */ + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, writeInst); + + /* Get LUT index */ + pConfig->writeLut = lutCount; + /* Build LUT command */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, writeInst)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE_DDR, QSPI_IP_LUT_PADS_8, 0x10U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicEraseInstr + * Description : Returns instructions for erase type . + */ +static uint8 Qspi_Ip_SfdpGetBasicEraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 cnt, + uint8 *addrbits + ) +{ + uint8 addr4; + uint8 eraseInst; + + /* Check 4-byte instr. support */ + addr4 = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD, + erase4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U); + if (addr4 == 1U) + { + /* Get erase instruction from 4-byte address instructions table */ + eraseInst = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD, + erase4ByteInstShift[cnt], QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH, 0x0U); + *addrbits = 32U; + } + else + { + /* Get erase instruction from basic parameters table */ + eraseInst = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseInstDword[cnt], + eraseInstShift[cnt], eraseInstWidth[cnt], 0x0U); + + /* No matter the device is operating in 3-Byte or 4-byte Address Mode, + the Erase with 4-Byte Address instruction will always require 32-bit address */ + if (eraseInst == erase4ByteInst[cnt]) + { + *addrbits = 32U; + } + else + { + *addrbits = basicAddrBits; + } + } + return eraseInst; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1EraseInstr + * Description : Returns instructions for erase type . + */ +static uint8 Qspi_Ip_SfdpGetXspi1EraseInstr(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + uint8 cnt + ) +{ + uint8 addr4; + uint8 eraseInst; + + /* Check 4-byte instr. support */ + addr4 = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_INSTR_SUP_DWORD, + erase4ByteSupShift[cnt], QSPI_IP_SFDP_4BADD_INSTR_SUP_WIDTH, 0x0U); + if (addr4 == 1U) + { + /* Get erase instruction from 4-byte address instructions table */ + eraseInst = (uint8)Qspi_Ip_SfdpGet4BAddParam(sfdpTables, QSPI_IP_SFDP_4BADD_ERASE_INST_DWORD, + erase4ByteInstShift[cnt], QSPI_IP_SFDP_4BADD_ERASE_INST_WIDTH, 0x0U); + } + else + { + /* Get erase instruction from basic parameters table */ + eraseInst = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseInstDword[cnt], + eraseInstShift[cnt], eraseInstWidth[cnt], 0x0U); + } + return eraseInst; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicEraseInfo + * Description : Builds configuration for SPI mode. + */ +static void Qspi_Ip_SfdpGetBasicEraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + uint8 eraseInst; + uint8 eraseSize; + uint8 addrbits; + uint8 cnt; + + /* Loop through the 4 possible erase types */ + for (cnt = 0U; cnt < 4U; cnt++) + { + /* Get erase size */ + eraseSize = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseSizeDword[cnt], + eraseSizeShift[cnt], eraseSizeWidth[cnt], 0x0U); + pConfig->eraseSettings.eraseTypes[cnt].size = eraseSize; + if (eraseSize > 0U) + { + /* Get erase instruction */ + eraseInst = Qspi_Ip_SfdpGetBasicEraseInstr(sfdpTables, cnt, &addrbits); + /* Get LUT index */ + pConfig->eraseSettings.eraseTypes[cnt].eraseLut = lutCount; + /* Build LUT command */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eraseInst)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR, cmdPads, (uint8)addrbits)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } + else + { + /* Erase type not supported */ + pConfig->eraseSettings.eraseTypes[cnt].eraseLut = QSPI_IP_LUT_INVALID; + } + } + + /* Chip erase */ + eraseInst = QSPI_IP_CMD_BASIC_CHIP_ERASE; + pConfig->eraseSettings.chipEraseLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eraseInst)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1EraseInfo + * Description : Builds configuration for octal DDR (DOPI) mode. + */ +static void Qspi_Ip_SfdpGetXspi1EraseInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 eraseInst; + uint8 eraseSize; + uint8 eraseExt; + uint8 cnt; + + /* Loop through the 4 possible erase types */ + for (cnt = 0U; cnt < 4U; cnt++) + { + /* Get erase size */ + eraseSize = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, eraseSizeDword[cnt], + eraseSizeShift[cnt], eraseSizeWidth[cnt], 0x0U); + pConfig->eraseSettings.eraseTypes[cnt].size = eraseSize; + if (eraseSize > 0U) + { + /* Get erase instruction */ + eraseInst = Qspi_Ip_SfdpGetXspi1EraseInstr(sfdpTables, cnt); + eraseExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eraseInst); + /* Get LUT index */ + pConfig->eraseSettings.eraseTypes[cnt].eraseLut = lutCount; + /* Build LUT command */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseInst)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_ADDR_DDR, QSPI_IP_LUT_PADS_8, (uint8)32U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } + else + { + /* Erase type not supported */ + pConfig->eraseSettings.eraseTypes[cnt].eraseLut = QSPI_IP_LUT_INVALID; + } + } + + /* Check chip erase support */ + eraseInst = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_CHIP_ERASE_DWORD, + QSPI_IP_SFDP_XSPI1_CHIP_ERASE_SHIFT, QSPI_IP_SFDP_XSPI1_CHIP_ERASE_WIDTH, 0x0U); + if (eraseInst == 0U) + { + pConfig->eraseSettings.chipEraseLut = QSPI_IP_LUT_INVALID; + } + else + { + pConfig->eraseSettings.chipEraseLut = lutCount; + /* Build LUT command */ + eraseInst = QSPI_IP_CMD_XSPI_CHIP_ERASE; + eraseExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eraseInst); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseInst)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eraseExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicStatusInfo + * Description : Builds configuration for SPI mode. + */ +static void Qspi_Ip_SfdpGetBasicStatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 instruction; + Qspi_Ip_StatusConfigType *statusConfig; + + statusConfig = &(pConfig->statusConfig); + + /* Build LUT sequence for read status reg. */ + if (QSPI_IP_LUT_PADS_1 == cmdPads) + { + /* Use same sequence */ + statusConfig->statusRegReadLut = statusConfig->statusRegInitReadLut; + } + else + { + statusConfig->statusRegReadLut = lutCount; + instruction = QSPI_IP_CMD_BASIC_READ_SR; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, cmdPads, 0x10)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } + + /* Build LUT sequence for write status reg. */ + statusConfig->statusRegWriteLut = lutCount; + instruction = QSPI_IP_CMD_BASIC_WRITE_SR; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, cmdPads, 0x1U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + + /* Build LUT sequence for write enable */ + statusConfig->writeEnableLut = lutCount; + instruction = QSPI_IP_CMD_BASIC_WRITE_ENABLE; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + + /* Build LUT sequence for SR write enable */ + instruction = Qspi_Ip_SfdpGetWeSrInstr(sfdpTables); + if (QSPI_IP_CMD_BASIC_WRITE_ENABLE == instruction) + { + statusConfig->writeEnableSRLut = statusConfig->writeEnableLut; + } + else + { + statusConfig->writeEnableSRLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1StatusInfo + * Description : Builds configuration for octal DDR (DOPI) mode. + */ +static void Qspi_Ip_SfdpGetXspi1StatusInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 instruction; + uint8 cmdExt; + uint8 dummy; + Qspi_Ip_StatusConfigType *statusConfig; + + statusConfig = &(pConfig->statusConfig); + + /* Build LUT sequence for read status reg. */ + statusConfig->statusRegReadLut = lutCount; + instruction = QSPI_IP_CMD_XSPI_READ_SR; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction); + dummy = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_DUMMY_8D_DWORD, + QSPI_IP_SFDP_SRMAP_DUMMY_8D_SHIFT, QSPI_IP_SFDP_SRMAP_DUMMY_8D_WIDTH, 0x0U); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAddSrAddr(&(pConfig->lutSequences), sfdpTables); + if (dummy != 0U) + { + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_DUMMY, QSPI_IP_LUT_PADS_8, dummy)); + } + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ_DDR, QSPI_IP_LUT_PADS_8, 0x10)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + + /* Build LUT sequence for write status reg. */ + statusConfig->statusRegWriteLut = lutCount; + instruction = QSPI_IP_CMD_XSPI_WRITE_SR; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAddSrAddr(&(pConfig->lutSequences), sfdpTables); + /* Use SDR write because reg. size is 1 */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_WRITE, QSPI_IP_LUT_PADS_8, 0x2U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + + /* Build LUT sequence for write enable */ + statusConfig->writeEnableSRLut = lutCount; + statusConfig->writeEnableLut = lutCount; + instruction = QSPI_IP_CMD_XSPI_WRITE_ENABLE; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigReset1 + * Description : Configure reset settings - option 1. + */ +static void Qspi_Ip_SfdpConfigReset1(const Qspi_Ip_MemoryConfigType * pConfig, + const Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ) +{ + /* drive Fh on all 4 data wires for 8 clocks */ + /* Not implemented */ + (void)pConfig; + (void)resetSettings; + (void)pads; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigReset2 + * Description : Configure reset settings - option 2. + */ +static void Qspi_Ip_SfdpConfigReset2(const Qspi_Ip_MemoryConfigType * pConfig, + const Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ) +{ + /* drive Fh on all 4 data wires for 10 clocks if device is operating in 4-byte address mode */ + /* Not implemented */ + (void)pConfig; + (void)resetSettings; + (void)pads; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigReset4 + * Description : Configure reset settings - option 4. + */ +static void Qspi_Ip_SfdpConfigReset4(const Qspi_Ip_MemoryConfigType * pConfig, + const Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ) +{ + /* drive Fh on all 4 data wires for 16 clocks */ + /* Not implemented */ + (void)pConfig; + (void)resetSettings; + (void)pads; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigReset8 + * Description : Configure reset settings - option 8. + */ +static void Qspi_Ip_SfdpConfigReset8(const Qspi_Ip_MemoryConfigType * pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ) +{ + /* issue instruction F0h */ + resetSettings->resetCmdLut = lutCount; + resetSettings->resetCmdCount = 1U; + /* Build LUT sequence */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0xF0U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigReset16 + * Description : Configure reset settings - option 16. + */ +static void Qspi_Ip_SfdpConfigReset16(const Qspi_Ip_MemoryConfigType * pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ) +{ + /* issue reset enable instruction 66h, then issue reset instruction 99h. + The reset enable, reset sequence may be issued on 1, 2, 4, or 8 wires depending on the device operating mode. */ + resetSettings->resetCmdLut = lutCount; + resetSettings->resetCmdCount = 2U; + /* 1st LUT sequence - 0x66 */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0x66U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* 2nd LUT sequence - 0x99 */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, pads, 0x99U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigResetOthers + * Description : Configure reset settings for 1, 2, 4 wires + */ +static void Qspi_Ip_SfdpConfigResetOthers(uint8 resetOption, + const Qspi_Ip_MemoryConfigType * pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ) +{ + if ((resetOption & 0x1U) != 0U) + { + Qspi_Ip_SfdpConfigReset1(pConfig, resetSettings, pads); + /* drive Fh on all 4 data wires for 8 clocks */ + } + else if ((resetOption & 0x2U) != 0U) + { + Qspi_Ip_SfdpConfigReset2(pConfig, resetSettings, pads); + /* drive Fh on all 4 data wires for 10 clocks if device is operating in 4-byte address mode */ + } + else if ((resetOption & 0x4U) != 0U) + { + Qspi_Ip_SfdpConfigReset4(pConfig, resetSettings, pads); + /* drive Fh on all 4 data wires for 16 clocks */ + } + else + { + /* unknown reset sequence */ + resetSettings->resetCmdLut = QSPI_IP_LUT_INVALID; + resetSettings->resetCmdCount = 0U; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicResetInfo + * Description : Configure reset settings - XPI mode. + */ +static void Qspi_Ip_SfdpGetBasicResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + const Qspi_Ip_MemoryConfigType *pConfig, + Qspi_Ip_ResetConfigType *resetSettings, + Qspi_Ip_LutPadsType pads + ) +{ + uint8 resetOption; + + resetOption = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_SW_RESET_DWORD, + QSPI_IP_SFDP_BASIC_SW_RESET_SHIFT, QSPI_IP_SFDP_BASIC_SW_RESET_WIDTH, 0x0U); + if ((resetOption & 0x10U) != 0U) + { + /* issue reset enable instruction 66h, then issue reset instruction 99h. + The reset enable, reset sequence may be issued on 1, 2, 4, or 8 wires depending on the device operating mode. */ + Qspi_Ip_SfdpConfigReset16(pConfig, resetSettings, pads); + } + else if ((resetOption & 0x8U) != 0U) + { + Qspi_Ip_SfdpConfigReset8(pConfig, resetSettings, pads); + /* issue instruction F0h */ + } + else + { + Qspi_Ip_SfdpConfigResetOthers(resetOption, pConfig, resetSettings, pads); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1ResetInfo + * Description : Configure reset settings - XPI mode. + */ +static void Qspi_Ip_SfdpGetXspi1ResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 rSup; + uint8 rEnSup; + uint8 instruction; + uint8 cmdExt; + + pConfig->resetSettings.resetCmdLut = QSPI_IP_LUT_INVALID; + pConfig->resetSettings.resetCmdCount = 0U; + + rEnSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD, + QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH, 0x0U); + rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD, + QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH, 0x0U); + if ((rEnSup == 1U) && (rSup == 1U)) + { + /* 0x66, 0x99 reset sequence */ + pConfig->resetSettings.resetCmdLut = lutCount; + pConfig->resetSettings.resetCmdCount = 2U; + instruction = QSPI_IP_CMD_XSPI_RESET_ENABLE; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + + instruction = QSPI_IP_CMD_XSPI_RESET_DEF; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } + else + { + rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DWORD, + QSPI_IP_SFDP_XSPI1_RESET_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_WIDTH, 0x0U); + if (rSup == 1U) + { + /* 0xF0 reset command */ + pConfig->resetSettings.resetCmdLut = lutCount; + pConfig->resetSettings.resetCmdCount = 1U; + instruction = QSPI_IP_CMD_XSPI_RESET; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, instruction); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1InitResetInfo + * Description : Configure initial reset settings - XPI mode + */ +static void Qspi_Ip_SfdpGetXspi1InitResetInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 rSup; + uint8 rEnSup; + uint8 instruction; + + /* Set the default value to be disabled */ + pConfig->initResetSettings.resetCmdLut = QSPI_IP_LUT_INVALID; + pConfig->initResetSettings.resetCmdCount = 0U; + + rEnSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_EN_DWORD, + QSPI_IP_SFDP_XSPI1_RESET_EN_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_EN_WIDTH, 0x0U); + rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DEF_DWORD, + QSPI_IP_SFDP_XSPI1_RESET_DEF_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_DEF_WIDTH, 0x0U); + if ((rEnSup == 1U) && (rSup == 1U)) + { + /* 0x66, 0x99 reset sequence */ + pConfig->initResetSettings.resetCmdLut = lutCount; + pConfig->initResetSettings.resetCmdCount = 2U; + instruction = QSPI_IP_CMD_XSPI_RESET_ENABLE; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U)); + + instruction = QSPI_IP_CMD_XSPI_RESET_DEF; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U)); + } + else + { + rSup = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_XSPI1_RESET_DWORD, + QSPI_IP_SFDP_XSPI1_RESET_SHIFT, QSPI_IP_SFDP_XSPI1_RESET_WIDTH, 0x0U); + if (rSup == 1U) + { + /* 0xF0 reset command */ + pConfig->initResetSettings.resetCmdLut = lutCount; + pConfig->initResetSettings.resetCmdCount = 1U; + instruction = QSPI_IP_CMD_XSPI_RESET; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPadsInit, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, cmdPadsInit, 0x0U)); + } + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicSuspendInfo + * Description : Configure suspend settings - SPI mode + */ +static void Qspi_Ip_SfdpGetBasicSuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + uint8 esus; + uint8 eres; + uint8 psus; + uint8 pres; + + esus = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH, 0xB0U); + eres = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH, 0x30U); + psus = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH, 0xB0U); + pres = (uint8)Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH, 0x30U); + + /* Erase suspend sequence */ + pConfig->suspendSettings.eraseSuspendLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, esus)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* Erase resume sequence */ + pConfig->suspendSettings.eraseResumeLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, eres)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* Program suspend sequence */ + if (esus == psus) + { + pConfig->suspendSettings.programSuspendLut = pConfig->suspendSettings.eraseSuspendLut; + } + else + { + pConfig->suspendSettings.programSuspendLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, psus)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } + /* Program resume sequence */ + if (eres == pres) + { + pConfig->suspendSettings.programResumeLut = pConfig->suspendSettings.eraseResumeLut; + } + else + { + pConfig->suspendSettings.programResumeLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, cmdPads, pres)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1SuspendInfo + * Description : Configure suspend settings - XPI mode + */ +static void Qspi_Ip_SfdpGetXspi1SuspendInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 esus; + uint8 eres; + uint8 psus; + uint8 pres; + uint8 cmdExt; + + esus = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_ESUS_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_ESUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ESUS_INSTR_WIDTH, 0xB0U); + eres = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_ERES_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_ERES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_ERES_INSTR_WIDTH, 0x30U); + psus = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_PSUS_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_PSUS_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PSUS_INSTR_WIDTH, 0xB0U); + pres = (uint8)Qspi_Ip_SfdpGetXspi1Param(sfdpTables, QSPI_IP_SFDP_BASIC_PRES_INSTR_DWORD, + QSPI_IP_SFDP_BASIC_PRES_INSTR_SHIFT, QSPI_IP_SFDP_BASIC_PRES_INSTR_WIDTH, 0x30U); + + /* Erase suspend sequence */ + pConfig->suspendSettings.eraseSuspendLut = lutCount; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, esus); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, esus)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* Erase resume sequence */ + pConfig->suspendSettings.eraseResumeLut = lutCount; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, eres); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, eres)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* Program suspend sequence */ + if (esus == psus) + { + pConfig->suspendSettings.programSuspendLut = pConfig->suspendSettings.eraseSuspendLut; + } + else + { + pConfig->suspendSettings.programSuspendLut = lutCount; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, psus); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, psus)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } + /* Program resume sequence */ + if (eres == pres) + { + pConfig->suspendSettings.programResumeLut = pConfig->suspendSettings.eraseResumeLut; + } + else + { + pConfig->suspendSettings.programResumeLut = lutCount; + cmdExt = Qspi_Ip_SfdpGetCmdExt(sfdpTables, pres); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, pres)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD_DDR, QSPI_IP_LUT_PADS_8, cmdExt)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + } +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpAdd2dopiOperation + * Description : Add a DOPI switch command to the operation list + */ +static void Qspi_Ip_SfdpAdd2dopiOperation(const Qspi_Ip_MemoryConfigType *pConfig, + uint8 seqSize, + const uint32 *words + ) +{ + Qspi_Ip_InitOperationType *operation; + uint8 nextByte; + uint8 cnt; + + if (initOpCount >= pConfig->initConfiguration.opCount) + { + /* operations list not big enough */ + overflow = TRUE; + } + else + { + operation = &(pConfig->initConfiguration.operations[initOpCount]); + initOpCount++; + operation->opType = QSPI_IP_OP_TYPE_CMD; + operation->command1Lut = lutCount; + operation->addr = 0U; + /* Build LUT sequence for this command */ + for (cnt = 0U; cnt < seqSize; cnt++) + { + nextByte = (uint8)((words[dopiSwitchWord[cnt]] >> dopiSwitchShift[cnt]) & 0xFFU); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, nextByte)); + } + /* Add STOP instruction */ + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); + /* Other operation fields are unused */ + operation->command2Lut = QSPI_IP_LUT_INVALID; + operation->weLut = QSPI_IP_LUT_INVALID; + operation->size = 0U; + operation->shift = 0U; + operation->width = 0U; + operation->value = 0U; + operation->ctrlCfgPtr = NULL_PTR; + } + + return; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpAddCheckBusyOperation + * Description : Add a READ_REG operation to check the BUSY flag of the status register. + */ +static void Qspi_Ip_SfdpAddCheckBusyOperation(const Qspi_Ip_MemoryConfigType *pConfig) +{ + Qspi_Ip_InitOperationType *operation; + const Qspi_Ip_StatusConfigType *statusConfig; + + if (initOpCount >= pConfig->initConfiguration.opCount) + { + /* operations list not big enough */ + overflow = TRUE; + } + else + { + /* Build a read operation to check the BUSY flag of the status register */ + operation = &(pConfig->initConfiguration.operations[initOpCount]); + initOpCount++; + + /* Use the initial read status reg that was configured before */ + statusConfig = &(pConfig->statusConfig); + + operation->opType = QSPI_IP_OP_TYPE_READ_REG; + operation->command1Lut = statusConfig->statusRegInitReadLut; + operation->size = statusConfig->regSize; + operation->shift = statusConfig->busyOffset; + operation->value = 1U - (uint32)statusConfig->busyValue; /* Reverse: wait until not busy */ + operation->width = 1U; + + /* Other operation fields are unused */ + operation->command2Lut = QSPI_IP_LUT_INVALID; + operation->weLut = QSPI_IP_LUT_INVALID; + operation->addr = 0U; + operation->ctrlCfgPtr = NULL_PTR; + } +} + + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1InitOpInfo + * Description : Configure initial operations list - XPI mode + */ +static void Qspi_Ip_SfdpGetXspi1InitOpInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint8 cnt; + uint8 seqSize; + + if (sfdpTables->paramTableLength_2dopi > 0U) + { + for (cnt = 0U; cnt < (sfdpTables->paramTableLength_2dopi - 1U); cnt += 2U) + { + seqSize = (uint8)Qspi_Ip_SfdpGet2DopiParam(sfdpTables, cnt + 1U, + QSPI_IP_SFDP_2DOPI_CMD_LEN_SHIFT, QSPI_IP_SFDP_2DOPI_CMD_LEN_WIDTH, 0x0U); + if (seqSize == 0U) + { + /* No more commands */ + break; + } + /* Add a wait operation to ensure the previous command is completed, needed for write in a non-volatile register */ + Qspi_Ip_SfdpAddCheckBusyOperation(pConfig); + + Qspi_Ip_SfdpAdd2dopiOperation(pConfig, seqSize, &sfdpTables->paramTable_2dopi[cnt]); + } + } + /* Update operations count */ + pConfig->initConfiguration.opCount = initOpCount; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetBasicInitOpInfo + * Description : Configure initial operations list - XPI mode + */ +static void Qspi_Ip_SfdpGetBasicInitOpInfo(Qspi_Ip_MemoryConfigType * pConfig) +{ + /* Init operations already added, update operations count */ + pConfig->initConfiguration.opCount = initOpCount; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGet0xxInfo + * Description : Configure 0xx capabilities - XPI mode + */ +static void Qspi_Ip_SfdpGet0xxInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + /* Not implemented */ + (void)sfdpTables; + pConfig->read0xxLut = QSPI_IP_LUT_INVALID; + pConfig->read0xxLutAHB = QSPI_IP_LUT_INVALID; +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigureOther + * Description : Configure unsupported features + */ +static void Qspi_Ip_SfdpConfigureOther(Qspi_Ip_MemoryConfigType * pConfig) +{ + pConfig->readIdSettings.readIdLut = QSPI_IP_LUT_INVALID; + pConfig->initCallout = NULL_PTR; + pConfig->resetCallout = NULL_PTR; + pConfig->errorCheckCallout = NULL_PTR; + pConfig->ctrlAutoCfgPtr = NULL_PTR; +} + + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetSize + * Description : Builds configuration for octal DDR (DOPI) mode. + */ +static void Qspi_Ip_SfdpGetSize(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + uint32 size; + + /* Dword 2 of parameter table: Flash Memory Density */ + size = Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_MEM_SIZE_DWORD, + QSPI_IP_SFDP_BASIC_MEM_SIZE_SHIFT, QSPI_IP_SFDP_BASIC_MEM_SIZE_WIDTH, 0xFFFFFU); + /* check MSB */ + if ((size & 0x80000000U) == 0U) + { + pConfig->memSize = (size + 1U) >> 3U; + } + else + { + pConfig->memSize = ((uint32)1U << ((size & (~(uint32)0x80000000U)) - (uint32)3U)); + } + + /* Dword 11 of parameter table: Page Size */ + size = Qspi_Ip_SfdpGetBasicParam(sfdpTables, QSPI_IP_SFDP_BASIC_PAGE_SIZE_DWORD, + QSPI_IP_SFDP_BASIC_PAGE_SIZE_SHIFT, QSPI_IP_SFDP_BASIC_PAGE_SIZE_WIDTH, 8U); + pConfig->pageSize = ((uint32)1U << size); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_GetBasicInfo + * Description : Builds basic configurations + */ +static inline void Qspi_Ip_SfdpGetBasicInfo(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + /* Configure read command */ + Qspi_Ip_SfdpGetBasicReadInfo(sfdpTables, pConfig); + /* Configure write command */ + Qspi_Ip_SfdpGetBasicWriteInfo(sfdpTables, pConfig); + /* Configure erase commands */ + Qspi_Ip_SfdpGetBasicEraseInfo(sfdpTables, pConfig); + /* Configure status register */ + Qspi_Ip_SfdpGetBasicStatusInfo(sfdpTables, pConfig); + + /* Configure reset settings */ + Qspi_Ip_SfdpGetBasicResetInfo(sfdpTables, pConfig, &(pConfig->resetSettings), cmdPads); + /* Configure initial reset settings */ + Qspi_Ip_SfdpGetBasicResetInfo(sfdpTables, pConfig, &(pConfig->initResetSettings), cmdPadsInit); + + /* Configure suspend settings */ + Qspi_Ip_SfdpGetBasicSuspendInfo(sfdpTables, pConfig); + /* Configure initial operations list */ + Qspi_Ip_SfdpGetBasicInitOpInfo(pConfig); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigureInitReadStatus + * Description : Builds configuration for initial read status reg. + */ +static void Qspi_Ip_SfdpConfigureInitReadStatus(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig, + uint8 instruction + ) +{ + Qspi_Ip_StatusConfigType *statusConfig; + + statusConfig = &(pConfig->statusConfig); + + statusConfig->regSize = 1U; + statusConfig->blockProtectionOffset = 0U; + statusConfig->blockProtectionWidth = 0U; + statusConfig->blockProtectionValue = 0U; + statusConfig->busyOffset = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WIP_OFFSET_DWORD, + QSPI_IP_SFDP_SRMAP_WIP_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_WIP_OFFSET_WIDTH, 0x0U); + /* Busy bit meaning is reversed (0: Positive (WIP=1 means write is in progress); 1: Inverted (WIP=0 means write is in progress) */ + statusConfig->busyValue = (uint8)(1U - Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WIP_VALUE_DWORD, + QSPI_IP_SFDP_SRMAP_WIP_VALUE_SHIFT, QSPI_IP_SFDP_SRMAP_WIP_VALUE_WIDTH, 0x0U)); + statusConfig->writeEnableOffset = (uint8)Qspi_Ip_SfdpGetSRMapParam(sfdpTables, QSPI_IP_SFDP_SRMAP_WEL_OFFSET_DWORD, + QSPI_IP_SFDP_SRMAP_WEL_OFFSET_SHIFT, QSPI_IP_SFDP_SRMAP_WEL_OFFSET_WIDTH, 0x1U); + /* Build LUT sequence for initial read status reg. */ + statusConfig->statusRegInitReadLut = lutCount; + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, instruction)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_READ, QSPI_IP_LUT_PADS_1, 0x1U)); + Qspi_Ip_SfdpLutAdd(&(pConfig->lutSequences), Qspi_Ip_PackLut(QSPI_IP_LUT_INSTR_STOP, QSPI_IP_LUT_PADS_1, 0x0U)); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureBasic + * Description : Builds configuration for octal DDR (DOPI) mode. + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureBasic(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Get size, page size */ + Qspi_Ip_SfdpGetSize(sfdpTables, pConfig); + /* Get addres size for read/write commands */ + Qspi_Ip_SfdpGetBasicAddrBits(sfdpTables, pConfig); + + /* Configure initial read status register */ + Qspi_Ip_SfdpConfigureInitReadStatus(sfdpTables, pConfig, QSPI_IP_CMD_BASIC_READ_SR); + + /* Check QE bit */ + Qspi_Ip_SfdpConfigureQE(sfdpTables, pConfig); + + /* Get basic info: read, write, erase, reset, suspend */ + Qspi_Ip_SfdpGetBasicInfo(sfdpTables, pConfig); + + /* Configure 0xx capabilities */ + Qspi_Ip_SfdpGet0xxInfo(sfdpTables, pConfig); + /* Configure unsupported features */ + Qspi_Ip_SfdpConfigureOther(pConfig); + + /* Check for LUT or Init operations overflow */ + if (overflow == TRUE) + { + status = STATUS_QSPI_IP_ERROR; + } + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1ResetConfig + * Description : Builds Xspi1 configure reset settings and initial reset settings. + */ +static void Qspi_Ip_SfdpGetXspi1ResetConfig(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + /* Configure reset settings */ + Qspi_Ip_SfdpGetXspi1ResetInfo(sfdpTables, pConfig); + /* Configure initial reset settings */ + Qspi_Ip_SfdpGetXspi1InitResetInfo(sfdpTables, pConfig); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpGetXspi1Info + * Description : Builds Xspi1 configurations. + */ +static inline void Qspi_Ip_SfdpGetXspi1Info(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType * pConfig + ) +{ + /* Configure read command */ + Qspi_Ip_SfdpGetXspi1ReadInfo(sfdpTables, pConfig); + /* Configure write command */ + Qspi_Ip_SfdpGetXspi1WriteInfo(sfdpTables, pConfig); + /* Configure erase commands */ + Qspi_Ip_SfdpGetXspi1EraseInfo(sfdpTables, pConfig); + /* Configure status register */ + Qspi_Ip_SfdpGetXspi1StatusInfo(sfdpTables, pConfig); + + /* Configure reset settings and initial reset settings */ + Qspi_Ip_SfdpGetXspi1ResetConfig(sfdpTables, pConfig); + /* Configure suspend settings */ + Qspi_Ip_SfdpGetXspi1SuspendInfo(sfdpTables, pConfig); + /* Configure initial operations list */ + Qspi_Ip_SfdpGetXspi1InitOpInfo(sfdpTables, pConfig); +} + + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ConfigureXspi1 + * Description : Builds octal DDR (DOPI) configuration for xSPI 1.0 devices. + */ +static Qspi_Ip_StatusType Qspi_Ip_ConfigureXspi1(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + + /* Get size, page size */ + Qspi_Ip_SfdpGetSize(sfdpTables, pConfig); + + /* Configure initial read status register */ + Qspi_Ip_SfdpConfigureInitReadStatus(sfdpTables, pConfig, QSPI_IP_CMD_XSPI_READ_SR); + + /* Get Xspi1 info: read, write, erase, reset, suspend */ + Qspi_Ip_SfdpGetXspi1Info(sfdpTables, pConfig); + + /* Configure 0xx capabilities */ + Qspi_Ip_SfdpGet0xxInfo(sfdpTables, pConfig); + /* Configure unsupported features */ + Qspi_Ip_SfdpConfigureOther(pConfig); + + /* Check for LUT or Init operations overflow */ + if (overflow == TRUE) + { + status = STATUS_QSPI_IP_ERROR; + } + return status; +} + + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_SfdpConfigure + * Description : Check xSPI 1.0 support + */ +static Qspi_Ip_StatusType Qspi_Ip_SfdpConfigure(const Qspi_Ip_SfdpTablesContainer *sfdpTables, + Qspi_Ip_MemoryConfigType *pConfig + ) +{ + Qspi_Ip_StatusType status; + if (sfdpTables->paramTableLength_xspi1 > 0U) + { + status = Qspi_Ip_ConfigureXspi1(sfdpTables, pConfig); + } + else + { + status = Qspi_Ip_ConfigureBasic(sfdpTables, pConfig); + } + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : Qspi_Ip_ReadSfdp + * Description : Auto-fills configuration from SFDP information +* @implements Qspi_Ip_ReadSfdp_Activity */ +Qspi_Ip_StatusType Qspi_Ip_ReadSfdp(Qspi_Ip_MemoryConfigType * pConfig, + const Qspi_Ip_MemoryConnectionType * pConnect + ) +{ + Qspi_Ip_StatusType status = STATUS_QSPI_IP_SUCCESS; + uint32 baseAddress; + /* SFDP Tables */ + Qspi_Ip_SfdpTablesContainer sfdpTables; + +#if (QSPI_IP_DEV_ERROR_DETECT == STD_ON) + /* Check for valid parameters */ + DEV_ASSERT_QSPI(pConnect != NULL_PTR); + DEV_ASSERT_QSPI(pConfig != NULL_PTR); + DEV_ASSERT_QSPI((pConfig->lutSequences.lutOps != NULL_PTR) && (pConfig->lutSequences.opCount > 0U)); +#endif + + /* Get device base address */ + baseAddress = Qspi_Ip_GetBaseAdress(pConnect->qspiInstance, pConnect->connectionType); + /* Initiate communication with flash, check SFDP support */ + status = Qspi_Ip_SfdpCheck(pConnect->qspiInstance, baseAddress); + if (status != STATUS_QSPI_IP_SUCCESS) + { + /* direct command - nothing to do */ + } + else + { + /* Read SFDP tables of interest */ + status = Qspi_Ip_SfdpReadTables(pConnect->qspiInstance, baseAddress, &sfdpTables); + if (status != STATUS_QSPI_IP_SUCCESS) + { + /* direct command - nothing to do */ + } + else + { + /* Initialize LUT and init operations count */ + Qspi_Ip_SfdpLutInit(); + /* Build the enter legacy XPI protocol initial operation */ + Qspi_Ip_SfdpLutInitEnterLegacySPI(pConfig); + /* Check xSPI 1.0 support */ + status = Qspi_Ip_SfdpConfigure(&sfdpTables, pConfig); + } + } + + return status; +} + + + +#define MEM_43_EXFLS_STOP_SEC_CODE +#include "Mem_43_EXFLS_MemMap.h" + +#endif /* (QSPI_IP_MEM_INSTANCE_COUNT > 0) */ + + +#ifdef __cplusplus +} +#endif + +/** @} */ + diff --git a/s32/drivers/s32ze/Rte/CMakeLists.txt b/s32/drivers/s32ze/Rte/CMakeLists.txt index 7ed99c705..c6aad44ae 100644 --- a/s32/drivers/s32ze/Rte/CMakeLists.txt +++ b/s32/drivers/s32ze/Rte/CMakeLists.txt @@ -10,3 +10,4 @@ zephyr_library_sources_ifdef(CONFIG_UART_NXP_S32_LINFLEXD src/SchM_Uart.c) zephyr_library_sources_ifdef(CONFIG_CAN_NXP_S32_CANXL src/SchM_Can_43_CANEXCEL.c) zephyr_library_sources_ifdef(CONFIG_ETH_NXP_S32_NETC src/SchM_Eth_43_NETC.c) zephyr_library_sources_ifdef(CONFIG_ETH_NXP_S32_NETC src/SchM_EthSwt_43_NETC.c) +zephyr_library_sources_ifdef(CONFIG_MEMC_NXP_S32_QSPI src/SchM_Mem_43_EXFLS.c) diff --git a/s32/drivers/s32ze/Rte/include/SchM_Mem_43_EXFLS.h b/s32/drivers/s32ze/Rte/include/SchM_Mem_43_EXFLS.h new file mode 100644 index 000000000..e3e8d6d36 --- /dev/null +++ b/s32/drivers/s32ze/Rte/include/SchM_Mem_43_EXFLS.h @@ -0,0 +1,120 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** +* @file SchM_Mem_43_EXFLS.h +* @version 2.0.0 +* +* @brief AUTOSAR Rte - module interface +* @details This file contains the functions prototypes and data types of the AUTOSAR Rte. +* This file contains sample code only. It is not part of the production code deliverables. +* +* @addtogroup RTE_MODULE +* @{ +*/ + +#ifndef SCHM_MEM_43_EXFLS_H +#define SCHM_MEM_43_EXFLS_H + +#ifdef __cplusplus +extern "C" { +#endif +/*================================================================================================== +* INCLUDE FILES +* 1) system and project includes +* 2) needed interfaces from external units +* 3) internal and external interfaces from this unit +==================================================================================================*/ + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define SCHM_MEM_43_EXFLS_AR_RELEASE_MAJOR_VERSION 4 +#define SCHM_MEM_43_EXFLS_AR_RELEASE_MINOR_VERSION 7 +#define SCHM_MEM_43_EXFLS_AR_RELEASE_REVISION_VERSION 0 +#define SCHM_MEM_43_EXFLS_SW_MAJOR_VERSION 2 +#define SCHM_MEM_43_EXFLS_SW_MINOR_VERSION 0 +#define SCHM_MEM_43_EXFLS_SW_PATCH_VERSION 0 + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ + + +/*================================================================================================== +* CONSTANTS +==================================================================================================*/ + +/*================================================================================================== +* DEFINES AND MACROS +==================================================================================================*/ +#define NUMBER_OF_CORES (uint8)(14U) + +/*================================================================================================== +* ENUMS +==================================================================================================*/ + +/*================================================================================================== +* STRUCTURES AND OTHER TYPEDEFS +==================================================================================================*/ + +/*================================================================================================== +* GLOBAL VARIABLE DECLARATIONS +==================================================================================================*/ + +/*================================================================================================== +* FUNCTION PROTOTYPES +==================================================================================================*/ +#define RTE_START_SEC_CODE +#include "Rte_MemMap.h" + +#ifdef MCAL_TESTING_ENVIRONMENT +/** +@brief This function checks that all entered exclusive areas were also exited. +@details This function checks that all entered exclusive areas were also exited. The check + is done by verifying that all reentry_guard_* static variables are back to the + zero value. + +@param[in] void No input parameters +@return void This function does not return a value. Test asserts are used instead. + +@pre None +@post None + +@remarks Covers +@remarks Implements +*/ +void SchM_Check_mem_43_exfls(void); +#endif /*MCAL_TESTING_ENVIRONMENT*/ + +extern void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_10(void); +extern void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_10(void); + +extern void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_11(void); +extern void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_11(void); + +extern void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_12(void); +extern void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_12(void); + +extern void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_13(void); +extern void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_13(void); + +extern void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_14(void); +extern void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_14(void); + + +void Mem_43_EXFLS_MainFunction(void); + +#define RTE_STOP_SEC_CODE +#include "Rte_MemMap.h" + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* SCHM_MEM_43_EXFLS_H */ diff --git a/s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c b/s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c new file mode 100644 index 000000000..061cc5a33 --- /dev/null +++ b/s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c @@ -0,0 +1,609 @@ +/* + * Copyright 2021-2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** +* @file SchM_Mem_43_EXFLS.c +* @version 2.0.0 +* +* @brief AUTOSAR Rte - module implementation +* @details This module implements stubs for the AUTOSAR Rte +* This file contains sample code only. It is not part of the production code deliverables. +* +* @addtogroup RTE_MODULE +* @{ +*/ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*================================================================================================== +* INCLUDE FILES +* 1) system and project includes +* 2) needed interfaces from external units +* 3) internal and external interfaces from this unit +==================================================================================================*/ +#include "Std_Types.h" +#include "Mcal.h" +#include "OsIf.h" +#include "SchM_Mem_43_EXFLS.h" +#ifdef MCAL_TESTING_ENVIRONMENT +#include "EUnit.h" /* EUnit Test Suite */ +#endif + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define SCHM_MEM_43_EXFLS_AR_RELEASE_MAJOR_VERSION_C 4 +#define SCHM_MEM_43_EXFLS_AR_RELEASE_MINOR_VERSION_C 7 +#define SCHM_MEM_43_EXFLS_AR_RELEASE_REVISION_VERSION_C 0 +#define SCHM_MEM_43_EXFLS_SW_MAJOR_VERSION_C 2 +#define SCHM_MEM_43_EXFLS_SW_MINOR_VERSION_C 0 +#define SCHM_MEM_43_EXFLS_SW_PATCH_VERSION_C 0 + +/*================================================================================================== +* LOCAL CONSTANTS +==================================================================================================*/ +#ifdef MCAL_PLATFORM_ARM + #if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64) + #define ISR_STATE_MASK ((uint32)0x000000C0UL) /**< @brief DAIF bit I and F */ + #elif (MCAL_PLATFORM_ARM == MCAL_ARM_RARCH) + #define ISR_STATE_MASK ((uint32)0x00000080UL) /**< @brief CPSR bit I */ + #else + #if ((defined MCAL_ENABLE_USER_MODE_SUPPORT)&&(!defined MCAL_PLATFORM_ARM_M0PLUS)) + #define ISR_STATE_MASK ((uint32)0x000000FFUL) /**< @brief BASEPRI[7:0] mask */ + #else + #define ISR_STATE_MASK ((uint32)0x00000001UL) /**< @brief PRIMASK bit 0 */ + #endif + #endif +#else + #ifdef MCAL_PLATFORM_S12 + #define ISR_STATE_MASK ((uint32)0x00000010UL) /**< @brief I bit of CCR */ + #else + #define ISR_STATE_MASK ((uint32)0x00008000UL) /**< @brief EE bit of MSR */ + #endif +#endif +/*================================================================================================== +* LOCAL MACROS +==================================================================================================*/ +#ifdef MCAL_PLATFORM_ARM + #if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64) + #define ISR_ON(msr) (uint32)(((uint32)(msr) & (uint32)(ISR_STATE_MASK)) != (uint32)(ISR_STATE_MASK)) + #elif (MCAL_PLATFORM_ARM == MCAL_ARM_RARCH) + #define ISR_ON(msr) (uint32)(((uint32)(msr) & (uint32)(ISR_STATE_MASK)) != (uint32)(ISR_STATE_MASK)) + #else + #define ISR_ON(msr) (uint32)(((uint32)(msr) & (uint32)(ISR_STATE_MASK)) == (uint32)0) + #endif +#else + #ifdef MCAL_PLATFORM_S12 + #define ISR_ON(msr) (uint32)(((uint32)(msr) & (uint32)(ISR_STATE_MASK)) == (uint32)0) + #else + #define ISR_ON(msr) (uint32)((uint32)(msr) & (uint32)(ISR_STATE_MASK)) + #endif +#endif + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ + +/*================================================================================================== +* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) +==================================================================================================*/ + + +/*================================================================================================== +* LOCAL VARIABLES +==================================================================================================*/ +#define RTE_START_SEC_VAR_CLEARED_32_NO_CACHEABLE +#include "Rte_MemMap.h" +static volatile uint32 msr_MEM_EXCLUSIVE_AREA_10[NUMBER_OF_CORES]; +static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_10[NUMBER_OF_CORES]; +static volatile uint32 msr_MEM_EXCLUSIVE_AREA_11[NUMBER_OF_CORES]; +static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_11[NUMBER_OF_CORES]; +static volatile uint32 msr_MEM_EXCLUSIVE_AREA_12[NUMBER_OF_CORES]; +static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_12[NUMBER_OF_CORES]; +static volatile uint32 msr_MEM_EXCLUSIVE_AREA_13[NUMBER_OF_CORES]; +static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_13[NUMBER_OF_CORES]; +static volatile uint32 msr_MEM_EXCLUSIVE_AREA_14[NUMBER_OF_CORES]; +static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_14[NUMBER_OF_CORES]; + +#define RTE_STOP_SEC_VAR_CLEARED_32_NO_CACHEABLE +#include "Rte_MemMap.h" +/*================================================================================================== +* GLOBAL CONSTANTS +==================================================================================================*/ + + +/*================================================================================================== +* GLOBAL VARIABLES +==================================================================================================*/ + +/*================================================================================================== +* LOCAL FUNCTION PROTOTYPES +==================================================================================================*/ + +#ifndef _COSMIC_C_S32ZE_ +/*================================================================================================*/ +/** +* @brief This function returns the MSR register value (32 bits). +* @details This function returns the MSR register value (32 bits). +* +* @param[in] void No input parameters +* @return uint32 msr This function returns the MSR register value (32 bits). +* +* @pre None +* @post None +* +*/ +uint32 Mem_43_EXFLS_schm_read_msr(void); +#endif /*ifndef _COSMIC_C_S32ZE_*/ +/*================================================================================================== +* LOCAL FUNCTIONS +==================================================================================================*/ +#define RTE_START_SEC_CODE +#include "Rte_MemMap.h" + +#if (defined(_GREENHILLS_C_S32ZE_) || defined(_CODEWARRIOR_C_S32ZE_)) +/*================================================================================================*/ +/** +* @brief This macro returns the MSR register value (32 bits). +* @details This macro function implementation returns the MSR register value in r3 (32 bits). +* +* @pre None +* @post None +* +*/ +#ifdef MCAL_PLATFORM_ARM +#if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64) +ASM_KEYWORD uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + mrs x0, S3_3_c4_c2_1 +} +#elif (MCAL_PLATFORM_ARM == MCAL_ARM_RARCH) +ASM_KEYWORD uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + mrs r0, CPSR +} +#else +ASM_KEYWORD uint32 Mem_43_EXFLS_schm_read_msr(void) +{ +#if ((defined MCAL_ENABLE_USER_MODE_SUPPORT)&&(!defined MCAL_PLATFORM_ARM_M0PLUS)) + mrs r0, BASEPRI +#else + mrs r0, PRIMASK +#endif +} +#endif +#else +#ifdef MCAL_PLATFORM_S12 +ASM_KEYWORD uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + tfr ccr, d6 +} +#else +ASM_KEYWORD uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + mfmsr r3 +} +#endif +#endif +#endif /*#ifdef GHS||CW*/ + +#ifdef _DIABDATA_C_S32ZE_ +/** +* @brief This function returns the MSR register value (32 bits). +* @details This function returns the MSR register value (32 bits). +* +* @param[in] void No input parameters +* @return uint32 msr This function returns the MSR register value (32 bits). +* +* @pre None +* @post None +* +*/ +#ifdef MCAL_PLATFORM_ARM +uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + register uint32 reg_tmp; + #if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64) + __asm volatile( " mrs %x0, DAIF " : "=r" (reg_tmp) ); + #elif (MCAL_PLATFORM_ARM == MCAL_ARM_RARCH) + __asm volatile( " mrs %0, CPSR " : "=r" (reg_tmp) ); + #else + #if ((defined MCAL_ENABLE_USER_MODE_SUPPORT)&&(!defined MCAL_PLATFORM_ARM_M0PLUS)) + __asm volatile( " mrs %0, basepri " : "=r" (reg_tmp) ); + #else + __asm volatile( " mrs %0, primask " : "=r" (reg_tmp) ); + #endif + #endif + return (uint32)reg_tmp; +} +#else +ASM_KEYWORD uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + mfmsr r3 +} +#endif /* MCAL_PLATFORM_ARM */ + +#endif /* _DIABDATA_C_S32ZE_*/ + +#ifdef _COSMIC_C_S32ZE_ +/*================================================================================================*/ +/** +* @brief This function returns the MSR register value (32 bits). +* @details This function returns the MSR register value (32 bits). +* +* @param[in] void No input parameters +* @return uint32 msr This function returns the MSR register value (32 bits). +* +* @pre None +* @post None +* +*/ + +#ifdef MCAL_PLATFORM_S12 + #define Mem_43_EXFLS_schm_read_msr() ASM_KEYWORD("tfr ccr, d6") +#else + #define Mem_43_EXFLS_schm_read_msr() ASM_KEYWORD("mfmsr r3") +#endif + +#endif /*Cosmic compiler only*/ + + +#ifdef _HITECH_C_S32ZE_ +/*================================================================================================*/ +/** +* @brief This function returns the MSR register value (32 bits). +* @details This function returns the MSR register value (32 bits). +* +* @param[in] void No input parameters +* @return uint32 msr This function returns the MSR register value (32 bits). +* +* @pre None +* @post None +* +*/ +uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + uint32 result; + __asm volatile("mfmsr %0" : "=r" (result) :); + return result; +} + +#endif /*HighTec compiler only*/ + /*================================================================================================*/ +#ifdef _GCC_C_S32ZE_ +/** +* @brief This function returns the MSR register value (32 bits). +* @details This function returns the MSR register value (32 bits). +* +* @param[in] void No input parameters +* @return uint32 msr This function returns the MSR register value (32 bits). +* +* @pre None +* @post None +* +*/ +uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + register uint32 reg_tmp; + #if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64) + __asm volatile( " mrs %x0, DAIF " : "=r" (reg_tmp) ); + #elif (MCAL_PLATFORM_ARM == MCAL_ARM_RARCH) + __asm volatile( " mrs %0, CPSR " : "=r" (reg_tmp) ); + #else + #if ((defined MCAL_ENABLE_USER_MODE_SUPPORT)&&(!defined MCAL_PLATFORM_ARM_M0PLUS)) + __asm volatile( " mrs %0, basepri " : "=r" (reg_tmp) ); + #else + __asm volatile( " mrs %0, primask " : "=r" (reg_tmp) ); + #endif + #endif + return (uint32)reg_tmp; +} +#endif /* _GCC_C_S32ZE_*/ +/*================================================================================================*/ + +#ifdef _ARM_DS5_C_S32ZE_ +/** +* @brief This function returns the MSR register value (32 bits). +* @details This function returns the MSR register value (32 bits). +* +* @param[in] void No input parameters +* @return uint32 msr This function returns the MSR register value (32 bits). +* +* @pre None +* @post None +* +*/ +uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + register uint32 reg_tmp; + #if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64) + __asm volatile( " mrs %x0, DAIF " : "=r" (reg_tmp) ); + #elif (MCAL_PLATFORM_ARM == MCAL_ARM_RARCH) + __asm volatile( " mrs %0, CPSR " : "=r" (reg_tmp) ); + #else + #if ((defined MCAL_ENABLE_USER_MODE_SUPPORT)&&(!defined MCAL_PLATFORM_ARM_M0PLUS)) + __asm volatile( " mrs %0, basepri " : "=r" (reg_tmp) ); + #else + __asm volatile( " mrs %0, primask " : "=r" (reg_tmp) ); + #endif + #endif + return (uint32)reg_tmp; +} +#endif /* _ARM_DS5_C_S32ZE_ */ + +#ifdef _IAR_C_S32ZE_ +/** +* @brief This function returns the MSR register value (32 bits). +* @details This function returns the MSR register value (32 bits). +* +* @param[in] void No input parameters +* @return uint32 msr This function returns the MSR register value (32 bits). +* +* @pre None +* @post None +* +*/ +uint32 Mem_43_EXFLS_schm_read_msr(void) +{ + register uint32 reg_tmp; + +#if ((defined MCAL_ENABLE_USER_MODE_SUPPORT)&&(!defined MCAL_PLATFORM_ARM_M0PLUS)) + __asm volatile( " mrs %0, basepri " : "=r" (reg_tmp) ); +#else + __asm volatile( " mrs %0, primask " : "=r" (reg_tmp) ); +#endif + + return (uint32)reg_tmp; +} +#endif /* _IAR_C_S32ZE_ */ + +#define RTE_STOP_SEC_CODE +#include "Rte_MemMap.h" + +/*================================================================================================== +* GLOBAL FUNCTIONS +==================================================================================================*/ +#define RTE_START_SEC_CODE +#include "Rte_MemMap.h" + +void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_10(void) +{ + uint32 msr; + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + if(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_10[u32CoreId]) + { +#if (defined MCAL_ENABLE_USER_MODE_SUPPORT) + msr = OsIf_Trusted_Call_Return(Mem_43_EXFLS_schm_read_msr); +#else + msr = Mem_43_EXFLS_schm_read_msr(); /*read MSR (to store interrupts state)*/ +#endif /* MCAL_ENABLE_USER_MODE_SUPPORT */ + if (ISR_ON(msr)) /*if MSR[EE] = 0, skip calling Suspend/Resume AllInterrupts*/ + { + OsIf_SuspendAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } + msr_MEM_EXCLUSIVE_AREA_10[u32CoreId] = msr; + } + reentry_guard_MEM_EXCLUSIVE_AREA_10[u32CoreId]++; +} + +void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_10(void) +{ + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + reentry_guard_MEM_EXCLUSIVE_AREA_10[u32CoreId]--; + if ((ISR_ON(msr_MEM_EXCLUSIVE_AREA_10[u32CoreId]))&&(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_10[u32CoreId])) /*if interrupts were enabled*/ + { + OsIf_ResumeAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } +} + +void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_11(void) +{ + uint32 msr; + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + if(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_11[u32CoreId]) + { +#if (defined MCAL_ENABLE_USER_MODE_SUPPORT) + msr = OsIf_Trusted_Call_Return(Mem_43_EXFLS_schm_read_msr); +#else + msr = Mem_43_EXFLS_schm_read_msr(); /*read MSR (to store interrupts state)*/ +#endif /* MCAL_ENABLE_USER_MODE_SUPPORT */ + if (ISR_ON(msr)) /*if MSR[EE] = 0, skip calling Suspend/Resume AllInterrupts*/ + { + OsIf_SuspendAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } + msr_MEM_EXCLUSIVE_AREA_11[u32CoreId] = msr; + } + reentry_guard_MEM_EXCLUSIVE_AREA_11[u32CoreId]++; +} + +void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_11(void) +{ + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + reentry_guard_MEM_EXCLUSIVE_AREA_11[u32CoreId]--; + if ((ISR_ON(msr_MEM_EXCLUSIVE_AREA_11[u32CoreId]))&&(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_11[u32CoreId])) /*if interrupts were enabled*/ + { + OsIf_ResumeAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } +} + +void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_12(void) +{ + uint32 msr; + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + if(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_12[u32CoreId]) + { +#if (defined MCAL_ENABLE_USER_MODE_SUPPORT) + msr = OsIf_Trusted_Call_Return(Mem_43_EXFLS_schm_read_msr); +#else + msr = Mem_43_EXFLS_schm_read_msr(); /*read MSR (to store interrupts state)*/ +#endif /* MCAL_ENABLE_USER_MODE_SUPPORT */ + if (ISR_ON(msr)) /*if MSR[EE] = 0, skip calling Suspend/Resume AllInterrupts*/ + { + OsIf_SuspendAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } + msr_MEM_EXCLUSIVE_AREA_12[u32CoreId] = msr; + } + reentry_guard_MEM_EXCLUSIVE_AREA_12[u32CoreId]++; +} + +void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_12(void) +{ + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + reentry_guard_MEM_EXCLUSIVE_AREA_12[u32CoreId]--; + if ((ISR_ON(msr_MEM_EXCLUSIVE_AREA_12[u32CoreId]))&&(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_12[u32CoreId])) /*if interrupts were enabled*/ + { + OsIf_ResumeAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } +} + +void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_13(void) +{ + uint32 msr; + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + if(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_13[u32CoreId]) + { +#if (defined MCAL_ENABLE_USER_MODE_SUPPORT) + msr = OsIf_Trusted_Call_Return(Mem_43_EXFLS_schm_read_msr); +#else + msr = Mem_43_EXFLS_schm_read_msr(); /*read MSR (to store interrupts state)*/ +#endif /* MCAL_ENABLE_USER_MODE_SUPPORT */ + if (ISR_ON(msr)) /*if MSR[EE] = 0, skip calling Suspend/Resume AllInterrupts*/ + { + OsIf_SuspendAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } + msr_MEM_EXCLUSIVE_AREA_13[u32CoreId] = msr; + } + reentry_guard_MEM_EXCLUSIVE_AREA_13[u32CoreId]++; +} + +void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_13(void) +{ + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + reentry_guard_MEM_EXCLUSIVE_AREA_13[u32CoreId]--; + if ((ISR_ON(msr_MEM_EXCLUSIVE_AREA_13[u32CoreId]))&&(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_13[u32CoreId])) /*if interrupts were enabled*/ + { + OsIf_ResumeAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } +} + +void SchM_Enter_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_14(void) +{ + uint32 msr; + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + if(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_14[u32CoreId]) + { +#if (defined MCAL_ENABLE_USER_MODE_SUPPORT) + msr = OsIf_Trusted_Call_Return(Mem_43_EXFLS_schm_read_msr); +#else + msr = Mem_43_EXFLS_schm_read_msr(); /*read MSR (to store interrupts state)*/ +#endif /* MCAL_ENABLE_USER_MODE_SUPPORT */ + if (ISR_ON(msr)) /*if MSR[EE] = 0, skip calling Suspend/Resume AllInterrupts*/ + { + OsIf_SuspendAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } + msr_MEM_EXCLUSIVE_AREA_14[u32CoreId] = msr; + } + reentry_guard_MEM_EXCLUSIVE_AREA_14[u32CoreId]++; +} + +void SchM_Exit_Mem_43_EXFLS_MEM_EXCLUSIVE_AREA_14(void) +{ + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + reentry_guard_MEM_EXCLUSIVE_AREA_14[u32CoreId]--; + if ((ISR_ON(msr_MEM_EXCLUSIVE_AREA_14[u32CoreId]))&&(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_14[u32CoreId])) /*if interrupts were enabled*/ + { + OsIf_ResumeAllInterrupts(); +#ifdef _ARM_DS5_C_S32ZE_ + ASM_KEYWORD(" nop ");/* Compiler fix - forces the CSPID instruction to be generated with -02, -Ospace are selected*/ +#endif + } +} + + +#ifdef MCAL_TESTING_ENVIRONMENT +/** +@brief This function checks that all entered exclusive areas were also exited. +@details This function checks that all entered exclusive areas were also exited. The check + is done by verifying that all reentry_guard_* static variables are back to the + zero value. + +@param[in] void No input parameters +@return void This function does not return a value. Test asserts are used instead. + +@pre None +@post None + +@remarks Covers +@remarks Implements +*/ +void SchM_Check_mem_43_exfls(void) +{ + uint32 u32CoreId = (uint32)OsIf_GetCoreID(); + + EU_ASSERT(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_10[u32CoreId]); + reentry_guard_MEM_EXCLUSIVE_AREA_10[u32CoreId] = 0UL; /*reset reentry_guard_MEM_EXCLUSIVE_AREA_10 for the next test in the suite*/ + + EU_ASSERT(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_11[u32CoreId]); + reentry_guard_MEM_EXCLUSIVE_AREA_11[u32CoreId] = 0UL; /*reset reentry_guard_MEM_EXCLUSIVE_AREA_11 for the next test in the suite*/ + + EU_ASSERT(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_12[u32CoreId]); + reentry_guard_MEM_EXCLUSIVE_AREA_12[u32CoreId] = 0UL; /*reset reentry_guard_MEM_EXCLUSIVE_AREA_12 for the next test in the suite*/ + + EU_ASSERT(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_13[u32CoreId]); + reentry_guard_MEM_EXCLUSIVE_AREA_13[u32CoreId] = 0UL; /*reset reentry_guard_MEM_EXCLUSIVE_AREA_13 for the next test in the suite*/ + + EU_ASSERT(0UL == reentry_guard_MEM_EXCLUSIVE_AREA_14[u32CoreId]); + reentry_guard_MEM_EXCLUSIVE_AREA_14[u32CoreId] = 0UL; /*reset reentry_guard_MEM_EXCLUSIVE_AREA_14 for the next test in the suite*/ +} +#endif /*MCAL_TESTING_ENVIRONMENT*/ + +#define RTE_STOP_SEC_CODE +#include "Rte_MemMap.h" + +#ifdef __cplusplus +} +#endif + +/** @} */ From 8f36ba022d1bbb73eea3e80b1ce5c6385ba15ad1 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Mon, 12 Aug 2024 14:07:49 +0700 Subject: [PATCH 2/5] s32: drivers: s32ze: mem_exfls: patch for nocache section Use zephyr .nocache section for non-cacheable variables. Signed-off-by: Cong Nguyen Huu --- s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c | 2 +- s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c index 5672cc49d..5b78266b8 100644 --- a/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c +++ b/s32/drivers/s32ze/Mem_EXFLS/src/Qspi_Ip.c @@ -144,7 +144,7 @@ extern "C"{ #include "Mem_43_EXFLS_MemMap.h" /* Pointer to runtime state structures */ -Qspi_Ip_StateType Qspi_Ip_MemoryStateStructure[QSPI_IP_MEM_INSTANCE_COUNT]; +VAR_SEC_NOCACHE(Qspi_Ip_MemoryStateStructure) Qspi_Ip_StateType Qspi_Ip_MemoryStateStructure[QSPI_IP_MEM_INSTANCE_COUNT]; #if( QSPI_IP_MULTICORE_ENABLED == STD_ON) #define MEM_43_EXFLS_STOP_SEC_VAR_SHARED_CLEARED_UNSPECIFIED_NO_CACHEABLE diff --git a/s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c b/s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c index 061cc5a33..73bfbeef9 100644 --- a/s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c +++ b/s32/drivers/s32ze/Rte/src/SchM_Mem_43_EXFLS.c @@ -99,16 +99,16 @@ extern "C"{ ==================================================================================================*/ #define RTE_START_SEC_VAR_CLEARED_32_NO_CACHEABLE #include "Rte_MemMap.h" -static volatile uint32 msr_MEM_EXCLUSIVE_AREA_10[NUMBER_OF_CORES]; -static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_10[NUMBER_OF_CORES]; -static volatile uint32 msr_MEM_EXCLUSIVE_AREA_11[NUMBER_OF_CORES]; -static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_11[NUMBER_OF_CORES]; -static volatile uint32 msr_MEM_EXCLUSIVE_AREA_12[NUMBER_OF_CORES]; -static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_12[NUMBER_OF_CORES]; -static volatile uint32 msr_MEM_EXCLUSIVE_AREA_13[NUMBER_OF_CORES]; -static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_13[NUMBER_OF_CORES]; -static volatile uint32 msr_MEM_EXCLUSIVE_AREA_14[NUMBER_OF_CORES]; -static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_14[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(msr_MEM_EXCLUSIVE_AREA_10) static volatile uint32 msr_MEM_EXCLUSIVE_AREA_10[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(reentry_guard_MEM_EXCLUSIVE_AREA_10) static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_10[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(msr_MEM_EXCLUSIVE_AREA_11) static volatile uint32 msr_MEM_EXCLUSIVE_AREA_11[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(reentry_guard_MEM_EXCLUSIVE_AREA_11) static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_11[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(msr_MEM_EXCLUSIVE_AREA_12) static volatile uint32 msr_MEM_EXCLUSIVE_AREA_12[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(reentry_guard_MEM_EXCLUSIVE_AREA_12) static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_12[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(msr_MEM_EXCLUSIVE_AREA_13) static volatile uint32 msr_MEM_EXCLUSIVE_AREA_13[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(reentry_guard_MEM_EXCLUSIVE_AREA_13) static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_13[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(msr_MEM_EXCLUSIVE_AREA_14) static volatile uint32 msr_MEM_EXCLUSIVE_AREA_14[NUMBER_OF_CORES]; +VAR_SEC_NOCACHE(reentry_guard_MEM_EXCLUSIVE_AREA_14) static volatile uint32 reentry_guard_MEM_EXCLUSIVE_AREA_14[NUMBER_OF_CORES]; #define RTE_STOP_SEC_VAR_CLEARED_32_NO_CACHEABLE #include "Rte_MemMap.h" From 87f569fa9f69c892549321a3493b67535fc3cb1e Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Mon, 12 Aug 2024 14:08:49 +0700 Subject: [PATCH 3/5] s32: soc: s32z2: add QSPI soc specific code Code autogenerated with S32 Design Studio for s32ze Signed-off-by: Cong Nguyen Huu --- s32/soc/s32z270/include/Qspi_Ip_Cfg.h | 115 +++++++++++++++++++ s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h | 65 +++++++++++ s32/soc/s32z270/include/Qspi_Ip_Features.h | 114 ++++++++++++++++++ 3 files changed, 294 insertions(+) create mode 100644 s32/soc/s32z270/include/Qspi_Ip_Cfg.h create mode 100644 s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h create mode 100644 s32/soc/s32z270/include/Qspi_Ip_Features.h diff --git a/s32/soc/s32z270/include/Qspi_Ip_Cfg.h b/s32/soc/s32z270/include/Qspi_Ip_Cfg.h new file mode 100644 index 000000000..6f59b0b4e --- /dev/null +++ b/s32/soc/s32z270/include/Qspi_Ip_Cfg.h @@ -0,0 +1,115 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_CFG_H +#define QSPI_IP_CFG_H + +/** +* @file Qspi_Ip_Cfg.h +* +* @addtogroup MEM_EXFLS +* Qspi_Ip_Cfg.h_Artifact +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +/*================================================================================================== +* INCLUDE FILES +* 1) system and project includes +* 2) needed interfaces from external units +* 3) internal and external interfaces from this unit +==================================================================================================*/ +#include "Qspi_Ip_Types.h" + + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_VENDOR_ID_CFG 43 +#define QSPI_IP_AR_RELEASE_MAJOR_VERSION_CFG 4 +#define QSPI_IP_AR_RELEASE_MINOR_VERSION_CFG 7 +#define QSPI_IP_AR_RELEASE_REVISION_VERSION_CFG 0 +#define QSPI_IP_SW_MAJOR_VERSION_CFG 2 +#define QSPI_IP_SW_MINOR_VERSION_CFG 0 +#define QSPI_IP_SW_PATCH_VERSION_CFG 0 + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ + + +/*================================================================================================== + DEFINES AND MACROS +==================================================================================================*/ + +/* Number of serial flash devices */ +#define QSPI_IP_MEM_INSTANCE_COUNT (1U) + +/* Maximum number of retries for Write Enable command */ +#define QSPI_IP_MAX_RETRY (3U) + +/* Development error detection for QSPI Ip API */ +#define QSPI_IP_DEV_ERROR_DETECT (STD_OFF) + +/* Timeout for DLL lock sequence */ +#define QSPI_IP_DLL_LOCK_TIMEOUT (10000000U) + +/* Timeout for QSPI command completion */ +#define QSPI_IP_CMD_COMPLETE_TIMEOUT (10000000U) + +/* After the FRAD checks pass we wait for QSPI to become idle */ +#define QSPI_IP_QSPI_IDLE_TIMEOUT (100U) + +/* Timeout for external flash software reset completion */ +#define QSPI_IP_RESET_TIMEOUT (2000000U) + +/* Timeout for external flash startup initialization sequence completion */ +#define QSPI_IP_FLS_INIT_TIMEOUT (2000000U) + +/* Timeout for a complete read operation */ +#define QSPI_IP_READ_TIMEOUT (2147483647U) + +/* OsIf counter type used in timeout detection for QSPI IP operations */ +#define QSPI_IP_TIMEOUT_TYPE (OSIF_COUNTER_DUMMY) + +/* Delay after changing the value of the QSPI software reset bits */ +#define QSPI_IP_SOFTWARE_RESET_DELAY (21U) + +/*! @brief Minimum delay in CPU cycles between Tx FIFO reset and Tx FIFO push */ +#define QSPI_IP_TX_BUFFER_RESET_DELAY (0U) + + +/* QSPI user mode support macro */ +#define QSPI_IP_ENABLE_USER_MODE_SUPPORT (STD_OFF) + +#ifndef MCAL_ENABLE_USER_MODE_SUPPORT + #if (STD_ON == QSPI_IP_ENABLE_USER_MODE_SUPPORT) + #error MCAL_ENABLE_USER_MODE_SUPPORT is not enabled. For running Fls in user mode the MCAL_ENABLE_USER_MODE_SUPPORT needs to be defined. + #endif +#endif + +#define QSPI_PERFORM_DEVICE_CONFIG (STD_ON) + + +/*================================================================================================== + DEFINES AND MACROS +==================================================================================================*/ +/*================================================================================================== +* GLOBAL VARIABLE DECLARATIONS +==================================================================================================*/ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_CFG_H */ diff --git a/s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h b/s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h new file mode 100644 index 000000000..3ee037154 --- /dev/null +++ b/s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h @@ -0,0 +1,65 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QSPI_IP_CFG_DEFINES_H +#define QSPI_IP_CFG_DEFINES_H + +/** +* @file Qspi_Ip_CfgDefines.h +* +* @addtogroup IPV_QSPI +* Qspi_Ip_CfgDefines.h_Artifact +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +/*================================================================================================== +* INCLUDE FILES +* 1) system and project includes +* 2) needed interfaces from external units +* 3) internal and external interfaces from this unit +==================================================================================================*/ + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_VENDOR_ID_CFG_DEFINES 43 +#define QSPI_IP_AR_RELEASE_MAJOR_VERSION_CFG_DEFINES 4 +#define QSPI_IP_AR_RELEASE_MINOR_VERSION_CFG_DEFINES 7 +#define QSPI_IP_AR_RELEASE_REVISION_VERSION_CFG_DEFINES 0 +#define QSPI_IP_SW_MAJOR_VERSION_CFG_DEFINES 2 +#define QSPI_IP_SW_MINOR_VERSION_CFG_DEFINES 0 +#define QSPI_IP_SW_PATCH_VERSION_CFG_DEFINES 0 + +/*================================================================================================== +* FILE VERSION CHECKS +==================================================================================================*/ + +/*================================================================================================== + DEFINES AND MACROS +==================================================================================================*/ + + +#define QSPI_IP_SFP_ENABLE_GLOBAL (STD_ON) +#define QSPI_IP_SFP_ENABLE_MDAD (STD_ON) +#define QSPI_IP_SFP_ENABLE_FRAD (STD_ON) + + +/* Enable Multicore support when using MemAcc*/ +#define QSPI_IP_MULTICORE_ENABLED (STD_OFF) + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_CFG_DEFINES_H */ diff --git a/s32/soc/s32z270/include/Qspi_Ip_Features.h b/s32/soc/s32z270/include/Qspi_Ip_Features.h new file mode 100644 index 000000000..3f62e4f73 --- /dev/null +++ b/s32/soc/s32z270/include/Qspi_Ip_Features.h @@ -0,0 +1,114 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#if !defined(QSPI_IP_FEATURES_H) +#define QSPI_IP_FEATURES_H + +/** +* @file Qspi_Ip_Features.h +* +* @addtogroup IPV_QSPI +* Qspi_Ip_Features.h_Artifact +* @{ +*/ + + +#ifdef __cplusplus +extern "C"{ +#endif + +/*================================================================================================== +* INCLUDE FILES +* 1) system and project includes +* 2) needed interfaces from external units +* 3) internal and external interfaces from this unit +==================================================================================================*/ +#include "S32Z2_QUADSPI.h" + +/*================================================================================================== +* SOURCE FILE VERSION INFORMATION +==================================================================================================*/ +#define QSPI_IP_FEATURES_VENDOR_ID_CFG 43 +#define QSPI_IP_FEATURES_AR_RELEASE_MAJOR_VERSION_CFG 4 +#define QSPI_IP_FEATURES_AR_RELEASE_MINOR_VERSION_CFG 7 +#define QSPI_IP_FEATURES_AR_RELEASE_REVISION_VERSION_CFG 0 +#define QSPI_IP_FEATURES_SW_MAJOR_VERSION_CFG 2 +#define QSPI_IP_FEATURES_SW_MINOR_VERSION_CFG 0 +#define QSPI_IP_FEATURES_SW_PATCH_VERSION_CFG 0 + + +/*================================================================================================== +* DEFINES AND MACROS +==================================================================================================*/ + +/* QuadSPI module features */ + +/*! @brief First address of the serial flash device on the AHB bus for QuadSPI instances */ +#define FEATURE_QSPI_AMBA_BASE {0x00000000UL,0x10000000UL} +/*! @brief Size of AHB buffer. */ +#define FEATURE_QSPI_AHB_BUF_SIZE 1024U +/*! @brief Size of Tx FIFO. */ +#define FEATURE_QSPI_TX_BUF_SIZE 1024U +/*! @brief Size of Rx FIFO. */ +#define FEATURE_QSPI_RX_BUF_SIZE 256U +/*! @brief Number of LUT registers that make up a LUT sequence */ +#define FEATURE_QSPI_LUT_SEQUENCE_SIZE 5U +/* Minimum entries of 4 bytes fill needed to allow Tx operation to start */ +#define FEATURE_QSPI_TX_MIN_BUF_FILL 1U + +/*! @brief Supports Double Data Rate operation */ +#define FEATURE_QSPI_DDR 1 +/*! @brief QSPI side B is available */ +#define FEATURE_QSPI_HAS_SIDE_B 1 +/*! @brief Configurable Idle Signal Drive */ +#define FEATURE_QSPI_CONFIGURABLE_ISD 1 + +/*! @brief Supports addr. config options (column address, word addressable) */ +#define FEATURE_QSPI_ADDR_CFG 1 +/*! @brief Supports byte swap */ +#define FEATURE_QSPI_BYTES_SWAP_ADDR 1 + +/*! @brief Supports center-aligned read strobe */ +#define FEATURE_QSPI_CENTER_ALIGNED_READ_STROBE 1 +/*! @brief Supports differential clock */ +#define FEATURE_QSPI_DIFFERENTIAL_CLOCK 1 + +/*! @brief Supports internal DQS sampling mode */ +#define FEATURE_QSPI_INTERNAL_DQS 0 +/*! @brief Supports loopback sampling mode */ +#define FEATURE_QSPI_LOOPBACK 1 +/*! @brief Supports DQS loopback sampling mode */ +#define FEATURE_QSPI_LOOPBACK_DQS 0 +/*! @brief Supports external DQS sampling mode */ +#define FEATURE_QSPI_EXTERNAL_DQS 1 +/*! @brief Supports DQS_FA_SEL/DQS_FB_SEL field in MCR register for DQS selection */ +#define FEATURE_QSPI_SELECT_DQS 1 + +/*! @brief Supports Dll feature */ +#define FEATURE_QSPI_HAS_DLL 1 +/*! @brief Supports full DLL features (as opposed to bypass mode only) */ +#define FEATURE_QSPI_EXTERNAL_DLL_FULL 1 +/*! @brief Supports DLL reference counter and DLL resolution */ +#define FEATURE_QSPI_DLL_LOOPCONTROL 1 + +/*! @brief Supports secure flash protection feature */ +#define FEATURE_QSPI_HAS_SFP 1 + + +/*! @brief The maximum size of manufacturer & device ID that flash memories can have */ +#define FEATURE_EXFLS_FLASH_MDID_SIZE 10U + +/*! @brief AHB base pointers initializer for all QSPI units */ +#define QuadSPI_AHB_PTRS FEATURE_QSPI_AMBA_BASE + + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* QSPI_IP_FEATURES_H */ From f56df6d7598c48dc240ca3c9ed8a926b9ced39dc Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Mon, 19 Aug 2024 11:12:49 +0700 Subject: [PATCH 4/5] s32: s32ze: patch QSPI for integration with zephyr Adapt macros that are used in the QSPI memc and QSPI flash shim drivers. Signed-off-by: Cong Nguyen Huu --- s32/drivers/s32ze/BaseNXP/header/S32Z2_QUADSPI.h | 4 ++-- s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h | 2 +- s32/soc/s32z270/include/Qspi_Ip_Cfg.h | 4 ++-- s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h | 7 ++++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/s32/drivers/s32ze/BaseNXP/header/S32Z2_QUADSPI.h b/s32/drivers/s32ze/BaseNXP/header/S32Z2_QUADSPI.h index 60e9af069..091411e26 100644 --- a/s32/drivers/s32ze/BaseNXP/header/S32Z2_QUADSPI.h +++ b/s32/drivers/s32ze/BaseNXP/header/S32Z2_QUADSPI.h @@ -71,8 +71,8 @@ /** QuadSPI - Size of Registers Arrays */ #define QuadSPI_RBDR_COUNT 64u #define QuadSPI_LUT_COUNT 80u -#define QuadSPI_FRAD_COUNT 8u -#define QuadSPI_MDAD_COUNT 2u +#define QuadSPI_FRAD_COUNT 8 +#define QuadSPI_MDAD_COUNT 2 /** QuadSPI - Register Layout Typedef */ typedef struct { diff --git a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h index a7d1d19ff..42d0ce66b 100644 --- a/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h +++ b/s32/drivers/s32ze/Mem_EXFLS/include/Qspi_Ip_Types.h @@ -121,7 +121,7 @@ extern "C"{ #define QSPI_IP_ERASE_TYPES (4U) /*! @brief Number of AHB buffers in the device */ -#define QSPI_IP_AHB_BUFFERS (4U) +#define QSPI_IP_AHB_BUFFERS 4 /*! Invalid index in virtual LUT, used for unsupported features */ #define QSPI_IP_LUT_INVALID (uint16)0xFFFFU diff --git a/s32/soc/s32z270/include/Qspi_Ip_Cfg.h b/s32/soc/s32z270/include/Qspi_Ip_Cfg.h index 6f59b0b4e..eb2c0b598 100644 --- a/s32/soc/s32z270/include/Qspi_Ip_Cfg.h +++ b/s32/soc/s32z270/include/Qspi_Ip_Cfg.h @@ -28,7 +28,7 @@ extern "C"{ * 3) internal and external interfaces from this unit ==================================================================================================*/ #include "Qspi_Ip_Types.h" - +#include /*================================================================================================== * SOURCE FILE VERSION INFORMATION @@ -51,7 +51,7 @@ extern "C"{ ==================================================================================================*/ /* Number of serial flash devices */ -#define QSPI_IP_MEM_INSTANCE_COUNT (1U) +#define QSPI_IP_MEM_INSTANCE_COUNT DT_NUM_INST_STATUS_OKAY(nxp_s32_qspi_hyperflash) /* Maximum number of retries for Write Enable command */ #define QSPI_IP_MAX_RETRY (3U) diff --git a/s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h b/s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h index 3ee037154..ce73329b3 100644 --- a/s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h +++ b/s32/soc/s32z270/include/Qspi_Ip_CfgDefines.h @@ -27,6 +27,7 @@ extern "C"{ * 2) needed interfaces from external units * 3) internal and external interfaces from this unit ==================================================================================================*/ +#include /*================================================================================================== * SOURCE FILE VERSION INFORMATION @@ -48,9 +49,9 @@ extern "C"{ ==================================================================================================*/ -#define QSPI_IP_SFP_ENABLE_GLOBAL (STD_ON) -#define QSPI_IP_SFP_ENABLE_MDAD (STD_ON) -#define QSPI_IP_SFP_ENABLE_FRAD (STD_ON) +#define QSPI_IP_SFP_ENABLE_MDAD DT_HAS_COMPAT_STATUS_OKAY(nxp_s32_qspi_sfp_mdad) +#define QSPI_IP_SFP_ENABLE_FRAD DT_HAS_COMPAT_STATUS_OKAY(nxp_s32_qspi_sfp_frad) +#define QSPI_IP_SFP_ENABLE_GLOBAL UTIL_OR(QSPI_IP_SFP_ENABLE_MDAD, QSPI_IP_SFP_ENABLE_FRAD) /* Enable Multicore support when using MemAcc*/ From 30b1f300a7f0cb305c1c250391d18b5db9b135e8 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Huu Date: Tue, 13 Aug 2024 13:20:31 +0700 Subject: [PATCH 5/5] s32: soc: s32z2: update QSPI clock sources Select PERIPHPLL_DFS0 clock as QSPI0 clock source Select PERIPHPLL_DFS2 clock as QSPI1 clock source Update QSPI dividers so that value clocks: P4_QSPI0_1X_CLK is 200 MHz P4_QSPI0_2X_CLK is 400 MHz P4_QSPI1_1X_CLK is 150 MHz P4_QSPI1_2X_CLK is 300 MHz Signed-off-by: Cong Nguyen Huu --- s32/soc/s32z270/src/Clock_Ip_Cfg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/s32/soc/s32z270/src/Clock_Ip_Cfg.c b/s32/soc/s32z270/src/Clock_Ip_Cfg.c index 7086c8a01..638a9f17e 100644 --- a/s32/soc/s32z270/src/Clock_Ip_Cfg.c +++ b/s32/soc/s32z270/src/Clock_Ip_Cfg.c @@ -557,7 +557,7 @@ static const Clock_Ip_SelectorConfigType Clock_Ip_SelectorConfigurations_0[CLOCK #if CLOCK_IP_CONFIGURED_SELECTORS_0_NO > 41U { P4_QSPI0_2X_CLK, /* Clock name associated to selector */ - FIRC_CLK, /* Name of the selected input source */ + PERIPHPLL_DFS0_CLK, /* Name of the selected input source */ }, #endif @@ -571,7 +571,7 @@ static const Clock_Ip_SelectorConfigType Clock_Ip_SelectorConfigurations_0[CLOCK #if CLOCK_IP_CONFIGURED_SELECTORS_0_NO > 43U { P4_SDHC_CLK, /* Clock name associated to selector */ - FIRC_CLK, /* Name of the selected input source */ + PERIPHPLL_DFS2_CLK, /* Name of the selected input source */ }, #endif @@ -1345,7 +1345,7 @@ static const Clock_Ip_DividerConfigType Clock_Ip_DividerConfigurations_0[CLOCK_I #if CLOCK_IP_CONFIGURED_DIVIDERS_0_NO > 63U { P4_QSPI0_2X_CLK, /* name */ - 1U, /* value */ + 2U, /* value */ { 0U, } @@ -1555,7 +1555,7 @@ static const Clock_Ip_DividerConfigType Clock_Ip_DividerConfigurations_0[CLOCK_I #if CLOCK_IP_CONFIGURED_DIVIDERS_0_NO > 84U { P4_SDHC_CLK, /* name */ - 1U, /* value */ + 2U, /* value */ { 0U, } @@ -1672,7 +1672,7 @@ static const Clock_Ip_FracDivConfigType Clock_Ip_FracDivsConfigurations_0[CLOCK_ 1U, /* Enabled */ { 2U, /* integer part */ - 18U, /* fractional part */ + 0U, /* fractional part */ }, }, #endif