1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2021 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef _FSL_USDHC_H_
9 #define _FSL_USDHC_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup usdhc
15  * @{
16  */
17 
18 /******************************************************************************
19  * Definitions.
20  *****************************************************************************/
21 
22 /*! @name Driver version */
23 /*@{*/
24 /*! @brief Driver version 2.8.2. */
25 #define FSL_USDHC_DRIVER_VERSION (MAKE_VERSION(2U, 8U, 2U))
26 /*@}*/
27 
28 /*! @brief Maximum block count can be set one time */
29 #define USDHC_MAX_BLOCK_COUNT (USDHC_BLK_ATT_BLKCNT_MASK >> USDHC_BLK_ATT_BLKCNT_SHIFT)
30 
31 /*! @brief USDHC scatter gather feature control macro */
32 #ifndef FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
33 #define FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER 0U
34 #endif
35 
36 /*! @brief Enum _usdhc_status. USDHC status. */
37 enum
38 {
39     kStatus_USDHC_BusyTransferring            = MAKE_STATUS(kStatusGroup_USDHC, 0U),  /*!< Transfer is on-going. */
40     kStatus_USDHC_PrepareAdmaDescriptorFailed = MAKE_STATUS(kStatusGroup_USDHC, 1U),  /*!< Set DMA descriptor failed. */
41     kStatus_USDHC_SendCommandFailed           = MAKE_STATUS(kStatusGroup_USDHC, 2U),  /*!< Send command failed. */
42     kStatus_USDHC_TransferDataFailed          = MAKE_STATUS(kStatusGroup_USDHC, 3U),  /*!< Transfer data failed. */
43     kStatus_USDHC_DMADataAddrNotAlign         = MAKE_STATUS(kStatusGroup_USDHC, 4U),  /*!< Data address not aligned. */
44     kStatus_USDHC_ReTuningRequest             = MAKE_STATUS(kStatusGroup_USDHC, 5U),  /*!< Re-tuning request. */
45     kStatus_USDHC_TuningError                 = MAKE_STATUS(kStatusGroup_USDHC, 6U),  /*!< Tuning error. */
46     kStatus_USDHC_NotSupport                  = MAKE_STATUS(kStatusGroup_USDHC, 7U),  /*!< Not support. */
47     kStatus_USDHC_TransferDataComplete        = MAKE_STATUS(kStatusGroup_USDHC, 8U),  /*!< Transfer data complete. */
48     kStatus_USDHC_SendCommandSuccess          = MAKE_STATUS(kStatusGroup_USDHC, 9U),  /*!< Transfer command complete. */
49     kStatus_USDHC_TransferDMAComplete         = MAKE_STATUS(kStatusGroup_USDHC, 10U), /*!< Transfer DMA complete. */
50 };
51 
52 /*! @brief Enum _usdhc_capability_flag. Host controller capabilities flag mask.
53  *  @anchor _usdhc_capability_flag
54  */
55 enum
56 {
57     kUSDHC_SupportAdmaFlag          = USDHC_HOST_CTRL_CAP_ADMAS_MASK, /*!< Support ADMA. */
58     kUSDHC_SupportHighSpeedFlag     = USDHC_HOST_CTRL_CAP_HSS_MASK,   /*!< Support high-speed. */
59     kUSDHC_SupportDmaFlag           = USDHC_HOST_CTRL_CAP_DMAS_MASK,  /*!< Support DMA. */
60     kUSDHC_SupportSuspendResumeFlag = USDHC_HOST_CTRL_CAP_SRS_MASK,   /*!< Support suspend/resume. */
61     kUSDHC_SupportV330Flag          = USDHC_HOST_CTRL_CAP_VS33_MASK,  /*!< Support voltage 3.3V. */
62     kUSDHC_SupportV300Flag          = USDHC_HOST_CTRL_CAP_VS30_MASK,  /*!< Support voltage 3.0V. */
63     kUSDHC_SupportV180Flag          = USDHC_HOST_CTRL_CAP_VS18_MASK,  /*!< Support voltage 1.8V. */
64     kUSDHC_Support4BitFlag          = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 0U),
65     /*!< Flag in HTCAPBLT_MBL's position, supporting 4-bit mode. */
66     kUSDHC_Support8BitFlag = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 1U),
67     /*!< Flag in HTCAPBLT_MBL's position, supporting 8-bit mode. */
68     kUSDHC_SupportDDR50Flag = USDHC_HOST_CTRL_CAP_DDR50_SUPPORT_MASK,
69 /*!< SD version 3.0 new feature, supporting DDR50 mode. */
70 
71 #if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR104_MODE)
72     kUSDHC_SupportSDR104Flag = 0, /*!< not support SDR104 mode */
73 #else
74     kUSDHC_SupportSDR104Flag   = USDHC_HOST_CTRL_CAP_SDR104_SUPPORT_MASK, /*!< Support SDR104 mode. */
75 #endif
76 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
77     kUSDHC_SupportSDR50Flag = 0U, /*!< not support SDR50 mode */
78 #else
79     kUSDHC_SupportSDR50Flag    = USDHC_HOST_CTRL_CAP_SDR50_SUPPORT_MASK,  /*!< Support SDR50 mode. */
80 #endif
81 };
82 
83 /*! @brief Enum _usdhc_wakeup_event. Wakeup event mask.
84  *  @anchor _usdhc_wakeup_event
85  */
86 enum
87 {
88     kUSDHC_WakeupEventOnCardInt    = USDHC_PROT_CTRL_WECINT_MASK, /*!< Wakeup on card interrupt. */
89     kUSDHC_WakeupEventOnCardInsert = USDHC_PROT_CTRL_WECINS_MASK, /*!< Wakeup on card insertion. */
90     kUSDHC_WakeupEventOnCardRemove = USDHC_PROT_CTRL_WECRM_MASK,  /*!< Wakeup on card removal. */
91     kUSDHC_WakeupEventsAll =
92         (kUSDHC_WakeupEventOnCardInt | kUSDHC_WakeupEventOnCardInsert | kUSDHC_WakeupEventOnCardRemove),
93     /*!< All wakeup events */
94 };
95 
96 /*! @brief Enum _usdhc_reset. Reset type mask.
97  *  @anchor _usdhc_reset
98  */
99 enum
100 {
101     kUSDHC_ResetAll     = USDHC_SYS_CTRL_RSTA_MASK, /*!< Reset all except card detection. */
102     kUSDHC_ResetCommand = USDHC_SYS_CTRL_RSTC_MASK, /*!< Reset command line. */
103     kUSDHC_ResetData    = USDHC_SYS_CTRL_RSTD_MASK, /*!< Reset data line. */
104 
105 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
106     kUSDHC_ResetTuning = 0U, /*!< no reset tuning circuit bit */
107 #else
108     kUSDHC_ResetTuning         = USDHC_SYS_CTRL_RSTT_MASK,                /*!< Reset tuning circuit. */
109 #endif
110 
111     kUSDHC_ResetsAll = (kUSDHC_ResetAll | kUSDHC_ResetCommand | kUSDHC_ResetData | kUSDHC_ResetTuning),
112     /*!< All reset types */
113 };
114 
115 /*! @brief Enum _usdhc_transfer_flag. Transfer flag mask. */
116 enum
117 {
118     kUSDHC_EnableDmaFlag = USDHC_MIX_CTRL_DMAEN_MASK, /*!< Enable DMA. */
119 
120     kUSDHC_CommandTypeSuspendFlag = USDHC_CMD_XFR_TYP_CMDTYP(1U), /*!< Suspend command. */
121     kUSDHC_CommandTypeResumeFlag  = USDHC_CMD_XFR_TYP_CMDTYP(2U), /*!< Resume command. */
122     kUSDHC_CommandTypeAbortFlag   = USDHC_CMD_XFR_TYP_CMDTYP(3U), /*!< Abort command. */
123 
124     kUSDHC_EnableBlockCountFlag    = USDHC_MIX_CTRL_BCEN_MASK,   /*!< Enable block count. */
125     kUSDHC_EnableAutoCommand12Flag = USDHC_MIX_CTRL_AC12EN_MASK, /*!< Enable auto CMD12. */
126     kUSDHC_DataReadFlag            = USDHC_MIX_CTRL_DTDSEL_MASK, /*!< Enable data read. */
127     kUSDHC_MultipleBlockFlag       = USDHC_MIX_CTRL_MSBSEL_MASK, /*!< Multiple block data read/write. */
128     kUSDHC_EnableAutoCommand23Flag = USDHC_MIX_CTRL_AC23EN_MASK, /*!< Enable auto CMD23. */
129 
130     kUSDHC_ResponseLength136Flag    = USDHC_CMD_XFR_TYP_RSPTYP(1U), /*!< 136-bit response length. */
131     kUSDHC_ResponseLength48Flag     = USDHC_CMD_XFR_TYP_RSPTYP(2U), /*!< 48-bit response length. */
132     kUSDHC_ResponseLength48BusyFlag = USDHC_CMD_XFR_TYP_RSPTYP(3U), /*!< 48-bit response length with busy status. */
133 
134     kUSDHC_EnableCrcCheckFlag   = USDHC_CMD_XFR_TYP_CCCEN_MASK, /*!< Enable CRC check. */
135     kUSDHC_EnableIndexCheckFlag = USDHC_CMD_XFR_TYP_CICEN_MASK, /*!< Enable index check. */
136     kUSDHC_DataPresentFlag      = USDHC_CMD_XFR_TYP_DPSEL_MASK, /*!< Data present flag. */
137 };
138 
139 /*! @brief Enum _usdhc_present_status_flag. Present status flag mask.
140  *  @anchor _usdhc_present_status_flag
141  */
142 enum
143 {
144     kUSDHC_CommandInhibitFlag      = USDHC_PRES_STATE_CIHB_MASK,  /*!< Command inhibit. */
145     kUSDHC_DataInhibitFlag         = USDHC_PRES_STATE_CDIHB_MASK, /*!< Data inhibit. */
146     kUSDHC_DataLineActiveFlag      = USDHC_PRES_STATE_DLA_MASK,   /*!< Data line active. */
147     kUSDHC_SdClockStableFlag       = USDHC_PRES_STATE_SDSTB_MASK, /*!< SD bus clock stable. */
148     kUSDHC_WriteTransferActiveFlag = USDHC_PRES_STATE_WTA_MASK,   /*!< Write transfer active. */
149     kUSDHC_ReadTransferActiveFlag  = USDHC_PRES_STATE_RTA_MASK,   /*!< Read transfer active. */
150     kUSDHC_BufferWriteEnableFlag   = USDHC_PRES_STATE_BWEN_MASK,  /*!< Buffer write enable. */
151     kUSDHC_BufferReadEnableFlag    = USDHC_PRES_STATE_BREN_MASK,  /*!< Buffer read enable. */
152 
153 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
154     kUSDHC_DelaySettingFinishedFlag = 0U, /*!< not support */
155     kUSDHC_ReTuningRequestFlag      = 0U, /*!< not support */
156 #else
157     kUSDHC_ReTuningRequestFlag = USDHC_PRES_STATE_RTR_MASK, /*!< Re-tuning request flag, only used for SDR104 mode. */
158     kUSDHC_DelaySettingFinishedFlag = USDHC_PRES_STATE_TSCD_MASK, /*!< Delay setting finished flag. */
159 #endif
160 
161     kUSDHC_CardInsertedFlag     = USDHC_PRES_STATE_CINST_MASK, /*!< Card inserted. */
162     kUSDHC_CommandLineLevelFlag = USDHC_PRES_STATE_CLSL_MASK,  /*!< Command line signal level. */
163 
164     kUSDHC_Data0LineLevelFlag = 1U << USDHC_PRES_STATE_DLSL_SHIFT,               /*!< Data0 line signal level. */
165     kUSDHC_Data1LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 1U),        /*!< Data1 line signal level. */
166     kUSDHC_Data2LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 2U),        /*!< Data2 line signal level. */
167     kUSDHC_Data3LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 3U),        /*!< Data3 line signal level. */
168     kUSDHC_Data4LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 4U),        /*!< Data4 line signal level. */
169     kUSDHC_Data5LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 5U),        /*!< Data5 line signal level. */
170     kUSDHC_Data6LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 6U),        /*!< Data6 line signal level. */
171     kUSDHC_Data7LineLevelFlag = (int)(1U << (USDHC_PRES_STATE_DLSL_SHIFT + 7U)), /*!< Data7 line signal level. */
172 };
173 
174 /*! @brief Enum _usdhc_interrupt_status_flag. Interrupt status flag mask.
175  *  @anchor _usdhc_interrupt_status_flag
176  */
177 enum
178 {
179     kUSDHC_CommandCompleteFlag  = USDHC_INT_STATUS_CC_MASK,   /*!< Command complete. */
180     kUSDHC_DataCompleteFlag     = USDHC_INT_STATUS_TC_MASK,   /*!< Data complete. */
181     kUSDHC_BlockGapEventFlag    = USDHC_INT_STATUS_BGE_MASK,  /*!< Block gap event. */
182     kUSDHC_DmaCompleteFlag      = USDHC_INT_STATUS_DINT_MASK, /*!< DMA interrupt. */
183     kUSDHC_BufferWriteReadyFlag = USDHC_INT_STATUS_BWR_MASK,  /*!< Buffer write ready. */
184     kUSDHC_BufferReadReadyFlag  = USDHC_INT_STATUS_BRR_MASK,  /*!< Buffer read ready. */
185     kUSDHC_CardInsertionFlag    = USDHC_INT_STATUS_CINS_MASK, /*!< Card inserted. */
186     kUSDHC_CardRemovalFlag      = USDHC_INT_STATUS_CRM_MASK,  /*!< Card removed. */
187     kUSDHC_CardInterruptFlag    = USDHC_INT_STATUS_CINT_MASK, /*!< Card interrupt. */
188 
189 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
190     kUSDHC_ReTuningEventFlag = 0U, /*!< Re-Tuning event, only for SD3.0 SDR104 mode. */
191     kUSDHC_TuningPassFlag    = 0U, /*!< SDR104 mode tuning pass flag. */
192     kUSDHC_TuningErrorFlag   = 0U, /*!< SDR104 tuning error flag. */
193 #else
194     kUSDHC_ReTuningEventFlag        = USDHC_INT_STATUS_RTE_MASK,  /*!< Re-Tuning event, only for SD3.0 SDR104 mode. */
195     kUSDHC_TuningPassFlag           = USDHC_INT_STATUS_TP_MASK,   /*!< SDR104 mode tuning pass flag. */
196     kUSDHC_TuningErrorFlag          = USDHC_INT_STATUS_TNE_MASK,  /*!< SDR104 tuning error flag. */
197 #endif
198 
199     kUSDHC_CommandTimeoutFlag     = USDHC_INT_STATUS_CTOE_MASK,  /*!< Command timeout error. */
200     kUSDHC_CommandCrcErrorFlag    = USDHC_INT_STATUS_CCE_MASK,   /*!< Command CRC error. */
201     kUSDHC_CommandEndBitErrorFlag = USDHC_INT_STATUS_CEBE_MASK,  /*!< Command end bit error. */
202     kUSDHC_CommandIndexErrorFlag  = USDHC_INT_STATUS_CIE_MASK,   /*!< Command index error. */
203     kUSDHC_DataTimeoutFlag        = USDHC_INT_STATUS_DTOE_MASK,  /*!< Data timeout error. */
204     kUSDHC_DataCrcErrorFlag       = USDHC_INT_STATUS_DCE_MASK,   /*!< Data CRC error. */
205     kUSDHC_DataEndBitErrorFlag    = USDHC_INT_STATUS_DEBE_MASK,  /*!< Data end bit error. */
206     kUSDHC_AutoCommand12ErrorFlag = USDHC_INT_STATUS_AC12E_MASK, /*!< Auto CMD12 error. */
207     kUSDHC_DmaErrorFlag           = USDHC_INT_STATUS_DMAE_MASK,  /*!< DMA error. */
208 
209     kUSDHC_CommandErrorFlag = (kUSDHC_CommandTimeoutFlag | kUSDHC_CommandCrcErrorFlag | kUSDHC_CommandEndBitErrorFlag |
210                                kUSDHC_CommandIndexErrorFlag), /*!< Command error */
211     kUSDHC_DataErrorFlag    = (kUSDHC_DataTimeoutFlag | kUSDHC_DataCrcErrorFlag | kUSDHC_DataEndBitErrorFlag |
212                             kUSDHC_AutoCommand12ErrorFlag),                                        /*!< Data error */
213     kUSDHC_ErrorFlag        = (kUSDHC_CommandErrorFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< All error */
214 
215     kUSDHC_DataFlag = (kUSDHC_DataCompleteFlag | kUSDHC_BufferWriteReadyFlag | kUSDHC_BufferReadReadyFlag |
216                        kUSDHC_DataErrorFlag), /*!< Data interrupts */
217 
218     kUSDHC_DataDMAFlag = (kUSDHC_DataCompleteFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< Data interrupts */
219 
220     kUSDHC_CommandFlag      = (kUSDHC_CommandErrorFlag | kUSDHC_CommandCompleteFlag), /*!< Command interrupts */
221     kUSDHC_CardDetectFlag   = (kUSDHC_CardInsertionFlag | kUSDHC_CardRemovalFlag),    /*!< Card detection interrupts */
222     kUSDHC_SDR104TuningFlag = (kUSDHC_TuningErrorFlag | kUSDHC_TuningPassFlag | kUSDHC_ReTuningEventFlag),
223     /*!< SDR104 tuning flag. */
224     kUSDHC_AllInterruptFlags =
225         (kUSDHC_BlockGapEventFlag | kUSDHC_CardInterruptFlag | kUSDHC_CommandFlag | kUSDHC_DataFlag | kUSDHC_ErrorFlag |
226          kUSDHC_SDR104TuningFlag | kUSDHC_DmaCompleteFlag), /*!< All flags mask */
227 };
228 
229 /*! @brief Enum _usdhc_auto_command12_error_status_flag. Auto CMD12 error status flag mask.
230  *  @anchor _usdhc_auto_command12_error_status_flag
231  */
232 enum
233 {
234     kUSDHC_AutoCommand12NotExecutedFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12NE_MASK,    /*!< Not executed error. */
235     kUSDHC_AutoCommand12TimeoutFlag     = USDHC_AUTOCMD12_ERR_STATUS_AC12TOE_MASK,   /*!< Timeout error. */
236     kUSDHC_AutoCommand12EndBitErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12EBE_MASK,   /*!< End bit error. */
237     kUSDHC_AutoCommand12CrcErrorFlag    = USDHC_AUTOCMD12_ERR_STATUS_AC12CE_MASK,    /*!< CRC error. */
238     kUSDHC_AutoCommand12IndexErrorFlag  = USDHC_AUTOCMD12_ERR_STATUS_AC12IE_MASK,    /*!< Index error. */
239     kUSDHC_AutoCommand12NotIssuedFlag   = USDHC_AUTOCMD12_ERR_STATUS_CNIBAC12E_MASK, /*!< Not issued error. */
240 };
241 
242 /*! @brief Enum _usdhc_standard_tuning. Standard tuning flag. */
243 enum
244 {
245 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
246     kUSDHC_ExecuteTuning        = 0U, /*!< not support */
247     kUSDHC_TuningSampleClockSel = 0U, /*!< not support */
248 #else
249     kUSDHC_ExecuteTuning = USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK, /*!< Used to start tuning procedure. */
250     kUSDHC_TuningSampleClockSel =
251         USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK,               /*!< When <b>std_tuning_en</b> bit is set, this
252                                                                     bit is used to select sampleing clock. */
253 #endif
254 };
255 
256 /*! @brief Enum _usdhc_adma_error_status_flag. ADMA error status flag mask.
257  *  @anchor _usdhc_adma_error_status_flag
258  */
259 enum
260 {
261     kUSDHC_AdmaLenghMismatchFlag   = USDHC_ADMA_ERR_STATUS_ADMALME_MASK, /*!< Length mismatch error. */
262     kUSDHC_AdmaDescriptorErrorFlag = USDHC_ADMA_ERR_STATUS_ADMADCE_MASK, /*!< Descriptor error. */
263 };
264 
265 /*!
266  * @brief Enum _usdhc_adma_error_state. ADMA error state.
267  *
268  * This state is the detail state when ADMA error has occurred.
269  */
270 enum
271 {
272     kUSDHC_AdmaErrorStateStopDma = 0x00U,
273     /*!< Stop DMA, previous location set in the ADMA system address is errored address. */
274     kUSDHC_AdmaErrorStateFetchDescriptor = 0x01U,
275     /*!< Fetch descriptor, current location set in the ADMA system address is errored address. */
276     kUSDHC_AdmaErrorStateChangeAddress = 0x02U, /*!< Change address, no DMA error has occurred. */
277     kUSDHC_AdmaErrorStateTransferData  = 0x03U,
278     /*!< Transfer data, previous location set in the ADMA system address is errored address. */
279     kUSDHC_AdmaErrorStateInvalidLength     = 0x04U, /*!< Invalid length in ADMA descriptor. */
280     kUSDHC_AdmaErrorStateInvalidDescriptor = 0x08U, /*!< Invalid descriptor fetched by ADMA. */
281 
282     kUSDHC_AdmaErrorState = kUSDHC_AdmaErrorStateInvalidLength | kUSDHC_AdmaErrorStateInvalidDescriptor |
283                             kUSDHC_AdmaErrorStateFetchDescriptor, /*!< ADMA error state */
284 };
285 
286 /*! @brief Enum _usdhc_force_event. Force event bit position.
287  *  @anchor _usdhc_force_event
288  */
289 enum
290 {
291     kUSDHC_ForceEventAutoCommand12NotExecuted =
292         USDHC_FORCE_EVENT_FEVTAC12NE_MASK, /*!< Auto CMD12 not executed error. */
293     kUSDHC_ForceEventAutoCommand12Timeout    = USDHC_FORCE_EVENT_FEVTAC12TOE_MASK,  /*!< Auto CMD12 timeout error. */
294     kUSDHC_ForceEventAutoCommand12CrcError   = USDHC_FORCE_EVENT_FEVTAC12CE_MASK,   /*!< Auto CMD12 CRC error. */
295     kUSDHC_ForceEventEndBitError             = USDHC_FORCE_EVENT_FEVTAC12EBE_MASK,  /*!< Auto CMD12 end bit error. */
296     kUSDHC_ForceEventAutoCommand12IndexError = USDHC_FORCE_EVENT_FEVTAC12IE_MASK,   /*!< Auto CMD12 index error. */
297     kUSDHC_ForceEventAutoCommand12NotIssued = USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK, /*!< Auto CMD12 not issued error. */
298     kUSDHC_ForceEventCommandTimeout         = USDHC_FORCE_EVENT_FEVTCTOE_MASK,      /*!< Command timeout error. */
299     kUSDHC_ForceEventCommandCrcError        = USDHC_FORCE_EVENT_FEVTCCE_MASK,       /*!< Command CRC error. */
300     kUSDHC_ForceEventCommandEndBitError     = USDHC_FORCE_EVENT_FEVTCEBE_MASK,      /*!< Command end bit error. */
301     kUSDHC_ForceEventCommandIndexError      = USDHC_FORCE_EVENT_FEVTCIE_MASK,       /*!< Command index error. */
302     kUSDHC_ForceEventDataTimeout            = USDHC_FORCE_EVENT_FEVTDTOE_MASK,      /*!< Data timeout error. */
303     kUSDHC_ForceEventDataCrcError           = USDHC_FORCE_EVENT_FEVTDCE_MASK,       /*!< Data CRC error. */
304     kUSDHC_ForceEventDataEndBitError        = USDHC_FORCE_EVENT_FEVTDEBE_MASK,      /*!< Data end bit error. */
305     kUSDHC_ForceEventAutoCommand12Error     = USDHC_FORCE_EVENT_FEVTAC12E_MASK,     /*!< Auto CMD12 error. */
306     kUSDHC_ForceEventCardInt                = (int)USDHC_FORCE_EVENT_FEVTCINT_MASK, /*!< Card interrupt. */
307     kUSDHC_ForceEventDmaError               = USDHC_FORCE_EVENT_FEVTDMAE_MASK,      /*!< Dma error. */
308 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
309     kUSDHC_ForceEventTuningError = 0U, /*!< not support */
310 #else
311     kUSDHC_ForceEventTuningError = USDHC_FORCE_EVENT_FEVTTNE_MASK, /*!< Tuning error. */
312 #endif
313 
314     kUSDHC_ForceEventsAll =
315         (int)(USDHC_FORCE_EVENT_FEVTAC12NE_MASK | USDHC_FORCE_EVENT_FEVTAC12TOE_MASK |
316               USDHC_FORCE_EVENT_FEVTAC12CE_MASK | USDHC_FORCE_EVENT_FEVTAC12EBE_MASK |
317               USDHC_FORCE_EVENT_FEVTAC12IE_MASK | USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK |
318               USDHC_FORCE_EVENT_FEVTCTOE_MASK | USDHC_FORCE_EVENT_FEVTCCE_MASK | USDHC_FORCE_EVENT_FEVTCEBE_MASK |
319               USDHC_FORCE_EVENT_FEVTCIE_MASK | USDHC_FORCE_EVENT_FEVTDTOE_MASK | USDHC_FORCE_EVENT_FEVTDCE_MASK |
320               USDHC_FORCE_EVENT_FEVTDEBE_MASK | USDHC_FORCE_EVENT_FEVTAC12E_MASK | USDHC_FORCE_EVENT_FEVTCINT_MASK |
321               USDHC_FORCE_EVENT_FEVTDMAE_MASK | kUSDHC_ForceEventTuningError), /*!< All force event flags mask. */
322 };
323 
324 /*! @brief Data transfer direction. */
325 typedef enum _usdhc_transfer_direction
326 {
327     kUSDHC_TransferDirectionReceive = 1U, /*!< USDHC transfer direction receive. */
328     kUSDHC_TransferDirectionSend    = 0U, /*!< USDHC transfer direction send. */
329 } usdhc_transfer_direction_t;
330 
331 /*! @brief Data transfer width. */
332 typedef enum _usdhc_data_bus_width
333 {
334     kUSDHC_DataBusWidth1Bit = 0U, /*!< 1-bit mode */
335     kUSDHC_DataBusWidth4Bit = 1U, /*!< 4-bit mode */
336     kUSDHC_DataBusWidth8Bit = 2U, /*!< 8-bit mode */
337 } usdhc_data_bus_width_t;
338 
339 /*! @brief Endian mode */
340 typedef enum _usdhc_endian_mode
341 {
342     kUSDHC_EndianModeBig         = 0U, /*!< Big endian mode. */
343     kUSDHC_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode. */
344     kUSDHC_EndianModeLittle      = 2U, /*!< Little endian mode. */
345 } usdhc_endian_mode_t;
346 
347 /*! @brief DMA mode */
348 typedef enum _usdhc_dma_mode
349 {
350     kUSDHC_DmaModeSimple = 0U, /*!< External DMA. */
351     kUSDHC_DmaModeAdma1  = 1U, /*!< ADMA1 is selected. */
352     kUSDHC_DmaModeAdma2  = 2U, /*!< ADMA2 is selected. */
353     kUSDHC_ExternalDMA   = 3U, /*!< External DMA mode selected. */
354 } usdhc_dma_mode_t;
355 
356 /*! @brief Enum _usdhc_sdio_control_flag. SDIO control flag mask.
357  *  @anchor _usdhc_sdio_control_flag
358  */
359 enum
360 {
361     kUSDHC_StopAtBlockGapFlag      = USDHC_PROT_CTRL_SABGREQ_MASK, /*!< Stop at block gap. */
362     kUSDHC_ReadWaitControlFlag     = USDHC_PROT_CTRL_RWCTL_MASK,   /*!< Read wait control. */
363     kUSDHC_InterruptAtBlockGapFlag = USDHC_PROT_CTRL_IABG_MASK,    /*!< Interrupt at block gap. */
364     kUSDHC_ReadDoneNo8CLK = USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK,  /*!< Read done without 8 clk for block gap. */
365     kUSDHC_ExactBlockNumberReadFlag = USDHC_PROT_CTRL_NON_EXACT_BLK_RD_MASK, /*!< Exact block number read. */
366 };
367 
368 /*! @brief MMC card boot mode */
369 typedef enum _usdhc_boot_mode
370 {
371     kUSDHC_BootModeNormal      = 0U, /*!< Normal boot */
372     kUSDHC_BootModeAlternative = 1U, /*!< Alternative boot */
373 } usdhc_boot_mode_t;
374 
375 /*! @brief The command type */
376 typedef enum _usdhc_card_command_type
377 {
378     kCARD_CommandTypeNormal  = 0U, /*!< Normal command */
379     kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */
380     kCARD_CommandTypeResume  = 2U, /*!< Resume command */
381     kCARD_CommandTypeAbort   = 3U, /*!< Abort command */
382     kCARD_CommandTypeEmpty   = 4U, /*!< Empty command */
383 } usdhc_card_command_type_t;
384 
385 /*!
386  * @brief The command response type.
387  *
388  * Defines the command response type from card to host controller.
389  */
390 typedef enum _usdhc_card_response_type
391 {
392     kCARD_ResponseTypeNone = 0U, /*!< Response type: none */
393     kCARD_ResponseTypeR1   = 1U, /*!< Response type: R1 */
394     kCARD_ResponseTypeR1b  = 2U, /*!< Response type: R1b */
395     kCARD_ResponseTypeR2   = 3U, /*!< Response type: R2 */
396     kCARD_ResponseTypeR3   = 4U, /*!< Response type: R3 */
397     kCARD_ResponseTypeR4   = 5U, /*!< Response type: R4 */
398     kCARD_ResponseTypeR5   = 6U, /*!< Response type: R5 */
399     kCARD_ResponseTypeR5b  = 7U, /*!< Response type: R5b */
400     kCARD_ResponseTypeR6   = 8U, /*!< Response type: R6 */
401     kCARD_ResponseTypeR7   = 9U, /*!< Response type: R7 */
402 } usdhc_card_response_type_t;
403 
404 /*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor. */
405 #define USDHC_ADMA1_ADDRESS_ALIGN (4096U)
406 /*! @brief The alignment size for LENGTH field in ADMA1's descriptor. */
407 #define USDHC_ADMA1_LENGTH_ALIGN (4096U)
408 /*! @brief The alignment size for ADDRESS field in ADMA2's descriptor. */
409 #define USDHC_ADMA2_ADDRESS_ALIGN (4U)
410 /*! @brief The alignment size for LENGTH filed in ADMA2's descriptor. */
411 #define USDHC_ADMA2_LENGTH_ALIGN (4U)
412 
413 /* ADMA1 descriptor table:
414  * |------------------------|---------|--------------------------|
415  * | Address/page field     |Reserved |         Attribute        |
416  * |------------------------|---------|--------------------------|
417  * |31                    12|11      6|05  |04  |03|02 |01 |00   |
418  * |------------------------|---------|----|----|--|---|---|-----|
419  * | address or data length | 000000  |Act2|Act1| 0|Int|End|Valid|
420  * |------------------------|---------|----|----|--|---|---|-----|
421  *
422  * ADMA2 action table:
423  * |------|------|-----------------|-------|-------------|
424  * | Act2 | Act1 |     Comment     | 31-28 | 27 - 12     |
425  * |------|------|-----------------|---------------------|
426  * |   0  |   0  | No op           | Don't care          |
427  * |------|------|-----------------|-------|-------------|
428  * |   0  |   1  | Set data length |  0000 | Data Length |
429  * |------|------|-----------------|-------|-------------|
430  * |   1  |   0  | Transfer data   | Data address        |
431  * |------|------|-----------------|---------------------|
432  * |   1  |   1  | Link descriptor | Descriptor address  |
433  * |------|------|-----------------|---------------------|
434  */
435 /****************************tables below are created only for Doxygen*********************************/
436 /*! @brief The bit shift for ADDRESS filed in ADMA1's descriptor.
437  *  <table>
438  *  <caption>ADMA1 descriptor table</caption>
439  *  <tr><th>Address/page field     <th>Reserved   <th colspan="6">Attribute
440  *  <tr><td>31 12                  <td>11 6       <td>05   <td>04   <td>03 <td>02  <td>01  <td>00
441  *  <tr><td>address or data length <td>000000     <td>Act2 <td>Act1 <td>0  <td>Int <td>End <td>Valid
442  *  </table>
443  *
444  *  <table>
445  *  <caption>ADMA2 action</caption>
446  *  <tr><th>Act2  <th>Act1      <th>Comment            <th>31-28    <th>27-12
447  *  <tr><td>0     <td>0         <td>No op              <td colspan="2">Don't care
448  *  <tr><td>0     <td>1         <td>Set data length    <td>0000     <td> Data Length
449  *  <tr><td>1     <td>0         <td>Transfer data      <td colspan="2">Data address
450  *  <tr><td>1     <td>1         <td>Link descriptor    <td colspan="2">Descriptor address
451  *  </table>
452  */
453 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT (12U)
454 /*! @brief The bit mask for ADDRESS field in ADMA1's descriptor. */
455 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_MASK (0xFFFFFU)
456 /*! @brief The bit shift for LENGTH filed in ADMA1's descriptor. */
457 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U)
458 /*! @brief The mask for LENGTH field in ADMA1's descriptor. */
459 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
460 /*! @brief The maximum value of LENGTH filed in ADMA1's descriptor.
461  * Since the max transfer size ADMA1 support is 65535 which is indivisible by
462  * 4096, so to make sure a large data load transfer (>64KB) continuously (require the data
463  * address be always align with 4096), software will set the maximum data length
464  * for ADMA1 to (64 - 4)KB.
465  */
466 #define USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK + 1U - 4096U)
467 
468 /*! @brief Enum _usdhc_adma1_descriptor_flag. The mask for the control/status field in ADMA1 descriptor. */
469 enum
470 {
471     kUSDHC_Adma1DescriptorValidFlag     = (1U << 0U),                        /*!< Valid flag. */
472     kUSDHC_Adma1DescriptorEndFlag       = (1U << 1U),                        /*!< End flag. */
473     kUSDHC_Adma1DescriptorInterrupFlag  = (1U << 2U),                        /*!< Interrupt flag. */
474     kUSDHC_Adma1DescriptorActivity1Flag = (1U << 4U),                        /*!< Activity 1 flag. */
475     kUSDHC_Adma1DescriptorActivity2Flag = (1U << 5U),                        /*!< Activity 2 flag. */
476     kUSDHC_Adma1DescriptorTypeNop       = (kUSDHC_Adma1DescriptorValidFlag), /*!< No operation. */
477     kUSDHC_Adma1DescriptorTypeTransfer  = (kUSDHC_Adma1DescriptorActivity2Flag | kUSDHC_Adma1DescriptorValidFlag),
478     /*!< Transfer data. */
479     kUSDHC_Adma1DescriptorTypeLink      = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorActivity2Flag |
480                                       kUSDHC_Adma1DescriptorValidFlag), /*!< Link descriptor. */
481     kUSDHC_Adma1DescriptorTypeSetLength = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorValidFlag),
482     /*!< Set data length. */
483 };
484 
485 /* ADMA2 descriptor table:
486  * |----------------|---------------|-------------|--------------------------|
487  * | Address field  |     Length    | Reserved    |         Attribute        |
488  * |----------------|---------------|-------------|--------------------------|
489  * |63            32|31           16|15         06|05  |04  |03|02 |01 |00   |
490  * |----------------|---------------|-------------|----|----|--|---|---|-----|
491  * | 32-bit address | 16-bit length | 0000000000  |Act2|Act1| 0|Int|End|Valid|
492  * |----------------|---------------|-------------|----|----|--|---|---|-----|
493  *
494  * ADMA2 action table:
495  * | Act2 | Act1 |     Comment     | Operation                                                         |
496  * |------|------|-----------------|-------------------------------------------------------------------|
497  * |   0  |   0  | No op           | Don't care                                                        |
498  * |------|------|-----------------|-------------------------------------------------------------------|
499  * |   0  |   1  | Reserved        | Read this line and go to next one                                 |
500  * |------|------|-----------------|-------------------------------------------------------------------|
501  * |   1  |   0  | Transfer data   | Transfer data with address and length set in this descriptor line |
502  * |------|------|-----------------|-------------------------------------------------------------------|
503  * |   1  |   1  | Link descriptor | Link to another descriptor                                        |
504  * |------|------|-----------------|-------------------------------------------------------------------|
505  */
506 /**********************************tables below are created only for Doxygen***********************************/
507 /*! @brief The bit shift for LENGTH field in ADMA2's descriptor.
508  *
509  * <table>
510  * <caption>ADMA2 descriptor table</caption>
511  * <tr><th>Address field    <th>Length         <th>Reserved     <th colspan="6">Attribute
512  * <tr><td>63 32            <td>31 16          <td>15 06        <td>05   <td>04   <td>03  <td>02  <td>01  <td>00
513  * <tr><td>32-bit address   <td>16-bit length  <td>0000000000   <td>Act2 <td>Act1 <td>0   <td>Int <td>End <td>Valid
514  *</table>
515  *
516  * <table>
517  * <caption>ADMA2 action</caption>
518  * <tr><th>Act2   <th>Act1   <th>Comment          <th>Operation
519  * <tr><td> 0     <td>0      <td>No op            <td>Don't care
520  * <tr><td> 0     <td>1      <td> Reserved        <td> Read this line and go to next one
521  * <tr><td> 1     <td>0      <td>Transfer data    <td>Transfer data with address and length set in this descriptor line
522  * <tr><td> 1     <td>1      <td>Link descriptor  <td>Link to another descriptor
523  * </table>
524  */
525 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U)
526 /*! @brief The bit mask for LENGTH field in ADMA2's descriptor. */
527 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
528 /*! @brief The maximum value of LENGTH field in ADMA2's descriptor. */
529 #define USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK - 3U)
530 
531 /*! @brief Enum _usdhc_adma2_descriptor_flag. ADMA1 descriptor control and status mask. */
532 enum
533 {
534     kUSDHC_Adma2DescriptorValidFlag     = (1U << 0U), /*!< Valid flag. */
535     kUSDHC_Adma2DescriptorEndFlag       = (1U << 1U), /*!< End flag. */
536     kUSDHC_Adma2DescriptorInterruptFlag = (1U << 2U), /*!< Interrupt flag. */
537     kUSDHC_Adma2DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 mask. */
538     kUSDHC_Adma2DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 mask. */
539 
540     kUSDHC_Adma2DescriptorTypeNop      = (kUSDHC_Adma2DescriptorValidFlag), /*!< No operation. */
541     kUSDHC_Adma2DescriptorTypeReserved = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorValidFlag),
542     /*!< Reserved. */
543     kUSDHC_Adma2DescriptorTypeTransfer = (kUSDHC_Adma2DescriptorActivity2Flag | kUSDHC_Adma2DescriptorValidFlag),
544     /*!< Transfer type. */
545     kUSDHC_Adma2DescriptorTypeLink = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorActivity2Flag |
546                                       kUSDHC_Adma2DescriptorValidFlag), /*!< Link type. */
547 };
548 
549 /*! @brief Enum _usdhc_adma_flag. ADMA descriptor configuration flag.
550  *  @anchor _usdhc_adma_flag
551  */
552 enum
553 {
554     kUSDHC_AdmaDescriptorSingleFlag = 0U,
555     /*!< Try to finish the transfer in a single ADMA descriptor. If transfer size is bigger than one
556        ADMA descriptor's ability, new another descriptor for data transfer. */
557     kUSDHC_AdmaDescriptorMultipleFlag =
558         1U, /*!< Create multiple ADMA descriptors within the ADMA table, this is used for
559              mmc boot mode specifically, which need
560              to modify the ADMA descriptor on the fly, so the flag should be used
561              combining with stop at block gap feature. */
562 };
563 
564 /*! @brief DMA transfer burst len config. */
565 typedef enum _usdhc_burst_len
566 {
567     kUSDHC_EnBurstLenForINCR         = 0x01U, /*!< Enable burst len for INCR. */
568     kUSDHC_EnBurstLenForINCR4816     = 0x02U, /*!< Enable burst len for INCR4/INCR8/INCR16. */
569     kUSDHC_EnBurstLenForINCR4816WRAP = 0x04U, /*!< Enable burst len for INCR4/8/16 WRAP. */
570 } usdhc_burst_len_t;
571 
572 /*! @brief Enum _usdhc_transfer_data_type. Tansfer data type definition. */
573 enum
574 {
575     kUSDHC_TransferDataNormal        = 0U, /*!< Transfer normal read/write data. */
576     kUSDHC_TransferDataTuning        = 1U, /*!< Transfer tuning data. */
577     kUSDHC_TransferDataBoot          = 2U, /*!< Transfer boot data. */
578     kUSDHC_TransferDataBootcontinous = 3U, /*!< Transfer boot data continuously. */
579 };
580 
581 /*! @brief Defines the ADMA1 descriptor structure. */
582 typedef uint32_t usdhc_adma1_descriptor_t;
583 
584 /*! @brief Defines the ADMA2 descriptor structure. */
585 typedef struct _usdhc_adma2_descriptor
586 {
587     uint32_t attribute;      /*!< The control and status field. */
588     const uint32_t *address; /*!< The address field. */
589 } usdhc_adma2_descriptor_t;
590 
591 /*!
592  * @brief USDHC capability information.
593  *
594  * Defines a structure to save the capability information of USDHC.
595  */
596 typedef struct _usdhc_capability
597 {
598     uint32_t sdVersion;      /*!< Support SD card/sdio version. */
599     uint32_t mmcVersion;     /*!< Support EMMC card version. */
600     uint32_t maxBlockLength; /*!< Maximum block length united as byte. */
601     uint32_t maxBlockCount;  /*!< Maximum block count can be set one time. */
602     uint32_t flags;          /*!< Capability flags to indicate the support information(@ref _usdhc_capability_flag). */
603 } usdhc_capability_t;
604 
605 /*! @brief Data structure to configure the MMC boot feature. */
606 typedef struct _usdhc_boot_config
607 {
608     uint32_t ackTimeoutCount;      /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */
609     usdhc_boot_mode_t bootMode;    /*!< Boot mode selection. */
610     uint32_t blockCount;           /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */
611     size_t blockSize;              /*!< Block size. */
612     bool enableBootAck;            /*!< Enable or disable boot ACK. */
613     bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period. */
614 } usdhc_boot_config_t;
615 
616 /*! @brief Data structure to initialize the USDHC. */
617 typedef struct _usdhc_config
618 {
619     uint32_t dataTimeout;           /*!< Data timeout value. */
620     usdhc_endian_mode_t endianMode; /*!< Endian mode. */
621     uint8_t readWatermarkLevel;     /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */
622     uint8_t writeWatermarkLevel;    /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */
623 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
624     uint8_t readBurstLen;  /*!< Read burst len. */
625     uint8_t writeBurstLen; /*!< Write burst len. */
626 #endif
627 } usdhc_config_t;
628 
629 /*!
630  * @brief Card command descriptor.
631  *
632  * Defines card command-related attribute.
633  */
634 typedef struct _usdhc_command
635 {
636     uint32_t index;                          /*!< Command index. */
637     uint32_t argument;                       /*!< Command argument. */
638     usdhc_card_command_type_t type;          /*!< Command type. */
639     usdhc_card_response_type_t responseType; /*!< Command response type. */
640     uint32_t response[4U];                   /*!< Response for this command. */
641     uint32_t responseErrorFlags;             /*!< Response error flag, which need to check
642                                                  the command reponse. */
643     uint32_t flags;                          /*!< Cmd flags. */
644 } usdhc_command_t;
645 
646 /*! @brief ADMA configuration. */
647 typedef struct _usdhc_adma_config
648 {
649     usdhc_dma_mode_t dmaMode; /*!< DMA mode. */
650 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
651     usdhc_burst_len_t burstLen; /*!< Burst len config. */
652 #endif
653     uint32_t *admaTable;     /*!< ADMA table address, can't be null if transfer way is ADMA1/ADMA2. */
654     uint32_t admaTableWords; /*!< ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. */
655 } usdhc_adma_config_t;
656 
657 /*!
658  * @brief Card scatter gather data list.
659  *
660  * Allow application register uncontinuous data buffer for data transfer.
661  */
662 typedef struct _usdhc_scatter_gather_data_list
663 {
664     uint32_t *dataAddr;
665     uint32_t dataSize;
666     struct _usdhc_scatter_gather_data_list *dataList;
667 } usdhc_scatter_gather_data_list_t;
668 
669 /*!
670  * @brief Card scatter gather data descriptor.
671  *
672  * Defines a structure to contain data-related attribute. The 'enableIgnoreError' is used when upper card
673  * driver wants to ignore the error event to read/write all the data and not to stop read/write immediately when an
674  * error event happens. For example, bus testing procedure for MMC card.
675  */
676 typedef struct _usdhc_scatter_gather_data
677 {
678     bool enableAutoCommand12; /*!< Enable auto CMD12. */
679     bool enableAutoCommand23; /*!< Enable auto CMD23. */
680     bool enableIgnoreError;   /*!< Enable to ignore error event to read/write all the data. */
681 
682     usdhc_transfer_direction_t dataDirection; /*!< data direction */
683     uint8_t dataType;                         /*!< this is used to distinguish the normal/tuning/boot data. */
684     size_t blockSize;                         /*!< Block size. */
685 
686     usdhc_scatter_gather_data_list_t sgData; /*!<  scatter gather data */
687 } usdhc_scatter_gather_data_t;
688 
689 /*! @brief usdhc scatter gather transfer. */
690 typedef struct _usdhc_scatter_gather_transfer
691 {
692     usdhc_scatter_gather_data_t *data; /*!< Data to transfer. */
693     usdhc_command_t *command;          /*!< Command to send. */
694 } usdhc_scatter_gather_transfer_t;
695 
696 /*!
697  * @brief Card data descriptor.
698  *
699  * Defines a structure to contain data-related attribute. The 'enableIgnoreError' is used when upper card
700  * driver wants to ignore the error event to read/write all the data and not to stop read/write immediately when an
701  * error event happens. For example, bus testing procedure for MMC card.
702  */
703 typedef struct _usdhc_data
704 {
705     bool enableAutoCommand12; /*!< Enable auto CMD12. */
706     bool enableAutoCommand23; /*!< Enable auto CMD23. */
707     bool enableIgnoreError;   /*!< Enable to ignore error event to read/write all the data. */
708     uint8_t dataType;         /*!< this is used to distinguish the normal/tuning/boot data. */
709     size_t blockSize;         /*!< Block size. */
710     uint32_t blockCount;      /*!< Block count. */
711     uint32_t *rxData;         /*!< Buffer to save data read. */
712     const uint32_t *txData;   /*!< Data buffer to write. */
713 } usdhc_data_t;
714 
715 /*! @brief Transfer state. */
716 typedef struct _usdhc_transfer
717 {
718     usdhc_data_t *data;       /*!< Data to transfer. */
719     usdhc_command_t *command; /*!< Command to send. */
720 } usdhc_transfer_t;
721 
722 /*! @brief USDHC handle typedef. */
723 typedef struct _usdhc_handle usdhc_handle_t;
724 
725 /*! @brief USDHC callback functions. */
726 typedef struct _usdhc_transfer_callback
727 {
728     void (*CardInserted)(USDHC_Type *base,
729                          void *userData); /*!< Card inserted occurs when DAT3/CD pin is for card detect */
730     void (*CardRemoved)(USDHC_Type *base, void *userData);   /*!< Card removed occurs */
731     void (*SdioInterrupt)(USDHC_Type *base, void *userData); /*!< SDIO card interrupt occurs */
732     void (*BlockGap)(USDHC_Type *base, void *userData);      /*!< stopped at block gap event */
733     void (*TransferComplete)(USDHC_Type *base,
734                              usdhc_handle_t *handle,
735                              status_t status,
736                              void *userData);           /*!< Transfer complete callback. */
737     void (*ReTuning)(USDHC_Type *base, void *userData); /*!< Handle the re-tuning. */
738 } usdhc_transfer_callback_t;
739 
740 /*!
741  * @brief USDHC handle.
742  *
743  * Defines the structure to save the USDHC state information and callback function.
744  *
745  * @note All the fields except interruptFlags and transferredWords must be allocated by the user.
746  */
747 struct _usdhc_handle
748 {
749 #if (defined FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER) && FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
750     usdhc_scatter_gather_data_t *volatile data; /*!< scatter gather data pointer  */
751 #else
752     usdhc_data_t *volatile data;                                   /*!< Transfer parameter. Data to transfer. */
753 #endif
754     usdhc_command_t *volatile command; /*!< Transfer parameter. Command to send. */
755 
756     volatile uint32_t transferredWords; /*!< Transfer status. Words transferred by DATAPORT way. */
757 
758     usdhc_transfer_callback_t callback; /*!< Callback function. */
759     void *userData;                     /*!< Parameter for transfer complete callback. */
760 };
761 
762 /*! @brief USDHC transfer function. */
763 typedef status_t (*usdhc_transfer_function_t)(USDHC_Type *base, usdhc_transfer_t *content);
764 
765 /*! @brief USDHC host descriptor. */
766 typedef struct _usdhc_host
767 {
768     USDHC_Type *base;                   /*!< USDHC peripheral base address. */
769     uint32_t sourceClock_Hz;            /*!< USDHC source clock frequency united in Hz. */
770     usdhc_config_t config;              /*!< USDHC configuration. */
771     usdhc_capability_t capability;      /*!< USDHC capability information. */
772     usdhc_transfer_function_t transfer; /*!< USDHC transfer function. */
773 } usdhc_host_t;
774 
775 /*************************************************************************************************
776  * API
777  ************************************************************************************************/
778 #if defined(__cplusplus)
779 extern "C" {
780 #endif
781 
782 /*!
783  * @name Initialization and deinitialization
784  * @{
785  */
786 
787 /*!
788  * @brief USDHC module initialization function.
789  *
790  * Configures the USDHC according to the user configuration.
791  *
792  * Example:
793    @code
794    usdhc_config_t config;
795    config.cardDetectDat3 = false;
796    config.endianMode = kUSDHC_EndianModeLittle;
797    config.dmaMode = kUSDHC_DmaModeAdma2;
798    config.readWatermarkLevel = 128U;
799    config.writeWatermarkLevel = 128U;
800    USDHC_Init(USDHC, &config);
801    @endcode
802  *
803  * @param base USDHC peripheral base address.
804  * @param config USDHC configuration information.
805  * @retval #kStatus_Success Operate successfully.
806  */
807 void USDHC_Init(USDHC_Type *base, const usdhc_config_t *config);
808 
809 /*!
810  * @brief Deinitializes the USDHC.
811  *
812  * @param base USDHC peripheral base address.
813  */
814 void USDHC_Deinit(USDHC_Type *base);
815 
816 /*!
817  * @brief Resets the USDHC.
818  *
819  * @param base USDHC peripheral base address.
820  * @param mask The reset type mask(@ref _usdhc_reset).
821  * @param timeout Timeout for reset.
822  * @retval true Reset successfully.
823  * @retval false Reset failed.
824  */
825 bool USDHC_Reset(USDHC_Type *base, uint32_t mask, uint32_t timeout);
826 
827 /* @} */
828 
829 /*!
830  * @name DMA Control
831  * @{
832  */
833 
834 /*!
835  * @brief Sets the DMA descriptor table configuration.
836  * A high level DMA descriptor configuration function.
837  * @param base USDHC peripheral base address.
838  * @param dmaConfig ADMA configuration
839  * @param dataConfig Data descriptor
840  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
841  *  refer to enum @ref _usdhc_adma_flag.
842  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
843  * @retval #kStatus_Success Operate successfully.
844  */
845 status_t USDHC_SetAdmaTableConfig(USDHC_Type *base,
846                                   usdhc_adma_config_t *dmaConfig,
847                                   usdhc_data_t *dataConfig,
848                                   uint32_t flags);
849 
850 /*!
851  * @brief Internal DMA configuration.
852  * This function is used to config the USDHC DMA related registers.
853  * @param base USDHC peripheral base address.
854  * @param dmaConfig ADMA configuration.
855  * @param dataAddr Transfer data address, a simple DMA parameter, if ADMA is used, leave it to NULL.
856  * @param enAutoCmd23 Flag to indicate Auto CMD23 is enable or not, a simple DMA parameter, if ADMA is used, leave it
857  * to false.
858  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
859  * @retval #kStatus_Success Operate successfully.
860  */
861 status_t USDHC_SetInternalDmaConfig(USDHC_Type *base,
862                                     usdhc_adma_config_t *dmaConfig,
863                                     const uint32_t *dataAddr,
864                                     bool enAutoCmd23);
865 
866 /*!
867  * @brief Sets the ADMA2 descriptor table configuration.
868  *
869  * @param admaTable ADMA table address.
870  * @param admaTableWords ADMA table length.
871  * @param dataBufferAddr Data buffer address.
872  * @param dataBytes Data Data length.
873  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
874  *  refer to enum @ref _usdhc_adma_flag.
875  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
876  * @retval #kStatus_Success Operate successfully.
877  */
878 status_t USDHC_SetADMA2Descriptor(
879     uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags);
880 
881 /*!
882  * @brief Sets the ADMA1 descriptor table configuration.
883  *
884  * @param admaTable ADMA table address.
885  * @param admaTableWords ADMA table length.
886  * @param dataBufferAddr Data buffer address.
887  * @param dataBytes Data length.
888  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
889  *  refer to enum @ref _usdhc_adma_flag.
890  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
891  * @retval #kStatus_Success Operate successfully.
892  */
893 status_t USDHC_SetADMA1Descriptor(
894     uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags);
895 
896 /*!
897  * @brief Enables internal DMA.
898  *
899  * @param base USDHC peripheral base address.
900  * @param enable enable or disable flag
901  */
USDHC_EnableInternalDMA(USDHC_Type * base,bool enable)902 static inline void USDHC_EnableInternalDMA(USDHC_Type *base, bool enable)
903 {
904     if (enable)
905     {
906         base->MIX_CTRL |= USDHC_MIX_CTRL_DMAEN_MASK;
907     }
908     else
909     {
910         base->MIX_CTRL &= ~USDHC_MIX_CTRL_DMAEN_MASK;
911         base->PROT_CTRL &= ~USDHC_PROT_CTRL_DMASEL_MASK;
912     }
913 }
914 
915 /* @} */
916 
917 /*!
918  * @name Interrupts
919  * @{
920  */
921 
922 /*!
923  * @brief Enables the interrupt status.
924  *
925  * @param base USDHC peripheral base address.
926  * @param mask Interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
927  */
USDHC_EnableInterruptStatus(USDHC_Type * base,uint32_t mask)928 static inline void USDHC_EnableInterruptStatus(USDHC_Type *base, uint32_t mask)
929 {
930     base->INT_STATUS_EN |= mask;
931 }
932 
933 /*!
934  * @brief Disables the interrupt status.
935  *
936  * @param base USDHC peripheral base address.
937  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
938  */
USDHC_DisableInterruptStatus(USDHC_Type * base,uint32_t mask)939 static inline void USDHC_DisableInterruptStatus(USDHC_Type *base, uint32_t mask)
940 {
941     base->INT_STATUS_EN &= ~mask;
942 }
943 
944 /*!
945  * @brief Enables the interrupt signal corresponding to the interrupt status flag.
946  *
947  * @param base USDHC peripheral base address.
948  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
949  */
USDHC_EnableInterruptSignal(USDHC_Type * base,uint32_t mask)950 static inline void USDHC_EnableInterruptSignal(USDHC_Type *base, uint32_t mask)
951 {
952     base->INT_SIGNAL_EN |= mask;
953 }
954 
955 /*!
956  * @brief Disables the interrupt signal corresponding to the interrupt status flag.
957  *
958  * @param base USDHC peripheral base address.
959  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
960  */
USDHC_DisableInterruptSignal(USDHC_Type * base,uint32_t mask)961 static inline void USDHC_DisableInterruptSignal(USDHC_Type *base, uint32_t mask)
962 {
963     base->INT_SIGNAL_EN &= ~mask;
964 }
965 
966 /* @} */
967 
968 /*!
969  * @name Status
970  * @{
971  */
972 
973 /*!
974  * @brief Gets the enabled interrupt status.
975  *
976  * @param base USDHC peripheral base address.
977  * @return Current interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
978  */
USDHC_GetEnabledInterruptStatusFlags(USDHC_Type * base)979 static inline uint32_t USDHC_GetEnabledInterruptStatusFlags(USDHC_Type *base)
980 {
981     uint32_t intStatus = base->INT_STATUS;
982 
983     return intStatus & base->INT_SIGNAL_EN;
984 }
985 
986 /*!
987  * @brief Gets the current interrupt status.
988  *
989  * @param base USDHC peripheral base address.
990  * @return Current interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
991  */
USDHC_GetInterruptStatusFlags(USDHC_Type * base)992 static inline uint32_t USDHC_GetInterruptStatusFlags(USDHC_Type *base)
993 {
994     return base->INT_STATUS;
995 }
996 
997 /*!
998  * @brief Clears a specified interrupt status.
999  * write 1 clears
1000  * @param base USDHC peripheral base address.
1001  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
1002  */
USDHC_ClearInterruptStatusFlags(USDHC_Type * base,uint32_t mask)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  */
USDHC_GetAutoCommand12ErrorStatusFlags(USDHC_Type * base)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  */
USDHC_GetAdmaErrorStatusFlags(USDHC_Type * base)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  */
USDHC_GetPresentStatusFlags(USDHC_Type * base)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  */
USDHC_ForceClockOn(USDHC_Type * base,bool enable)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  */
USDHC_AssertHardwareReset(USDHC_Type * base,bool high)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  */
USDHC_SetDataBusWidth(USDHC_Type * base,usdhc_data_bus_width_t width)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  */
USDHC_WriteData(USDHC_Type * base,uint32_t data)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  */
USDHC_ReadData(USDHC_Type * base)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  */
USDHC_EnableWakeupEvent(USDHC_Type * base,uint32_t mask,bool enable)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  */
USDHC_CardDetectByData3(USDHC_Type * base,bool enable)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  */
USDHC_DetectCardInsert(USDHC_Type * base)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  */
USDHC_EnableSdioControl(USDHC_Type * base,uint32_t mask,bool enable)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  */
USDHC_SetContinueRequest(USDHC_Type * base)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  */
USDHC_RequestStopAtBlockGap(USDHC_Type * base,bool enable)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  */
USDHC_EnableMmcBoot(USDHC_Type * base,bool enable)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  */
USDHC_SetForceEvent(USDHC_Type * base,uint32_t mask)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  */
UDSHC_SelectVoltage(USDHC_Type * base,bool en18v)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  */
USDHC_RequestTuningForSDR50(USDHC_Type * base)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  */
USDHC_RequestReTuning(USDHC_Type * base)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  */
USDHC_EnableAutoTuning(USDHC_Type * base,bool enable)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  */
USDHC_SetRetuningTimer(USDHC_Type * base,uint32_t counter)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  */
USDHC_GetTuningDelayStatus(USDHC_Type * base)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  */
USDHC_SetStandardTuningCounter(USDHC_Type * base,uint8_t counter)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  */
USDHC_GetExecuteStdTuningStatus(USDHC_Type * base)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  */
USDHC_CheckStdTuningResult(USDHC_Type * base)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  */
USDHC_CheckTuningError(USDHC_Type * base)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  */
USDHC_EnableHS400Mode(USDHC_Type * base,bool enable)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  */
USDHC_ResetStrobeDLL(USDHC_Type * base)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  */
USDHC_EnableStrobeDLL(USDHC_Type * base,bool enable)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  */
USDHC_SetStrobeDllOverride(USDHC_Type * base,uint32_t delayTaps)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  */
USDHC_GetStrobeDLLStatus(USDHC_Type * base)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_*/
1704