Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:02

0001 /*
0002  * Copyright (c) 2016, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2021 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 #ifndef _FSL_USDHC_H_
0009 #define _FSL_USDHC_H_
0010 
0011 #include "fsl_common.h"
0012 
0013 /*!
0014  * @addtogroup usdhc
0015  * @{
0016  */
0017 
0018 /******************************************************************************
0019  * Definitions.
0020  *****************************************************************************/
0021 
0022 /*! @name Driver version */
0023 /*@{*/
0024 /*! @brief Driver version 2.8.2. */
0025 #define FSL_USDHC_DRIVER_VERSION (MAKE_VERSION(2U, 8U, 2U))
0026 /*@}*/
0027 
0028 /*! @brief Maximum block count can be set one time */
0029 #define USDHC_MAX_BLOCK_COUNT (USDHC_BLK_ATT_BLKCNT_MASK >> USDHC_BLK_ATT_BLKCNT_SHIFT)
0030 
0031 /*! @brief USDHC scatter gather feature control macro */
0032 #ifndef FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
0033 #define FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER 0U
0034 #endif
0035 
0036 /*! @brief Enum _usdhc_status. USDHC status. */
0037 enum
0038 {
0039     kStatus_USDHC_BusyTransferring            = MAKE_STATUS(kStatusGroup_USDHC, 0U),  /*!< Transfer is on-going. */
0040     kStatus_USDHC_PrepareAdmaDescriptorFailed = MAKE_STATUS(kStatusGroup_USDHC, 1U),  /*!< Set DMA descriptor failed. */
0041     kStatus_USDHC_SendCommandFailed           = MAKE_STATUS(kStatusGroup_USDHC, 2U),  /*!< Send command failed. */
0042     kStatus_USDHC_TransferDataFailed          = MAKE_STATUS(kStatusGroup_USDHC, 3U),  /*!< Transfer data failed. */
0043     kStatus_USDHC_DMADataAddrNotAlign         = MAKE_STATUS(kStatusGroup_USDHC, 4U),  /*!< Data address not aligned. */
0044     kStatus_USDHC_ReTuningRequest             = MAKE_STATUS(kStatusGroup_USDHC, 5U),  /*!< Re-tuning request. */
0045     kStatus_USDHC_TuningError                 = MAKE_STATUS(kStatusGroup_USDHC, 6U),  /*!< Tuning error. */
0046     kStatus_USDHC_NotSupport                  = MAKE_STATUS(kStatusGroup_USDHC, 7U),  /*!< Not support. */
0047     kStatus_USDHC_TransferDataComplete        = MAKE_STATUS(kStatusGroup_USDHC, 8U),  /*!< Transfer data complete. */
0048     kStatus_USDHC_SendCommandSuccess          = MAKE_STATUS(kStatusGroup_USDHC, 9U),  /*!< Transfer command complete. */
0049     kStatus_USDHC_TransferDMAComplete         = MAKE_STATUS(kStatusGroup_USDHC, 10U), /*!< Transfer DMA complete. */
0050 };
0051 
0052 /*! @brief Enum _usdhc_capability_flag. Host controller capabilities flag mask.
0053  *  @anchor _usdhc_capability_flag
0054  */
0055 enum
0056 {
0057     kUSDHC_SupportAdmaFlag          = USDHC_HOST_CTRL_CAP_ADMAS_MASK, /*!< Support ADMA. */
0058     kUSDHC_SupportHighSpeedFlag     = USDHC_HOST_CTRL_CAP_HSS_MASK,   /*!< Support high-speed. */
0059     kUSDHC_SupportDmaFlag           = USDHC_HOST_CTRL_CAP_DMAS_MASK,  /*!< Support DMA. */
0060     kUSDHC_SupportSuspendResumeFlag = USDHC_HOST_CTRL_CAP_SRS_MASK,   /*!< Support suspend/resume. */
0061     kUSDHC_SupportV330Flag          = USDHC_HOST_CTRL_CAP_VS33_MASK,  /*!< Support voltage 3.3V. */
0062     kUSDHC_SupportV300Flag          = USDHC_HOST_CTRL_CAP_VS30_MASK,  /*!< Support voltage 3.0V. */
0063     kUSDHC_SupportV180Flag          = USDHC_HOST_CTRL_CAP_VS18_MASK,  /*!< Support voltage 1.8V. */
0064     kUSDHC_Support4BitFlag          = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 0U),
0065     /*!< Flag in HTCAPBLT_MBL's position, supporting 4-bit mode. */
0066     kUSDHC_Support8BitFlag = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 1U),
0067     /*!< Flag in HTCAPBLT_MBL's position, supporting 8-bit mode. */
0068     kUSDHC_SupportDDR50Flag = USDHC_HOST_CTRL_CAP_DDR50_SUPPORT_MASK,
0069 /*!< SD version 3.0 new feature, supporting DDR50 mode. */
0070 
0071 #if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR104_MODE)
0072     kUSDHC_SupportSDR104Flag = 0, /*!< not support SDR104 mode */
0073 #else
0074     kUSDHC_SupportSDR104Flag   = USDHC_HOST_CTRL_CAP_SDR104_SUPPORT_MASK, /*!< Support SDR104 mode. */
0075 #endif
0076 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
0077     kUSDHC_SupportSDR50Flag = 0U, /*!< not support SDR50 mode */
0078 #else
0079     kUSDHC_SupportSDR50Flag    = USDHC_HOST_CTRL_CAP_SDR50_SUPPORT_MASK,  /*!< Support SDR50 mode. */
0080 #endif
0081 };
0082 
0083 /*! @brief Enum _usdhc_wakeup_event. Wakeup event mask.
0084  *  @anchor _usdhc_wakeup_event
0085  */
0086 enum
0087 {
0088     kUSDHC_WakeupEventOnCardInt    = USDHC_PROT_CTRL_WECINT_MASK, /*!< Wakeup on card interrupt. */
0089     kUSDHC_WakeupEventOnCardInsert = USDHC_PROT_CTRL_WECINS_MASK, /*!< Wakeup on card insertion. */
0090     kUSDHC_WakeupEventOnCardRemove = USDHC_PROT_CTRL_WECRM_MASK,  /*!< Wakeup on card removal. */
0091     kUSDHC_WakeupEventsAll =
0092         (kUSDHC_WakeupEventOnCardInt | kUSDHC_WakeupEventOnCardInsert | kUSDHC_WakeupEventOnCardRemove),
0093     /*!< All wakeup events */
0094 };
0095 
0096 /*! @brief Enum _usdhc_reset. Reset type mask.
0097  *  @anchor _usdhc_reset
0098  */
0099 enum
0100 {
0101     kUSDHC_ResetAll     = USDHC_SYS_CTRL_RSTA_MASK, /*!< Reset all except card detection. */
0102     kUSDHC_ResetCommand = USDHC_SYS_CTRL_RSTC_MASK, /*!< Reset command line. */
0103     kUSDHC_ResetData    = USDHC_SYS_CTRL_RSTD_MASK, /*!< Reset data line. */
0104 
0105 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
0106     kUSDHC_ResetTuning = 0U, /*!< no reset tuning circuit bit */
0107 #else
0108     kUSDHC_ResetTuning         = USDHC_SYS_CTRL_RSTT_MASK,                /*!< Reset tuning circuit. */
0109 #endif
0110 
0111     kUSDHC_ResetsAll = (kUSDHC_ResetAll | kUSDHC_ResetCommand | kUSDHC_ResetData | kUSDHC_ResetTuning),
0112     /*!< All reset types */
0113 };
0114 
0115 /*! @brief Enum _usdhc_transfer_flag. Transfer flag mask. */
0116 enum
0117 {
0118     kUSDHC_EnableDmaFlag = USDHC_MIX_CTRL_DMAEN_MASK, /*!< Enable DMA. */
0119 
0120     kUSDHC_CommandTypeSuspendFlag = USDHC_CMD_XFR_TYP_CMDTYP(1U), /*!< Suspend command. */
0121     kUSDHC_CommandTypeResumeFlag  = USDHC_CMD_XFR_TYP_CMDTYP(2U), /*!< Resume command. */
0122     kUSDHC_CommandTypeAbortFlag   = USDHC_CMD_XFR_TYP_CMDTYP(3U), /*!< Abort command. */
0123 
0124     kUSDHC_EnableBlockCountFlag    = USDHC_MIX_CTRL_BCEN_MASK,   /*!< Enable block count. */
0125     kUSDHC_EnableAutoCommand12Flag = USDHC_MIX_CTRL_AC12EN_MASK, /*!< Enable auto CMD12. */
0126     kUSDHC_DataReadFlag            = USDHC_MIX_CTRL_DTDSEL_MASK, /*!< Enable data read. */
0127     kUSDHC_MultipleBlockFlag       = USDHC_MIX_CTRL_MSBSEL_MASK, /*!< Multiple block data read/write. */
0128     kUSDHC_EnableAutoCommand23Flag = USDHC_MIX_CTRL_AC23EN_MASK, /*!< Enable auto CMD23. */
0129 
0130     kUSDHC_ResponseLength136Flag    = USDHC_CMD_XFR_TYP_RSPTYP(1U), /*!< 136-bit response length. */
0131     kUSDHC_ResponseLength48Flag     = USDHC_CMD_XFR_TYP_RSPTYP(2U), /*!< 48-bit response length. */
0132     kUSDHC_ResponseLength48BusyFlag = USDHC_CMD_XFR_TYP_RSPTYP(3U), /*!< 48-bit response length with busy status. */
0133 
0134     kUSDHC_EnableCrcCheckFlag   = USDHC_CMD_XFR_TYP_CCCEN_MASK, /*!< Enable CRC check. */
0135     kUSDHC_EnableIndexCheckFlag = USDHC_CMD_XFR_TYP_CICEN_MASK, /*!< Enable index check. */
0136     kUSDHC_DataPresentFlag      = USDHC_CMD_XFR_TYP_DPSEL_MASK, /*!< Data present flag. */
0137 };
0138 
0139 /*! @brief Enum _usdhc_present_status_flag. Present status flag mask.
0140  *  @anchor _usdhc_present_status_flag
0141  */
0142 enum
0143 {
0144     kUSDHC_CommandInhibitFlag      = USDHC_PRES_STATE_CIHB_MASK,  /*!< Command inhibit. */
0145     kUSDHC_DataInhibitFlag         = USDHC_PRES_STATE_CDIHB_MASK, /*!< Data inhibit. */
0146     kUSDHC_DataLineActiveFlag      = USDHC_PRES_STATE_DLA_MASK,   /*!< Data line active. */
0147     kUSDHC_SdClockStableFlag       = USDHC_PRES_STATE_SDSTB_MASK, /*!< SD bus clock stable. */
0148     kUSDHC_WriteTransferActiveFlag = USDHC_PRES_STATE_WTA_MASK,   /*!< Write transfer active. */
0149     kUSDHC_ReadTransferActiveFlag  = USDHC_PRES_STATE_RTA_MASK,   /*!< Read transfer active. */
0150     kUSDHC_BufferWriteEnableFlag   = USDHC_PRES_STATE_BWEN_MASK,  /*!< Buffer write enable. */
0151     kUSDHC_BufferReadEnableFlag    = USDHC_PRES_STATE_BREN_MASK,  /*!< Buffer read enable. */
0152 
0153 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
0154     kUSDHC_DelaySettingFinishedFlag = 0U, /*!< not support */
0155     kUSDHC_ReTuningRequestFlag      = 0U, /*!< not support */
0156 #else
0157     kUSDHC_ReTuningRequestFlag = USDHC_PRES_STATE_RTR_MASK, /*!< Re-tuning request flag, only used for SDR104 mode. */
0158     kUSDHC_DelaySettingFinishedFlag = USDHC_PRES_STATE_TSCD_MASK, /*!< Delay setting finished flag. */
0159 #endif
0160 
0161     kUSDHC_CardInsertedFlag     = USDHC_PRES_STATE_CINST_MASK, /*!< Card inserted. */
0162     kUSDHC_CommandLineLevelFlag = USDHC_PRES_STATE_CLSL_MASK,  /*!< Command line signal level. */
0163 
0164     kUSDHC_Data0LineLevelFlag = 1U << USDHC_PRES_STATE_DLSL_SHIFT,               /*!< Data0 line signal level. */
0165     kUSDHC_Data1LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 1U),        /*!< Data1 line signal level. */
0166     kUSDHC_Data2LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 2U),        /*!< Data2 line signal level. */
0167     kUSDHC_Data3LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 3U),        /*!< Data3 line signal level. */
0168     kUSDHC_Data4LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 4U),        /*!< Data4 line signal level. */
0169     kUSDHC_Data5LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 5U),        /*!< Data5 line signal level. */
0170     kUSDHC_Data6LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 6U),        /*!< Data6 line signal level. */
0171     kUSDHC_Data7LineLevelFlag = (int)(1U << (USDHC_PRES_STATE_DLSL_SHIFT + 7U)), /*!< Data7 line signal level. */
0172 };
0173 
0174 /*! @brief Enum _usdhc_interrupt_status_flag. Interrupt status flag mask.
0175  *  @anchor _usdhc_interrupt_status_flag
0176  */
0177 enum
0178 {
0179     kUSDHC_CommandCompleteFlag  = USDHC_INT_STATUS_CC_MASK,   /*!< Command complete. */
0180     kUSDHC_DataCompleteFlag     = USDHC_INT_STATUS_TC_MASK,   /*!< Data complete. */
0181     kUSDHC_BlockGapEventFlag    = USDHC_INT_STATUS_BGE_MASK,  /*!< Block gap event. */
0182     kUSDHC_DmaCompleteFlag      = USDHC_INT_STATUS_DINT_MASK, /*!< DMA interrupt. */
0183     kUSDHC_BufferWriteReadyFlag = USDHC_INT_STATUS_BWR_MASK,  /*!< Buffer write ready. */
0184     kUSDHC_BufferReadReadyFlag  = USDHC_INT_STATUS_BRR_MASK,  /*!< Buffer read ready. */
0185     kUSDHC_CardInsertionFlag    = USDHC_INT_STATUS_CINS_MASK, /*!< Card inserted. */
0186     kUSDHC_CardRemovalFlag      = USDHC_INT_STATUS_CRM_MASK,  /*!< Card removed. */
0187     kUSDHC_CardInterruptFlag    = USDHC_INT_STATUS_CINT_MASK, /*!< Card interrupt. */
0188 
0189 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
0190     kUSDHC_ReTuningEventFlag = 0U, /*!< Re-Tuning event, only for SD3.0 SDR104 mode. */
0191     kUSDHC_TuningPassFlag    = 0U, /*!< SDR104 mode tuning pass flag. */
0192     kUSDHC_TuningErrorFlag   = 0U, /*!< SDR104 tuning error flag. */
0193 #else
0194     kUSDHC_ReTuningEventFlag        = USDHC_INT_STATUS_RTE_MASK,  /*!< Re-Tuning event, only for SD3.0 SDR104 mode. */
0195     kUSDHC_TuningPassFlag           = USDHC_INT_STATUS_TP_MASK,   /*!< SDR104 mode tuning pass flag. */
0196     kUSDHC_TuningErrorFlag          = USDHC_INT_STATUS_TNE_MASK,  /*!< SDR104 tuning error flag. */
0197 #endif
0198 
0199     kUSDHC_CommandTimeoutFlag     = USDHC_INT_STATUS_CTOE_MASK,  /*!< Command timeout error. */
0200     kUSDHC_CommandCrcErrorFlag    = USDHC_INT_STATUS_CCE_MASK,   /*!< Command CRC error. */
0201     kUSDHC_CommandEndBitErrorFlag = USDHC_INT_STATUS_CEBE_MASK,  /*!< Command end bit error. */
0202     kUSDHC_CommandIndexErrorFlag  = USDHC_INT_STATUS_CIE_MASK,   /*!< Command index error. */
0203     kUSDHC_DataTimeoutFlag        = USDHC_INT_STATUS_DTOE_MASK,  /*!< Data timeout error. */
0204     kUSDHC_DataCrcErrorFlag       = USDHC_INT_STATUS_DCE_MASK,   /*!< Data CRC error. */
0205     kUSDHC_DataEndBitErrorFlag    = USDHC_INT_STATUS_DEBE_MASK,  /*!< Data end bit error. */
0206     kUSDHC_AutoCommand12ErrorFlag = USDHC_INT_STATUS_AC12E_MASK, /*!< Auto CMD12 error. */
0207     kUSDHC_DmaErrorFlag           = USDHC_INT_STATUS_DMAE_MASK,  /*!< DMA error. */
0208 
0209     kUSDHC_CommandErrorFlag = (kUSDHC_CommandTimeoutFlag | kUSDHC_CommandCrcErrorFlag | kUSDHC_CommandEndBitErrorFlag |
0210                                kUSDHC_CommandIndexErrorFlag), /*!< Command error */
0211     kUSDHC_DataErrorFlag    = (kUSDHC_DataTimeoutFlag | kUSDHC_DataCrcErrorFlag | kUSDHC_DataEndBitErrorFlag |
0212                             kUSDHC_AutoCommand12ErrorFlag),                                        /*!< Data error */
0213     kUSDHC_ErrorFlag        = (kUSDHC_CommandErrorFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< All error */
0214 
0215     kUSDHC_DataFlag = (kUSDHC_DataCompleteFlag | kUSDHC_BufferWriteReadyFlag | kUSDHC_BufferReadReadyFlag |
0216                        kUSDHC_DataErrorFlag), /*!< Data interrupts */
0217 
0218     kUSDHC_DataDMAFlag = (kUSDHC_DataCompleteFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< Data interrupts */
0219 
0220     kUSDHC_CommandFlag      = (kUSDHC_CommandErrorFlag | kUSDHC_CommandCompleteFlag), /*!< Command interrupts */
0221     kUSDHC_CardDetectFlag   = (kUSDHC_CardInsertionFlag | kUSDHC_CardRemovalFlag),    /*!< Card detection interrupts */
0222     kUSDHC_SDR104TuningFlag = (kUSDHC_TuningErrorFlag | kUSDHC_TuningPassFlag | kUSDHC_ReTuningEventFlag),
0223     /*!< SDR104 tuning flag. */
0224     kUSDHC_AllInterruptFlags =
0225         (kUSDHC_BlockGapEventFlag | kUSDHC_CardInterruptFlag | kUSDHC_CommandFlag | kUSDHC_DataFlag | kUSDHC_ErrorFlag |
0226          kUSDHC_SDR104TuningFlag | kUSDHC_DmaCompleteFlag), /*!< All flags mask */
0227 };
0228 
0229 /*! @brief Enum _usdhc_auto_command12_error_status_flag. Auto CMD12 error status flag mask.
0230  *  @anchor _usdhc_auto_command12_error_status_flag
0231  */
0232 enum
0233 {
0234     kUSDHC_AutoCommand12NotExecutedFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12NE_MASK,    /*!< Not executed error. */
0235     kUSDHC_AutoCommand12TimeoutFlag     = USDHC_AUTOCMD12_ERR_STATUS_AC12TOE_MASK,   /*!< Timeout error. */
0236     kUSDHC_AutoCommand12EndBitErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12EBE_MASK,   /*!< End bit error. */
0237     kUSDHC_AutoCommand12CrcErrorFlag    = USDHC_AUTOCMD12_ERR_STATUS_AC12CE_MASK,    /*!< CRC error. */
0238     kUSDHC_AutoCommand12IndexErrorFlag  = USDHC_AUTOCMD12_ERR_STATUS_AC12IE_MASK,    /*!< Index error. */
0239     kUSDHC_AutoCommand12NotIssuedFlag   = USDHC_AUTOCMD12_ERR_STATUS_CNIBAC12E_MASK, /*!< Not issued error. */
0240 };
0241 
0242 /*! @brief Enum _usdhc_standard_tuning. Standard tuning flag. */
0243 enum
0244 {
0245 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
0246     kUSDHC_ExecuteTuning        = 0U, /*!< not support */
0247     kUSDHC_TuningSampleClockSel = 0U, /*!< not support */
0248 #else
0249     kUSDHC_ExecuteTuning = USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK, /*!< Used to start tuning procedure. */
0250     kUSDHC_TuningSampleClockSel =
0251         USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK,               /*!< When <b>std_tuning_en</b> bit is set, this
0252                                                                     bit is used to select sampleing clock. */
0253 #endif
0254 };
0255 
0256 /*! @brief Enum _usdhc_adma_error_status_flag. ADMA error status flag mask.
0257  *  @anchor _usdhc_adma_error_status_flag
0258  */
0259 enum
0260 {
0261     kUSDHC_AdmaLenghMismatchFlag   = USDHC_ADMA_ERR_STATUS_ADMALME_MASK, /*!< Length mismatch error. */
0262     kUSDHC_AdmaDescriptorErrorFlag = USDHC_ADMA_ERR_STATUS_ADMADCE_MASK, /*!< Descriptor error. */
0263 };
0264 
0265 /*!
0266  * @brief Enum _usdhc_adma_error_state. ADMA error state.
0267  *
0268  * This state is the detail state when ADMA error has occurred.
0269  */
0270 enum
0271 {
0272     kUSDHC_AdmaErrorStateStopDma = 0x00U,
0273     /*!< Stop DMA, previous location set in the ADMA system address is errored address. */
0274     kUSDHC_AdmaErrorStateFetchDescriptor = 0x01U,
0275     /*!< Fetch descriptor, current location set in the ADMA system address is errored address. */
0276     kUSDHC_AdmaErrorStateChangeAddress = 0x02U, /*!< Change address, no DMA error has occurred. */
0277     kUSDHC_AdmaErrorStateTransferData  = 0x03U,
0278     /*!< Transfer data, previous location set in the ADMA system address is errored address. */
0279     kUSDHC_AdmaErrorStateInvalidLength     = 0x04U, /*!< Invalid length in ADMA descriptor. */
0280     kUSDHC_AdmaErrorStateInvalidDescriptor = 0x08U, /*!< Invalid descriptor fetched by ADMA. */
0281 
0282     kUSDHC_AdmaErrorState = kUSDHC_AdmaErrorStateInvalidLength | kUSDHC_AdmaErrorStateInvalidDescriptor |
0283                             kUSDHC_AdmaErrorStateFetchDescriptor, /*!< ADMA error state */
0284 };
0285 
0286 /*! @brief Enum _usdhc_force_event. Force event bit position.
0287  *  @anchor _usdhc_force_event
0288  */
0289 enum
0290 {
0291     kUSDHC_ForceEventAutoCommand12NotExecuted =
0292         USDHC_FORCE_EVENT_FEVTAC12NE_MASK, /*!< Auto CMD12 not executed error. */
0293     kUSDHC_ForceEventAutoCommand12Timeout    = USDHC_FORCE_EVENT_FEVTAC12TOE_MASK,  /*!< Auto CMD12 timeout error. */
0294     kUSDHC_ForceEventAutoCommand12CrcError   = USDHC_FORCE_EVENT_FEVTAC12CE_MASK,   /*!< Auto CMD12 CRC error. */
0295     kUSDHC_ForceEventEndBitError             = USDHC_FORCE_EVENT_FEVTAC12EBE_MASK,  /*!< Auto CMD12 end bit error. */
0296     kUSDHC_ForceEventAutoCommand12IndexError = USDHC_FORCE_EVENT_FEVTAC12IE_MASK,   /*!< Auto CMD12 index error. */
0297     kUSDHC_ForceEventAutoCommand12NotIssued = USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK, /*!< Auto CMD12 not issued error. */
0298     kUSDHC_ForceEventCommandTimeout         = USDHC_FORCE_EVENT_FEVTCTOE_MASK,      /*!< Command timeout error. */
0299     kUSDHC_ForceEventCommandCrcError        = USDHC_FORCE_EVENT_FEVTCCE_MASK,       /*!< Command CRC error. */
0300     kUSDHC_ForceEventCommandEndBitError     = USDHC_FORCE_EVENT_FEVTCEBE_MASK,      /*!< Command end bit error. */
0301     kUSDHC_ForceEventCommandIndexError      = USDHC_FORCE_EVENT_FEVTCIE_MASK,       /*!< Command index error. */
0302     kUSDHC_ForceEventDataTimeout            = USDHC_FORCE_EVENT_FEVTDTOE_MASK,      /*!< Data timeout error. */
0303     kUSDHC_ForceEventDataCrcError           = USDHC_FORCE_EVENT_FEVTDCE_MASK,       /*!< Data CRC error. */
0304     kUSDHC_ForceEventDataEndBitError        = USDHC_FORCE_EVENT_FEVTDEBE_MASK,      /*!< Data end bit error. */
0305     kUSDHC_ForceEventAutoCommand12Error     = USDHC_FORCE_EVENT_FEVTAC12E_MASK,     /*!< Auto CMD12 error. */
0306     kUSDHC_ForceEventCardInt                = (int)USDHC_FORCE_EVENT_FEVTCINT_MASK, /*!< Card interrupt. */
0307     kUSDHC_ForceEventDmaError               = USDHC_FORCE_EVENT_FEVTDMAE_MASK,      /*!< Dma error. */
0308 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
0309     kUSDHC_ForceEventTuningError = 0U, /*!< not support */
0310 #else
0311     kUSDHC_ForceEventTuningError = USDHC_FORCE_EVENT_FEVTTNE_MASK, /*!< Tuning error. */
0312 #endif
0313 
0314     kUSDHC_ForceEventsAll =
0315         (int)(USDHC_FORCE_EVENT_FEVTAC12NE_MASK | USDHC_FORCE_EVENT_FEVTAC12TOE_MASK |
0316               USDHC_FORCE_EVENT_FEVTAC12CE_MASK | USDHC_FORCE_EVENT_FEVTAC12EBE_MASK |
0317               USDHC_FORCE_EVENT_FEVTAC12IE_MASK | USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK |
0318               USDHC_FORCE_EVENT_FEVTCTOE_MASK | USDHC_FORCE_EVENT_FEVTCCE_MASK | USDHC_FORCE_EVENT_FEVTCEBE_MASK |
0319               USDHC_FORCE_EVENT_FEVTCIE_MASK | USDHC_FORCE_EVENT_FEVTDTOE_MASK | USDHC_FORCE_EVENT_FEVTDCE_MASK |
0320               USDHC_FORCE_EVENT_FEVTDEBE_MASK | USDHC_FORCE_EVENT_FEVTAC12E_MASK | USDHC_FORCE_EVENT_FEVTCINT_MASK |
0321               USDHC_FORCE_EVENT_FEVTDMAE_MASK | kUSDHC_ForceEventTuningError), /*!< All force event flags mask. */
0322 };
0323 
0324 /*! @brief Data transfer direction. */
0325 typedef enum _usdhc_transfer_direction
0326 {
0327     kUSDHC_TransferDirectionReceive = 1U, /*!< USDHC transfer direction receive. */
0328     kUSDHC_TransferDirectionSend    = 0U, /*!< USDHC transfer direction send. */
0329 } usdhc_transfer_direction_t;
0330 
0331 /*! @brief Data transfer width. */
0332 typedef enum _usdhc_data_bus_width
0333 {
0334     kUSDHC_DataBusWidth1Bit = 0U, /*!< 1-bit mode */
0335     kUSDHC_DataBusWidth4Bit = 1U, /*!< 4-bit mode */
0336     kUSDHC_DataBusWidth8Bit = 2U, /*!< 8-bit mode */
0337 } usdhc_data_bus_width_t;
0338 
0339 /*! @brief Endian mode */
0340 typedef enum _usdhc_endian_mode
0341 {
0342     kUSDHC_EndianModeBig         = 0U, /*!< Big endian mode. */
0343     kUSDHC_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode. */
0344     kUSDHC_EndianModeLittle      = 2U, /*!< Little endian mode. */
0345 } usdhc_endian_mode_t;
0346 
0347 /*! @brief DMA mode */
0348 typedef enum _usdhc_dma_mode
0349 {
0350     kUSDHC_DmaModeSimple = 0U, /*!< External DMA. */
0351     kUSDHC_DmaModeAdma1  = 1U, /*!< ADMA1 is selected. */
0352     kUSDHC_DmaModeAdma2  = 2U, /*!< ADMA2 is selected. */
0353     kUSDHC_ExternalDMA   = 3U, /*!< External DMA mode selected. */
0354 } usdhc_dma_mode_t;
0355 
0356 /*! @brief Enum _usdhc_sdio_control_flag. SDIO control flag mask.
0357  *  @anchor _usdhc_sdio_control_flag
0358  */
0359 enum
0360 {
0361     kUSDHC_StopAtBlockGapFlag      = USDHC_PROT_CTRL_SABGREQ_MASK, /*!< Stop at block gap. */
0362     kUSDHC_ReadWaitControlFlag     = USDHC_PROT_CTRL_RWCTL_MASK,   /*!< Read wait control. */
0363     kUSDHC_InterruptAtBlockGapFlag = USDHC_PROT_CTRL_IABG_MASK,    /*!< Interrupt at block gap. */
0364     kUSDHC_ReadDoneNo8CLK = USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK,  /*!< Read done without 8 clk for block gap. */
0365     kUSDHC_ExactBlockNumberReadFlag = USDHC_PROT_CTRL_NON_EXACT_BLK_RD_MASK, /*!< Exact block number read. */
0366 };
0367 
0368 /*! @brief MMC card boot mode */
0369 typedef enum _usdhc_boot_mode
0370 {
0371     kUSDHC_BootModeNormal      = 0U, /*!< Normal boot */
0372     kUSDHC_BootModeAlternative = 1U, /*!< Alternative boot */
0373 } usdhc_boot_mode_t;
0374 
0375 /*! @brief The command type */
0376 typedef enum _usdhc_card_command_type
0377 {
0378     kCARD_CommandTypeNormal  = 0U, /*!< Normal command */
0379     kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */
0380     kCARD_CommandTypeResume  = 2U, /*!< Resume command */
0381     kCARD_CommandTypeAbort   = 3U, /*!< Abort command */
0382     kCARD_CommandTypeEmpty   = 4U, /*!< Empty command */
0383 } usdhc_card_command_type_t;
0384 
0385 /*!
0386  * @brief The command response type.
0387  *
0388  * Defines the command response type from card to host controller.
0389  */
0390 typedef enum _usdhc_card_response_type
0391 {
0392     kCARD_ResponseTypeNone = 0U, /*!< Response type: none */
0393     kCARD_ResponseTypeR1   = 1U, /*!< Response type: R1 */
0394     kCARD_ResponseTypeR1b  = 2U, /*!< Response type: R1b */
0395     kCARD_ResponseTypeR2   = 3U, /*!< Response type: R2 */
0396     kCARD_ResponseTypeR3   = 4U, /*!< Response type: R3 */
0397     kCARD_ResponseTypeR4   = 5U, /*!< Response type: R4 */
0398     kCARD_ResponseTypeR5   = 6U, /*!< Response type: R5 */
0399     kCARD_ResponseTypeR5b  = 7U, /*!< Response type: R5b */
0400     kCARD_ResponseTypeR6   = 8U, /*!< Response type: R6 */
0401     kCARD_ResponseTypeR7   = 9U, /*!< Response type: R7 */
0402 } usdhc_card_response_type_t;
0403 
0404 /*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor. */
0405 #define USDHC_ADMA1_ADDRESS_ALIGN (4096U)
0406 /*! @brief The alignment size for LENGTH field in ADMA1's descriptor. */
0407 #define USDHC_ADMA1_LENGTH_ALIGN (4096U)
0408 /*! @brief The alignment size for ADDRESS field in ADMA2's descriptor. */
0409 #define USDHC_ADMA2_ADDRESS_ALIGN (4U)
0410 /*! @brief The alignment size for LENGTH filed in ADMA2's descriptor. */
0411 #define USDHC_ADMA2_LENGTH_ALIGN (4U)
0412 
0413 /* ADMA1 descriptor table:
0414  * |------------------------|---------|--------------------------|
0415  * | Address/page field     |Reserved |         Attribute        |
0416  * |------------------------|---------|--------------------------|
0417  * |31                    12|11      6|05  |04  |03|02 |01 |00   |
0418  * |------------------------|---------|----|----|--|---|---|-----|
0419  * | address or data length | 000000  |Act2|Act1| 0|Int|End|Valid|
0420  * |------------------------|---------|----|----|--|---|---|-----|
0421  *
0422  * ADMA2 action table:
0423  * |------|------|-----------------|-------|-------------|
0424  * | Act2 | Act1 |     Comment     | 31-28 | 27 - 12     |
0425  * |------|------|-----------------|---------------------|
0426  * |   0  |   0  | No op           | Don't care          |
0427  * |------|------|-----------------|-------|-------------|
0428  * |   0  |   1  | Set data length |  0000 | Data Length |
0429  * |------|------|-----------------|-------|-------------|
0430  * |   1  |   0  | Transfer data   | Data address        |
0431  * |------|------|-----------------|---------------------|
0432  * |   1  |   1  | Link descriptor | Descriptor address  |
0433  * |------|------|-----------------|---------------------|
0434  */
0435 /****************************tables below are created only for Doxygen*********************************/
0436 /*! @brief The bit shift for ADDRESS filed in ADMA1's descriptor.
0437  *  <table>
0438  *  <caption>ADMA1 descriptor table</caption>
0439  *  <tr><th>Address/page field     <th>Reserved   <th colspan="6">Attribute
0440  *  <tr><td>31 12                  <td>11 6       <td>05   <td>04   <td>03 <td>02  <td>01  <td>00
0441  *  <tr><td>address or data length <td>000000     <td>Act2 <td>Act1 <td>0  <td>Int <td>End <td>Valid
0442  *  </table>
0443  *
0444  *  <table>
0445  *  <caption>ADMA2 action</caption>
0446  *  <tr><th>Act2  <th>Act1      <th>Comment            <th>31-28    <th>27-12
0447  *  <tr><td>0     <td>0         <td>No op              <td colspan="2">Don't care
0448  *  <tr><td>0     <td>1         <td>Set data length    <td>0000     <td> Data Length
0449  *  <tr><td>1     <td>0         <td>Transfer data      <td colspan="2">Data address
0450  *  <tr><td>1     <td>1         <td>Link descriptor    <td colspan="2">Descriptor address
0451  *  </table>
0452  */
0453 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT (12U)
0454 /*! @brief The bit mask for ADDRESS field in ADMA1's descriptor. */
0455 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_MASK (0xFFFFFU)
0456 /*! @brief The bit shift for LENGTH filed in ADMA1's descriptor. */
0457 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U)
0458 /*! @brief The mask for LENGTH field in ADMA1's descriptor. */
0459 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
0460 /*! @brief The maximum value of LENGTH filed in ADMA1's descriptor.
0461  * Since the max transfer size ADMA1 support is 65535 which is indivisible by
0462  * 4096, so to make sure a large data load transfer (>64KB) continuously (require the data
0463  * address be always align with 4096), software will set the maximum data length
0464  * for ADMA1 to (64 - 4)KB.
0465  */
0466 #define USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK + 1U - 4096U)
0467 
0468 /*! @brief Enum _usdhc_adma1_descriptor_flag. The mask for the control/status field in ADMA1 descriptor. */
0469 enum
0470 {
0471     kUSDHC_Adma1DescriptorValidFlag     = (1U << 0U),                        /*!< Valid flag. */
0472     kUSDHC_Adma1DescriptorEndFlag       = (1U << 1U),                        /*!< End flag. */
0473     kUSDHC_Adma1DescriptorInterrupFlag  = (1U << 2U),                        /*!< Interrupt flag. */
0474     kUSDHC_Adma1DescriptorActivity1Flag = (1U << 4U),                        /*!< Activity 1 flag. */
0475     kUSDHC_Adma1DescriptorActivity2Flag = (1U << 5U),                        /*!< Activity 2 flag. */
0476     kUSDHC_Adma1DescriptorTypeNop       = (kUSDHC_Adma1DescriptorValidFlag), /*!< No operation. */
0477     kUSDHC_Adma1DescriptorTypeTransfer  = (kUSDHC_Adma1DescriptorActivity2Flag | kUSDHC_Adma1DescriptorValidFlag),
0478     /*!< Transfer data. */
0479     kUSDHC_Adma1DescriptorTypeLink      = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorActivity2Flag |
0480                                       kUSDHC_Adma1DescriptorValidFlag), /*!< Link descriptor. */
0481     kUSDHC_Adma1DescriptorTypeSetLength = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorValidFlag),
0482     /*!< Set data length. */
0483 };
0484 
0485 /* ADMA2 descriptor table:
0486  * |----------------|---------------|-------------|--------------------------|
0487  * | Address field  |     Length    | Reserved    |         Attribute        |
0488  * |----------------|---------------|-------------|--------------------------|
0489  * |63            32|31           16|15         06|05  |04  |03|02 |01 |00   |
0490  * |----------------|---------------|-------------|----|----|--|---|---|-----|
0491  * | 32-bit address | 16-bit length | 0000000000  |Act2|Act1| 0|Int|End|Valid|
0492  * |----------------|---------------|-------------|----|----|--|---|---|-----|
0493  *
0494  * ADMA2 action table:
0495  * | Act2 | Act1 |     Comment     | Operation                                                         |
0496  * |------|------|-----------------|-------------------------------------------------------------------|
0497  * |   0  |   0  | No op           | Don't care                                                        |
0498  * |------|------|-----------------|-------------------------------------------------------------------|
0499  * |   0  |   1  | Reserved        | Read this line and go to next one                                 |
0500  * |------|------|-----------------|-------------------------------------------------------------------|
0501  * |   1  |   0  | Transfer data   | Transfer data with address and length set in this descriptor line |
0502  * |------|------|-----------------|-------------------------------------------------------------------|
0503  * |   1  |   1  | Link descriptor | Link to another descriptor                                        |
0504  * |------|------|-----------------|-------------------------------------------------------------------|
0505  */
0506 /**********************************tables below are created only for Doxygen***********************************/
0507 /*! @brief The bit shift for LENGTH field in ADMA2's descriptor.
0508  *
0509  * <table>
0510  * <caption>ADMA2 descriptor table</caption>
0511  * <tr><th>Address field    <th>Length         <th>Reserved     <th colspan="6">Attribute
0512  * <tr><td>63 32            <td>31 16          <td>15 06        <td>05   <td>04   <td>03  <td>02  <td>01  <td>00
0513  * <tr><td>32-bit address   <td>16-bit length  <td>0000000000   <td>Act2 <td>Act1 <td>0   <td>Int <td>End <td>Valid
0514  *</table>
0515  *
0516  * <table>
0517  * <caption>ADMA2 action</caption>
0518  * <tr><th>Act2   <th>Act1   <th>Comment          <th>Operation
0519  * <tr><td> 0     <td>0      <td>No op            <td>Don't care
0520  * <tr><td> 0     <td>1      <td> Reserved        <td> Read this line and go to next one
0521  * <tr><td> 1     <td>0      <td>Transfer data    <td>Transfer data with address and length set in this descriptor line
0522  * <tr><td> 1     <td>1      <td>Link descriptor  <td>Link to another descriptor
0523  * </table>
0524  */
0525 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U)
0526 /*! @brief The bit mask for LENGTH field in ADMA2's descriptor. */
0527 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
0528 /*! @brief The maximum value of LENGTH field in ADMA2's descriptor. */
0529 #define USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK - 3U)
0530 
0531 /*! @brief Enum _usdhc_adma2_descriptor_flag. ADMA1 descriptor control and status mask. */
0532 enum
0533 {
0534     kUSDHC_Adma2DescriptorValidFlag     = (1U << 0U), /*!< Valid flag. */
0535     kUSDHC_Adma2DescriptorEndFlag       = (1U << 1U), /*!< End flag. */
0536     kUSDHC_Adma2DescriptorInterruptFlag = (1U << 2U), /*!< Interrupt flag. */
0537     kUSDHC_Adma2DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 mask. */
0538     kUSDHC_Adma2DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 mask. */
0539 
0540     kUSDHC_Adma2DescriptorTypeNop      = (kUSDHC_Adma2DescriptorValidFlag), /*!< No operation. */
0541     kUSDHC_Adma2DescriptorTypeReserved = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorValidFlag),
0542     /*!< Reserved. */
0543     kUSDHC_Adma2DescriptorTypeTransfer = (kUSDHC_Adma2DescriptorActivity2Flag | kUSDHC_Adma2DescriptorValidFlag),
0544     /*!< Transfer type. */
0545     kUSDHC_Adma2DescriptorTypeLink = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorActivity2Flag |
0546                                       kUSDHC_Adma2DescriptorValidFlag), /*!< Link type. */
0547 };
0548 
0549 /*! @brief Enum _usdhc_adma_flag. ADMA descriptor configuration flag.
0550  *  @anchor _usdhc_adma_flag
0551  */
0552 enum
0553 {
0554     kUSDHC_AdmaDescriptorSingleFlag = 0U,
0555     /*!< Try to finish the transfer in a single ADMA descriptor. If transfer size is bigger than one
0556        ADMA descriptor's ability, new another descriptor for data transfer. */
0557     kUSDHC_AdmaDescriptorMultipleFlag =
0558         1U, /*!< Create multiple ADMA descriptors within the ADMA table, this is used for
0559              mmc boot mode specifically, which need
0560              to modify the ADMA descriptor on the fly, so the flag should be used
0561              combining with stop at block gap feature. */
0562 };
0563 
0564 /*! @brief DMA transfer burst len config. */
0565 typedef enum _usdhc_burst_len
0566 {
0567     kUSDHC_EnBurstLenForINCR         = 0x01U, /*!< Enable burst len for INCR. */
0568     kUSDHC_EnBurstLenForINCR4816     = 0x02U, /*!< Enable burst len for INCR4/INCR8/INCR16. */
0569     kUSDHC_EnBurstLenForINCR4816WRAP = 0x04U, /*!< Enable burst len for INCR4/8/16 WRAP. */
0570 } usdhc_burst_len_t;
0571 
0572 /*! @brief Enum _usdhc_transfer_data_type. Tansfer data type definition. */
0573 enum
0574 {
0575     kUSDHC_TransferDataNormal        = 0U, /*!< Transfer normal read/write data. */
0576     kUSDHC_TransferDataTuning        = 1U, /*!< Transfer tuning data. */
0577     kUSDHC_TransferDataBoot          = 2U, /*!< Transfer boot data. */
0578     kUSDHC_TransferDataBootcontinous = 3U, /*!< Transfer boot data continuously. */
0579 };
0580 
0581 /*! @brief Defines the ADMA1 descriptor structure. */
0582 typedef uint32_t usdhc_adma1_descriptor_t;
0583 
0584 /*! @brief Defines the ADMA2 descriptor structure. */
0585 typedef struct _usdhc_adma2_descriptor
0586 {
0587     uint32_t attribute;      /*!< The control and status field. */
0588     const uint32_t *address; /*!< The address field. */
0589 } usdhc_adma2_descriptor_t;
0590 
0591 /*!
0592  * @brief USDHC capability information.
0593  *
0594  * Defines a structure to save the capability information of USDHC.
0595  */
0596 typedef struct _usdhc_capability
0597 {
0598     uint32_t sdVersion;      /*!< Support SD card/sdio version. */
0599     uint32_t mmcVersion;     /*!< Support EMMC card version. */
0600     uint32_t maxBlockLength; /*!< Maximum block length united as byte. */
0601     uint32_t maxBlockCount;  /*!< Maximum block count can be set one time. */
0602     uint32_t flags;          /*!< Capability flags to indicate the support information(@ref _usdhc_capability_flag). */
0603 } usdhc_capability_t;
0604 
0605 /*! @brief Data structure to configure the MMC boot feature. */
0606 typedef struct _usdhc_boot_config
0607 {
0608     uint32_t ackTimeoutCount;      /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */
0609     usdhc_boot_mode_t bootMode;    /*!< Boot mode selection. */
0610     uint32_t blockCount;           /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */
0611     size_t blockSize;              /*!< Block size. */
0612     bool enableBootAck;            /*!< Enable or disable boot ACK. */
0613     bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period. */
0614 } usdhc_boot_config_t;
0615 
0616 /*! @brief Data structure to initialize the USDHC. */
0617 typedef struct _usdhc_config
0618 {
0619     uint32_t dataTimeout;           /*!< Data timeout value. */
0620     usdhc_endian_mode_t endianMode; /*!< Endian mode. */
0621     uint8_t readWatermarkLevel;     /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */
0622     uint8_t writeWatermarkLevel;    /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */
0623 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
0624     uint8_t readBurstLen;  /*!< Read burst len. */
0625     uint8_t writeBurstLen; /*!< Write burst len. */
0626 #endif
0627 } usdhc_config_t;
0628 
0629 /*!
0630  * @brief Card command descriptor.
0631  *
0632  * Defines card command-related attribute.
0633  */
0634 typedef struct _usdhc_command
0635 {
0636     uint32_t index;                          /*!< Command index. */
0637     uint32_t argument;                       /*!< Command argument. */
0638     usdhc_card_command_type_t type;          /*!< Command type. */
0639     usdhc_card_response_type_t responseType; /*!< Command response type. */
0640     uint32_t response[4U];                   /*!< Response for this command. */
0641     uint32_t responseErrorFlags;             /*!< Response error flag, which need to check
0642                                                  the command reponse. */
0643     uint32_t flags;                          /*!< Cmd flags. */
0644 } usdhc_command_t;
0645 
0646 /*! @brief ADMA configuration. */
0647 typedef struct _usdhc_adma_config
0648 {
0649     usdhc_dma_mode_t dmaMode; /*!< DMA mode. */
0650 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
0651     usdhc_burst_len_t burstLen; /*!< Burst len config. */
0652 #endif
0653     uint32_t *admaTable;     /*!< ADMA table address, can't be null if transfer way is ADMA1/ADMA2. */
0654     uint32_t admaTableWords; /*!< ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. */
0655 } usdhc_adma_config_t;
0656 
0657 /*!
0658  * @brief Card scatter gather data list.
0659  *
0660  * Allow application register uncontinuous data buffer for data transfer.
0661  */
0662 typedef struct _usdhc_scatter_gather_data_list
0663 {
0664     uint32_t *dataAddr;
0665     uint32_t dataSize;
0666     struct _usdhc_scatter_gather_data_list *dataList;
0667 } usdhc_scatter_gather_data_list_t;
0668 
0669 /*!
0670  * @brief Card scatter gather data descriptor.
0671  *
0672  * Defines a structure to contain data-related attribute. The 'enableIgnoreError' is used when upper card
0673  * driver wants to ignore the error event to read/write all the data and not to stop read/write immediately when an
0674  * error event happens. For example, bus testing procedure for MMC card.
0675  */
0676 typedef struct _usdhc_scatter_gather_data
0677 {
0678     bool enableAutoCommand12; /*!< Enable auto CMD12. */
0679     bool enableAutoCommand23; /*!< Enable auto CMD23. */
0680     bool enableIgnoreError;   /*!< Enable to ignore error event to read/write all the data. */
0681 
0682     usdhc_transfer_direction_t dataDirection; /*!< data direction */
0683     uint8_t dataType;                         /*!< this is used to distinguish the normal/tuning/boot data. */
0684     size_t blockSize;                         /*!< Block size. */
0685 
0686     usdhc_scatter_gather_data_list_t sgData; /*!<  scatter gather data */
0687 } usdhc_scatter_gather_data_t;
0688 
0689 /*! @brief usdhc scatter gather transfer. */
0690 typedef struct _usdhc_scatter_gather_transfer
0691 {
0692     usdhc_scatter_gather_data_t *data; /*!< Data to transfer. */
0693     usdhc_command_t *command;          /*!< Command to send. */
0694 } usdhc_scatter_gather_transfer_t;
0695 
0696 /*!
0697  * @brief Card data descriptor.
0698  *
0699  * Defines a structure to contain data-related attribute. The 'enableIgnoreError' is used when upper card
0700  * driver wants to ignore the error event to read/write all the data and not to stop read/write immediately when an
0701  * error event happens. For example, bus testing procedure for MMC card.
0702  */
0703 typedef struct _usdhc_data
0704 {
0705     bool enableAutoCommand12; /*!< Enable auto CMD12. */
0706     bool enableAutoCommand23; /*!< Enable auto CMD23. */
0707     bool enableIgnoreError;   /*!< Enable to ignore error event to read/write all the data. */
0708     uint8_t dataType;         /*!< this is used to distinguish the normal/tuning/boot data. */
0709     size_t blockSize;         /*!< Block size. */
0710     uint32_t blockCount;      /*!< Block count. */
0711     uint32_t *rxData;         /*!< Buffer to save data read. */
0712     const uint32_t *txData;   /*!< Data buffer to write. */
0713 } usdhc_data_t;
0714 
0715 /*! @brief Transfer state. */
0716 typedef struct _usdhc_transfer
0717 {
0718     usdhc_data_t *data;       /*!< Data to transfer. */
0719     usdhc_command_t *command; /*!< Command to send. */
0720 } usdhc_transfer_t;
0721 
0722 /*! @brief USDHC handle typedef. */
0723 typedef struct _usdhc_handle usdhc_handle_t;
0724 
0725 /*! @brief USDHC callback functions. */
0726 typedef struct _usdhc_transfer_callback
0727 {
0728     void (*CardInserted)(USDHC_Type *base,
0729                          void *userData); /*!< Card inserted occurs when DAT3/CD pin is for card detect */
0730     void (*CardRemoved)(USDHC_Type *base, void *userData);   /*!< Card removed occurs */
0731     void (*SdioInterrupt)(USDHC_Type *base, void *userData); /*!< SDIO card interrupt occurs */
0732     void (*BlockGap)(USDHC_Type *base, void *userData);      /*!< stopped at block gap event */
0733     void (*TransferComplete)(USDHC_Type *base,
0734                              usdhc_handle_t *handle,
0735                              status_t status,
0736                              void *userData);           /*!< Transfer complete callback. */
0737     void (*ReTuning)(USDHC_Type *base, void *userData); /*!< Handle the re-tuning. */
0738 } usdhc_transfer_callback_t;
0739 
0740 /*!
0741  * @brief USDHC handle.
0742  *
0743  * Defines the structure to save the USDHC state information and callback function.
0744  *
0745  * @note All the fields except interruptFlags and transferredWords must be allocated by the user.
0746  */
0747 struct _usdhc_handle
0748 {
0749 #if (defined FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER) && FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
0750     usdhc_scatter_gather_data_t *volatile data; /*!< scatter gather data pointer  */
0751 #else
0752     usdhc_data_t *volatile data;                                   /*!< Transfer parameter. Data to transfer. */
0753 #endif
0754     usdhc_command_t *volatile command; /*!< Transfer parameter. Command to send. */
0755 
0756     volatile uint32_t transferredWords; /*!< Transfer status. Words transferred by DATAPORT way. */
0757 
0758     usdhc_transfer_callback_t callback; /*!< Callback function. */
0759     void *userData;                     /*!< Parameter for transfer complete callback. */
0760 };
0761 
0762 /*! @brief USDHC transfer function. */
0763 typedef status_t (*usdhc_transfer_function_t)(USDHC_Type *base, usdhc_transfer_t *content);
0764 
0765 /*! @brief USDHC host descriptor. */
0766 typedef struct _usdhc_host
0767 {
0768     USDHC_Type *base;                   /*!< USDHC peripheral base address. */
0769     uint32_t sourceClock_Hz;            /*!< USDHC source clock frequency united in Hz. */
0770     usdhc_config_t config;              /*!< USDHC configuration. */
0771     usdhc_capability_t capability;      /*!< USDHC capability information. */
0772     usdhc_transfer_function_t transfer; /*!< USDHC transfer function. */
0773 } usdhc_host_t;
0774 
0775 /*************************************************************************************************
0776  * API
0777  ************************************************************************************************/
0778 #if defined(__cplusplus)
0779 extern "C" {
0780 #endif
0781 
0782 /*!
0783  * @name Initialization and deinitialization
0784  * @{
0785  */
0786 
0787 /*!
0788  * @brief USDHC module initialization function.
0789  *
0790  * Configures the USDHC according to the user configuration.
0791  *
0792  * Example:
0793    @code
0794    usdhc_config_t config;
0795    config.cardDetectDat3 = false;
0796    config.endianMode = kUSDHC_EndianModeLittle;
0797    config.dmaMode = kUSDHC_DmaModeAdma2;
0798    config.readWatermarkLevel = 128U;
0799    config.writeWatermarkLevel = 128U;
0800    USDHC_Init(USDHC, &config);
0801    @endcode
0802  *
0803  * @param base USDHC peripheral base address.
0804  * @param config USDHC configuration information.
0805  * @retval #kStatus_Success Operate successfully.
0806  */
0807 void USDHC_Init(USDHC_Type *base, const usdhc_config_t *config);
0808 
0809 /*!
0810  * @brief Deinitializes the USDHC.
0811  *
0812  * @param base USDHC peripheral base address.
0813  */
0814 void USDHC_Deinit(USDHC_Type *base);
0815 
0816 /*!
0817  * @brief Resets the USDHC.
0818  *
0819  * @param base USDHC peripheral base address.
0820  * @param mask The reset type mask(@ref _usdhc_reset).
0821  * @param timeout Timeout for reset.
0822  * @retval true Reset successfully.
0823  * @retval false Reset failed.
0824  */
0825 bool USDHC_Reset(USDHC_Type *base, uint32_t mask, uint32_t timeout);
0826 
0827 /* @} */
0828 
0829 /*!
0830  * @name DMA Control
0831  * @{
0832  */
0833 
0834 /*!
0835  * @brief Sets the DMA descriptor table configuration.
0836  * A high level DMA descriptor configuration function.
0837  * @param base USDHC peripheral base address.
0838  * @param dmaConfig ADMA configuration
0839  * @param dataConfig Data descriptor
0840  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
0841  *  refer to enum @ref _usdhc_adma_flag.
0842  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
0843  * @retval #kStatus_Success Operate successfully.
0844  */
0845 status_t USDHC_SetAdmaTableConfig(USDHC_Type *base,
0846                                   usdhc_adma_config_t *dmaConfig,
0847                                   usdhc_data_t *dataConfig,
0848                                   uint32_t flags);
0849 
0850 /*!
0851  * @brief Internal DMA configuration.
0852  * This function is used to config the USDHC DMA related registers.
0853  * @param base USDHC peripheral base address.
0854  * @param dmaConfig ADMA configuration.
0855  * @param dataAddr Transfer data address, a simple DMA parameter, if ADMA is used, leave it to NULL.
0856  * @param enAutoCmd23 Flag to indicate Auto CMD23 is enable or not, a simple DMA parameter, if ADMA is used, leave it
0857  * to false.
0858  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
0859  * @retval #kStatus_Success Operate successfully.
0860  */
0861 status_t USDHC_SetInternalDmaConfig(USDHC_Type *base,
0862                                     usdhc_adma_config_t *dmaConfig,
0863                                     const uint32_t *dataAddr,
0864                                     bool enAutoCmd23);
0865 
0866 /*!
0867  * @brief Sets the ADMA2 descriptor table configuration.
0868  *
0869  * @param admaTable ADMA table address.
0870  * @param admaTableWords ADMA table length.
0871  * @param dataBufferAddr Data buffer address.
0872  * @param dataBytes Data Data length.
0873  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
0874  *  refer to enum @ref _usdhc_adma_flag.
0875  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
0876  * @retval #kStatus_Success Operate successfully.
0877  */
0878 status_t USDHC_SetADMA2Descriptor(
0879     uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags);
0880 
0881 /*!
0882  * @brief Sets the ADMA1 descriptor table configuration.
0883  *
0884  * @param admaTable ADMA table address.
0885  * @param admaTableWords ADMA table length.
0886  * @param dataBufferAddr Data buffer address.
0887  * @param dataBytes Data length.
0888  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
0889  *  refer to enum @ref _usdhc_adma_flag.
0890  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
0891  * @retval #kStatus_Success Operate successfully.
0892  */
0893 status_t USDHC_SetADMA1Descriptor(
0894     uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags);
0895 
0896 /*!
0897  * @brief Enables internal DMA.
0898  *
0899  * @param base USDHC peripheral base address.
0900  * @param enable enable or disable flag
0901  */
0902 static inline void USDHC_EnableInternalDMA(USDHC_Type *base, bool enable)
0903 {
0904     if (enable)
0905     {
0906         base->MIX_CTRL |= USDHC_MIX_CTRL_DMAEN_MASK;
0907     }
0908     else
0909     {
0910         base->MIX_CTRL &= ~USDHC_MIX_CTRL_DMAEN_MASK;
0911         base->PROT_CTRL &= ~USDHC_PROT_CTRL_DMASEL_MASK;
0912     }
0913 }
0914 
0915 /* @} */
0916 
0917 /*!
0918  * @name Interrupts
0919  * @{
0920  */
0921 
0922 /*!
0923  * @brief Enables the interrupt status.
0924  *
0925  * @param base USDHC peripheral base address.
0926  * @param mask Interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
0927  */
0928 static inline void USDHC_EnableInterruptStatus(USDHC_Type *base, uint32_t mask)
0929 {
0930     base->INT_STATUS_EN |= mask;
0931 }
0932 
0933 /*!
0934  * @brief Disables the interrupt status.
0935  *
0936  * @param base USDHC peripheral base address.
0937  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
0938  */
0939 static inline void USDHC_DisableInterruptStatus(USDHC_Type *base, uint32_t mask)
0940 {
0941     base->INT_STATUS_EN &= ~mask;
0942 }
0943 
0944 /*!
0945  * @brief Enables the interrupt signal corresponding to the interrupt status flag.
0946  *
0947  * @param base USDHC peripheral base address.
0948  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
0949  */
0950 static inline void USDHC_EnableInterruptSignal(USDHC_Type *base, uint32_t mask)
0951 {
0952     base->INT_SIGNAL_EN |= mask;
0953 }
0954 
0955 /*!
0956  * @brief Disables the interrupt signal corresponding to the interrupt status flag.
0957  *
0958  * @param base USDHC peripheral base address.
0959  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
0960  */
0961 static inline void USDHC_DisableInterruptSignal(USDHC_Type *base, uint32_t mask)
0962 {
0963     base->INT_SIGNAL_EN &= ~mask;
0964 }
0965 
0966 /* @} */
0967 
0968 /*!
0969  * @name Status
0970  * @{
0971  */
0972 
0973 /*!
0974  * @brief Gets the enabled interrupt status.
0975  *
0976  * @param base USDHC peripheral base address.
0977  * @return Current interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
0978  */
0979 static inline uint32_t USDHC_GetEnabledInterruptStatusFlags(USDHC_Type *base)
0980 {
0981     uint32_t intStatus = base->INT_STATUS;
0982 
0983     return intStatus & base->INT_SIGNAL_EN;
0984 }
0985 
0986 /*!
0987  * @brief Gets the current interrupt status.
0988  *
0989  * @param base USDHC peripheral base address.
0990  * @return Current interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
0991  */
0992 static inline uint32_t USDHC_GetInterruptStatusFlags(USDHC_Type *base)
0993 {
0994     return base->INT_STATUS;
0995 }
0996 
0997 /*!
0998  * @brief Clears a specified interrupt status.
0999  * write 1 clears
1000  * @param base USDHC peripheral base address.
1001  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
1002  */
1003 static inline void USDHC_ClearInterruptStatusFlags(USDHC_Type *base, uint32_t mask)
1004 {
1005     base->INT_STATUS = mask;
1006 }
1007 
1008 /*!
1009  * @brief Gets the status of auto command 12 error.
1010  *
1011  * @param base USDHC peripheral base address.
1012  * @return Auto command 12 error status flags mask(@ref _usdhc_auto_command12_error_status_flag).
1013  */
1014 static inline uint32_t USDHC_GetAutoCommand12ErrorStatusFlags(USDHC_Type *base)
1015 {
1016     return base->AUTOCMD12_ERR_STATUS;
1017 }
1018 
1019 /*!
1020  * @brief Gets the status of the ADMA error.
1021  *
1022  * @param base USDHC peripheral base address.
1023  * @return ADMA error status flags mask(@ref _usdhc_adma_error_status_flag).
1024  */
1025 static inline uint32_t USDHC_GetAdmaErrorStatusFlags(USDHC_Type *base)
1026 {
1027     return base->ADMA_ERR_STATUS & 0xFUL;
1028 }
1029 
1030 /*!
1031  * @brief Gets a present status.
1032  *
1033  * This function gets the present USDHC's status except for an interrupt status and an error status.
1034  *
1035  * @param base USDHC peripheral base address.
1036  * @return Present USDHC's status flags mask(@ref _usdhc_present_status_flag).
1037  */
1038 static inline uint32_t USDHC_GetPresentStatusFlags(USDHC_Type *base)
1039 {
1040     return base->PRES_STATE;
1041 }
1042 
1043 /* @} */
1044 
1045 /*!
1046  * @name Bus Operations
1047  * @{
1048  */
1049 
1050 /*!
1051  * @brief Gets the capability information.
1052  *
1053  * @param base USDHC peripheral base address.
1054  * @param capability Structure to save capability information.
1055  */
1056 void USDHC_GetCapability(USDHC_Type *base, usdhc_capability_t *capability);
1057 
1058 /*!
1059  * @brief Forces the card clock on.
1060  *
1061  * @param base USDHC peripheral base address.
1062  * @param enable enable/disable flag
1063  */
1064 static inline void USDHC_ForceClockOn(USDHC_Type *base, bool enable)
1065 {
1066     if (enable)
1067     {
1068         base->VEND_SPEC |= USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
1069     }
1070     else
1071     {
1072         base->VEND_SPEC &= ~USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
1073     }
1074 }
1075 
1076 /*!
1077  * @brief Sets the SD bus clock frequency.
1078  *
1079  * @param base USDHC peripheral base address.
1080  * @param srcClock_Hz USDHC source clock frequency united in Hz.
1081  * @param busClock_Hz SD bus clock frequency united in Hz.
1082  *
1083  * @return The nearest frequency of busClock_Hz configured for SD bus.
1084  */
1085 uint32_t USDHC_SetSdClock(USDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz);
1086 
1087 /*!
1088  * @brief Sends 80 clocks to the card to set it to the active state.
1089  *
1090  * This function must be called each time the card is inserted to ensure that the card can receive the command
1091  * correctly.
1092  *
1093  * @param base USDHC peripheral base address.
1094  * @param timeout Timeout to initialize card.
1095  * @retval true Set card active successfully.
1096  * @retval false Set card active failed.
1097  */
1098 bool USDHC_SetCardActive(USDHC_Type *base, uint32_t timeout);
1099 
1100 /*!
1101  * @brief Triggers a hardware reset.
1102  *
1103  * @param base USDHC peripheral base address.
1104  * @param high 1 or 0 level
1105  */
1106 static inline void USDHC_AssertHardwareReset(USDHC_Type *base, bool high)
1107 {
1108     if (high)
1109     {
1110         base->SYS_CTRL |= USDHC_SYS_CTRL_IPP_RST_N_MASK;
1111     }
1112     else
1113     {
1114         base->SYS_CTRL &= ~USDHC_SYS_CTRL_IPP_RST_N_MASK;
1115     }
1116 }
1117 
1118 /*!
1119  * @brief Sets the data transfer width.
1120  *
1121  * @param base USDHC peripheral base address.
1122  * @param width Data transfer width.
1123  */
1124 static inline void USDHC_SetDataBusWidth(USDHC_Type *base, usdhc_data_bus_width_t width)
1125 {
1126     base->PROT_CTRL = ((base->PROT_CTRL & ~USDHC_PROT_CTRL_DTW_MASK) | USDHC_PROT_CTRL_DTW(width));
1127 }
1128 
1129 /*!
1130  * @brief Fills the data port.
1131  *
1132  * This function is used to implement the data transfer by Data Port instead of DMA.
1133  *
1134  * @param base USDHC peripheral base address.
1135  * @param data The data about to be sent.
1136  */
1137 static inline void USDHC_WriteData(USDHC_Type *base, uint32_t data)
1138 {
1139     base->DATA_BUFF_ACC_PORT = data;
1140 }
1141 
1142 /*!
1143  * @brief Retrieves the data from the data port.
1144  *
1145  * This function is used to implement the data transfer by Data Port instead of DMA.
1146  *
1147  * @param base USDHC peripheral base address.
1148  * @return The data has been read.
1149  */
1150 static inline uint32_t USDHC_ReadData(USDHC_Type *base)
1151 {
1152     return base->DATA_BUFF_ACC_PORT;
1153 }
1154 
1155 /*!
1156  * @brief Sends command function.
1157  *
1158  * @param base USDHC peripheral base address.
1159  * @param command configuration
1160  */
1161 void USDHC_SendCommand(USDHC_Type *base, usdhc_command_t *command);
1162 
1163 /*!
1164  * @brief Enables or disables a wakeup event in low-power mode.
1165  *
1166  * @param base USDHC peripheral base address.
1167  * @param mask Wakeup events mask(@ref _usdhc_wakeup_event).
1168  * @param enable True to enable, false to disable.
1169  */
1170 static inline void USDHC_EnableWakeupEvent(USDHC_Type *base, uint32_t mask, bool enable)
1171 {
1172     if (enable)
1173     {
1174         base->PROT_CTRL |= mask;
1175     }
1176     else
1177     {
1178         base->PROT_CTRL &= ~mask;
1179     }
1180 }
1181 
1182 /*!
1183  * @brief Detects card insert status.
1184  *
1185  * @param base USDHC peripheral base address.
1186  * @param enable enable/disable flag
1187  */
1188 static inline void USDHC_CardDetectByData3(USDHC_Type *base, bool enable)
1189 {
1190     if (enable)
1191     {
1192         base->PROT_CTRL |= USDHC_PROT_CTRL_D3CD_MASK;
1193     }
1194     else
1195     {
1196         base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK;
1197     }
1198 }
1199 
1200 /*!
1201  * @brief Detects card insert status.
1202  *
1203  * @param base USDHC peripheral base address.
1204  */
1205 static inline bool USDHC_DetectCardInsert(USDHC_Type *base)
1206 {
1207     return ((base->PRES_STATE & (uint32_t)kUSDHC_CardInsertedFlag) != 0UL) ? true : false;
1208 }
1209 
1210 /*!
1211  * @brief Enables or disables the SDIO card control.
1212  *
1213  * @param base USDHC peripheral base address.
1214  * @param mask SDIO card control flags mask(@ref _usdhc_sdio_control_flag).
1215  * @param enable True to enable, false to disable.
1216  */
1217 static inline void USDHC_EnableSdioControl(USDHC_Type *base, uint32_t mask, bool enable)
1218 {
1219     if (enable)
1220     {
1221         base->PROT_CTRL |= mask;
1222     }
1223     else
1224     {
1225         base->PROT_CTRL &= ~mask;
1226     }
1227 }
1228 
1229 /*!
1230  * @brief Restarts a transaction which has stopped at the block GAP for the SDIO card.
1231  *
1232  * @param base USDHC peripheral base address.
1233  */
1234 static inline void USDHC_SetContinueRequest(USDHC_Type *base)
1235 {
1236     base->PROT_CTRL |= USDHC_PROT_CTRL_CREQ_MASK;
1237 }
1238 
1239 /*!
1240  * @brief Request stop at block gap function.
1241  *
1242  * @param base USDHC peripheral base address.
1243  * @param enable True to stop at block gap, false to normal transfer.
1244  */
1245 static inline void USDHC_RequestStopAtBlockGap(USDHC_Type *base, bool enable)
1246 {
1247     if (enable)
1248     {
1249         base->PROT_CTRL |= USDHC_PROT_CTRL_SABGREQ_MASK;
1250     }
1251     else
1252     {
1253         base->PROT_CTRL &= ~USDHC_PROT_CTRL_SABGREQ_MASK;
1254     }
1255 }
1256 
1257 /*!
1258  * @brief Configures the MMC boot feature.
1259  *
1260  * Example:
1261    @code
1262    usdhc_boot_config_t config;
1263    config.ackTimeoutCount = 4;
1264    config.bootMode = kUSDHC_BootModeNormal;
1265    config.blockCount = 5;
1266    config.enableBootAck = true;
1267    config.enableBoot = true;
1268    config.enableAutoStopAtBlockGap = true;
1269    USDHC_SetMmcBootConfig(USDHC, &config);
1270    @endcode
1271  *
1272  * @param base USDHC peripheral base address.
1273  * @param config The MMC boot configuration information.
1274  */
1275 void USDHC_SetMmcBootConfig(USDHC_Type *base, const usdhc_boot_config_t *config);
1276 
1277 /*!
1278  * @brief Enables or disables the mmc boot mode.
1279  *
1280  * @param base USDHC peripheral base address.
1281  * @param enable True to enable, false to disable.
1282  */
1283 static inline void USDHC_EnableMmcBoot(USDHC_Type *base, bool enable)
1284 {
1285     if (enable)
1286     {
1287         base->MMC_BOOT |= USDHC_MMC_BOOT_BOOT_EN_MASK;
1288     }
1289     else
1290     {
1291         base->MMC_BOOT &= ~USDHC_MMC_BOOT_BOOT_EN_MASK;
1292     }
1293 }
1294 
1295 /*!
1296  * @brief Forces generating events according to the given mask.
1297  *
1298  * @param base USDHC peripheral base address.
1299  * @param mask The force events bit posistion (_usdhc_force_event).
1300  */
1301 static inline void USDHC_SetForceEvent(USDHC_Type *base, uint32_t mask)
1302 {
1303     base->FORCE_EVENT = mask;
1304 }
1305 
1306 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_VOLTAGE_SELECT) && (FSL_FEATURE_USDHC_HAS_NO_VOLTAGE_SELECT))
1307 /*!
1308  * @brief Selects the USDHC output voltage.
1309  *
1310  * @param base USDHC peripheral base address.
1311  * @param en18v True means 1.8V, false means 3.0V.
1312  */
1313 static inline void UDSHC_SelectVoltage(USDHC_Type *base, bool en18v)
1314 {
1315     if (en18v)
1316     {
1317         base->VEND_SPEC |= USDHC_VEND_SPEC_VSELECT_MASK;
1318     }
1319     else
1320     {
1321         base->VEND_SPEC &= ~USDHC_VEND_SPEC_VSELECT_MASK;
1322     }
1323 }
1324 #endif
1325 
1326 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE)
1327 /*!
1328  * @brief Checks the SDR50 mode request tuning bit.
1329  * When this bit set, application shall perform tuning for SDR50 mode.
1330  * @param base USDHC peripheral base address.
1331  */
1332 static inline bool USDHC_RequestTuningForSDR50(USDHC_Type *base)
1333 {
1334     return ((base->HOST_CTRL_CAP & USDHC_HOST_CTRL_CAP_USE_TUNING_SDR50_MASK) != 0UL) ? true : false;
1335 }
1336 
1337 /*!
1338  * @brief Checks the request re-tuning bit.
1339  * When this bit is set, user should do manual tuning or standard tuning function.
1340  * @param base USDHC peripheral base address.
1341  */
1342 static inline bool USDHC_RequestReTuning(USDHC_Type *base)
1343 {
1344     return ((base->PRES_STATE & USDHC_PRES_STATE_RTR_MASK) != 0UL) ? true : false;
1345 }
1346 
1347 /*!
1348  * @brief The SDR104 mode auto tuning enable and disable.
1349  * This function should be called after tuning function execute pass, auto tuning will handle
1350  * by hardware.
1351  * @param base USDHC peripheral base address.
1352  * @param enable enable/disable flag
1353  */
1354 static inline void USDHC_EnableAutoTuning(USDHC_Type *base, bool enable)
1355 {
1356     if (enable)
1357     {
1358         base->MIX_CTRL |= USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK;
1359     }
1360     else
1361     {
1362         base->MIX_CTRL &= ~USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK;
1363     }
1364 }
1365 
1366 #if !(defined(FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_NO_RETUNING_TIME_COUNTER) && \
1367       FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_NO_RETUNING_TIME_COUNTER)
1368 /*!
1369  * @brief Configs the re-tuning timer for mode 1 and mode 3.
1370  * This timer is used for standard tuning auto re-tuning,
1371  * @param base USDHC peripheral base address.
1372  * @param counter timer counter value
1373  */
1374 static inline void USDHC_SetRetuningTimer(USDHC_Type *base, uint32_t counter)
1375 {
1376     base->HOST_CTRL_CAP &= ~USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING_MASK;
1377     base->HOST_CTRL_CAP |= USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING(counter);
1378 }
1379 #endif /* FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_RETUNING_TIME_COUNTER */
1380 
1381 /*!
1382  * @brief The auto tuning enbale for CMD/DATA line.
1383  *
1384  * @param base USDHC peripheral base address.
1385  */
1386 void USDHC_EnableAutoTuningForCmdAndData(USDHC_Type *base);
1387 
1388 /*!
1389  * @brief Manual tuning trigger or abort.
1390  * User should handle the tuning cmd and find the boundary of the delay
1391  * then calucate a average value which will be configured to the <b>CLK_TUNE_CTRL_STATUS</b>
1392  * This function should be called before function @ref USDHC_AdjustDelayForManualTuning.
1393  * @param base USDHC peripheral base address.
1394  * @param enable tuning enable flag
1395  */
1396 void USDHC_EnableManualTuning(USDHC_Type *base, bool enable);
1397 
1398 /*!
1399  * @brief Get the tuning delay cell setting.
1400  *
1401  * @param base USDHC peripheral base address.
1402  * @retval CLK Tuning Control and Status register value.
1403  */
1404 static inline uint32_t USDHC_GetTuningDelayStatus(USDHC_Type *base)
1405 {
1406     return base->CLK_TUNE_CTRL_STATUS >> 16U;
1407 }
1408 
1409 /*!
1410  * @brief The tuning delay cell setting.
1411  *
1412  * @param base USDHC peripheral base address.
1413  * @param preDelay Set the number of delay cells on the feedback clock between the feedback clock and CLK_PRE.
1414  * @param outDelay Set the number of delay cells on the feedback clock between CLK_PRE and CLK_OUT.
1415  * @param postDelay Set the number of delay cells on the feedback clock between CLK_OUT and CLK_POST.
1416  * @retval kStatus_Fail config the delay setting fail
1417  * @retval kStatus_Success config the delay setting success
1418  */
1419 status_t USDHC_SetTuningDelay(USDHC_Type *base, uint32_t preDelay, uint32_t outDelay, uint32_t postDelay);
1420 
1421 /*!
1422  * @brief Adjusts delay for mannual tuning.
1423  * @deprecated Do not use this function.  It has been superceded by USDHC_SetTuingDelay
1424  * @param base USDHC peripheral base address.
1425  * @param delay setting configuration
1426  * @retval #kStatus_Fail config the delay setting fail
1427  * @retval #kStatus_Success config the delay setting success
1428  */
1429 status_t USDHC_AdjustDelayForManualTuning(USDHC_Type *base, uint32_t delay);
1430 
1431 /*!
1432  * @brief set tuning counter tuning.
1433  * @param base USDHC peripheral base address.
1434  * @param counter tuning counter
1435  * @retval #kStatus_Fail config the delay setting fail
1436  * @retval #kStatus_Success config the delay setting success
1437  */
1438 static inline void USDHC_SetStandardTuningCounter(USDHC_Type *base, uint8_t counter)
1439 {
1440     base->TUNING_CTRL =
1441         (base->TUNING_CTRL & (~USDHC_TUNING_CTRL_TUNING_COUNTER_MASK)) | USDHC_TUNING_CTRL_TUNING_COUNTER(counter);
1442 }
1443 
1444 /*!
1445  * @brief The enable standard tuning function.
1446  * The standard tuning window and tuning counter using the default config
1447  * tuning cmd is sent by the software, user need to check whether the tuning result
1448  * can be used for SDR50, SDR104, and HS200 mode tuning.
1449  * @param base USDHC peripheral base address.
1450  * @param tuningStartTap start tap
1451  * @param step tuning step
1452  * @param enable enable/disable flag
1453  */
1454 void USDHC_EnableStandardTuning(USDHC_Type *base, uint32_t tuningStartTap, uint32_t step, bool enable);
1455 
1456 /*!
1457  * @brief Gets execute STD tuning status.
1458  *
1459  * @param base USDHC peripheral base address.
1460  */
1461 static inline uint32_t USDHC_GetExecuteStdTuningStatus(USDHC_Type *base)
1462 {
1463     return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK);
1464 }
1465 
1466 /*!
1467  * @brief Checks STD tuning result.
1468  *
1469  * @param base USDHC peripheral base address.
1470  */
1471 static inline uint32_t USDHC_CheckStdTuningResult(USDHC_Type *base)
1472 {
1473     return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK);
1474 }
1475 
1476 /*!
1477  * @brief Checks tuning error.
1478  *
1479  * @param base USDHC peripheral base address.
1480  */
1481 static inline uint32_t USDHC_CheckTuningError(USDHC_Type *base)
1482 {
1483     return (base->CLK_TUNE_CTRL_STATUS &
1484             (USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK | USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK));
1485 }
1486 
1487 #endif
1488 /*!
1489  * @brief The enable/disable DDR mode.
1490  *
1491  * @param base USDHC peripheral base address.
1492  * @param enable enable/disable flag
1493  * @param nibblePos nibble position
1494  */
1495 void USDHC_EnableDDRMode(USDHC_Type *base, bool enable, uint32_t nibblePos);
1496 
1497 #if FSL_FEATURE_USDHC_HAS_HS400_MODE
1498 /*!
1499  * @brief The enable/disable HS400 mode.
1500  *
1501  * @param base USDHC peripheral base address.
1502  * @param enable enable/disable flag
1503  */
1504 static inline void USDHC_EnableHS400Mode(USDHC_Type *base, bool enable)
1505 {
1506     if (enable)
1507     {
1508         base->MIX_CTRL |= USDHC_MIX_CTRL_HS400_MODE_MASK;
1509     }
1510     else
1511     {
1512         base->MIX_CTRL &= ~USDHC_MIX_CTRL_HS400_MODE_MASK;
1513     }
1514 }
1515 
1516 /*!
1517  * @brief Resets the strobe DLL.
1518  *
1519  * @param base USDHC peripheral base address.
1520  */
1521 static inline void USDHC_ResetStrobeDLL(USDHC_Type *base)
1522 {
1523     base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_RESET_MASK;
1524 }
1525 
1526 /*!
1527  * @brief Enables/disables the strobe DLL.
1528  *
1529  * @param base USDHC peripheral base address.
1530  * @param enable enable/disable flag
1531  */
1532 static inline void USDHC_EnableStrobeDLL(USDHC_Type *base, bool enable)
1533 {
1534     if (enable)
1535     {
1536         base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK;
1537     }
1538     else
1539     {
1540         base->STROBE_DLL_CTRL &= ~USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK;
1541     }
1542 }
1543 
1544 /*!
1545  * @brief Configs the strobe DLL delay target and update interval.
1546  *
1547  * @param base USDHC peripheral base address.
1548  * @param delayTarget delay target
1549  * @param updateInterval update interval
1550  */
1551 void USDHC_ConfigStrobeDLL(USDHC_Type *base, uint32_t delayTarget, uint32_t updateInterval);
1552 
1553 /*!
1554  * @brief Enables manual override for slave delay chain using <b>STROBE_SLV_OVERRIDE_VAL</b>.
1555  *
1556  * @param base USDHC peripheral base address.
1557  * @param delayTaps Valid delay taps range from 1 - 128 taps. A value of 0 selects tap 1, and a value of 0x7F selects
1558  * tap 128.
1559  */
1560 static inline void USDHC_SetStrobeDllOverride(USDHC_Type *base, uint32_t delayTaps)
1561 {
1562     base->STROBE_DLL_CTRL &= (USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK |
1563                               USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_OVERRIDE_VAL_MASK);
1564 
1565     base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_OVERRIDE_MASK |
1566                              USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_OVERRIDE_VAL(delayTaps);
1567 }
1568 
1569 /*!
1570  * @brief Gets the strobe DLL status.
1571  *
1572  * @param base USDHC peripheral base address.
1573  */
1574 static inline uint32_t USDHC_GetStrobeDLLStatus(USDHC_Type *base)
1575 {
1576     return base->STROBE_DLL_STATUS;
1577 }
1578 
1579 #endif
1580 
1581 /*!
1582  * @brief USDHC data configuration.
1583  *
1584  * @param base USDHC peripheral base address.
1585  * @param dataDirection Data direction, tx or rx.
1586  * @param blockCount Data block count.
1587  * @param blockSize Data block size.
1588  *
1589  */
1590 void USDHC_SetDataConfig(USDHC_Type *base,
1591                          usdhc_transfer_direction_t dataDirection,
1592                          uint32_t blockCount,
1593                          uint32_t blockSize);
1594 /* @} */
1595 
1596 /*!
1597  * @name Transactional functions
1598  * @{
1599  */
1600 
1601 /*!
1602  * @brief Creates the USDHC handle.
1603  *
1604  * @param base USDHC peripheral base address.
1605  * @param handle USDHC handle pointer.
1606  * @param callback Structure pointer to contain all callback functions.
1607  * @param userData Callback function parameter.
1608  */
1609 void USDHC_TransferCreateHandle(USDHC_Type *base,
1610                                 usdhc_handle_t *handle,
1611                                 const usdhc_transfer_callback_t *callback,
1612                                 void *userData);
1613 
1614 #if (defined FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER) && FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
1615 /*!
1616  * @brief Transfers the command/scatter gather data using an interrupt and an asynchronous method.
1617  *
1618  * This function sends a command and data and returns immediately. It doesn't wait for the transfer to complete or
1619  * to encounter an error. The application must not call this API in multiple threads at the same time. Because of that
1620  * this API doesn't support the re-entry mechanism.
1621  * This function is target for the application would like to have scatter gather buffer to be transferred within one
1622  * read/write request, non scatter gather buffer is support by this function also.
1623  *
1624  * @note Call API @ref USDHC_TransferCreateHandle when calling this API.
1625  *
1626  * @param base USDHC peripheral base address.
1627  * @param handle USDHC handle.
1628  * @param dmaConfig adma configurations, must be not NULL, since the function is target for ADMA only.
1629  * @param transfer scatter gather transfer content.
1630  *
1631  * @retval #kStatus_InvalidArgument Argument is invalid.
1632  * @retval #kStatus_USDHC_BusyTransferring Busy transferring.
1633  * @retval #kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1634  * @retval #kStatus_Success Operate successfully.
1635  */
1636 status_t USDHC_TransferScatterGatherADMANonBlocking(USDHC_Type *base,
1637                                                     usdhc_handle_t *handle,
1638                                                     usdhc_adma_config_t *dmaConfig,
1639                                                     usdhc_scatter_gather_transfer_t *transfer);
1640 #else
1641 /*!
1642  * @brief Transfers the command/data using an interrupt and an asynchronous method.
1643  *
1644  * This function sends a command and data and returns immediately. It doesn't wait for the transfer to complete or
1645  * to encounter an error. The application must not call this API in multiple threads at the same time. Because of that
1646  * this API doesn't support the re-entry mechanism.
1647  *
1648  * @note Call API @ref USDHC_TransferCreateHandle when calling this API.
1649  *
1650  * @param base USDHC peripheral base address.
1651  * @param handle USDHC handle.
1652  * @param dmaConfig ADMA configuration.
1653  * @param transfer Transfer content.
1654  * @retval #kStatus_InvalidArgument Argument is invalid.
1655  * @retval #kStatus_USDHC_BusyTransferring Busy transferring.
1656  * @retval #kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1657  * @retval #kStatus_Success Operate successfully.
1658  */
1659 status_t USDHC_TransferNonBlocking(USDHC_Type *base,
1660                                    usdhc_handle_t *handle,
1661                                    usdhc_adma_config_t *dmaConfig,
1662                                    usdhc_transfer_t *transfer);
1663 #endif
1664 
1665 /*!
1666  * @brief Transfers the command/data using a blocking method.
1667  *
1668  * This function waits until the command response/data is received or the USDHC encounters an error by polling the
1669  * status flag. \n
1670  * The application must not call this API in multiple threads at the same time. Because this API doesn't
1671  * support the re-entry mechanism.
1672  *
1673  * @note There is no need to call API @ref USDHC_TransferCreateHandle when calling this API.
1674  *
1675  * @param base USDHC peripheral base address.
1676  * @param dmaConfig adma configuration
1677  * @param transfer Transfer content.
1678  * @retval #kStatus_InvalidArgument Argument is invalid.
1679  * @retval #kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1680  * @retval #kStatus_USDHC_SendCommandFailed Send command failed.
1681  * @retval #kStatus_USDHC_TransferDataFailed Transfer data failed.
1682  * @retval #kStatus_Success Operate successfully.
1683  */
1684 status_t USDHC_TransferBlocking(USDHC_Type *base, usdhc_adma_config_t *dmaConfig, usdhc_transfer_t *transfer);
1685 
1686 /*!
1687  * @brief IRQ handler for the USDHC.
1688  *
1689  * This function deals with the IRQs on the given host controller.
1690  *
1691  * @param base USDHC peripheral base address.
1692  * @param handle USDHC handle.
1693  */
1694 void USDHC_TransferHandleIRQ(USDHC_Type *base, usdhc_handle_t *handle);
1695 
1696 /* @} */
1697 
1698 #if defined(__cplusplus)
1699 }
1700 #endif
1701 /*! @} */
1702 
1703 #endif /* _FSL_USDHC_H_*/