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