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