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.4. */
25 #define FSL_USDHC_DRIVER_VERSION (MAKE_VERSION(2U, 8U, 4U))
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 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_VS18) && FSL_FEATURE_USDHC_HAS_NO_VS18)
64     kUSDHC_SupportV180Flag          = USDHC_HOST_CTRL_CAP_VS18_MASK,  /*!< Support voltage 1.8V. */
65 #endif
66     kUSDHC_Support4BitFlag          = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 0U),
67     /*!< Flag in HTCAPBLT_MBL's position, supporting 4-bit mode. */
68     kUSDHC_Support8BitFlag = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 1U),
69     /*!< Flag in HTCAPBLT_MBL's position, supporting 8-bit mode. */
70     kUSDHC_SupportDDR50Flag = USDHC_HOST_CTRL_CAP_DDR50_SUPPORT_MASK,
71 /*!< SD version 3.0 new feature, supporting DDR50 mode. */
72 
73 #if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR104_MODE)
74     kUSDHC_SupportSDR104Flag = 0, /*!< not support SDR104 mode */
75 #else
76     kUSDHC_SupportSDR104Flag   = USDHC_HOST_CTRL_CAP_SDR104_SUPPORT_MASK, /*!< Support SDR104 mode. */
77 #endif
78 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
79     kUSDHC_SupportSDR50Flag = 0U, /*!< not support SDR50 mode */
80 #else
81     kUSDHC_SupportSDR50Flag    = USDHC_HOST_CTRL_CAP_SDR50_SUPPORT_MASK,  /*!< Support SDR50 mode. */
82 #endif
83 };
84 
85 /*! @brief Enum _usdhc_wakeup_event. Wakeup event mask.
86  *  @anchor _usdhc_wakeup_event
87  */
88 enum
89 {
90     kUSDHC_WakeupEventOnCardInt    = USDHC_PROT_CTRL_WECINT_MASK, /*!< Wakeup on card interrupt. */
91     kUSDHC_WakeupEventOnCardInsert = USDHC_PROT_CTRL_WECINS_MASK, /*!< Wakeup on card insertion. */
92     kUSDHC_WakeupEventOnCardRemove = USDHC_PROT_CTRL_WECRM_MASK,  /*!< Wakeup on card removal. */
93     kUSDHC_WakeupEventsAll =
94         (kUSDHC_WakeupEventOnCardInt | kUSDHC_WakeupEventOnCardInsert | kUSDHC_WakeupEventOnCardRemove),
95     /*!< All wakeup events */
96 };
97 
98 /*! @brief Enum _usdhc_reset. Reset type mask.
99  *  @anchor _usdhc_reset
100  */
101 enum
102 {
103     kUSDHC_ResetAll     = USDHC_SYS_CTRL_RSTA_MASK, /*!< Reset all except card detection. */
104     kUSDHC_ResetCommand = USDHC_SYS_CTRL_RSTC_MASK, /*!< Reset command line. */
105     kUSDHC_ResetData    = USDHC_SYS_CTRL_RSTD_MASK, /*!< Reset data line. */
106 
107 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
108     kUSDHC_ResetTuning = 0U, /*!< no reset tuning circuit bit */
109 #else
110     kUSDHC_ResetTuning         = USDHC_SYS_CTRL_RSTT_MASK,                /*!< Reset tuning circuit. */
111 #endif
112 
113     kUSDHC_ResetsAll = (kUSDHC_ResetAll | kUSDHC_ResetCommand | kUSDHC_ResetData | kUSDHC_ResetTuning),
114     /*!< All reset types */
115 };
116 
117 /*! @brief Enum _usdhc_transfer_flag. Transfer flag mask. */
118 enum
119 {
120     kUSDHC_EnableDmaFlag = USDHC_MIX_CTRL_DMAEN_MASK, /*!< Enable DMA. */
121 
122     kUSDHC_CommandTypeSuspendFlag = USDHC_CMD_XFR_TYP_CMDTYP(1U), /*!< Suspend command. */
123     kUSDHC_CommandTypeResumeFlag  = USDHC_CMD_XFR_TYP_CMDTYP(2U), /*!< Resume command. */
124     kUSDHC_CommandTypeAbortFlag   = USDHC_CMD_XFR_TYP_CMDTYP(3U), /*!< Abort command. */
125 
126     kUSDHC_EnableBlockCountFlag    = USDHC_MIX_CTRL_BCEN_MASK,   /*!< Enable block count. */
127     kUSDHC_EnableAutoCommand12Flag = USDHC_MIX_CTRL_AC12EN_MASK, /*!< Enable auto CMD12. */
128     kUSDHC_DataReadFlag            = USDHC_MIX_CTRL_DTDSEL_MASK, /*!< Enable data read. */
129     kUSDHC_MultipleBlockFlag       = USDHC_MIX_CTRL_MSBSEL_MASK, /*!< Multiple block data read/write. */
130     kUSDHC_EnableAutoCommand23Flag = USDHC_MIX_CTRL_AC23EN_MASK, /*!< Enable auto CMD23. */
131 
132     kUSDHC_ResponseLength136Flag    = USDHC_CMD_XFR_TYP_RSPTYP(1U), /*!< 136-bit response length. */
133     kUSDHC_ResponseLength48Flag     = USDHC_CMD_XFR_TYP_RSPTYP(2U), /*!< 48-bit response length. */
134     kUSDHC_ResponseLength48BusyFlag = USDHC_CMD_XFR_TYP_RSPTYP(3U), /*!< 48-bit response length with busy status. */
135 
136     kUSDHC_EnableCrcCheckFlag   = USDHC_CMD_XFR_TYP_CCCEN_MASK, /*!< Enable CRC check. */
137     kUSDHC_EnableIndexCheckFlag = USDHC_CMD_XFR_TYP_CICEN_MASK, /*!< Enable index check. */
138     kUSDHC_DataPresentFlag      = USDHC_CMD_XFR_TYP_DPSEL_MASK, /*!< Data present flag. */
139 };
140 
141 /*! @brief Enum _usdhc_present_status_flag. Present status flag mask.
142  *  @anchor _usdhc_present_status_flag
143  */
144 enum
145 {
146     kUSDHC_CommandInhibitFlag      = USDHC_PRES_STATE_CIHB_MASK,  /*!< Command inhibit. */
147     kUSDHC_DataInhibitFlag         = USDHC_PRES_STATE_CDIHB_MASK, /*!< Data inhibit. */
148     kUSDHC_DataLineActiveFlag      = USDHC_PRES_STATE_DLA_MASK,   /*!< Data line active. */
149     kUSDHC_SdClockStableFlag       = USDHC_PRES_STATE_SDSTB_MASK, /*!< SD bus clock stable. */
150     kUSDHC_WriteTransferActiveFlag = USDHC_PRES_STATE_WTA_MASK,   /*!< Write transfer active. */
151     kUSDHC_ReadTransferActiveFlag  = USDHC_PRES_STATE_RTA_MASK,   /*!< Read transfer active. */
152     kUSDHC_BufferWriteEnableFlag   = USDHC_PRES_STATE_BWEN_MASK,  /*!< Buffer write enable. */
153     kUSDHC_BufferReadEnableFlag    = USDHC_PRES_STATE_BREN_MASK,  /*!< Buffer read enable. */
154 
155 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
156     kUSDHC_DelaySettingFinishedFlag = 0U, /*!< not support */
157     kUSDHC_ReTuningRequestFlag      = 0U, /*!< not support */
158 #else
159     kUSDHC_ReTuningRequestFlag = USDHC_PRES_STATE_RTR_MASK, /*!< Re-tuning request flag, only used for SDR104 mode. */
160     kUSDHC_DelaySettingFinishedFlag = USDHC_PRES_STATE_TSCD_MASK, /*!< Delay setting finished flag. */
161 #endif
162 
163     kUSDHC_CardInsertedFlag     = USDHC_PRES_STATE_CINST_MASK, /*!< Card inserted. */
164     kUSDHC_CommandLineLevelFlag = USDHC_PRES_STATE_CLSL_MASK,  /*!< Command line signal level. */
165 
166     kUSDHC_Data0LineLevelFlag = 1U << USDHC_PRES_STATE_DLSL_SHIFT,               /*!< Data0 line signal level. */
167     kUSDHC_Data1LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 1U),        /*!< Data1 line signal level. */
168     kUSDHC_Data2LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 2U),        /*!< Data2 line signal level. */
169     kUSDHC_Data3LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 3U),        /*!< Data3 line signal level. */
170     kUSDHC_Data4LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 4U),        /*!< Data4 line signal level. */
171     kUSDHC_Data5LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 5U),        /*!< Data5 line signal level. */
172     kUSDHC_Data6LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 6U),        /*!< Data6 line signal level. */
173     kUSDHC_Data7LineLevelFlag = (int)(1U << (USDHC_PRES_STATE_DLSL_SHIFT + 7U)), /*!< Data7 line signal level. */
174 };
175 
176 /*! @brief Enum _usdhc_interrupt_status_flag. Interrupt status flag mask.
177  *  @anchor _usdhc_interrupt_status_flag
178  */
179 enum
180 {
181     kUSDHC_CommandCompleteFlag  = USDHC_INT_STATUS_CC_MASK,   /*!< Command complete. */
182     kUSDHC_DataCompleteFlag     = USDHC_INT_STATUS_TC_MASK,   /*!< Data complete. */
183     kUSDHC_BlockGapEventFlag    = USDHC_INT_STATUS_BGE_MASK,  /*!< Block gap event. */
184     kUSDHC_DmaCompleteFlag      = USDHC_INT_STATUS_DINT_MASK, /*!< DMA interrupt. */
185     kUSDHC_BufferWriteReadyFlag = USDHC_INT_STATUS_BWR_MASK,  /*!< Buffer write ready. */
186     kUSDHC_BufferReadReadyFlag  = USDHC_INT_STATUS_BRR_MASK,  /*!< Buffer read ready. */
187     kUSDHC_CardInsertionFlag    = USDHC_INT_STATUS_CINS_MASK, /*!< Card inserted. */
188     kUSDHC_CardRemovalFlag      = USDHC_INT_STATUS_CRM_MASK,  /*!< Card removed. */
189     kUSDHC_CardInterruptFlag    = USDHC_INT_STATUS_CINT_MASK, /*!< Card interrupt. */
190 
191 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
192     kUSDHC_ReTuningEventFlag = 0U, /*!< Re-Tuning event, only for SD3.0 SDR104 mode. */
193     kUSDHC_TuningPassFlag    = 0U, /*!< SDR104 mode tuning pass flag. */
194     kUSDHC_TuningErrorFlag   = 0U, /*!< SDR104 tuning error flag. */
195 #else
196     kUSDHC_ReTuningEventFlag        = USDHC_INT_STATUS_RTE_MASK,  /*!< Re-Tuning event, only for SD3.0 SDR104 mode. */
197     kUSDHC_TuningPassFlag           = USDHC_INT_STATUS_TP_MASK,   /*!< SDR104 mode tuning pass flag. */
198     kUSDHC_TuningErrorFlag          = USDHC_INT_STATUS_TNE_MASK,  /*!< SDR104 tuning error flag. */
199 #endif
200 
201     kUSDHC_CommandTimeoutFlag     = USDHC_INT_STATUS_CTOE_MASK,  /*!< Command timeout error. */
202     kUSDHC_CommandCrcErrorFlag    = USDHC_INT_STATUS_CCE_MASK,   /*!< Command CRC error. */
203     kUSDHC_CommandEndBitErrorFlag = USDHC_INT_STATUS_CEBE_MASK,  /*!< Command end bit error. */
204     kUSDHC_CommandIndexErrorFlag  = USDHC_INT_STATUS_CIE_MASK,   /*!< Command index error. */
205     kUSDHC_DataTimeoutFlag        = USDHC_INT_STATUS_DTOE_MASK,  /*!< Data timeout error. */
206     kUSDHC_DataCrcErrorFlag       = USDHC_INT_STATUS_DCE_MASK,   /*!< Data CRC error. */
207     kUSDHC_DataEndBitErrorFlag    = USDHC_INT_STATUS_DEBE_MASK,  /*!< Data end bit error. */
208     kUSDHC_AutoCommand12ErrorFlag = USDHC_INT_STATUS_AC12E_MASK, /*!< Auto CMD12 error. */
209     kUSDHC_DmaErrorFlag           = USDHC_INT_STATUS_DMAE_MASK,  /*!< DMA error. */
210 
211     kUSDHC_CommandErrorFlag = (kUSDHC_CommandTimeoutFlag | kUSDHC_CommandCrcErrorFlag | kUSDHC_CommandEndBitErrorFlag |
212                                kUSDHC_CommandIndexErrorFlag), /*!< Command error */
213     kUSDHC_DataErrorFlag    = (kUSDHC_DataTimeoutFlag | kUSDHC_DataCrcErrorFlag | kUSDHC_DataEndBitErrorFlag |
214                             kUSDHC_AutoCommand12ErrorFlag),                                        /*!< Data error */
215     kUSDHC_ErrorFlag        = (kUSDHC_CommandErrorFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< All error */
216 
217     kUSDHC_DataFlag = (kUSDHC_DataCompleteFlag | kUSDHC_BufferWriteReadyFlag | kUSDHC_BufferReadReadyFlag |
218                        kUSDHC_DataErrorFlag), /*!< Data interrupts */
219 
220     kUSDHC_DataDMAFlag = (kUSDHC_DataCompleteFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< Data interrupts */
221 
222     kUSDHC_CommandFlag      = (kUSDHC_CommandErrorFlag | kUSDHC_CommandCompleteFlag), /*!< Command interrupts */
223     kUSDHC_CardDetectFlag   = (kUSDHC_CardInsertionFlag | kUSDHC_CardRemovalFlag),    /*!< Card detection interrupts */
224     kUSDHC_SDR104TuningFlag = (kUSDHC_TuningErrorFlag | kUSDHC_TuningPassFlag | kUSDHC_ReTuningEventFlag),
225     /*!< SDR104 tuning flag. */
226     kUSDHC_AllInterruptFlags =
227         (kUSDHC_BlockGapEventFlag | kUSDHC_CardInterruptFlag | kUSDHC_CommandFlag | kUSDHC_DataFlag | kUSDHC_ErrorFlag |
228          kUSDHC_SDR104TuningFlag | kUSDHC_DmaCompleteFlag), /*!< All flags mask */
229 };
230 
231 /*! @brief Enum _usdhc_auto_command12_error_status_flag. Auto CMD12 error status flag mask.
232  *  @anchor _usdhc_auto_command12_error_status_flag
233  */
234 enum
235 {
236     kUSDHC_AutoCommand12NotExecutedFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12NE_MASK,    /*!< Not executed error. */
237     kUSDHC_AutoCommand12TimeoutFlag     = USDHC_AUTOCMD12_ERR_STATUS_AC12TOE_MASK,   /*!< Timeout error. */
238     kUSDHC_AutoCommand12EndBitErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12EBE_MASK,   /*!< End bit error. */
239     kUSDHC_AutoCommand12CrcErrorFlag    = USDHC_AUTOCMD12_ERR_STATUS_AC12CE_MASK,    /*!< CRC error. */
240     kUSDHC_AutoCommand12IndexErrorFlag  = USDHC_AUTOCMD12_ERR_STATUS_AC12IE_MASK,    /*!< Index error. */
241     kUSDHC_AutoCommand12NotIssuedFlag   = USDHC_AUTOCMD12_ERR_STATUS_CNIBAC12E_MASK, /*!< Not issued error. */
242 };
243 
244 /*! @brief Enum _usdhc_standard_tuning. Standard tuning flag. */
245 enum
246 {
247 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
248     kUSDHC_ExecuteTuning        = 0U, /*!< not support */
249     kUSDHC_TuningSampleClockSel = 0U, /*!< not support */
250 #else
251     kUSDHC_ExecuteTuning = USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK, /*!< Used to start tuning procedure. */
252     kUSDHC_TuningSampleClockSel =
253         USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK,               /*!< When <b>std_tuning_en</b> bit is set, this
254                                                                     bit is used to select sampleing clock. */
255 #endif
256 };
257 
258 /*! @brief Enum _usdhc_adma_error_status_flag. ADMA error status flag mask.
259  *  @anchor _usdhc_adma_error_status_flag
260  */
261 enum
262 {
263     kUSDHC_AdmaLenghMismatchFlag   = USDHC_ADMA_ERR_STATUS_ADMALME_MASK, /*!< Length mismatch error. */
264     kUSDHC_AdmaDescriptorErrorFlag = USDHC_ADMA_ERR_STATUS_ADMADCE_MASK, /*!< Descriptor error. */
265 };
266 
267 /*!
268  * @brief Enum _usdhc_adma_error_state. ADMA error state.
269  *
270  * This state is the detail state when ADMA error has occurred.
271  */
272 enum
273 {
274     kUSDHC_AdmaErrorStateStopDma = 0x00U,
275     /*!< Stop DMA, previous location set in the ADMA system address is errored address. */
276     kUSDHC_AdmaErrorStateFetchDescriptor = 0x01U,
277     /*!< Fetch descriptor, current location set in the ADMA system address is errored address. */
278     kUSDHC_AdmaErrorStateChangeAddress = 0x02U, /*!< Change address, no DMA error has occurred. */
279     kUSDHC_AdmaErrorStateTransferData  = 0x03U,
280     /*!< Transfer data, previous location set in the ADMA system address is errored address. */
281     kUSDHC_AdmaErrorStateInvalidLength     = 0x04U, /*!< Invalid length in ADMA descriptor. */
282     kUSDHC_AdmaErrorStateInvalidDescriptor = 0x08U, /*!< Invalid descriptor fetched by ADMA. */
283 
284     kUSDHC_AdmaErrorState = kUSDHC_AdmaErrorStateInvalidLength | kUSDHC_AdmaErrorStateInvalidDescriptor |
285                             kUSDHC_AdmaErrorStateFetchDescriptor, /*!< ADMA error state */
286 };
287 
288 /*! @brief Enum _usdhc_force_event. Force event bit position.
289  *  @anchor _usdhc_force_event
290  */
291 enum
292 {
293     kUSDHC_ForceEventAutoCommand12NotExecuted =
294         USDHC_FORCE_EVENT_FEVTAC12NE_MASK, /*!< Auto CMD12 not executed error. */
295     kUSDHC_ForceEventAutoCommand12Timeout    = USDHC_FORCE_EVENT_FEVTAC12TOE_MASK,  /*!< Auto CMD12 timeout error. */
296     kUSDHC_ForceEventAutoCommand12CrcError   = USDHC_FORCE_EVENT_FEVTAC12CE_MASK,   /*!< Auto CMD12 CRC error. */
297     kUSDHC_ForceEventEndBitError             = USDHC_FORCE_EVENT_FEVTAC12EBE_MASK,  /*!< Auto CMD12 end bit error. */
298     kUSDHC_ForceEventAutoCommand12IndexError = USDHC_FORCE_EVENT_FEVTAC12IE_MASK,   /*!< Auto CMD12 index error. */
299     kUSDHC_ForceEventAutoCommand12NotIssued = USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK, /*!< Auto CMD12 not issued error. */
300     kUSDHC_ForceEventCommandTimeout         = USDHC_FORCE_EVENT_FEVTCTOE_MASK,      /*!< Command timeout error. */
301     kUSDHC_ForceEventCommandCrcError        = USDHC_FORCE_EVENT_FEVTCCE_MASK,       /*!< Command CRC error. */
302     kUSDHC_ForceEventCommandEndBitError     = USDHC_FORCE_EVENT_FEVTCEBE_MASK,      /*!< Command end bit error. */
303     kUSDHC_ForceEventCommandIndexError      = USDHC_FORCE_EVENT_FEVTCIE_MASK,       /*!< Command index error. */
304     kUSDHC_ForceEventDataTimeout            = USDHC_FORCE_EVENT_FEVTDTOE_MASK,      /*!< Data timeout error. */
305     kUSDHC_ForceEventDataCrcError           = USDHC_FORCE_EVENT_FEVTDCE_MASK,       /*!< Data CRC error. */
306     kUSDHC_ForceEventDataEndBitError        = USDHC_FORCE_EVENT_FEVTDEBE_MASK,      /*!< Data end bit error. */
307     kUSDHC_ForceEventAutoCommand12Error     = USDHC_FORCE_EVENT_FEVTAC12E_MASK,     /*!< Auto CMD12 error. */
308     kUSDHC_ForceEventCardInt                = (int)USDHC_FORCE_EVENT_FEVTCINT_MASK, /*!< Card interrupt. */
309     kUSDHC_ForceEventDmaError               = USDHC_FORCE_EVENT_FEVTDMAE_MASK,      /*!< Dma error. */
310 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
311     kUSDHC_ForceEventTuningError = 0U, /*!< not support */
312 #else
313     kUSDHC_ForceEventTuningError = USDHC_FORCE_EVENT_FEVTTNE_MASK, /*!< Tuning error. */
314 #endif
315 
316     kUSDHC_ForceEventsAll =
317         (int)(USDHC_FORCE_EVENT_FEVTAC12NE_MASK | USDHC_FORCE_EVENT_FEVTAC12TOE_MASK |
318               USDHC_FORCE_EVENT_FEVTAC12CE_MASK | USDHC_FORCE_EVENT_FEVTAC12EBE_MASK |
319               USDHC_FORCE_EVENT_FEVTAC12IE_MASK | USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK |
320               USDHC_FORCE_EVENT_FEVTCTOE_MASK | USDHC_FORCE_EVENT_FEVTCCE_MASK | USDHC_FORCE_EVENT_FEVTCEBE_MASK |
321               USDHC_FORCE_EVENT_FEVTCIE_MASK | USDHC_FORCE_EVENT_FEVTDTOE_MASK | USDHC_FORCE_EVENT_FEVTDCE_MASK |
322               USDHC_FORCE_EVENT_FEVTDEBE_MASK | USDHC_FORCE_EVENT_FEVTAC12E_MASK | USDHC_FORCE_EVENT_FEVTCINT_MASK |
323               USDHC_FORCE_EVENT_FEVTDMAE_MASK | kUSDHC_ForceEventTuningError), /*!< All force event flags mask. */
324 };
325 
326 /*! @brief Data transfer direction. */
327 typedef enum _usdhc_transfer_direction
328 {
329     kUSDHC_TransferDirectionReceive = 1U, /*!< USDHC transfer direction receive. */
330     kUSDHC_TransferDirectionSend    = 0U, /*!< USDHC transfer direction send. */
331 } usdhc_transfer_direction_t;
332 
333 /*! @brief Data transfer width. */
334 typedef enum _usdhc_data_bus_width
335 {
336     kUSDHC_DataBusWidth1Bit = 0U, /*!< 1-bit mode */
337     kUSDHC_DataBusWidth4Bit = 1U, /*!< 4-bit mode */
338     kUSDHC_DataBusWidth8Bit = 2U, /*!< 8-bit mode */
339 } usdhc_data_bus_width_t;
340 
341 /*! @brief Endian mode */
342 typedef enum _usdhc_endian_mode
343 {
344     kUSDHC_EndianModeBig         = 0U, /*!< Big endian mode. */
345     kUSDHC_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode. */
346     kUSDHC_EndianModeLittle      = 2U, /*!< Little endian mode. */
347 } usdhc_endian_mode_t;
348 
349 /*! @brief DMA mode */
350 typedef enum _usdhc_dma_mode
351 {
352     kUSDHC_DmaModeSimple = 0U, /*!< External DMA. */
353     kUSDHC_DmaModeAdma1  = 1U, /*!< ADMA1 is selected. */
354     kUSDHC_DmaModeAdma2  = 2U, /*!< ADMA2 is selected. */
355     kUSDHC_ExternalDMA   = 3U, /*!< External DMA mode selected. */
356 } usdhc_dma_mode_t;
357 
358 /*! @brief Enum _usdhc_sdio_control_flag. SDIO control flag mask.
359  *  @anchor _usdhc_sdio_control_flag
360  */
361 enum
362 {
363     kUSDHC_StopAtBlockGapFlag      = USDHC_PROT_CTRL_SABGREQ_MASK, /*!< Stop at block gap. */
364     kUSDHC_ReadWaitControlFlag     = USDHC_PROT_CTRL_RWCTL_MASK,   /*!< Read wait control. */
365     kUSDHC_InterruptAtBlockGapFlag = USDHC_PROT_CTRL_IABG_MASK,    /*!< Interrupt at block gap. */
366     kUSDHC_ReadDoneNo8CLK = USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK,  /*!< Read done without 8 clk for block gap. */
367     kUSDHC_ExactBlockNumberReadFlag = USDHC_PROT_CTRL_NON_EXACT_BLK_RD_MASK, /*!< Exact block number read. */
368 };
369 
370 /*! @brief MMC card boot mode */
371 typedef enum _usdhc_boot_mode
372 {
373     kUSDHC_BootModeNormal      = 0U, /*!< Normal boot */
374     kUSDHC_BootModeAlternative = 1U, /*!< Alternative boot */
375 } usdhc_boot_mode_t;
376 
377 /*! @brief The command type */
378 typedef enum _usdhc_card_command_type
379 {
380     kCARD_CommandTypeNormal  = 0U, /*!< Normal command */
381     kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */
382     kCARD_CommandTypeResume  = 2U, /*!< Resume command */
383     kCARD_CommandTypeAbort   = 3U, /*!< Abort command */
384     kCARD_CommandTypeEmpty   = 4U, /*!< Empty command */
385 } usdhc_card_command_type_t;
386 
387 /*!
388  * @brief The command response type.
389  *
390  * Defines the command response type from card to host controller.
391  */
392 typedef enum _usdhc_card_response_type
393 {
394     kCARD_ResponseTypeNone = 0U, /*!< Response type: none */
395     kCARD_ResponseTypeR1   = 1U, /*!< Response type: R1 */
396     kCARD_ResponseTypeR1b  = 2U, /*!< Response type: R1b */
397     kCARD_ResponseTypeR2   = 3U, /*!< Response type: R2 */
398     kCARD_ResponseTypeR3   = 4U, /*!< Response type: R3 */
399     kCARD_ResponseTypeR4   = 5U, /*!< Response type: R4 */
400     kCARD_ResponseTypeR5   = 6U, /*!< Response type: R5 */
401     kCARD_ResponseTypeR5b  = 7U, /*!< Response type: R5b */
402     kCARD_ResponseTypeR6   = 8U, /*!< Response type: R6 */
403     kCARD_ResponseTypeR7   = 9U, /*!< Response type: R7 */
404 } usdhc_card_response_type_t;
405 
406 /*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor. */
407 #define USDHC_ADMA1_ADDRESS_ALIGN (4096U)
408 /*! @brief The alignment size for LENGTH field in ADMA1's descriptor. */
409 #define USDHC_ADMA1_LENGTH_ALIGN (4096U)
410 /*! @brief The alignment size for ADDRESS field in ADMA2's descriptor. */
411 #define USDHC_ADMA2_ADDRESS_ALIGN (4U)
412 /*! @brief The alignment size for LENGTH filed in ADMA2's descriptor. */
413 #define USDHC_ADMA2_LENGTH_ALIGN (4U)
414 
415 /* ADMA1 descriptor table:
416  * |------------------------|---------|--------------------------|
417  * | Address/page field     |Reserved |         Attribute        |
418  * |------------------------|---------|--------------------------|
419  * |31                    12|11      6|05  |04  |03|02 |01 |00   |
420  * |------------------------|---------|----|----|--|---|---|-----|
421  * | address or data length | 000000  |Act2|Act1| 0|Int|End|Valid|
422  * |------------------------|---------|----|----|--|---|---|-----|
423  *
424  * ADMA2 action table:
425  * |------|------|-----------------|-------|-------------|
426  * | Act2 | Act1 |     Comment     | 31-28 | 27 - 12     |
427  * |------|------|-----------------|---------------------|
428  * |   0  |   0  | No op           | Don't care          |
429  * |------|------|-----------------|-------|-------------|
430  * |   0  |   1  | Set data length |  0000 | Data Length |
431  * |------|------|-----------------|-------|-------------|
432  * |   1  |   0  | Transfer data   | Data address        |
433  * |------|------|-----------------|---------------------|
434  * |   1  |   1  | Link descriptor | Descriptor address  |
435  * |------|------|-----------------|---------------------|
436  */
437 /****************************tables below are created only for Doxygen*********************************/
438 /*! @brief The bit shift for ADDRESS filed in ADMA1's descriptor.
439  *  <table>
440  *  <caption>ADMA1 descriptor table</caption>
441  *  <tr><th>Address/page field     <th>Reserved   <th colspan="6">Attribute
442  *  <tr><td>31 12                  <td>11 6       <td>05   <td>04   <td>03 <td>02  <td>01  <td>00
443  *  <tr><td>address or data length <td>000000     <td>Act2 <td>Act1 <td>0  <td>Int <td>End <td>Valid
444  *  </table>
445  *
446  *  <table>
447  *  <caption>ADMA2 action</caption>
448  *  <tr><th>Act2  <th>Act1      <th>Comment            <th>31-28    <th>27-12
449  *  <tr><td>0     <td>0         <td>No op              <td colspan="2">Don't care
450  *  <tr><td>0     <td>1         <td>Set data length    <td>0000     <td> Data Length
451  *  <tr><td>1     <td>0         <td>Transfer data      <td colspan="2">Data address
452  *  <tr><td>1     <td>1         <td>Link descriptor    <td colspan="2">Descriptor address
453  *  </table>
454  */
455 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT (12U)
456 /*! @brief The bit mask for ADDRESS field in ADMA1's descriptor. */
457 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_MASK (0xFFFFFU)
458 /*! @brief The bit shift for LENGTH filed in ADMA1's descriptor. */
459 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U)
460 /*! @brief The mask for LENGTH field in ADMA1's descriptor. */
461 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
462 /*! @brief The maximum value of LENGTH filed in ADMA1's descriptor.
463  * Since the max transfer size ADMA1 support is 65535 which is indivisible by
464  * 4096, so to make sure a large data load transfer (>64KB) continuously (require the data
465  * address be always align with 4096), software will set the maximum data length
466  * for ADMA1 to (64 - 4)KB.
467  */
468 #define USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK + 1U - 4096U)
469 
470 /*! @brief Enum _usdhc_adma1_descriptor_flag. The mask for the control/status field in ADMA1 descriptor. */
471 enum
472 {
473     kUSDHC_Adma1DescriptorValidFlag     = (1U << 0U),                        /*!< Valid flag. */
474     kUSDHC_Adma1DescriptorEndFlag       = (1U << 1U),                        /*!< End flag. */
475     kUSDHC_Adma1DescriptorInterrupFlag  = (1U << 2U),                        /*!< Interrupt flag. */
476     kUSDHC_Adma1DescriptorActivity1Flag = (1U << 4U),                        /*!< Activity 1 flag. */
477     kUSDHC_Adma1DescriptorActivity2Flag = (1U << 5U),                        /*!< Activity 2 flag. */
478     kUSDHC_Adma1DescriptorTypeNop       = (kUSDHC_Adma1DescriptorValidFlag), /*!< No operation. */
479     kUSDHC_Adma1DescriptorTypeTransfer  = (kUSDHC_Adma1DescriptorActivity2Flag | kUSDHC_Adma1DescriptorValidFlag),
480     /*!< Transfer data. */
481     kUSDHC_Adma1DescriptorTypeLink      = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorActivity2Flag |
482                                       kUSDHC_Adma1DescriptorValidFlag), /*!< Link descriptor. */
483     kUSDHC_Adma1DescriptorTypeSetLength = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorValidFlag),
484     /*!< Set data length. */
485 };
486 
487 /* ADMA2 descriptor table:
488  * |----------------|---------------|-------------|--------------------------|
489  * | Address field  |     Length    | Reserved    |         Attribute        |
490  * |----------------|---------------|-------------|--------------------------|
491  * |63            32|31           16|15         06|05  |04  |03|02 |01 |00   |
492  * |----------------|---------------|-------------|----|----|--|---|---|-----|
493  * | 32-bit address | 16-bit length | 0000000000  |Act2|Act1| 0|Int|End|Valid|
494  * |----------------|---------------|-------------|----|----|--|---|---|-----|
495  *
496  * ADMA2 action table:
497  * | Act2 | Act1 |     Comment     | Operation                                                         |
498  * |------|------|-----------------|-------------------------------------------------------------------|
499  * |   0  |   0  | No op           | Don't care                                                        |
500  * |------|------|-----------------|-------------------------------------------------------------------|
501  * |   0  |   1  | Reserved        | Read this line and go to next one                                 |
502  * |------|------|-----------------|-------------------------------------------------------------------|
503  * |   1  |   0  | Transfer data   | Transfer data with address and length set in this descriptor line |
504  * |------|------|-----------------|-------------------------------------------------------------------|
505  * |   1  |   1  | Link descriptor | Link to another descriptor                                        |
506  * |------|------|-----------------|-------------------------------------------------------------------|
507  */
508 /**********************************tables below are created only for Doxygen***********************************/
509 /*! @brief The bit shift for LENGTH field in ADMA2's descriptor.
510  *
511  * <table>
512  * <caption>ADMA2 descriptor table</caption>
513  * <tr><th>Address field    <th>Length         <th>Reserved     <th colspan="6">Attribute
514  * <tr><td>63 32            <td>31 16          <td>15 06        <td>05   <td>04   <td>03  <td>02  <td>01  <td>00
515  * <tr><td>32-bit address   <td>16-bit length  <td>0000000000   <td>Act2 <td>Act1 <td>0   <td>Int <td>End <td>Valid
516  *</table>
517  *
518  * <table>
519  * <caption>ADMA2 action</caption>
520  * <tr><th>Act2   <th>Act1   <th>Comment          <th>Operation
521  * <tr><td> 0     <td>0      <td>No op            <td>Don't care
522  * <tr><td> 0     <td>1      <td> Reserved        <td> Read this line and go to next one
523  * <tr><td> 1     <td>0      <td>Transfer data    <td>Transfer data with address and length set in this descriptor line
524  * <tr><td> 1     <td>1      <td>Link descriptor  <td>Link to another descriptor
525  * </table>
526  */
527 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U)
528 /*! @brief The bit mask for LENGTH field in ADMA2's descriptor. */
529 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
530 /*! @brief The maximum value of LENGTH field in ADMA2's descriptor. */
531 #define USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK - 3U)
532 
533 /*! @brief Enum _usdhc_adma2_descriptor_flag. ADMA1 descriptor control and status mask. */
534 enum
535 {
536     kUSDHC_Adma2DescriptorValidFlag     = (1U << 0U), /*!< Valid flag. */
537     kUSDHC_Adma2DescriptorEndFlag       = (1U << 1U), /*!< End flag. */
538     kUSDHC_Adma2DescriptorInterruptFlag = (1U << 2U), /*!< Interrupt flag. */
539     kUSDHC_Adma2DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 mask. */
540     kUSDHC_Adma2DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 mask. */
541 
542     kUSDHC_Adma2DescriptorTypeNop      = (kUSDHC_Adma2DescriptorValidFlag), /*!< No operation. */
543     kUSDHC_Adma2DescriptorTypeReserved = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorValidFlag),
544     /*!< Reserved. */
545     kUSDHC_Adma2DescriptorTypeTransfer = (kUSDHC_Adma2DescriptorActivity2Flag | kUSDHC_Adma2DescriptorValidFlag),
546     /*!< Transfer type. */
547     kUSDHC_Adma2DescriptorTypeLink = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorActivity2Flag |
548                                       kUSDHC_Adma2DescriptorValidFlag), /*!< Link type. */
549 };
550 
551 /*! @brief Enum _usdhc_adma_flag. ADMA descriptor configuration flag.
552  *  @anchor _usdhc_adma_flag
553  */
554 enum
555 {
556     kUSDHC_AdmaDescriptorSingleFlag = 0U,
557     /*!< Try to finish the transfer in a single ADMA descriptor. If transfer size is bigger than one
558        ADMA descriptor's ability, new another descriptor for data transfer. */
559     kUSDHC_AdmaDescriptorMultipleFlag =
560         1U, /*!< Create multiple ADMA descriptors within the ADMA table, this is used for
561              mmc boot mode specifically, which need
562              to modify the ADMA descriptor on the fly, so the flag should be used
563              combining with stop at block gap feature. */
564 };
565 
566 /*! @brief DMA transfer burst len config. */
567 typedef enum _usdhc_burst_len
568 {
569     kUSDHC_EnBurstLenForINCR         = 0x01U, /*!< Enable burst len for INCR. */
570     kUSDHC_EnBurstLenForINCR4816     = 0x02U, /*!< Enable burst len for INCR4/INCR8/INCR16. */
571     kUSDHC_EnBurstLenForINCR4816WRAP = 0x04U, /*!< Enable burst len for INCR4/8/16 WRAP. */
572 } usdhc_burst_len_t;
573 
574 /*! @brief Enum _usdhc_transfer_data_type. Tansfer data type definition. */
575 enum
576 {
577     kUSDHC_TransferDataNormal        = 0U, /*!< Transfer normal read/write data. */
578     kUSDHC_TransferDataTuning        = 1U, /*!< Transfer tuning data. */
579     kUSDHC_TransferDataBoot          = 2U, /*!< Transfer boot data. */
580     kUSDHC_TransferDataBootcontinous = 3U, /*!< Transfer boot data continuously. */
581 };
582 
583 /*! @brief Defines the ADMA1 descriptor structure. */
584 typedef uint32_t usdhc_adma1_descriptor_t;
585 
586 /*! @brief Defines the ADMA2 descriptor structure. */
587 typedef struct _usdhc_adma2_descriptor
588 {
589     uint32_t attribute;      /*!< The control and status field. */
590     const uint32_t *address; /*!< The address field. */
591 } usdhc_adma2_descriptor_t;
592 
593 /*!
594  * @brief USDHC capability information.
595  *
596  * Defines a structure to save the capability information of USDHC.
597  */
598 typedef struct _usdhc_capability
599 {
600     uint32_t sdVersion;      /*!< Support SD card/sdio version. */
601     uint32_t mmcVersion;     /*!< Support EMMC card version. */
602     uint32_t maxBlockLength; /*!< Maximum block length united as byte. */
603     uint32_t maxBlockCount;  /*!< Maximum block count can be set one time. */
604     uint32_t flags;          /*!< Capability flags to indicate the support information(@ref _usdhc_capability_flag). */
605 } usdhc_capability_t;
606 
607 /*! @brief Data structure to configure the MMC boot feature. */
608 typedef struct _usdhc_boot_config
609 {
610     uint32_t ackTimeoutCount;      /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */
611     usdhc_boot_mode_t bootMode;    /*!< Boot mode selection. */
612     uint32_t blockCount;           /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */
613     size_t blockSize;              /*!< Block size. */
614     bool enableBootAck;            /*!< Enable or disable boot ACK. */
615     bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period. */
616 } usdhc_boot_config_t;
617 
618 /*! @brief Data structure to initialize the USDHC. */
619 typedef struct _usdhc_config
620 {
621     uint32_t dataTimeout;           /*!< Data timeout value. */
622     usdhc_endian_mode_t endianMode; /*!< Endian mode. */
623     uint8_t readWatermarkLevel;     /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */
624     uint8_t writeWatermarkLevel;    /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */
625 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
626     uint8_t readBurstLen;  /*!< Read burst len. */
627     uint8_t writeBurstLen; /*!< Write burst len. */
628 #endif
629 } usdhc_config_t;
630 
631 /*!
632  * @brief Card command descriptor.
633  *
634  * Defines card command-related attribute.
635  */
636 typedef struct _usdhc_command
637 {
638     uint32_t index;                          /*!< Command index. */
639     uint32_t argument;                       /*!< Command argument. */
640     usdhc_card_command_type_t type;          /*!< Command type. */
641     usdhc_card_response_type_t responseType; /*!< Command response type. */
642     uint32_t response[4U];                   /*!< Response for this command. */
643     uint32_t responseErrorFlags;             /*!< Response error flag, which need to check
644                                                  the command reponse. */
645     uint32_t flags;                          /*!< Cmd flags. */
646 } usdhc_command_t;
647 
648 /*! @brief ADMA configuration. */
649 typedef struct _usdhc_adma_config
650 {
651     usdhc_dma_mode_t dmaMode; /*!< DMA mode. */
652 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
653     usdhc_burst_len_t burstLen; /*!< Burst len config. */
654 #endif
655     uint32_t *admaTable;     /*!< ADMA table address, can't be null if transfer way is ADMA1/ADMA2. */
656     uint32_t admaTableWords; /*!< ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. */
657 } usdhc_adma_config_t;
658 
659 /*!
660  * @brief Card scatter gather data list.
661  *
662  * Allow application register uncontinuous data buffer for data transfer.
663  */
664 typedef struct _usdhc_scatter_gather_data_list
665 {
666     uint32_t *dataAddr;
667     uint32_t dataSize;
668     struct _usdhc_scatter_gather_data_list *dataList;
669 } usdhc_scatter_gather_data_list_t;
670 
671 /*!
672  * @brief Card scatter gather data descriptor.
673  *
674  * Defines a structure to contain data-related attribute. The 'enableIgnoreError' is used when upper card
675  * driver wants to ignore the error event to read/write all the data and not to stop read/write immediately when an
676  * error event happens. For example, bus testing procedure for MMC card.
677  */
678 typedef struct _usdhc_scatter_gather_data
679 {
680     bool enableAutoCommand12; /*!< Enable auto CMD12. */
681     bool enableAutoCommand23; /*!< Enable auto CMD23. */
682     bool enableIgnoreError;   /*!< Enable to ignore error event to read/write all the data. */
683 
684     usdhc_transfer_direction_t dataDirection; /*!< data direction */
685     uint8_t dataType;                         /*!< this is used to distinguish the normal/tuning/boot data. */
686     size_t blockSize;                         /*!< Block size. */
687 
688     usdhc_scatter_gather_data_list_t sgData; /*!<  scatter gather data */
689 } usdhc_scatter_gather_data_t;
690 
691 /*! @brief usdhc scatter gather transfer. */
692 typedef struct _usdhc_scatter_gather_transfer
693 {
694     usdhc_scatter_gather_data_t *data; /*!< Data to transfer. */
695     usdhc_command_t *command;          /*!< Command to send. */
696 } usdhc_scatter_gather_transfer_t;
697 
698 /*!
699  * @brief Card data descriptor.
700  *
701  * Defines a structure to contain data-related attribute. The 'enableIgnoreError' is used when upper card
702  * driver wants to ignore the error event to read/write all the data and not to stop read/write immediately when an
703  * error event happens. For example, bus testing procedure for MMC card.
704  */
705 typedef struct _usdhc_data
706 {
707     bool enableAutoCommand12; /*!< Enable auto CMD12. */
708     bool enableAutoCommand23; /*!< Enable auto CMD23. */
709     bool enableIgnoreError;   /*!< Enable to ignore error event to read/write all the data. */
710     uint8_t dataType;         /*!< this is used to distinguish the normal/tuning/boot data. */
711     size_t blockSize;         /*!< Block size. */
712     uint32_t blockCount;      /*!< Block count. */
713     uint32_t *rxData;         /*!< Buffer to save data read. */
714     const uint32_t *txData;   /*!< Data buffer to write. */
715 } usdhc_data_t;
716 
717 /*! @brief Transfer state. */
718 typedef struct _usdhc_transfer
719 {
720     usdhc_data_t *data;       /*!< Data to transfer. */
721     usdhc_command_t *command; /*!< Command to send. */
722 } usdhc_transfer_t;
723 
724 /*! @brief USDHC handle typedef. */
725 typedef struct _usdhc_handle usdhc_handle_t;
726 
727 /*! @brief USDHC callback functions. */
728 typedef struct _usdhc_transfer_callback
729 {
730     void (*CardInserted)(USDHC_Type *base,
731                          void *userData); /*!< Card inserted occurs when DAT3/CD pin is for card detect */
732     void (*CardRemoved)(USDHC_Type *base, void *userData);   /*!< Card removed occurs */
733     void (*SdioInterrupt)(USDHC_Type *base, void *userData); /*!< SDIO card interrupt occurs */
734     void (*BlockGap)(USDHC_Type *base, void *userData);      /*!< stopped at block gap event */
735     void (*TransferComplete)(USDHC_Type *base,
736                              usdhc_handle_t *handle,
737                              status_t status,
738                              void *userData);           /*!< Transfer complete callback. */
739     void (*ReTuning)(USDHC_Type *base, void *userData); /*!< Handle the re-tuning. */
740 } usdhc_transfer_callback_t;
741 
742 /*!
743  * @brief USDHC handle.
744  *
745  * Defines the structure to save the USDHC state information and callback function.
746  *
747  * @note All the fields except interruptFlags and transferredWords must be allocated by the user.
748  */
749 struct _usdhc_handle
750 {
751 #if (defined FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER) && FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
752     usdhc_scatter_gather_data_t *volatile data; /*!< scatter gather data pointer  */
753 #else
754     usdhc_data_t *volatile data;                                   /*!< Transfer parameter. Data to transfer. */
755 #endif
756     usdhc_command_t *volatile command; /*!< Transfer parameter. Command to send. */
757 
758     volatile uint32_t transferredWords; /*!< Transfer status. Words transferred by DATAPORT way. */
759 
760     usdhc_transfer_callback_t callback; /*!< Callback function. */
761     void *userData;                     /*!< Parameter for transfer complete callback. */
762 };
763 
764 /*! @brief USDHC transfer function. */
765 typedef status_t (*usdhc_transfer_function_t)(USDHC_Type *base, usdhc_transfer_t *content);
766 
767 /*! @brief USDHC host descriptor. */
768 typedef struct _usdhc_host
769 {
770     USDHC_Type *base;                   /*!< USDHC peripheral base address. */
771     uint32_t sourceClock_Hz;            /*!< USDHC source clock frequency united in Hz. */
772     usdhc_config_t config;              /*!< USDHC configuration. */
773     usdhc_capability_t capability;      /*!< USDHC capability information. */
774     usdhc_transfer_function_t transfer; /*!< USDHC transfer function. */
775 } usdhc_host_t;
776 
777 /*************************************************************************************************
778  * API
779  ************************************************************************************************/
780 #if defined(__cplusplus)
781 extern "C" {
782 #endif
783 
784 /*!
785  * @name Initialization and deinitialization
786  * @{
787  */
788 
789 /*!
790  * @brief USDHC module initialization function.
791  *
792  * Configures the USDHC according to the user configuration.
793  *
794  * Example:
795    @code
796    usdhc_config_t config;
797    config.cardDetectDat3 = false;
798    config.endianMode = kUSDHC_EndianModeLittle;
799    config.dmaMode = kUSDHC_DmaModeAdma2;
800    config.readWatermarkLevel = 128U;
801    config.writeWatermarkLevel = 128U;
802    USDHC_Init(USDHC, &config);
803    @endcode
804  *
805  * @param base USDHC peripheral base address.
806  * @param config USDHC configuration information.
807  * @retval #kStatus_Success Operate successfully.
808  */
809 void USDHC_Init(USDHC_Type *base, const usdhc_config_t *config);
810 
811 /*!
812  * @brief Deinitializes the USDHC.
813  *
814  * @param base USDHC peripheral base address.
815  */
816 void USDHC_Deinit(USDHC_Type *base);
817 
818 /*!
819  * @brief Resets the USDHC.
820  *
821  * @param base USDHC peripheral base address.
822  * @param mask The reset type mask(@ref _usdhc_reset).
823  * @param timeout Timeout for reset.
824  * @retval true Reset successfully.
825  * @retval false Reset failed.
826  */
827 bool USDHC_Reset(USDHC_Type *base, uint32_t mask, uint32_t timeout);
828 
829 /*! @} */
830 
831 /*!
832  * @name DMA Control
833  * @{
834  */
835 
836 /*!
837  * @brief Sets the DMA descriptor table configuration.
838  * A high level DMA descriptor configuration function.
839  * @param base USDHC peripheral base address.
840  * @param dmaConfig ADMA configuration
841  * @param dataConfig Data descriptor
842  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
843  *  refer to enum @ref _usdhc_adma_flag.
844  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
845  * @retval #kStatus_Success Operate successfully.
846  */
847 status_t USDHC_SetAdmaTableConfig(USDHC_Type *base,
848                                   usdhc_adma_config_t *dmaConfig,
849                                   usdhc_data_t *dataConfig,
850                                   uint32_t flags);
851 
852 /*!
853  * @brief Internal DMA configuration.
854  * This function is used to config the USDHC DMA related registers.
855  * @param base USDHC peripheral base address.
856  * @param dmaConfig ADMA configuration.
857  * @param dataAddr Transfer data address, a simple DMA parameter, if ADMA is used, leave it to NULL.
858  * @param enAutoCmd23 Flag to indicate Auto CMD23 is enable or not, a simple DMA parameter, if ADMA is used, leave it
859  * to false.
860  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
861  * @retval #kStatus_Success Operate successfully.
862  */
863 status_t USDHC_SetInternalDmaConfig(USDHC_Type *base,
864                                     usdhc_adma_config_t *dmaConfig,
865                                     const uint32_t *dataAddr,
866                                     bool enAutoCmd23);
867 
868 /*!
869  * @brief Sets the ADMA2 descriptor table configuration.
870  *
871  * @param admaTable ADMA table address.
872  * @param admaTableWords ADMA table length.
873  * @param dataBufferAddr Data buffer address.
874  * @param dataBytes Data Data length.
875  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
876  *  refer to enum @ref _usdhc_adma_flag.
877  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
878  * @retval #kStatus_Success Operate successfully.
879  */
880 status_t USDHC_SetADMA2Descriptor(
881     uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags);
882 
883 /*!
884  * @brief Sets the ADMA1 descriptor table configuration.
885  *
886  * @param admaTable ADMA table address.
887  * @param admaTableWords ADMA table length.
888  * @param dataBufferAddr Data buffer address.
889  * @param dataBytes Data length.
890  * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please
891  *  refer to enum @ref _usdhc_adma_flag.
892  * @retval #kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
893  * @retval #kStatus_Success Operate successfully.
894  */
895 status_t USDHC_SetADMA1Descriptor(
896     uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags);
897 
898 /*!
899  * @brief Enables internal DMA.
900  *
901  * @param base USDHC peripheral base address.
902  * @param enable enable or disable flag
903  */
USDHC_EnableInternalDMA(USDHC_Type * base,bool enable)904 static inline void USDHC_EnableInternalDMA(USDHC_Type *base, bool enable)
905 {
906     if (enable)
907     {
908         base->MIX_CTRL |= USDHC_MIX_CTRL_DMAEN_MASK;
909     }
910     else
911     {
912         base->MIX_CTRL &= ~USDHC_MIX_CTRL_DMAEN_MASK;
913         base->PROT_CTRL &= ~USDHC_PROT_CTRL_DMASEL_MASK;
914     }
915 }
916 
917 /*! @} */
918 
919 /*!
920  * @name Interrupts
921  * @{
922  */
923 
924 /*!
925  * @brief Enables the interrupt status.
926  *
927  * @param base USDHC peripheral base address.
928  * @param mask Interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
929  */
USDHC_EnableInterruptStatus(USDHC_Type * base,uint32_t mask)930 static inline void USDHC_EnableInterruptStatus(USDHC_Type *base, uint32_t mask)
931 {
932     base->INT_STATUS_EN |= mask;
933 }
934 
935 /*!
936  * @brief Disables the interrupt status.
937  *
938  * @param base USDHC peripheral base address.
939  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
940  */
USDHC_DisableInterruptStatus(USDHC_Type * base,uint32_t mask)941 static inline void USDHC_DisableInterruptStatus(USDHC_Type *base, uint32_t mask)
942 {
943     base->INT_STATUS_EN &= ~mask;
944 }
945 
946 /*!
947  * @brief Enables the interrupt signal corresponding to the interrupt status flag.
948  *
949  * @param base USDHC peripheral base address.
950  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
951  */
USDHC_EnableInterruptSignal(USDHC_Type * base,uint32_t mask)952 static inline void USDHC_EnableInterruptSignal(USDHC_Type *base, uint32_t mask)
953 {
954     base->INT_SIGNAL_EN |= mask;
955 }
956 
957 /*!
958  * @brief Disables the interrupt signal corresponding to the interrupt status flag.
959  *
960  * @param base USDHC peripheral base address.
961  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
962  */
USDHC_DisableInterruptSignal(USDHC_Type * base,uint32_t mask)963 static inline void USDHC_DisableInterruptSignal(USDHC_Type *base, uint32_t mask)
964 {
965     base->INT_SIGNAL_EN &= ~mask;
966 }
967 
968 /*! @} */
969 
970 /*!
971  * @name Status
972  * @{
973  */
974 
975 /*!
976  * @brief Gets the enabled interrupt status.
977  *
978  * @param base USDHC peripheral base address.
979  * @return Current interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
980  */
USDHC_GetEnabledInterruptStatusFlags(USDHC_Type * base)981 static inline uint32_t USDHC_GetEnabledInterruptStatusFlags(USDHC_Type *base)
982 {
983     uint32_t intStatus = base->INT_STATUS;
984 
985     return intStatus & base->INT_SIGNAL_EN;
986 }
987 
988 /*!
989  * @brief Gets the current interrupt status.
990  *
991  * @param base USDHC peripheral base address.
992  * @return Current interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
993  */
USDHC_GetInterruptStatusFlags(USDHC_Type * base)994 static inline uint32_t USDHC_GetInterruptStatusFlags(USDHC_Type *base)
995 {
996     return base->INT_STATUS;
997 }
998 
999 /*!
1000  * @brief Clears a specified interrupt status.
1001  * write 1 clears
1002  * @param base USDHC peripheral base address.
1003  * @param mask The interrupt status flags mask(@ref _usdhc_interrupt_status_flag).
1004  */
USDHC_ClearInterruptStatusFlags(USDHC_Type * base,uint32_t mask)1005 static inline void USDHC_ClearInterruptStatusFlags(USDHC_Type *base, uint32_t mask)
1006 {
1007     base->INT_STATUS = mask;
1008 }
1009 
1010 /*!
1011  * @brief Gets the status of auto command 12 error.
1012  *
1013  * @param base USDHC peripheral base address.
1014  * @return Auto command 12 error status flags mask(@ref _usdhc_auto_command12_error_status_flag).
1015  */
USDHC_GetAutoCommand12ErrorStatusFlags(USDHC_Type * base)1016 static inline uint32_t USDHC_GetAutoCommand12ErrorStatusFlags(USDHC_Type *base)
1017 {
1018     return base->AUTOCMD12_ERR_STATUS;
1019 }
1020 
1021 /*!
1022  * @brief Gets the status of the ADMA error.
1023  *
1024  * @param base USDHC peripheral base address.
1025  * @return ADMA error status flags mask(@ref _usdhc_adma_error_status_flag).
1026  */
USDHC_GetAdmaErrorStatusFlags(USDHC_Type * base)1027 static inline uint32_t USDHC_GetAdmaErrorStatusFlags(USDHC_Type *base)
1028 {
1029     return base->ADMA_ERR_STATUS & 0xFUL;
1030 }
1031 
1032 /*!
1033  * @brief Gets a present status.
1034  *
1035  * This function gets the present USDHC's status except for an interrupt status and an error status.
1036  *
1037  * @param base USDHC peripheral base address.
1038  * @return Present USDHC's status flags mask(@ref _usdhc_present_status_flag).
1039  */
USDHC_GetPresentStatusFlags(USDHC_Type * base)1040 static inline uint32_t USDHC_GetPresentStatusFlags(USDHC_Type *base)
1041 {
1042     return base->PRES_STATE;
1043 }
1044 
1045 /*! @} */
1046 
1047 /*!
1048  * @name Bus Operations
1049  * @{
1050  */
1051 
1052 /*!
1053  * @brief Gets the capability information.
1054  *
1055  * @param base USDHC peripheral base address.
1056  * @param capability Structure to save capability information.
1057  */
1058 void USDHC_GetCapability(USDHC_Type *base, usdhc_capability_t *capability);
1059 
1060 /*!
1061  * @brief Forces the card clock on.
1062  *
1063  * @param base USDHC peripheral base address.
1064  * @param enable enable/disable flag
1065  */
USDHC_ForceClockOn(USDHC_Type * base,bool enable)1066 static inline void USDHC_ForceClockOn(USDHC_Type *base, bool enable)
1067 {
1068     if (enable)
1069     {
1070         base->VEND_SPEC |= USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
1071     }
1072     else
1073     {
1074         base->VEND_SPEC &= ~USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
1075     }
1076 }
1077 
1078 /*!
1079  * @brief Sets the SD bus clock frequency.
1080  *
1081  * @param base USDHC peripheral base address.
1082  * @param srcClock_Hz USDHC source clock frequency united in Hz.
1083  * @param busClock_Hz SD bus clock frequency united in Hz.
1084  *
1085  * @return The nearest frequency of busClock_Hz configured for SD bus.
1086  */
1087 uint32_t USDHC_SetSdClock(USDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz);
1088 
1089 /*!
1090  * @brief Sends 80 clocks to the card to set it to the active state.
1091  *
1092  * This function must be called each time the card is inserted to ensure that the card can receive the command
1093  * correctly.
1094  *
1095  * @param base USDHC peripheral base address.
1096  * @param timeout Timeout to initialize card.
1097  * @retval true Set card active successfully.
1098  * @retval false Set card active failed.
1099  */
1100 bool USDHC_SetCardActive(USDHC_Type *base, uint32_t timeout);
1101 
1102 /*!
1103  * @brief Triggers a hardware reset.
1104  *
1105  * @param base USDHC peripheral base address.
1106  * @param high 1 or 0 level
1107  */
USDHC_AssertHardwareReset(USDHC_Type * base,bool high)1108 static inline void USDHC_AssertHardwareReset(USDHC_Type *base, bool high)
1109 {
1110     if (high)
1111     {
1112         base->SYS_CTRL |= USDHC_SYS_CTRL_IPP_RST_N_MASK;
1113     }
1114     else
1115     {
1116         base->SYS_CTRL &= ~USDHC_SYS_CTRL_IPP_RST_N_MASK;
1117     }
1118 }
1119 
1120 /*!
1121  * @brief Sets the data transfer width.
1122  *
1123  * @param base USDHC peripheral base address.
1124  * @param width Data transfer width.
1125  */
USDHC_SetDataBusWidth(USDHC_Type * base,usdhc_data_bus_width_t width)1126 static inline void USDHC_SetDataBusWidth(USDHC_Type *base, usdhc_data_bus_width_t width)
1127 {
1128     base->PROT_CTRL = ((base->PROT_CTRL & ~USDHC_PROT_CTRL_DTW_MASK) | USDHC_PROT_CTRL_DTW(width));
1129 }
1130 
1131 /*!
1132  * @brief Fills the data port.
1133  *
1134  * This function is used to implement the data transfer by Data Port instead of DMA.
1135  *
1136  * @param base USDHC peripheral base address.
1137  * @param data The data about to be sent.
1138  */
USDHC_WriteData(USDHC_Type * base,uint32_t data)1139 static inline void USDHC_WriteData(USDHC_Type *base, uint32_t data)
1140 {
1141     base->DATA_BUFF_ACC_PORT = data;
1142 }
1143 
1144 /*!
1145  * @brief Retrieves the data from the data port.
1146  *
1147  * This function is used to implement the data transfer by Data Port instead of DMA.
1148  *
1149  * @param base USDHC peripheral base address.
1150  * @return The data has been read.
1151  */
USDHC_ReadData(USDHC_Type * base)1152 static inline uint32_t USDHC_ReadData(USDHC_Type *base)
1153 {
1154     return base->DATA_BUFF_ACC_PORT;
1155 }
1156 
1157 /*!
1158  * @brief Sends command function.
1159  *
1160  * @param base USDHC peripheral base address.
1161  * @param command configuration
1162  */
1163 void USDHC_SendCommand(USDHC_Type *base, usdhc_command_t *command);
1164 
1165 /*!
1166  * @brief Enables or disables a wakeup event in low-power mode.
1167  *
1168  * @param base USDHC peripheral base address.
1169  * @param mask Wakeup events mask(@ref _usdhc_wakeup_event).
1170  * @param enable True to enable, false to disable.
1171  */
USDHC_EnableWakeupEvent(USDHC_Type * base,uint32_t mask,bool enable)1172 static inline void USDHC_EnableWakeupEvent(USDHC_Type *base, uint32_t mask, bool enable)
1173 {
1174     if (enable)
1175     {
1176         base->PROT_CTRL |= mask;
1177     }
1178     else
1179     {
1180         base->PROT_CTRL &= ~mask;
1181     }
1182 }
1183 
1184 /*!
1185  * @brief Detects card insert status.
1186  *
1187  * @param base USDHC peripheral base address.
1188  * @param enable enable/disable flag
1189  */
USDHC_CardDetectByData3(USDHC_Type * base,bool enable)1190 static inline void USDHC_CardDetectByData3(USDHC_Type *base, bool enable)
1191 {
1192     if (enable)
1193     {
1194         base->PROT_CTRL |= USDHC_PROT_CTRL_D3CD_MASK;
1195     }
1196     else
1197     {
1198         base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK;
1199     }
1200 }
1201 
1202 /*!
1203  * @brief Detects card insert status.
1204  *
1205  * @param base USDHC peripheral base address.
1206  */
USDHC_DetectCardInsert(USDHC_Type * base)1207 static inline bool USDHC_DetectCardInsert(USDHC_Type *base)
1208 {
1209     return ((base->PRES_STATE & (uint32_t)kUSDHC_CardInsertedFlag) != 0UL) ? true : false;
1210 }
1211 
1212 /*!
1213  * @brief Enables or disables the SDIO card control.
1214  *
1215  * @param base USDHC peripheral base address.
1216  * @param mask SDIO card control flags mask(@ref _usdhc_sdio_control_flag).
1217  * @param enable True to enable, false to disable.
1218  */
USDHC_EnableSdioControl(USDHC_Type * base,uint32_t mask,bool enable)1219 static inline void USDHC_EnableSdioControl(USDHC_Type *base, uint32_t mask, bool enable)
1220 {
1221     if (enable)
1222     {
1223         base->PROT_CTRL |= mask;
1224     }
1225     else
1226     {
1227         base->PROT_CTRL &= ~mask;
1228     }
1229 }
1230 
1231 /*!
1232  * @brief Restarts a transaction which has stopped at the block GAP for the SDIO card.
1233  *
1234  * @param base USDHC peripheral base address.
1235  */
USDHC_SetContinueRequest(USDHC_Type * base)1236 static inline void USDHC_SetContinueRequest(USDHC_Type *base)
1237 {
1238     base->PROT_CTRL |= USDHC_PROT_CTRL_CREQ_MASK;
1239 }
1240 
1241 /*!
1242  * @brief Request stop at block gap function.
1243  *
1244  * @param base USDHC peripheral base address.
1245  * @param enable True to stop at block gap, false to normal transfer.
1246  */
USDHC_RequestStopAtBlockGap(USDHC_Type * base,bool enable)1247 static inline void USDHC_RequestStopAtBlockGap(USDHC_Type *base, bool enable)
1248 {
1249     if (enable)
1250     {
1251         base->PROT_CTRL |= USDHC_PROT_CTRL_SABGREQ_MASK;
1252     }
1253     else
1254     {
1255         base->PROT_CTRL &= ~USDHC_PROT_CTRL_SABGREQ_MASK;
1256     }
1257 }
1258 
1259 /*!
1260  * @brief Configures the MMC boot feature.
1261  *
1262  * Example:
1263    @code
1264    usdhc_boot_config_t config;
1265    config.ackTimeoutCount = 4;
1266    config.bootMode = kUSDHC_BootModeNormal;
1267    config.blockCount = 5;
1268    config.enableBootAck = true;
1269    config.enableBoot = true;
1270    config.enableAutoStopAtBlockGap = true;
1271    USDHC_SetMmcBootConfig(USDHC, &config);
1272    @endcode
1273  *
1274  * @param base USDHC peripheral base address.
1275  * @param config The MMC boot configuration information.
1276  */
1277 void USDHC_SetMmcBootConfig(USDHC_Type *base, const usdhc_boot_config_t *config);
1278 
1279 /*!
1280  * @brief Enables or disables the mmc boot mode.
1281  *
1282  * @param base USDHC peripheral base address.
1283  * @param enable True to enable, false to disable.
1284  */
USDHC_EnableMmcBoot(USDHC_Type * base,bool enable)1285 static inline void USDHC_EnableMmcBoot(USDHC_Type *base, bool enable)
1286 {
1287     if (enable)
1288     {
1289         base->MMC_BOOT |= USDHC_MMC_BOOT_BOOT_EN_MASK;
1290     }
1291     else
1292     {
1293         base->MMC_BOOT &= ~USDHC_MMC_BOOT_BOOT_EN_MASK;
1294     }
1295 }
1296 
1297 /*!
1298  * @brief Forces generating events according to the given mask.
1299  *
1300  * @param base USDHC peripheral base address.
1301  * @param mask The force events bit posistion (_usdhc_force_event).
1302  */
USDHC_SetForceEvent(USDHC_Type * base,uint32_t mask)1303 static inline void USDHC_SetForceEvent(USDHC_Type *base, uint32_t mask)
1304 {
1305     base->FORCE_EVENT = mask;
1306 }
1307 
1308 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_VOLTAGE_SELECT) && (FSL_FEATURE_USDHC_HAS_NO_VOLTAGE_SELECT))
1309 /*!
1310  * @brief Selects the USDHC output voltage.
1311  *
1312  * @param base USDHC peripheral base address.
1313  * @param en18v True means 1.8V, false means 3.0V.
1314  */
UDSHC_SelectVoltage(USDHC_Type * base,bool en18v)1315 static inline void UDSHC_SelectVoltage(USDHC_Type *base, bool en18v)
1316 {
1317     if (en18v)
1318     {
1319         base->VEND_SPEC |= USDHC_VEND_SPEC_VSELECT_MASK;
1320     }
1321     else
1322     {
1323         base->VEND_SPEC &= ~USDHC_VEND_SPEC_VSELECT_MASK;
1324     }
1325 }
1326 #endif
1327 
1328 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE)
1329 /*!
1330  * @brief Checks the SDR50 mode request tuning bit.
1331  * When this bit set, application shall perform tuning for SDR50 mode.
1332  * @param base USDHC peripheral base address.
1333  */
USDHC_RequestTuningForSDR50(USDHC_Type * base)1334 static inline bool USDHC_RequestTuningForSDR50(USDHC_Type *base)
1335 {
1336     return ((base->HOST_CTRL_CAP & USDHC_HOST_CTRL_CAP_USE_TUNING_SDR50_MASK) != 0UL) ? true : false;
1337 }
1338 
1339 /*!
1340  * @brief Checks the request re-tuning bit.
1341  * When this bit is set, user should do manual tuning or standard tuning function.
1342  * @param base USDHC peripheral base address.
1343  */
USDHC_RequestReTuning(USDHC_Type * base)1344 static inline bool USDHC_RequestReTuning(USDHC_Type *base)
1345 {
1346     return ((base->PRES_STATE & USDHC_PRES_STATE_RTR_MASK) != 0UL) ? true : false;
1347 }
1348 
1349 /*!
1350  * @brief The SDR104 mode auto tuning enable and disable.
1351  * This function should be called after tuning function execute pass, auto tuning will handle
1352  * by hardware.
1353  * @param base USDHC peripheral base address.
1354  * @param enable enable/disable flag
1355  */
USDHC_EnableAutoTuning(USDHC_Type * base,bool enable)1356 static inline void USDHC_EnableAutoTuning(USDHC_Type *base, bool enable)
1357 {
1358     if (enable)
1359     {
1360         base->MIX_CTRL |= USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK;
1361     }
1362     else
1363     {
1364         base->MIX_CTRL &= ~USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK;
1365     }
1366 }
1367 
1368 #if !(defined(FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_NO_RETUNING_TIME_COUNTER) && \
1369       FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_NO_RETUNING_TIME_COUNTER)
1370 /*!
1371  * @brief Configs the re-tuning timer for mode 1 and mode 3.
1372  * This timer is used for standard tuning auto re-tuning,
1373  * @param base USDHC peripheral base address.
1374  * @param counter timer counter value
1375  */
USDHC_SetRetuningTimer(USDHC_Type * base,uint32_t counter)1376 static inline void USDHC_SetRetuningTimer(USDHC_Type *base, uint32_t counter)
1377 {
1378     base->HOST_CTRL_CAP &= ~USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING_MASK;
1379     base->HOST_CTRL_CAP |= USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING(counter);
1380 }
1381 #endif /* FSL_FEATURE_USDHC_REGISTER_HOST_CTRL_CAP_HAS_RETUNING_TIME_COUNTER */
1382 
1383 /*!
1384  * @brief The auto tuning enbale for CMD/DATA line.
1385  *
1386  * @param base USDHC peripheral base address.
1387  */
1388 void USDHC_EnableAutoTuningForCmdAndData(USDHC_Type *base);
1389 
1390 /*!
1391  * @brief Manual tuning trigger or abort.
1392  * User should handle the tuning cmd and find the boundary of the delay
1393  * then calucate a average value which will be configured to the <b>CLK_TUNE_CTRL_STATUS</b>
1394  * This function should be called before function @ref USDHC_AdjustDelayForManualTuning.
1395  * @param base USDHC peripheral base address.
1396  * @param enable tuning enable flag
1397  */
1398 void USDHC_EnableManualTuning(USDHC_Type *base, bool enable);
1399 
1400 /*!
1401  * @brief Get the tuning delay cell setting.
1402  *
1403  * @param base USDHC peripheral base address.
1404  * @retval CLK Tuning Control and Status register value.
1405  */
USDHC_GetTuningDelayStatus(USDHC_Type * base)1406 static inline uint32_t USDHC_GetTuningDelayStatus(USDHC_Type *base)
1407 {
1408     return base->CLK_TUNE_CTRL_STATUS >> 16U;
1409 }
1410 
1411 /*!
1412  * @brief The tuning delay cell setting.
1413  *
1414  * @param base USDHC peripheral base address.
1415  * @param preDelay Set the number of delay cells on the feedback clock between the feedback clock and CLK_PRE.
1416  * @param outDelay Set the number of delay cells on the feedback clock between CLK_PRE and CLK_OUT.
1417  * @param postDelay Set the number of delay cells on the feedback clock between CLK_OUT and CLK_POST.
1418  * @retval kStatus_Fail config the delay setting fail
1419  * @retval kStatus_Success config the delay setting success
1420  */
1421 status_t USDHC_SetTuningDelay(USDHC_Type *base, uint32_t preDelay, uint32_t outDelay, uint32_t postDelay);
1422 
1423 /*!
1424  * @brief Adjusts delay for mannual tuning.
1425  * @deprecated Do not use this function.  It has been superceded by USDHC_SetTuingDelay
1426  * @param base USDHC peripheral base address.
1427  * @param delay setting configuration
1428  * @retval #kStatus_Fail config the delay setting fail
1429  * @retval #kStatus_Success config the delay setting success
1430  */
1431 status_t USDHC_AdjustDelayForManualTuning(USDHC_Type *base, uint32_t delay);
1432 
1433 /*!
1434  * @brief set tuning counter tuning.
1435  * @param base USDHC peripheral base address.
1436  * @param counter tuning counter
1437  * @retval #kStatus_Fail config the delay setting fail
1438  * @retval #kStatus_Success config the delay setting success
1439  */
USDHC_SetStandardTuningCounter(USDHC_Type * base,uint8_t counter)1440 static inline void USDHC_SetStandardTuningCounter(USDHC_Type *base, uint8_t counter)
1441 {
1442     base->TUNING_CTRL =
1443         (base->TUNING_CTRL & (~USDHC_TUNING_CTRL_TUNING_COUNTER_MASK)) | USDHC_TUNING_CTRL_TUNING_COUNTER(counter);
1444 }
1445 
1446 /*!
1447  * @brief The enable standard tuning function.
1448  * The standard tuning window and tuning counter using the default config
1449  * tuning cmd is sent by the software, user need to check whether the tuning result
1450  * can be used for SDR50, SDR104, and HS200 mode tuning.
1451  * @param base USDHC peripheral base address.
1452  * @param tuningStartTap start tap
1453  * @param step tuning step
1454  * @param enable enable/disable flag
1455  */
1456 void USDHC_EnableStandardTuning(USDHC_Type *base, uint32_t tuningStartTap, uint32_t step, bool enable);
1457 
1458 /*!
1459  * @brief Gets execute STD tuning status.
1460  *
1461  * @param base USDHC peripheral base address.
1462  */
USDHC_GetExecuteStdTuningStatus(USDHC_Type * base)1463 static inline uint32_t USDHC_GetExecuteStdTuningStatus(USDHC_Type *base)
1464 {
1465     return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK);
1466 }
1467 
1468 /*!
1469  * @brief Checks STD tuning result.
1470  *
1471  * @param base USDHC peripheral base address.
1472  */
USDHC_CheckStdTuningResult(USDHC_Type * base)1473 static inline uint32_t USDHC_CheckStdTuningResult(USDHC_Type *base)
1474 {
1475     return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK);
1476 }
1477 
1478 /*!
1479  * @brief Checks tuning error.
1480  *
1481  * @param base USDHC peripheral base address.
1482  */
USDHC_CheckTuningError(USDHC_Type * base)1483 static inline uint32_t USDHC_CheckTuningError(USDHC_Type *base)
1484 {
1485     return (base->CLK_TUNE_CTRL_STATUS &
1486             (USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK | USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK));
1487 }
1488 
1489 #endif
1490 /*!
1491  * @brief The enable/disable DDR mode.
1492  *
1493  * @param base USDHC peripheral base address.
1494  * @param enable enable/disable flag
1495  * @param nibblePos nibble position
1496  */
1497 void USDHC_EnableDDRMode(USDHC_Type *base, bool enable, uint32_t nibblePos);
1498 
1499 #if FSL_FEATURE_USDHC_HAS_HS400_MODE
1500 /*!
1501  * @brief The enable/disable HS400 mode.
1502  *
1503  * @param base USDHC peripheral base address.
1504  * @param enable enable/disable flag
1505  */
USDHC_EnableHS400Mode(USDHC_Type * base,bool enable)1506 static inline void USDHC_EnableHS400Mode(USDHC_Type *base, bool enable)
1507 {
1508     if (enable)
1509     {
1510         base->MIX_CTRL |= USDHC_MIX_CTRL_HS400_MODE_MASK;
1511     }
1512     else
1513     {
1514         base->MIX_CTRL &= ~USDHC_MIX_CTRL_HS400_MODE_MASK;
1515     }
1516 }
1517 
1518 /*!
1519  * @brief Resets the strobe DLL.
1520  *
1521  * @param base USDHC peripheral base address.
1522  */
USDHC_ResetStrobeDLL(USDHC_Type * base)1523 static inline void USDHC_ResetStrobeDLL(USDHC_Type *base)
1524 {
1525     base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_RESET_MASK;
1526 }
1527 
1528 /*!
1529  * @brief Enables/disables the strobe DLL.
1530  *
1531  * @param base USDHC peripheral base address.
1532  * @param enable enable/disable flag
1533  */
USDHC_EnableStrobeDLL(USDHC_Type * base,bool enable)1534 static inline void USDHC_EnableStrobeDLL(USDHC_Type *base, bool enable)
1535 {
1536     if (enable)
1537     {
1538         base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK;
1539     }
1540     else
1541     {
1542         base->STROBE_DLL_CTRL &= ~USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK;
1543     }
1544 }
1545 
1546 /*!
1547  * @brief Configs the strobe DLL delay target and update interval.
1548  *
1549  * @param base USDHC peripheral base address.
1550  * @param delayTarget delay target
1551  * @param updateInterval update interval
1552  */
1553 void USDHC_ConfigStrobeDLL(USDHC_Type *base, uint32_t delayTarget, uint32_t updateInterval);
1554 
1555 /*!
1556  * @brief Enables manual override for slave delay chain using <b>STROBE_SLV_OVERRIDE_VAL</b>.
1557  *
1558  * @param base USDHC peripheral base address.
1559  * @param delayTaps Valid delay taps range from 1 - 128 taps. A value of 0 selects tap 1, and a value of 0x7F selects
1560  * tap 128.
1561  */
USDHC_SetStrobeDllOverride(USDHC_Type * base,uint32_t delayTaps)1562 static inline void USDHC_SetStrobeDllOverride(USDHC_Type *base, uint32_t delayTaps)
1563 {
1564     base->STROBE_DLL_CTRL &= (USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK |
1565                               USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_OVERRIDE_VAL_MASK);
1566 
1567     base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_OVERRIDE_MASK |
1568                              USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_OVERRIDE_VAL(delayTaps);
1569 }
1570 
1571 /*!
1572  * @brief Gets the strobe DLL status.
1573  *
1574  * @param base USDHC peripheral base address.
1575  */
USDHC_GetStrobeDLLStatus(USDHC_Type * base)1576 static inline uint32_t USDHC_GetStrobeDLLStatus(USDHC_Type *base)
1577 {
1578     return base->STROBE_DLL_STATUS;
1579 }
1580 
1581 #endif
1582 
1583 /*!
1584  * @brief USDHC data configuration.
1585  *
1586  * @param base USDHC peripheral base address.
1587  * @param dataDirection Data direction, tx or rx.
1588  * @param blockCount Data block count.
1589  * @param blockSize Data block size.
1590  *
1591  */
1592 void USDHC_SetDataConfig(USDHC_Type *base,
1593                          usdhc_transfer_direction_t dataDirection,
1594                          uint32_t blockCount,
1595                          uint32_t blockSize);
1596 /*! @} */
1597 
1598 /*!
1599  * @name Transactional functions
1600  * @{
1601  */
1602 
1603 /*!
1604  * @brief Creates the USDHC handle.
1605  *
1606  * @param base USDHC peripheral base address.
1607  * @param handle USDHC handle pointer.
1608  * @param callback Structure pointer to contain all callback functions.
1609  * @param userData Callback function parameter.
1610  */
1611 void USDHC_TransferCreateHandle(USDHC_Type *base,
1612                                 usdhc_handle_t *handle,
1613                                 const usdhc_transfer_callback_t *callback,
1614                                 void *userData);
1615 
1616 #if (defined FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER) && FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
1617 /*!
1618  * @brief Transfers the command/scatter gather data using an interrupt and an asynchronous method.
1619  *
1620  * This function sends a command and data and returns immediately. It doesn't wait for the transfer to complete or
1621  * to encounter an error. The application must not call this API in multiple threads at the same time. Because of that
1622  * this API doesn't support the re-entry mechanism.
1623  * This function is target for the application would like to have scatter gather buffer to be transferred within one
1624  * read/write request, non scatter gather buffer is support by this function also.
1625  *
1626  * @note Call API @ref USDHC_TransferCreateHandle when calling this API.
1627  *
1628  * @param base USDHC peripheral base address.
1629  * @param handle USDHC handle.
1630  * @param dmaConfig adma configurations, must be not NULL, since the function is target for ADMA only.
1631  * @param transfer scatter gather transfer content.
1632  *
1633  * @retval #kStatus_InvalidArgument Argument is invalid.
1634  * @retval #kStatus_USDHC_BusyTransferring Busy transferring.
1635  * @retval #kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1636  * @retval #kStatus_Success Operate successfully.
1637  */
1638 status_t USDHC_TransferScatterGatherADMANonBlocking(USDHC_Type *base,
1639                                                     usdhc_handle_t *handle,
1640                                                     usdhc_adma_config_t *dmaConfig,
1641                                                     usdhc_scatter_gather_transfer_t *transfer);
1642 #else
1643 /*!
1644  * @brief Transfers the command/data using an interrupt and an asynchronous method.
1645  *
1646  * This function sends a command and data and returns immediately. It doesn't wait for the transfer to complete or
1647  * to encounter an error. The application must not call this API in multiple threads at the same time. Because of that
1648  * this API doesn't support the re-entry mechanism.
1649  *
1650  * @note Call API @ref USDHC_TransferCreateHandle when calling this API.
1651  *
1652  * @param base USDHC peripheral base address.
1653  * @param handle USDHC handle.
1654  * @param dmaConfig ADMA configuration.
1655  * @param transfer Transfer content.
1656  * @retval #kStatus_InvalidArgument Argument is invalid.
1657  * @retval #kStatus_USDHC_BusyTransferring Busy transferring.
1658  * @retval #kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1659  * @retval #kStatus_Success Operate successfully.
1660  */
1661 status_t USDHC_TransferNonBlocking(USDHC_Type *base,
1662                                    usdhc_handle_t *handle,
1663                                    usdhc_adma_config_t *dmaConfig,
1664                                    usdhc_transfer_t *transfer);
1665 #endif
1666 
1667 /*!
1668  * @brief Transfers the command/data using a blocking method.
1669  *
1670  * This function waits until the command response/data is received or the USDHC encounters an error by polling the
1671  * status flag. \n
1672  * The application must not call this API in multiple threads at the same time. Because this API doesn't
1673  * support the re-entry mechanism.
1674  *
1675  * @note There is no need to call API @ref USDHC_TransferCreateHandle when calling this API.
1676  *
1677  * @param base USDHC peripheral base address.
1678  * @param dmaConfig adma configuration
1679  * @param transfer Transfer content.
1680  * @retval #kStatus_InvalidArgument Argument is invalid.
1681  * @retval #kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1682  * @retval #kStatus_USDHC_SendCommandFailed Send command failed.
1683  * @retval #kStatus_USDHC_TransferDataFailed Transfer data failed.
1684  * @retval #kStatus_Success Operate successfully.
1685  */
1686 status_t USDHC_TransferBlocking(USDHC_Type *base, usdhc_adma_config_t *dmaConfig, usdhc_transfer_t *transfer);
1687 
1688 /*!
1689  * @brief IRQ handler for the USDHC.
1690  *
1691  * This function deals with the IRQs on the given host controller.
1692  *
1693  * @param base USDHC peripheral base address.
1694  * @param handle USDHC handle.
1695  */
1696 void USDHC_TransferHandleIRQ(USDHC_Type *base, usdhc_handle_t *handle);
1697 
1698 /*! @} */
1699 
1700 #if defined(__cplusplus)
1701 }
1702 #endif
1703 /*! @} */
1704 
1705 #endif /* FSL_USDHC_H_*/
1706