/* * Copyright 2023-2024 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef FSL_XSPI_H_ #define FSL_XSPI_H_ #include "fsl_common.h" /*! * @addtogroup xspi * @{ */ /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ #define FSL_XSPI_DRIVER_VERSION (MAKE_VERSION(2, 2, 1)) /*@{*/ /*! @brief Formula to form XSPI instructions in LUT table. */ #define XSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ (XSPI_LUT_INSTR0(cmd0) | XSPI_LUT_PAD0(pad0) | XSPI_LUT_OPRND0(op0) | XSPI_LUT_INSTR1(cmd1) | \ XSPI_LUT_PAD1(pad1) | XSPI_LUT_OPRND1(op1)) /*! @brief Status structure of XSPI.*/ enum { kStatus_XSPI_Busy = MAKE_STATUS(kStatusGroup_XSPI, 0), /*!< XSPI is Busy */ kStatus_XSPI_IpCommandUsageError = MAKE_STATUS(kStatusGroup_XSPI, 1), /*!< XSPI Ip Command Usage Error*/ kStatus_XSPI_IpCommandtriggerError = MAKE_STATUS(kStatusGroup_XSPI, 2), /*!< XSPI Ip Command Trigger Error*/ kStatus_XSPI_IllegalInstructionError = MAKE_STATUS(kStatusGroup_XSPI, 3), /*!< XSPI Illegal Instruction Error*/ kStatus_XSPI_SequenceExecutionTimeout = MAKE_STATUS(kStatusGroup_XSPI, 4), /*!< XSPI Sequence Execution Timeout*/ kStatus_XSPI_FradCheckError = MAKE_STATUS(kStatusGroup_XSPI, 5), /*!< XSPI Frad Check Error*/ kStatus_XSPI_TgQueueWritingError = MAKE_STATUS(kStatusGroup_XSPI, 6), /*!< XSPI Tg Queue Writing Error*/ kStatus_XSPI_IpsBusTransError = MAKE_STATUS(kStatusGroup_XSPI, 7), /*!< XSPI Ip Bus Transfer Error*/ kStatus_XSPI_AhbReadAccessAsserted = MAKE_STATUS(kStatusGroup_XSPI, 8), /*!< AHB read access is asserted. */ kStatus_XSPI_AhbWriteAccessAsserted = MAKE_STATUS(kStatusGroup_XSPI, 9), /*!< AHB write access is asserted. */ kStatus_XSPI_IPAccessAsserted = MAKE_STATUS(kStatusGroup_XSPI, 10), /*!< IP access is asserted. */ kStatus_XSPI_AhbSubBufferFactorError = MAKE_STATUS(kStatusGroup_XSPI, 11), /*!< Wrong sub buffer factor input. */ kStatus_XSPI_RegWriteLocked = MAKE_STATUS(kStatusGroup_XSPI, 12), /*!< Fail to write register due to write operation is locked. */ kStatus_XSPI_WaterMarkIllegal = MAKE_STATUS(kStatusGroup_XSPI, 13), /*!< The watermark value to set is not in multiple of 4 bytes. */ kStatus_XSPI_PageProgramWaitFlagAsserted = MAKE_STATUS(kStatusGroup_XSPI, 14), /*!< The page program wait flag already asserted. */ kStatus_XSPI_IpAccessAddrSettingInvalid = MAKE_STATUS(kStatusGroup_XSPI, 15), /*!< The input address for Ip access is invalid. */ kStatus_XSPI_RxBufferEntriesCountError = MAKE_STATUS(kStatusGroup_XSPI, 16), /*!< The count of entries of RX buffer is incorrect. */ kStatus_XSPI_IpAccessIPCRInvalid = MAKE_STATUS(kStatusGroup_XSPI, 17), /*!< Access attributes to write IPCR are not correct. */ }; /*! @brief CMD definition of XSPI, use to form LUT instruction, xspi_lut_instr_t. */ typedef enum _xspi_lut_instr { kXSPI_Command_STOP = 0x00U, /*!< Stop execution, de-assert CS. */ kXSPI_Command_SDR = 0x01U, /*!< Transmit Command code to Flash, using SDR mode. */ kXSPI_Command_RADDR_SDR = 0x02U, /*!< Transmit Row Address to Flash, using SDR mode. */ kXSPI_Command_DUMMY_SDR = 0x03U, /*!< Leave data lines un-driven by xSPI controller, using SDR mode. */ kXSPI_Command_MODE_SDR = 0x04U, /*!< Transmit 8-bit Mode bits to Flash, using SDR mode. */ kXSPI_Command_MODE2_SDR = 0x05U, /*!< Transmit 2-bit Mode bits to Flash, using SDR mode. */ kXSPI_Command_MODE4_SDR = 0x06U, /*!< Transmit 4-bit Mode bits to Flash, using SDR mode. */ kXSPI_Command_READ_SDR = 0x07U, /*!< Receive Read Data from Flash, using SDR mode. */ kXSPI_Command_WRITE_SDR = 0x08U, /*!< Transmit Programming Data to Flash, using SDR mode. */ kXSPI_Command_JMP_ON_CS = 0x09U, /*!< Stop execution, de-assert CS and save operand[7:0] as the instruction start pointer for next sequence*/ kXSPI_Command_RADDR_DDR = 0x0AU, /*!< Transmit Row Address to Flash, using DDR mode. */ kXSPI_Command_MODE_DDR = 0x0BU, /*!< Transmit 8-bit Mode bits to Flash, using DDR mode. */ kXSPI_Command_MODE2_DDR = 0x0CU, /*!< Transmit 2-bit Mode bits to Flash, using DDR mode. */ kXSPI_Command_MODE4_DDR = 0x0DU, /*!< Transmit 4-bit Mode bits to Flash, using DDR mode. */ kXSPI_Command_READ_DDR = 0x0EU, /*!< Receive Read Data from Flash, using DDR mode. */ kXSPI_Command_WRITE_DDR = 0x0FU, /*!< Transmit Programming Data to Flash, using DDR mode. */ kXSPI_Command_LEARN_DDR = 0x10U, /*!< Receive Read Data or Preamble bit from Flash, DDR mode. */ kXSPI_Command_DDR = 0x11U, /*!< Transmit Command code to Flash, using DDR mode. */ kXSPI_Command_CADDR_SDR = 0x12U, /*!< Transmit Column Address to Flash, using SDR mode. */ kXSPI_Command_CADDR_DDR = 0x13U, /*!< Transmit Column Address to Flash, using DDR mode. */ kXSPI_Command_JUMP_TO_SEQ = 0x14U, /*!< Jump the LUT sequence pointed to by the operand. */ } xspi_lut_instr_t; /*! @brief pad definition of XSPI, use to form LUT instruction. */ typedef enum _xspi_pad { kXSPI_1PAD = 0x00U, /*!< Transmit command/address and transmit/receive data only through DATA0/DATA1. */ kXSPI_2PAD = 0x01U, /*!< Transmit command/address and transmit/receive data only through DATA[1:0]. */ kXSPI_4PAD = 0x02U, /*!< Transmit command/address and transmit/receive data only through DATA[3:0]. */ kXSPI_8PAD = 0x03U, /*!< Transmit command/address and transmit/receive data only through DATA[7:0]. */ } xspi_pad_t; /*! @brief XSPI interrupt status flags.*/ typedef enum _xspi_flags { kXSPI_DataLearningFailedFlag = XSPI_FR_DLPFF_MASK, /*!< Data learning failed. */ kXSPI_DllAbortFlag = XSPI_FR_DLLABRT_MASK, /*!< DLL Abort. */ kXSPI_DllUnlockFlag = XSPI_FR_DLLUNLCK_MASK, /*!< This field is set whenever DLL unlock event occurs, irrespective of flash memory access.*/ kXSPI_TxBufferFillFlag = XSPI_FR_TBFF_MASK, /*!< If the field remains cleared, the TX buffer can be considered as full.*/ kXSPI_TxBufferUnderrunFlag = XSPI_FR_TBUF_MASK, /*!< This field is set if the module tries to pull data when the TX buffer is empty*/ kXSPI_RxBufferOverflowFlag = XSPI_FR_RBOF_MASK, /*!< This field is set when no more data can be pushed into the RX buffer from the serial flash memory device.*/ kXSPI_RxBufferDrainFlag = XSPI_FR_RBDF_MASK, /*!< This field is set if SR[RXWE] is asserted.*/ kXSPI_AhbAbortErrorFlag = XSPI_FR_AAEF_MASK, /*!< This flag can be set when AHB transaction error*/ kXSPI_AhbIllegalTransactionErrorFlag = XSPI_FR_AITEF_MASK, kXSPI_AhbIllegalBurstSizeErrorFlag = XSPI_FR_AIBSEF_MASK, /*!< The total burst size is more than prefetch size. */ kXSPI_AhbBufferOverflowFlag = XSPI_FR_ABOF_MASK, /*!< The size of the AHB access exceed the size of the AHB buffer. */ kXSPI_AhbPerformanceMonitorOverflowFlag = XSPI_FR_PERFOVF_MASK, /*!< AHB performance hit or miss counter overflow. */ kXSPI_AhbReadAddressErrorFlag = XSPI_FR_RDADDR_MASK, /*!< The master send an AHB read address to that buffer is not within the address range of any sub-buffers or the address within multiple sub-buffers. */ kXSPI_IllegalInstructionErrorFlag = XSPI_FR_ILLINE_MASK, /*!< This field is set when an illegal instruction is encountered by the controller in any of the sequences.*/ kXSPI_IpCmdtriggerErrorFlag = XSPI_FR_IPIEF_MASK, /*!< Write access to Rx buffer control reg when IP-triggered command is executing. */ kXSPI_PageProgramWaitFlag = XSPI_FR_PPWF_MASK, /*!< Indicates assertion of the page-program wait flag after writing to flash memory. */ #if defined(XSPI_FR_IPEDERR_MASK) kXSPI_IPEDRxDecryptionErrorFlag = XSPI_FR_IPEDERR_MASK, /*!< only support XSPI0 XSPI1*/ #endif /* defined(XSPI_FR_IPEDERR_MASK) */ kXSPI_IpCommandExecutionDoneFlag = XSPI_FR_TFF_MASK, /*!< Indicates XSPI has completed a running IP command. */ kXSPI_SequenceExecutionTimeoutFlag = XSPI_INT_EN_TO_ERR_MASK, /*!< Sequence execution timeout. */ kXSPI_FradMatchErrorFlag = XSPI_INT_EN_FRADMTCH_MASK, /*Transaction address does not lie within address range of any FRAD descriptor.*/ kXSPI_Frad0AccessErrorFlag = XSPI_INT_EN_FRAD0ACC_MASK, /*SPTRCLR = (base->SPTRCLR & (~XSPI_SPTRCLR_OTFAD_BNDRY_MASK)) | XSPI_SPTRCLR_OTFAD_BNDRY(boundary); } /* @} */ /*! * @name XSPI Controller Low-Level Inferfaces */ static inline void XSPI_UpdateByteOrder(XSPI_Type *base, xspi_byte_order_t byteOrder) { base->MCR = ((base->MCR) & (~XSPI_MCR_END_CFG_MASK)) | XSPI_MCR_END_CFG(byteOrder); } /*! * @brief Enable or disable the XSPI module. * * @param base XSPI peripheral base address. * @param enable true means enable XSPI, false means disable. */ static inline void XSPI_EnableModule(XSPI_Type *base, bool enable) { if (enable) { base->MCR &= ~XSPI_MCR_MDIS_MASK; } else { base->MCR |= XSPI_MCR_MDIS_MASK; } } /*! * @brief Check if the XSPI module is enabled. * * @param base XSPI peripheral base address. * * @retval true XSPI module is enabled. * @retval false XSPI module is disabled. */ static inline bool XSPI_CheckModuleEnabled(XSPI_Type *base) { return ((base->MCR & XSPI_MCR_MDIS_MASK) == 0UL); } /*! * @brief Reset Serial flash memory domain and AHB domain at the same time. * * @note Resetting only the Serial flash memory domain and AHB domain may cause undesirable side effects. * * @param base XSPI peripheral base address. */ void XSPI_ResetSfmAndAhbDomain(XSPI_Type *base); /*! * @brief Reset IPS target group queue. * * @param base XSPI peripheral base address. */ static inline void XSPI_ResetTgQueue(XSPI_Type *base) { base->MCR |= XSPI_MCR_IPS_TG_RST_MASK; } /*! * @brief Software reset flash memory domain, AHB domain, and Target group at the same time. * * @param base XSPI peripheral base address. */ static inline void XSPI_SoftwareReset(XSPI_Type *base) { XSPI_ResetTgQueue(base); XSPI_ResetSfmAndAhbDomain(base); } /*! * @brief Check if write access to registers(MGC, MRC, MTO, SFP_ARB_TIMEOUT, SFP_LUT_ENn, LUTn, BFGENCR) is locked. * * @param base XSPI peripheral base address. * * @retval false Write access to listed registers is not locked. * @retval true Write access to listed registers is locked. */ static inline bool XSPI_CheckGlobalConfigLocked(XSPI_Type *base) { return (bool)((base->MGC & XSPI_MGC_GCLCK_MASK) != 0UL); } /* @} */ /*! * @name External Device Control Low-Level Interfaces * @{ */ /*! * @brief Set Hyper bus X16 mode. * * @param base XSPI peripheral base address. * @param x16Mode Specify X16 mode. */ void XSPI_SetHyperBusX16Mode(XSPI_Type *base, xspi_hyper_bus_x16_mode_t x16Mode); /*! * @brief Update address mode to access external device. * * @param base XSPI peripheral base address. * @param addrMode Specify the address mode to update. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail to update address mode due to AHB read access asserted. * @retval kStatus_XSPI_IPAccessAsserted Fail to update address mode due to a IP access already asserted. * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail to update address mode due to AHB write access asserted. * @retval kStatus_Success Successfully to update address mode. */ status_t XSPI_UpdateDeviceAddrMode(XSPI_Type *base, xspi_device_addr_mode_t addrMode); /*! * @brief Enable/disable variable latency for XSPI. * * @note Only useful for hyper bus device. * @note It is application responsibility to enable variable latency for external hyper bus * device(by change device's register). * * @param base XSPI peripheral base address. * @param enable Specify operation: - \b true Enable variable latency; - \b false Disable variable latency. */ static inline void XSPI_EnableVariableLatency(XSPI_Type *base, bool enable) { if (enable) { base->MCR |= XSPI_MCR_VAR_LAT_EN_MASK; } else { base->MCR &= ~XSPI_MCR_VAR_LAT_EN_MASK; } } /*! * @brief Enable/disable Doze mode for XSPI controller. * * @note Once doze mode is enabled, the XSPI controller will enter disable mode when system in low power modes. * * @param base XSPI peripheral base address * @param enable Specify operation: * - \b true Enable Doze mode; * - \b false Disable Doze mode. */ static inline void XSPI_EnableDozeMode(XSPI_Type *base, bool enable) { if (enable) { base->MCR |= XSPI_MCR_DOZE_MASK; } else { base->MCR &= ~XSPI_MCR_DOZE_MASK; } } /*! * @brief Specify the logic level of the XSPI IOFA[3] and IOFA[2] output in the inactive state. * * @param base XSPI peripheral base address * @param signalMask Should be the OR'ed value of _xspi_external_signal. * @param outputLogic Output logic of selected signals, * - \b false Output logic 0; * - \b true Output logic 1. */ static inline void XSPI_SetSignalOutputValue(XSPI_Type *base, uint32_t signalMask, bool outputLogic) { bool moduleEnabled = false; if (XSPI_CheckModuleEnabled(base)) { moduleEnabled = true; XSPI_EnableModule(base, false); } if (outputLogic) { /* Output logic High for input mask of signals. */ base->MCR |= signalMask; } else { /* Output logic Low for input mask of signals. */ base->MCR &= ~signalMask; } if (moduleEnabled) { XSPI_EnableModule(base, true); } } /*! * @brief Enable/disable inverted serial clock output for XSPI controller. * * @note It is application responsibility to enable CLKn for external device(by change device's register). * * @param[in] base XSPI peripheral base address * @param[in] enable Enable/disable inverted serial clock output: * - \b true Enable inverted serial clock output; * - \b false Disable inverted serial clock output. */ static inline void XSPI_EnableInvertedSerialClockOutput(XSPI_Type *base, bool enable) { bool moduleEnabled = false; if (XSPI_CheckModuleEnabled(base)) { moduleEnabled = true; XSPI_EnableModule(base, false); } if (enable) { base->MCR |= XSPI_MCR_CKN_FA_EN_MASK; } else { base->MCR &= ~XSPI_MCR_CKN_FA_EN_MASK; } if (moduleEnabled) { XSPI_EnableModule(base, true); } } /*! * @brief Update DLL configuration. * * @param[in] base XSPI peripheral base address. * @param[in] ptrDllConfig Pointer to the DLL configuration. * @param[in] enableDDR DDR mode is enabled or not. * @param[in] enableX16Mode X16 mode is enabled or not. * @param[in] xspiRootClk The frequency of xspi root clock, the unit is Hz. */ void XSPI_UpdateDllValue( XSPI_Type *base, xspi_dll_config_t *ptrDllConfig, bool enableDDR, bool enableX16Mode, uint32_t xspiRootClk); /*! * @brief Set Data learning configurations. * * @param[in] base XSPI peripheral base address. * @param[in] ptrDataLearningConfig Pointer to data learning configuration. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail to set data learning configuration due to AHB read access asserted. * @retval kStatus_XSPI_IPAccessAsserted Fail to set data learning configuration due to a IP access already asserted. * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail to set data learning configuration due to AHB write access asserted. * @retval kStatus_Success Successfully to set Data learning configurations. */ status_t XSPI_SetDataLearningConfig(XSPI_Type *base, xspi_data_learning_config_t *ptrDataLearningConfig); /*! * @brief Check if data learning failure has detected. * * @param[in] base XSPI peripheral base address. * * @retval true Data learning has failed. * @retval false Data learning not fail. */ static inline bool XSPI_CheckDataLearningFailure(XSPI_Type *base) { return (bool)((base->DLSR_F[0] & XSPI_DLSR_F_DLPFF_MASK) == XSPI_DLSR_F_DLPFF_MASK); } /*! * @brief Get data learning positive and negative edge match signature. * * @param[in] base XSPI peripheral base address. * @param[out] posEdgeMatch Pointer to the memory to store positive edge match signature. * @param[out] negEdgeMatch Pointer to the memory to store negative edge match signature. */ static inline void XSPI_GetDataLearningEdgeMatchSignature(XSPI_Type *base, uint8_t *posEdgeMatch, uint8_t *negEdgeMatch) { uint32_t tmp32 = base->DLSR_F[0]; *negEdgeMatch = (uint8_t)((tmp32 & XSPI_DLSR_F_NEG_EDGE_MASK) >> XSPI_DLSR_F_NEG_EDGE_SHIFT); *posEdgeMatch = (uint8_t)((tmp32 & XSPI_DLSR_F_POS_EDGE_MASK) >> XSPI_DLSR_F_POS_EDGE_SHIFT); } /* @} */ /*! * @name External Device Control Functional Interfaces */ /*! * @brief Set device configuration. * * @param[in] base XSPI peripheral base address. * @param[in] devConfig Pointer to device configuration. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail to set device configuration due to AHB read access asserted. * @retval kStatus_XSPI_IPAccessAsserted Fail to set device configuration due to a IP access already asserted. * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail to set device configuration due to AHB write access asserted. * @retval kStatus_Success Successfully to set device configurations. */ status_t XSPI_SetDeviceConfig(XSPI_Type *base, xspi_device_config_t *devConfig); /* @} */ /*! * @name Interrupts * @{ */ /*! * @brief Enables the XSPI interrupts. * * @param base XSPI peripheral base address. * @param mask XSPI interrupt source. */ static inline void XSPI_EnableInterrupts(XSPI_Type *base, uint32_t mask) { base->RSER |= mask; } /*! * @brief Disable the XSPI interrupts. * * @param base XSPI peripheral base address. * @param mask XSPI interrupt source. */ static inline void XSPI_DisableInterrupts(XSPI_Type *base, uint32_t mask) { base->RSER &= ~mask; } /* @} */ /*! @name DMA control */ /*@{*/ /*! * @brief Enables or disables XSPI IP Tx FIFO DMA requests. * * @param[in] base XSPI peripheral base address. * @param[in] enable Enable flag for transmit DMA request. Pass true for enable, false for disable. */ static inline void XSPI_EnableTxDMA(XSPI_Type *base, bool enable) { if (enable) { base->RSER |= XSPI_RSER_TBFDE_MASK; } else { base->RSER &= ~XSPI_RSER_TBFDE_MASK; } } /*! * @brief Enables or disables XSPI IP Rx FIFO DMA requests. * * @param[in] base XSPI peripheral base address. * @param[in] enable Enable flag for receive DMA request. Pass true for enable, false for disable. */ static inline void XSPI_EnableRxDMA(XSPI_Type *base, bool enable) { if (enable) { base->RSER |= XSPI_RSER_RBDDE_MASK; } else { base->RSER &= ~XSPI_RSER_RBDDE_MASK; } } /*! * @brief Gets XSPI IP tx fifo address for DMA transfer. * * @param[in] base XSPI peripheral base address. * * @return The tx fifo address. */ static inline uint32_t XSPI_GetTxFifoAddress(XSPI_Type *base) { return (uint32_t)&base->TBDR; } /*! * @brief Gets XSPI IP rx fifo address for DMA transfer. * * @param[in] base XSPI peripheral base address. * * @return The rx fifo address. */ static inline uint32_t XSPI_GetRxFifoAddress(XSPI_Type *base) { return (uint32_t)&base->RBDR[0]; } /*@}*/ /*! * @name Status * @{ */ /*! * @brief Get the XSPI interrupt status flags. * * @param[in] base XSPI peripheral base address. * * @return interrupt status flag, use status flag to AND #xspi_flags_t could get the related status. */ static inline uint32_t XSPI_GetInterruptStatusFlags(XSPI_Type *base) { return base->ERRSTAT; } /*! @brief Return whether the bus is idle. * * @param[in] base XSPI peripheral base address. * * @retval true Bus is idle. * @retval false Bus is busy. */ static inline bool XSPI_GetBusIdleStatus(XSPI_Type *base) { return (bool)(XSPI_SR_BUSY_MASK != (base->SR & XSPI_SR_BUSY_MASK)); } /*! * @brief Check if AHB read access has been requested or is ongoing. * * @param[in] base XSPI peripheral base address. * * @retval true AHB read access is requested or is ongoing. * @retval false AHB read access is not requested and is not ongoing. */ static inline bool XSPI_CheckAhbReadAccessAsserted(XSPI_Type *base) { return (bool)((base->SR & XSPI_SR_AHB_ACC_MASK) != 0UL); } /*! * @brief Check if AHB write access has been requested or is ongoing. * * @param[in] base XSPI peripheral base address. * * @retval true AHB read access is requested or is ongoing. * @retval false AHB read access is not requested and is not ongoing. */ static inline bool XSPI_CheckAhbWriteAccessAsserted(XSPI_Type *base) { return (bool)((base->SR & XSPI_SR_AWRACC_MASK) != 0UL); } /*@}*/ /*! * @name IPS Access Control Low-Level Interfaces * @{ */ /*! @brief Clear the XSPI IP TX/RX buffer logic. * * @param[in] base XSPI peripheral base address. * @param[in] txFifo Pass true to reset TX FIFO. * @param[in] rxFifo Pass true to reset RX FIFO. */ static inline void XSPI_ResetTxRxBuffer(XSPI_Type *base, bool txFifo, bool rxFifo) { if (txFifo) { base->MCR |= XSPI_MCR_CLR_TXF_MASK; } if (rxFifo) { base->MCR |= XSPI_MCR_CLR_RXF_MASK; } } /*! * @brief Clear TX buffer. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_ClearTxBuffer(XSPI_Type *base) { base->MCR |= XSPI_MCR_CLR_TXF_MASK; for (uint8_t i = 0U; i < 10U; i++) { __NOP(); } } /*! * @brief Update watermark for TX buffer. * * @param[in] base XSPI peripheral base address. * @param[in] waterMark The watermark to set, the unit is byte, should be the multiple of 4 byte. * * @retval kStatus_XSPI_IPAccessAsserted Fail to update watermark for Tx buffer, due to IP access is asserted. * @retval kStatus_XSPI_WaterMarkIllegal Fail to update watermark for Tx buffer, due to input watermark is not the * multiple of 4 bytes. * @retval kStatus_Success Successful to update watermark. */ status_t XSPI_UpdateTxBufferWaterMark(XSPI_Type *base, uint32_t waterMark); /*! * @brief Check if IP manager can write to TX buffer. * * @param[in] base XSPI peripheral base address. * * @retval true Tx buffer lock is open. * @retval false Tx buffer lock is not open. */ static inline bool XSPI_CheckTxBuffLockOpen(XSPI_Type *base) { return (bool)((base->FSMSTAT & XSPI_FSMSTAT_STATE_MASK) == XSPI_FSMSTAT_STATE(1UL)); } /*! * @brief Writes data into IPS TX Buffer. * * @param[in] base XSPI peripheral base address * @param[in] data The data bytes to send. */ static inline void XSPI_WriteTxBuffer(XSPI_Type *base, uint32_t data) { base->TBDR = data; } /*! * @brief Clear RX buffer. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_ClearRxBuffer(XSPI_Type *base) { base->MCR |= XSPI_MCR_CLR_RXF_MASK; for (uint8_t i = 0U; i < 10U; i++) { __NOP(); } } /*! * @brief Receive data from IPX RX FIFO. * * @param[in] base XSPI peripheral base address * @param[in] fifoIndex Source fifo index. * * @return The data in the FIFO. */ static inline uint32_t XSPI_ReadRxBuffer(XSPI_Type *base, uint8_t fifoIndex) { return base->RBDR[fifoIndex]; } /*! * @brief Trigger a pop event for RX buffer pop event. * * @note Each pop event discard watermark + 1 enties from RX buffer. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_TriggerRxBufferPopEvent(XSPI_Type *base) { base->FR = XSPI_FR_RBDF_MASK; } /*! * @brief Update watermark for RX buffer. * * @code * Set watermark as 4 bytes: * XSPI_UpdateRxBufferWaterMark(XSPI0, 4UL); * Set watermark as 8 bytes: * XSPI_UpdateRxBufferWaterMark(XSPI0, 8UL); * @endcode * * * @param[in] base XSPI peripheral base address. * @param[in] waterMark Specify the number of bytes in the RX buffer which causes XSPI to assert the watermark exceeded * flag, should be in multiple of 4 bytes. * * @retval kStatus_XSPI_IPAccessAsserted Fail to update watermark for Rx buffer, due to IP access is asserted. * @retval kStatus_XSPI_WaterMarkIllegal Fail to update watermark for Tx buffer, due to input watermark is not the * multiple of 4 bytes. * @retval kStatus_Success Successful to update watermark. */ status_t XSPI_UpdateRxBufferWaterMark(XSPI_Type *base, uint32_t waterMark); /*! * @brief Check if RX buffer watermark is exceed. * * @param[in] base XSPI peripheral base address. * * @retval true The RX buffer watermark has been excceded. * @retval false The RX buffer watermark has not been exceeded. */ static inline bool XSPI_CheckRxBufferWaterMarkExceed(XSPI_Type *base) { return (bool)((base->FR & XSPI_FR_RBDF_MASK) == XSPI_FR_RBDF_MASK); } /*! * @brief Get RX buffer aviailable bytes count. * * @param[in] base XSPI peripheral base address. * * @return The available counts if bytes in RX buffer. */ static inline uint32_t XSPI_GetRxBufferAvailableBytesCount(XSPI_Type *base) { return ((base->RBSR & XSPI_RBSR_RDBFL_MASK) >> XSPI_RBSR_RDBFL_SHIFT) * 4UL; } /*! * @brief Get counts of bytes already removed from RX buffer. * * @param[in] base XSPI peripheral base address. * * @return Counts of removed bytes. */ static inline uint32_t XSPI_GetRxBufferRemovedBytesCount(XSPI_Type *base) { return ((base->RBSR & XSPI_RBSR_RDCTR_MASK) >> XSPI_RBSR_RDCTR_SHIFT) * 4UL; } /*! * @brief Set exclusive access lock mode for the specific frad.. * * @param[in] base XSPI peripheral base address. * @param[in] ealMode Specify the exclusive access lock mode. * @param[in] fradId Specify the frad. */ void XSPI_SetSFPFradEALMode(XSPI_Type *base, xspi_exclusive_access_lock_mode_t ealMode, uint8_t fradId); /*! * @brief Update SFP configurations, including MDAD configurations and FRAD configurations. * * @param[in] base XSPI peripheral base address. * @param[in] ptrMdadConfig Pointer to the SFP MDAD configuration. * @param[in] ptrFradConfig Pointer to the SFP FRAD configuration. */ void XSPI_UpdateSFPConfig(XSPI_Type *base, xspi_sfp_mdad_config_t *ptrSfpMdadConfig, xspi_sfp_frad_config_t *ptrSfpFradConfig); /*! * @brief Check if SFP FRAD check is enabled for IP write access. * * @param[in] base XSPI peripheral base address. * * @retval false SFP FRAD check is disabled. * @retval true SFP FRAD check is enabled for IP write access. */ static inline bool XSPI_CheckSFPFradEnabled(XSPI_Type *base) { return (bool)((base->MGC & XSPI_MGC_GVLDFRAD_MASK) != 0UL); } /*! * @brief Get MDAD check error reason for specific target group. * * @param[in] base XSPI peripheral base address. * @param[in] tgId Specify the target group. * * @return The details of MDAD error reason, in type of @ref xspi_mdad_error_reason_t. */ xspi_mdad_error_reason_t XSPI_GetMdadErrorReason(XSPI_Type *base, xspi_target_group_t tgId); /*! * @brief Get FARD latest transaction information. * * @param[in] base XSPI peripheral base address. * @param[out] ptrInfo Pointer to the variable in type of @ref xspi_frad_transaction_info_t to store information. * @param[in] fradId Specify the frad Id. */ void XSPI_GetFradLastTransactionsInfo(XSPI_Type *base, xspi_frad_transaction_info_t *ptrInfo, uint8_t fradId); /*! * @brief Update SFP arbitration lock timeout counter. * * @note The SFP arbitration lock time out counter starts when Page program wait flag asserted. * * @param[in] base XSPI peripheral base address. * @param[in] countValue The count value, specify the time in IPS clock cycles. * * @retval kStatus_XSPI_RegWriteLocked Write operation to related register is locked. * @retval kStatus_Success Success to update timeout counter. */ status_t XSPI_UpdateSFPArbitrationLockTimeoutCounter(XSPI_Type *base, uint32_t countValue); /*! * @brief Clear address write status for specific target group. * * @param[in] base XSPI peripheral base address. * @param[in] tgId Specify the target group to clear address write status. */ void XSPI_ClearTgAddrWriteStatus(XSPI_Type *base, xspi_target_group_t tgId); /*! * @brief Get address write status for specific target group. * * @param[in] base XSPI peripheral base address. * @param[in] tgId Specify the target group. * @param[out] ptrStatus Pointer to the variable in type of @ref xspi_tg_add_write_status_t to store address write status. */ void XSPI_GetTgAddrWriteStatus(XSPI_Type *base, xspi_target_group_t tgId, xspi_tg_add_write_status_t *ptrStatus); /*! * @brief Unlock Ip access arbitration. * * @param[in] base XSPI peripheral base address. * @param[in] tgId Specify the target group. */ void XSPI_UnlockIpAccessArbitration(XSPI_Type *base, xspi_target_group_t tgId); /*! * @brief Check if IP access is asserted. * * @param[in] base XSPI peripheral base address. * * @retval false The Access triggered by IP bus is not asserted. * @retval true The Access triggered by IP bus is asserted. */ static inline bool XSPI_CheckIPAccessAsserted(XSPI_Type *base) { return (bool)((base->SR & XSPI_SR_IP_ACC_MASK) != 0UL); } /*! * @brief Clear Ip access sequence pointer. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_ClearIPAccessSeqPointer(XSPI_Type *base) { base->SPTRCLR |= XSPI_SPTRCLR_IPPTRC_MASK; } /*! * @brief Update the count of SFP access timeout counter. * * @note The counter starts when any IP access pass SFP check(if enabled), and request is granted by XSPI arbiter and * XSPI is IDLE. * * @note The counter does not start in case of IP access was granted by XSPI is not IDLE. * * @param base XSPI peripheral base address. * @param countValue The count value, specify the time in IPS clock cycles. * * @retval kStatus_XSPI_RegWriteLocked Write operation to related register is locked. * @retval kStatus_Success Success to update timeout counter. */ status_t XSPI_UpdateIPAccessTimeoutCounter(XSPI_Type *base, uint32_t countValue); /*! * @brief Check if IP access is granted by XSPI arbitration. * * @param base XSPI peripheral base address. * * @retval true The IP access is granted arbitration. * @retval false No IP access is queued. */ static inline bool XSPI_CheckIPAccessGranted(XSPI_Type *base) { return (bool)((base->FSMSTAT & XSPI_FSMSTAT_VLD_MASK) != 0UL); } /*! * @brief Check if IP write access is triggered. * * @param[in] base XSPI peripheral base address. * * @retval true The IP write access is granted arbitration. * @retval false No IP write access is queued. */ static inline bool XSPI_CheckIpWriteTriggered(XSPI_Type *base) { return (bool)((base->FSMSTAT & XSPI_FSMSTAT_STATE_MASK) == XSPI_FSMSTAT_STATE(2U)); } /*! * @brief Check if IP read access is triggered. * * @param[in] base XSPI peripheral base address. * * @retval true The IP read access is granted arbitration. * @retval false No IP read access is queued. */ static inline bool XSPI_CheckIpReadTriggered(XSPI_Type *base) { return (bool)((base->FSMSTAT & XSPI_FSMSTAT_STATE_MASK) == XSPI_FSMSTAT_STATE(3U)); } /*! * @brief Start IP access(including read and write). * * @param[in] base XSPI peripheral base address. * @param[in] addr Address of external device to read/write. * @param[in] seqIndex Sequence Id of the pre-programed LUT. * @param[in] byteSize Size of data to read/write, the unit of byte. * @param[in] tgId Specify the target group used to write/read. * @param[in] lockArbitration Lock arbitration or not. * * @retval kStatus_XSPI_IpAccessAddrSettingInvalid Wrong Address input. * @retval kStatus_XSPI_IpAccessIPCRInvalid Wrong seqindex or bytesize input. * @retval kStatus_Success Success to start Ip access. */ status_t XSPI_StartIpAccess(XSPI_Type *base, uint32_t addr, uint8_t seqIndex, size_t byteSize, xspi_target_group_t tgId, bool lockArbitration); /* @} */ /*! * @name IPS Access Control Functional Interfaces * @{ */ /*! * @brief Set IP access configurations, including SFP configurations, sfp arbitration lock timeout value, Ip access * timeout value. * * @param[in] base XSPI peripheral base address. * @param[in] ptrIpAccessConfig Pointer to the variable which contains Ip access configurations. * * @retval kStatus_XSPI_RegWriteLocked Write operation to related register is locked. * @retval kStatus_Success Success to update timeout counter. */ status_t XSPI_SetIpAccessConfig(XSPI_Type *base, xspi_ip_access_config_t *ptrIpAccessConfig); /*! * @brief Sends a buffer of data bytes using blocking method. * * @note This function blocks via polling until all bytes have been sent. * * @param[in] base XSPI peripheral base address * @param[in] buffer Pointer to the buffer to send. * @param[in] size The number of data bytes to send * * @retval kStatus_Success write success without error * @retval kStatus_XSPI_SequenceExecutionTimeout sequence execution timeout * @retval kStatus_XSPI_IpCommandSequenceError IP command sequence error detected * @retval kStatus_XSPI_IpCommandGrantTimeout IP command grant timeout detected */ status_t XSPI_WriteBlocking(XSPI_Type *base, uint8_t *buffer, size_t size); /*! * @brief Receives a buffer of data bytes using a blocking method. * * @note This function blocks via polling until all bytes have been sent. * * @param[in] base XSPI peripheral base address * @param[out] buffer Pointer to the buffer to store read data. * @param[in] size The number of data bytes to receive * * @retval kStatus_Success read success without error * @retval kStatus_XSPI_SequenceExecutionTimeout sequence execution timeout * @retval kStatus_XSPI_IpCommandSequenceError IP command sequence error detected * @retval kStatus_XSPI_IpCommandGrantTimeout IP command grant timeout detected */ status_t XSPI_ReadBlocking(XSPI_Type *base, uint8_t *buffer, size_t size); /*! * @brief Execute command to transfer a buffer data bytes using a blocking method. * * @param[in] base XSPI peripheral base address * @param[in] xfer pointer to the transfer structure. * * @retval kStatus_Success command transfer success without error * @retval kStatus_XSPI_SequenceExecutionTimeout sequence execution timeout * @retval kStatus_XSPI_IpCommandSequenceError IP command sequence error detected * @retval kStatus_XSPI_IpCommandGrantTimeout IP command grant timeout detected */ status_t XSPI_TransferBlocking(XSPI_Type *base, xspi_transfer_t *xfer); /*! * @brief Initialize the XSPI handle which is used in transactional functions. * * @param[in] base XSPI peripheral base address. * @param[in] handle pointer to xspi_handle_t structure to store the transfer state. * @param[in] callback pointer to user callback function. * @param[in] userData user parameter passed to the callback function. */ void XSPI_TransferCreateHandle(XSPI_Type *base, xspi_handle_t *handle, xspi_transfer_callback_t callback, void *userData); /*! * @brief Perform a interrupt non-blocking transfer on the XSPI bus. * * @note Calling the API returns immediately after transfer initiates. The user needs * to call XSPI_GetTransferCount to poll the transfer status to check whether * the transfer is finished. If the return status is not kStatus_XSPI_Busy, the transfer * is finished. For XSPI_Read, the dataSize should be multiple of rx watermark level, or * XSPI could not read data properly. * * @param[in] base XSPI peripheral base address. * @param[in] handle pointer to xspi_handle_t structure which stores the transfer state. * @param[in] xfer pointer to xspi_transfer_t structure. * * @retval kStatus_Success Successfully start the data transmission. * @retval kStatus_XSPI_Busy Previous transmission still not finished. */ status_t XSPI_TransferNonBlocking(XSPI_Type *base, xspi_handle_t *handle, xspi_transfer_t *xfer); /*! * @brief Get the master transfer status during a interrupt non-blocking transfer. * * @param[in] base XSPI peripheral base address. * @param[in] handle pointer to xspi_handle_t structure which stores the transfer state. * @param[out] count Number of bytes transferred so far by the non-blocking transaction. * * @retval kStatus_InvalidArgument count is Invalid. * @retval kStatus_Success Successfully return the count. */ status_t XSPI_TransferGetCount(XSPI_Type *base, xspi_handle_t *handle, size_t *count); /*! * @brief Abort an interrupt non-blocking transfer early. * * @note This API can be called at any time when an interrupt non-blocking transfer initiates * to abort the transfer early. * * @param[in] base XSPI peripheral base address. * @param[in] handle pointer to xspi_handle_t structure which stores the transfer state */ void XSPI_TransferAbort(XSPI_Type *base, xspi_handle_t *handle); /*! @} */ /*! * @name AHB Access Control Low-Level Interfaces * @{ */ /*! * @brief Blocks to clear AHB buffer and abort ongoing prefetch transaction(if prefetch is enabled.) * * @note The function return only after all AHB buffer pointers are cleared. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_ClearAhbBuffer(XSPI_Type *base) { base->SPTRCLR |= XSPI_SPTRCLR_ABRT_CLR_MASK; while ((base->SPTRCLR & XSPI_SPTRCLR_ABRT_CLR_MASK) != 0UL) { } } /*! * @brief Enable/disable the clearing of AHB read prefetch buffers when the same flash address is written by an * AHB or IP command. * * @param[in] base XSPI peripheral base address. * @param[in] enable Used to enable/disable write flush. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted. * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted. * @retval kStatus_Success Successfully to enable/disable AHB buffer write flush. */ status_t XSPI_EnableAhbBufferWriteFlush(XSPI_Type *base, bool enable); /*! * @brief Set AHB buffer configurations. * * @param[in] base XSPI peripheral base address. * @param[in] ptrBuffer0Config Pointer to the variable which contain buffer0 configurations. * @param[in] ptrBuffer1Config Pointer to the variable which contain buffer1 configurations. * @param[in] ptrBuffer2Config Pointer to the variable which contain buffer2 configurations. * @param[in] ptrBuffer3Config Pointer to the variable which contain buffer3 configurations. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted. * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted. * @retval kStatus_Success Success to set AHB buffer configurations. */ status_t XSPI_SetAhbBufferConfig(XSPI_Type *base, xspi_ahbBuffer_config_t *ptrBuffer0Config, xspi_ahbBuffer_config_t *ptrBuffer1Config, xspi_ahbBuffer_config_t *ptrBuffer2Config, xspi_ahbBuffer_config_t *ptrBuffer3Config); /*! * @brief Set Buffer size for all 4 AHB buffers. * * @param[in] base XSPI peripheral base address. * @param[in] buf0Size Specify size of AHB buffer0, range of 512, 256, 128, 64, 32, 16, 8, 4, 2, 0. * @param[in] buf1Size Specify size of AHB buffer1, range of 512, 256, 128, 64, 32, 16, 8, 4, 2, 0. * @param[in] buf2Size Specify size of AHB buffer2, range of 512, 256, 128, 64, 32, 16, 8, 4, 2, 0. * @param[in] buf3Size Specify size of AHB buffer3, range of 512, 256, 128, 64, 32, 16, 8, 4, 2, 0. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted. * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted. * @retval kStatus_Success Success to set AHB buffer size. */ status_t XSPI_UpdateAhbBufferSize(XSPI_Type *base, uint16_t buf0Size, uint16_t buf1Size, uint16_t buf2Size, uint16_t buf3Size); /*! * @brief Get status of AHB sub buffer. * * @note This function only useful when sub-division feature of the selected AHB buffer is enabled. * * @param[in] base XSPI peripheral base address. * @param[in] ahbBufferId The Id of AHB buffer, range from 0 to 3. * @param[in] subBufferId The Id of AHB buffer sub division, range from 0 to 3. * * @return Current status of selected AHB sub buffer, in type of @ref xspi_ahb_sub_buffer_status_t. */ xspi_ahb_sub_buffer_status_t XSPI_GetAhbSubBufferStatus(XSPI_Type *base, uint8_t ahbBufferId, uint8_t subBufferId); /*! * @brief Start AHB buffer performance monitor. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_StartAhbBufferPerfMonitor(XSPI_Type *base) { base->AHB_PERF_CTRL |= XSPI_AHB_PERF_CTRL_CNTSTART_MASK; } /*! * @brief Enable AHB buffer performance monitor for selected AHB buffer's sub buffer. * * @param[in] base XSPI peripheral base address. * @param[in] ahbBufferId Specify the selected AHB buffer. * @param[in] subBufferId Specify the selected sub-buffer. */ void XSPI_EnableAhbBufferPerfMonitor(XSPI_Type *base, uint8_t ahbBufferId, uint8_t subBufferId); /*! * @brief Disable AHB buffer performance monitor for selected AHB buffer. * * @param[in] base XSPI peripheral base address. * @param[in] ahbBufferId Specify the selected AHB buffer. */ static inline void XSPI_DisableAhbBufferPerfMonitor(XSPI_Type *base, uint8_t ahbBufferId) { base->AHB_PERF_CTRL &= (uint32_t)(~(uint32_t)(XSPI_AHB_PERF_CTRL_BUF0_EN_MASK << (uint32_t)(ahbBufferId))); } /*! * @brief Stop AHB buffer performance monitor. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_StopAhbBufferPerfMonitor(XSPI_Type *base) { base->AHB_PERF_CTRL |= XSPI_AHB_PERF_CTRL_CNTSTP_MASK; } /*! * @brief Get AHB buffer performance monitor result. * * @param[in] base XSPI peripheral base address. * @param[in] ahbBufferId Specify AHB buffer Id. * @param[out] ptrPerfMonitorResult Pointer to the variable to store selected AHB buffer's performance monitor result. */ static inline void XSPI_GetAhbBufferPerfMonitorResult(XSPI_Type *base, uint8_t ahbBufferId, xspi_ahbBuffer_perf_monitor_result_t *ptrPerfMonitorResult) { uint32_t tmp32 = 0UL; tmp32 = (uint32_t)(base->AHB_PERF_BUF[ahbBufferId]); ptrPerfMonitorResult->bufferMissCount = (uint16_t)(tmp32 & 0xFFFFUL); ptrPerfMonitorResult->bufferHitCount = (uint16_t)((tmp32 & 0xFFFF0000UL) >> 16UL); } /*! * @brief Check if AHB buffer performance monitor timeout counter is overflow. * * @param base XSPI peripheral base address. * * @retval false AHB buffer performance monitor timeout counter is not overflow. * @retval true AHB buffer performance monitor timeout counter is overflow. */ static inline bool XSPI_CheckAhbBufferPerfMonitorTimeCounterOverflow(XSPI_Type *base) { return (bool)((base->AHB_PERF_CTRL & XSPI_AHB_PERF_CTRL_TCNTO_MASK) != 0UL); } /*! * @brief Check if AHB buffer performance monitor buffer hit counter is overflow. * * @param[in] base XSPI peripheral base address. * @param[in] ahbBufferId Specify the AHB buffer Id. * * @retval false Overflow not detected. * @retval true Overflow is detected. */ static inline bool XSPI_CheckAhbBufferPerfMonitorHitOverflow(XSPI_Type *base, uint8_t ahbBufferId) { return (bool)((base->AHB_PERF_CTRL & (XSPI_AHB_PERF_CTRL_BUF0_HIT_OVF_MASK << (uint32_t)ahbBufferId)) != 0UL); } /*! * @brief Check if AHB buffer performance monitor buffer miss counter is overflow. * * @param[in] base XSPI peripheral base address. * @param[in] ahbBufferId Specify the AHB buffer Id. * * @retval false Overflow not detected. * @retval true Overflow is detected. */ static inline bool XSPI_CheckAhbBufferPerfMonitorMissOverflow(XSPI_Type *base, uint8_t ahbBufferId) { return (bool)((base->AHB_PERF_CTRL & ((uint32_t)XSPI_AHB_PERF_CTRL_BUF0_MISS_OVF_MASK << (uint32_t)ahbBufferId)) != 0UL); } /*! * @brief Get AHB buffer performance monitor timeout value. * * @param[in] base XSPI peripheral base address. * * @return The value of time counter, in AHB clock cycles, since the performance monitor was running. */ static inline uint32_t XSPI_GetAhbBufferPerfMonitorTimeCounter(XSPI_Type *base) { return base->AHB_PERF_TIME_CNT; } /*! * @brief Set AHB transaction(read/write) split size. * * @note For AHB write, if enable split feature(ahbSplitSize not set as kXSPI_AhbSplitSizeDisabled), XSPI will split one * single AHB write burst into smaller bursts on external device side. * * @note For AHB read, if enable split feature, HW will realign the prefetch size to split size and in that way split * a single read burst into smaller bursts. * * @param[in] base XSPI peripheral base address. * @param[in] ahbSplitSize Specify the AHB split size. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_RegWriteLocked Fail due to write operation to related registers is locked. * @retval kStatus_Success Success to set AHB access split size. */ status_t XSPI_SetAhbAccessSplitSize(XSPI_Type *base, xspi_ahb_split_size_t ahbSplitSize); /*! * @brief Set AHB transaction(read/write) boundary. * * @note For AHB write, XSPI keeps track of the start address and then compares it with the address of subsequent * transaction receive on the AHB bus, when the input alignment is reached, XSPI negates AHB HREADY to block new * accesses. This signal will be kept low until all the previous received write data is written to external memory and * chip select is de-asserted. After that it allows next AHB write data to be received by making HREADY high thus * ensuring that transaction is split at address boundary on external memory. * * @note For AHB read, XSPI checks the start address and end address to see if it is crossing the address boundary * specified by input alignment. If the transaction crosses the address boundary, then it reduces the transaction size * such that the data pre-fetch is stopped before the address boundary. Now if the AHB master is reading the data * sequentially it will get buffer hits up to the input alignment boundary. When it reaches the next address boundary * it will get a buffer miss and a new data pre-fetch will be launched towards the external memory device. * * @param[in] base XSPI peripheral base address. * @param[in] alignment Specify the AHB alignment, in type of @ref xspi_ahb_alignment_t. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_RegWriteLocked Fail due to write operation to related registers is locked. * @retval kStatus_Success Success to set AHB access boundary. */ status_t XSPI_SetAhbAccessBoundary(XSPI_Type *base, xspi_ahb_alignment_t alignment); /*! * @brief Set AHB read sequence Id. * * @param[in] base XSPI peripheral base address. * @param[in] seqId Specify the sequence Id in LUT used for AHB read. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_RegWriteLocked Fail due to write operation to related registers is locked. * @retval kStatus_Success Success to set AHB read sequence Id. */ status_t XSPI_SetAhbReadDataSeqId(XSPI_Type *base, uint8_t seqId); /*! * @brief Set AHB write sequence Id. * * @param[in] base XSPI peripheral base address. * @param[in] seqId Specify the sequence Id in LUT used for AHB write. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_RegWriteLocked Fail due to write operation to related registers is locked. * @retval kStatus_Success Success to set AHB write sequence Id. */ status_t XSPI_SetAhbWriteDataSeqId(XSPI_Type *base, uint8_t seqId); /*! * @brief Specify how long XSPI can hold HEADY low while waiting for response to an AHB transfer. * * @note If the specified time out value expired, an AHB illegal transaction error will be triggerred. * * @param[in] base XSPI peripheral base address. * @param[in] timeoutValue In multiples of 50000 AHB clock cycles, default value is 3, * it means waiting for 150000 AHB clock cycles. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_Success Success to set AHB HREADY timeout value. */ status_t XSPI_UpdateAhbHreadyTimeOutValue(XSPI_Type *base, uint16_t timeoutValue); /*! * @brief Pre-define error payload which will be provided on the read data bus when the HEADY timeout counter expires. * * @note If the incoming AHB read request master is not mapped to any of the AHB buffer, the XSPI will keep the AHB * HREADY signal low and will provided this pre-defined error payload on the AHB read data bus when the HEADY timeout * counter expires. * * @param[in] base XSPI peripheral base address. * @param[in] highPayload High 32bits payload to set. * @param[in] lowPayload Low 32bits payload to set. * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_Success Success to set AHB HREADY timeout value. */ status_t XSPI_SetAhbErrorPayload(XSPI_Type *base, uint32_t highPayload, uint32_t lowPayload); /*! * @brief Return AHB read error information. * * @param[in] base XSPI peripheral base address. * * @return Latest AHB read error information, in type of xspi_ahb_read_error_info_t. */ xspi_ahb_read_error_info_t XSPI_ReturnAhbReadErrorInfo(XSPI_Type *base); /*! * @brief Clear AHB access sequence pointer. * * @param[in] base XSPI peripheral base address. */ static inline void XSPI_ClearAhbAccessSeqPointer(XSPI_Type *base) { base->SPTRCLR |= XSPI_SPTRCLR_BFPTRC_MASK; } /*! * @brief Get Ahb request suspend information if priority mechanism is enabled. * * @param[in] base XSPI peripheral base address. * @param[out] ptrSuspendInfo Contain latest suspend info, the value may be 0xFF if the item is invalid in current * suspend state. */ void XSPI_GetAhbRequestSuspendInfo(XSPI_Type *base, xspi_ahb_request_suspend_info_t *ptrSuspendInfo); /*! * @brief Enable/disable AHB Read Prefetch feature. * * @param[in] base XSPI peripheral base address. * @param[in] enable Used to enable/disable AHB read prefetch: * - \b false Disable AHB read prefetch; * - \b true Enable AHB read prefetch. */ static inline void XSPI_EnableAhbReadPrefetch(XSPI_Type *base, bool enable) { if (enable) { base->SPTRCLR &= ~XSPI_SPTRCLR_PREFETCH_DIS_MASK; } else { base->SPTRCLR |= XSPI_SPTRCLR_PREFETCH_DIS_MASK; } } /*! * @brief Block access(write and read) after the AHB write operation. * * @note If external flash support RWW, read should not be blocked: * @code * XSPI_BlockAccessAfterAhbWrite(XSPI0, true, false); * @endcode * * @note If either of access is blocked, the page program wait flag will be asserted after * an AHB write sequence completed. The assertion of flag will lock the arbitration and all * access to the external memory are blocked. And the internal "page wait time" counter * starts(Invoke XSPI_UpdatePageWaitTimeCounter to update counter value). After this counter * reaches the value, a read is triggered by the XSPI module to read external device's * status register(The seq id should be pre-defiend by XSPI_SetAhbReadStatusRegSeqId), * and the value is stored in the XSPI internal regsiter. And there are two * options(Invoke XSPI_SelectPPWFlagClearPolicy to select) to clear the asserted page program wait flag. * 1. Automatic cleared by XSPI hardware; * 2. Cleared by software. * * @note As soon as the page program wait flag is asserted, another counter(SFP arbitration * lock counter) also started, if the flag not cleared in desired counter value the * arbitration lock timeout error will be generated. * * @param[in] base XSPI peripheral base address. * @param[in] blockSequentWrite Block sequence write or not. * @param[in] blockRead Block read or not. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_Success Success to set related registers.. */ status_t XSPI_BlockAccessAfterAhbWrite(XSPI_Type *base, bool blockSequentWrite, bool blockRead); /*! * @brief Set Page program wait flag clear policy. * * @note If set as hardware policy, the device's WIP information should be set by invoking XSPI_SetSFMStatusRegInfo() * * @param[in] base XSPI peripheral base address. * @param[in] policy Specify the policy to clear page program wait flag. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_RegWriteLocked Fail due to write operation to related registers is locked. * @retval kStatus_Success Success to set PPW flag clear policy. */ status_t XSPI_SelectPPWFlagClearPolicy(XSPI_Type *base, xspi_ppw_flag_clear_policy_t policy); /*! * @brief Update page wait timeout counter. * * @param[in] base XSPI peripheral base address. * @param[in] countValue The value of counter, in AHB clock cycles. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_PageProgramWaitFlagAsserted Page program wait flag already asserted. * @retval kStatus_Success Successfully to update page wait timeout counter. */ status_t XSPI_UpdatePageWaitTimeCounter(XSPI_Type *base, uint32_t countValue); /*! * @brief Set AHB read status register sequence Id * * @note The read status sequence only triggerred when the page wait time counter expired. * * @param[in] base XSPI peripheral base address. * @param[in] seqId Specify the sequence Id in LUT used for AHB read status register. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_RegWriteLocked Fail due to write operation to related registers is locked. * @retval kStatus_Success Success to set AHB read status register sequence Id. */ status_t XSPI_SetAhbReadStatusRegSeqId(XSPI_Type *base, uint8_t seqId); /*! * @brief Get external serial flash's status register value. * * @note This function is only useful after the Page program wait flag is asserted due to * either wait/read access is blocked after the AHB write operation. * * @param[in] base XSPI peripheral base address. * * @return The status regsiter value of external device. */ static inline uint16_t XSPI_GetSFMStatusRegValue(XSPI_Type *base) { while ((base->PPW_RDSR & XSPI_PPW_RDSR_VALID_MASK) == 0UL) { } return (uint16_t)(base->PPW_RDSR & XSPI_PPW_RDSR_RDSR_MASK); } /*! * @brief Set Serial flash memory status register information * * @param[in] base XSPI peripheral base address. * @param[in] ptrStatusRegInfo Pointer to the variable which contain status register information. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_PageProgramWaitFlagAsserted Page program wait flag already asserted. * @retval kStatus_Success Successfully to set status register information. */ status_t XSPI_SetSFMStatusRegInfo(XSPI_Type *base, xspi_device_status_reg_info_t *ptrStatusRegInfo); /*! @} */ /*! * @name AHB Access Control Functional Interfaces * @{ */ /*! * @brief Set AHB access configuration. * * @param[in] base XSPI peripheral base address. * @param[in] ptrAhbAccessConfig Pointer to the variable which contains AHB access configurations. * * @retval kStatus_XSPI_AhbReadAccessAsserted Fail due to an AHB read access already asserted * @retval kStatus_XSPI_AhbWriteAccessAsserted Fail due to an AHB write access already asserted * @retval kStatus_XSPI_RegWriteLocked Fail due to write operation to related registers is locked. * @retval kStatus_Success Success to set AHB read status register sequence Id. */ status_t XSPI_SetAhbAccessConfig(XSPI_Type *base, xspi_ahb_access_config_t *ptrAhbAccessConfig); /*! @} */ /*! @} */ #if defined(__cplusplus) } #endif /*_cplusplus. */ /*@}*/ #endif /* FSL_XSPI_H_ */