1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 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.1.2. */
25 #define FSL_USDHC_DRIVER_VERSION (MAKE_VERSION(2U, 1U, 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 status */
32 enum _usdhc_status
33 {
34     kStatus_USDHC_BusyTransferring = MAKE_STATUS(kStatusGroup_USDHC, 0U),            /*!< Transfer is on-going */
35     kStatus_USDHC_PrepareAdmaDescriptorFailed = MAKE_STATUS(kStatusGroup_USDHC, 1U), /*!< Set DMA descriptor failed */
36     kStatus_USDHC_SendCommandFailed = MAKE_STATUS(kStatusGroup_USDHC, 2U),           /*!< Send command failed */
37     kStatus_USDHC_TransferDataFailed = MAKE_STATUS(kStatusGroup_USDHC, 3U),          /*!< Transfer data failed */
38     kStatus_USDHC_DMADataAddrNotAlign = MAKE_STATUS(kStatusGroup_USDHC, 4U),         /*!< data address not align */
39     kStatus_USDHC_ReTuningRequest = MAKE_STATUS(kStatusGroup_USDHC, 5U),             /*!< re-tuning request */
40     kStatus_USDHC_TuningError = MAKE_STATUS(kStatusGroup_USDHC, 6U),                 /*!< tuning error */
41 
42 };
43 
44 /*! @brief Host controller capabilities flag mask */
45 enum _usdhc_capability_flag
46 {
47     kUSDHC_SupportAdmaFlag = USDHC_HOST_CTRL_CAP_ADMAS_MASK,        /*!< Support ADMA */
48     kUSDHC_SupportHighSpeedFlag = USDHC_HOST_CTRL_CAP_HSS_MASK,     /*!< Support high-speed */
49     kUSDHC_SupportDmaFlag = USDHC_HOST_CTRL_CAP_DMAS_MASK,          /*!< Support DMA */
50     kUSDHC_SupportSuspendResumeFlag = USDHC_HOST_CTRL_CAP_SRS_MASK, /*!< Support suspend/resume */
51     kUSDHC_SupportV330Flag = USDHC_HOST_CTRL_CAP_VS33_MASK,         /*!< Support voltage 3.3V */
52     kUSDHC_SupportV300Flag = USDHC_HOST_CTRL_CAP_VS30_MASK,         /*!< Support voltage 3.0V */
53     kUSDHC_SupportV180Flag = USDHC_HOST_CTRL_CAP_VS18_MASK,         /*!< Support voltage 1.8V */
54     /* Put additional two flags in HTCAPBLT_MBL's position. */
55     kUSDHC_Support4BitFlag = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 0U), /*!< Support 4 bit mode */
56     kUSDHC_Support8BitFlag = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 1U), /*!< Support 8 bit mode */
57     /* sd version 3.0 new feature */
58     kUSDHC_SupportDDR50Flag = USDHC_HOST_CTRL_CAP_DDR50_SUPPORT_MASK, /*!< support DDR50 mode */
59 
60 #if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR104_MODE)
61     kUSDHC_SupportSDR104Flag = 0, /*!< not support SDR104 mode */
62 #else
63     kUSDHC_SupportSDR104Flag = USDHC_HOST_CTRL_CAP_SDR104_SUPPORT_MASK, /*!< support SDR104 mode */
64 #endif
65 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
66     kUSDHC_SupportSDR50Flag = 0U, /*!< not support SDR50 mode */
67 #else
68     kUSDHC_SupportSDR50Flag = USDHC_HOST_CTRL_CAP_SDR50_SUPPORT_MASK,   /*!< support SDR50 mode */
69 #endif
70 };
71 
72 /*! @brief Wakeup event mask */
73 enum _usdhc_wakeup_event
74 {
75     kUSDHC_WakeupEventOnCardInt = USDHC_PROT_CTRL_WECINT_MASK,    /*!< Wakeup on card interrupt */
76     kUSDHC_WakeupEventOnCardInsert = USDHC_PROT_CTRL_WECINS_MASK, /*!< Wakeup on card insertion */
77     kUSDHC_WakeupEventOnCardRemove = USDHC_PROT_CTRL_WECRM_MASK,  /*!< Wakeup on card removal */
78 
79     kUSDHC_WakeupEventsAll = (kUSDHC_WakeupEventOnCardInt | kUSDHC_WakeupEventOnCardInsert |
80                               kUSDHC_WakeupEventOnCardRemove), /*!< All wakeup events */
81 };
82 
83 /*! @brief Reset type mask */
84 enum _usdhc_reset
85 {
86     kUSDHC_ResetAll = USDHC_SYS_CTRL_RSTA_MASK,     /*!< Reset all except card detection */
87     kUSDHC_ResetCommand = USDHC_SYS_CTRL_RSTC_MASK, /*!< Reset command line */
88     kUSDHC_ResetData = USDHC_SYS_CTRL_RSTD_MASK,    /*!< Reset data line */
89 
90 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
91     kUSDHC_ResetTuning = 0U, /*!< no reset tuning circuit bit */
92 #else
93     kUSDHC_ResetTuning = USDHC_SYS_CTRL_RSTT_MASK,                      /*!< reset tuning circuit */
94 #endif
95 
96     kUSDHC_ResetsAll =
97         (kUSDHC_ResetAll | kUSDHC_ResetCommand | kUSDHC_ResetData | kUSDHC_ResetTuning), /*!< All reset types */
98 };
99 
100 /*! @brief Transfer flag mask */
101 enum _usdhc_transfer_flag
102 {
103     kUSDHC_EnableDmaFlag = USDHC_MIX_CTRL_DMAEN_MASK, /*!< Enable DMA */
104 
105     kUSDHC_CommandTypeSuspendFlag = (USDHC_CMD_XFR_TYP_CMDTYP(1U)), /*!< Suspend command */
106     kUSDHC_CommandTypeResumeFlag = (USDHC_CMD_XFR_TYP_CMDTYP(2U)),  /*!< Resume command */
107     kUSDHC_CommandTypeAbortFlag = (USDHC_CMD_XFR_TYP_CMDTYP(3U)),   /*!< Abort command */
108 
109     kUSDHC_EnableBlockCountFlag = USDHC_MIX_CTRL_BCEN_MASK,      /*!< Enable block count */
110     kUSDHC_EnableAutoCommand12Flag = USDHC_MIX_CTRL_AC12EN_MASK, /*!< Enable auto CMD12 */
111     kUSDHC_DataReadFlag = USDHC_MIX_CTRL_DTDSEL_MASK,            /*!< Enable data read */
112     kUSDHC_MultipleBlockFlag = USDHC_MIX_CTRL_MSBSEL_MASK,       /*!< Multiple block data read/write */
113     kUSDHC_EnableAutoCommand23Flag = USDHC_MIX_CTRL_AC23EN_MASK, /*!< Enable auto CMD23 */
114 
115     kUSDHC_ResponseLength136Flag = USDHC_CMD_XFR_TYP_RSPTYP(1U),    /*!< 136 bit response length */
116     kUSDHC_ResponseLength48Flag = USDHC_CMD_XFR_TYP_RSPTYP(2U),     /*!< 48 bit response length */
117     kUSDHC_ResponseLength48BusyFlag = USDHC_CMD_XFR_TYP_RSPTYP(3U), /*!< 48 bit response length with busy status */
118 
119     kUSDHC_EnableCrcCheckFlag = USDHC_CMD_XFR_TYP_CCCEN_MASK,   /*!< Enable CRC check */
120     kUSDHC_EnableIndexCheckFlag = USDHC_CMD_XFR_TYP_CICEN_MASK, /*!< Enable index check */
121     kUSDHC_DataPresentFlag = USDHC_CMD_XFR_TYP_DPSEL_MASK,      /*!< Data present flag */
122 };
123 
124 /*! @brief Present status flag mask */
125 enum _usdhc_present_status_flag
126 {
127     kUSDHC_CommandInhibitFlag = USDHC_PRES_STATE_CIHB_MASK,     /*!< Command inhibit */
128     kUSDHC_DataInhibitFlag = USDHC_PRES_STATE_CDIHB_MASK,       /*!< Data inhibit */
129     kUSDHC_DataLineActiveFlag = USDHC_PRES_STATE_DLA_MASK,      /*!< Data line active */
130     kUSDHC_SdClockStableFlag = USDHC_PRES_STATE_SDSTB_MASK,     /*!< SD bus clock stable */
131     kUSDHC_WriteTransferActiveFlag = USDHC_PRES_STATE_WTA_MASK, /*!< Write transfer active */
132     kUSDHC_ReadTransferActiveFlag = USDHC_PRES_STATE_RTA_MASK,  /*!< Read transfer active */
133     kUSDHC_BufferWriteEnableFlag = USDHC_PRES_STATE_BWEN_MASK,  /*!< Buffer write enable */
134     kUSDHC_BufferReadEnableFlag = USDHC_PRES_STATE_BREN_MASK,   /*!< Buffer read enable */
135 
136 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
137     kUSDHC_DelaySettingFinishedFlag = 0U, /*!< not support */
138     kUSDHC_ReTuningRequestFlag = 0U,      /*!< not support */
139 #else
140     kUSDHC_ReTuningRequestFlag = USDHC_PRES_STATE_RTR_MASK, /*!< re-tuning request flag ,only used for SDR104 mode */
141     kUSDHC_DelaySettingFinishedFlag = USDHC_PRES_STATE_TSCD_MASK, /*!< delay setting finished flag */
142 #endif
143 
144     kUSDHC_CardInsertedFlag = USDHC_PRES_STATE_CINST_MASK,    /*!< Card inserted */
145     kUSDHC_CommandLineLevelFlag = USDHC_PRES_STATE_CLSL_MASK, /*!< Command line signal level */
146 
147     kUSDHC_Data0LineLevelFlag = (1U << USDHC_PRES_STATE_DLSL_SHIFT),        /*!< Data0 line signal level */
148     kUSDHC_Data1LineLevelFlag = (1U << (USDHC_PRES_STATE_DLSL_SHIFT + 1U)), /*!< Data1 line signal level */
149     kUSDHC_Data2LineLevelFlag = (1U << (USDHC_PRES_STATE_DLSL_SHIFT + 2U)), /*!< Data2 line signal level */
150     kUSDHC_Data3LineLevelFlag = (1U << (USDHC_PRES_STATE_DLSL_SHIFT + 3U)), /*!< Data3 line signal level */
151     kUSDHC_Data4LineLevelFlag = (1U << (USDHC_PRES_STATE_DLSL_SHIFT + 4U)), /*!< Data4 line signal level */
152     kUSDHC_Data5LineLevelFlag = (1U << (USDHC_PRES_STATE_DLSL_SHIFT + 5U)), /*!< Data5 line signal level */
153     kUSDHC_Data6LineLevelFlag = (1U << (USDHC_PRES_STATE_DLSL_SHIFT + 6U)), /*!< Data6 line signal level */
154     kUSDHC_Data7LineLevelFlag = (1U << (USDHC_PRES_STATE_DLSL_SHIFT + 7U)), /*!< Data7 line signal level */
155 };
156 
157 /*! @brief Interrupt status flag mask */
158 enum _usdhc_interrupt_status_flag
159 {
160     kUSDHC_CommandCompleteFlag = USDHC_INT_STATUS_CC_MASK,   /*!< Command complete */
161     kUSDHC_DataCompleteFlag = USDHC_INT_STATUS_TC_MASK,      /*!< Data complete */
162     kUSDHC_BlockGapEventFlag = USDHC_INT_STATUS_BGE_MASK,    /*!< Block gap event */
163     kUSDHC_DmaCompleteFlag = USDHC_INT_STATUS_DINT_MASK,     /*!< DMA interrupt */
164     kUSDHC_BufferWriteReadyFlag = USDHC_INT_STATUS_BWR_MASK, /*!< Buffer write ready */
165     kUSDHC_BufferReadReadyFlag = USDHC_INT_STATUS_BRR_MASK,  /*!< Buffer read ready */
166     kUSDHC_CardInsertionFlag = USDHC_INT_STATUS_CINS_MASK,   /*!< Card inserted */
167     kUSDHC_CardRemovalFlag = USDHC_INT_STATUS_CRM_MASK,      /*!< Card removed */
168     kUSDHC_CardInterruptFlag = USDHC_INT_STATUS_CINT_MASK,   /*!< Card interrupt */
169 
170 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
171     kUSDHC_ReTuningEventFlag = 0U, /*!< Re-Tuning event,only for SD3.0 SDR104 mode */
172     kUSDHC_TuningPassFlag = 0U,    /*!< SDR104 mode tuning pass flag */
173     kUSDHC_TuningErrorFlag = 0U,   /*!< SDR104 tuning error flag */
174 #else
175     kUSDHC_ReTuningEventFlag = USDHC_INT_STATUS_RTE_MASK,         /*!< Re-Tuning event,only for SD3.0 SDR104 mode */
176     kUSDHC_TuningPassFlag = USDHC_INT_STATUS_TP_MASK,             /*!< SDR104 mode tuning pass flag */
177     kUSDHC_TuningErrorFlag = USDHC_INT_STATUS_TNE_MASK,           /*!< SDR104 tuning error flag */
178 #endif
179 
180     kUSDHC_CommandTimeoutFlag = USDHC_INT_STATUS_CTOE_MASK,      /*!< Command timeout error */
181     kUSDHC_CommandCrcErrorFlag = USDHC_INT_STATUS_CCE_MASK,      /*!< Command CRC error */
182     kUSDHC_CommandEndBitErrorFlag = USDHC_INT_STATUS_CEBE_MASK,  /*!< Command end bit error */
183     kUSDHC_CommandIndexErrorFlag = USDHC_INT_STATUS_CIE_MASK,    /*!< Command index error */
184     kUSDHC_DataTimeoutFlag = USDHC_INT_STATUS_DTOE_MASK,         /*!< Data timeout error */
185     kUSDHC_DataCrcErrorFlag = USDHC_INT_STATUS_DCE_MASK,         /*!< Data CRC error */
186     kUSDHC_DataEndBitErrorFlag = USDHC_INT_STATUS_DEBE_MASK,     /*!< Data end bit error */
187     kUSDHC_AutoCommand12ErrorFlag = USDHC_INT_STATUS_AC12E_MASK, /*!< Auto CMD12 error */
188     kUSDHC_DmaErrorFlag = USDHC_INT_STATUS_DMAE_MASK,            /*!< DMA error */
189 
190     kUSDHC_CommandErrorFlag = (kUSDHC_CommandTimeoutFlag | kUSDHC_CommandCrcErrorFlag | kUSDHC_CommandEndBitErrorFlag |
191                                kUSDHC_CommandIndexErrorFlag), /*!< Command error */
192     kUSDHC_DataErrorFlag = (kUSDHC_DataTimeoutFlag | kUSDHC_DataCrcErrorFlag | kUSDHC_DataEndBitErrorFlag |
193                             kUSDHC_AutoCommand12ErrorFlag),                                    /*!< Data error */
194     kUSDHC_ErrorFlag = (kUSDHC_CommandErrorFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< All error */
195     kUSDHC_DataFlag = (kUSDHC_DataCompleteFlag | kUSDHC_DmaCompleteFlag | kUSDHC_BufferWriteReadyFlag |
196                        kUSDHC_BufferReadReadyFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< Data interrupts */
197     kUSDHC_CommandFlag = (kUSDHC_CommandErrorFlag | kUSDHC_CommandCompleteFlag), /*!< Command interrupts */
198     kUSDHC_CardDetectFlag = (kUSDHC_CardInsertionFlag | kUSDHC_CardRemovalFlag), /*!< Card detection interrupts */
199     kUSDHC_SDR104TuningFlag = (kUSDHC_TuningErrorFlag | kUSDHC_TuningPassFlag | kUSDHC_ReTuningEventFlag),
200 
201     kUSDHC_AllInterruptFlags = (kUSDHC_BlockGapEventFlag | kUSDHC_CardInterruptFlag | kUSDHC_CommandFlag |
202                                 kUSDHC_DataFlag | kUSDHC_ErrorFlag | kUSDHC_SDR104TuningFlag), /*!< All flags mask */
203 };
204 
205 /*! @brief Auto CMD12 error status flag mask */
206 enum _usdhc_auto_command12_error_status_flag
207 {
208     kUSDHC_AutoCommand12NotExecutedFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12NE_MASK,  /*!< Not executed error */
209     kUSDHC_AutoCommand12TimeoutFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12TOE_MASK,     /*!< Timeout error */
210     kUSDHC_AutoCommand12EndBitErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12EBE_MASK, /*!< End bit error */
211     kUSDHC_AutoCommand12CrcErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12CE_MASK,     /*!< CRC error */
212     kUSDHC_AutoCommand12IndexErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12IE_MASK,   /*!< Index error */
213     kUSDHC_AutoCommand12NotIssuedFlag = USDHC_AUTOCMD12_ERR_STATUS_CNIBAC12E_MASK, /*!< Not issued error */
214 };
215 
216 /*! @brief standard tuning flag */
217 enum _usdhc_standard_tuning
218 {
219 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
220     kUSDHC_ExecuteTuning = 0U,        /*!< not support */
221     kUSDHC_TuningSampleClockSel = 0U, /*!< not support */
222 #else
223     kUSDHC_ExecuteTuning = USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK, /*!< used to start tuning procedure */
224     kUSDHC_TuningSampleClockSel =
225         USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK,               /*!< when std_tuning_en bit is set, this bit is used
226                                                                     select sampleing clock */
227 #endif
228 };
229 
230 /*! @brief ADMA error status flag mask */
231 enum _usdhc_adma_error_status_flag
232 {
233     kUSDHC_AdmaLenghMismatchFlag = USDHC_ADMA_ERR_STATUS_ADMALME_MASK,   /*!< Length mismatch error */
234     kUSDHC_AdmaDescriptorErrorFlag = USDHC_ADMA_ERR_STATUS_ADMADCE_MASK, /*!< Descriptor error */
235 };
236 
237 /*!
238  * @brief ADMA error state
239  *
240  * This state is the detail state when ADMA error has occurred.
241  */
242 typedef enum _usdhc_adma_error_state
243 {
244     kUSDHC_AdmaErrorStateStopDma = 0x00U,         /*!< Stop DMA */
245     kUSDHC_AdmaErrorStateFetchDescriptor = 0x01U, /*!< Fetch descriptor */
246     kUSDHC_AdmaErrorStateChangeAddress = 0x02U,   /*!< Change address */
247     kUSDHC_AdmaErrorStateTransferData = 0x03U,    /*!< Transfer data */
248 } usdhc_adma_error_state_t;
249 
250 /*! @brief Force event mask */
251 enum _usdhc_force_event
252 {
253     kUSDHC_ForceEventAutoCommand12NotExecuted = USDHC_FORCE_EVENT_FEVTAC12NE_MASK, /*!< Auto CMD12 not executed error */
254     kUSDHC_ForceEventAutoCommand12Timeout = USDHC_FORCE_EVENT_FEVTAC12TOE_MASK,    /*!< Auto CMD12 timeout error */
255     kUSDHC_ForceEventAutoCommand12CrcError = USDHC_FORCE_EVENT_FEVTAC12CE_MASK,    /*!< Auto CMD12 CRC error */
256     kUSDHC_ForceEventEndBitError = USDHC_FORCE_EVENT_FEVTAC12EBE_MASK,             /*!< Auto CMD12 end bit error */
257     kUSDHC_ForceEventAutoCommand12IndexError = USDHC_FORCE_EVENT_FEVTAC12IE_MASK,  /*!< Auto CMD12 index error */
258     kUSDHC_ForceEventAutoCommand12NotIssued = USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK, /*!< Auto CMD12 not issued error */
259     kUSDHC_ForceEventCommandTimeout = USDHC_FORCE_EVENT_FEVTCTOE_MASK,              /*!< Command timeout error */
260     kUSDHC_ForceEventCommandCrcError = USDHC_FORCE_EVENT_FEVTCCE_MASK,              /*!< Command CRC error */
261     kUSDHC_ForceEventCommandEndBitError = USDHC_FORCE_EVENT_FEVTCEBE_MASK,          /*!< Command end bit error */
262     kUSDHC_ForceEventCommandIndexError = USDHC_FORCE_EVENT_FEVTCIE_MASK,            /*!< Command index error */
263     kUSDHC_ForceEventDataTimeout = USDHC_FORCE_EVENT_FEVTDTOE_MASK,                 /*!< Data timeout error */
264     kUSDHC_ForceEventDataCrcError = USDHC_FORCE_EVENT_FEVTDCE_MASK,                 /*!< Data CRC error */
265     kUSDHC_ForceEventDataEndBitError = USDHC_FORCE_EVENT_FEVTDEBE_MASK,             /*!< Data end bit error */
266     kUSDHC_ForceEventAutoCommand12Error = USDHC_FORCE_EVENT_FEVTAC12E_MASK,         /*!< Auto CMD12 error */
267     kUSDHC_ForceEventCardInt = USDHC_FORCE_EVENT_FEVTCINT_MASK,                     /*!< Card interrupt */
268     kUSDHC_ForceEventDmaError = USDHC_FORCE_EVENT_FEVTDMAE_MASK,                    /*!< Dma error */
269 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
270     kUSDHC_ForceEventTuningError = 0U, /*!< not support */
271 #else
272     kUSDHC_ForceEventTuningError = USDHC_FORCE_EVENT_FEVTTNE_MASK, /*!< Tuning error */
273 #endif
274     kUSDHC_ForceEventsAll =
275         (kUSDHC_ForceEventAutoCommand12NotExecuted | kUSDHC_ForceEventAutoCommand12Timeout |
276          kUSDHC_ForceEventAutoCommand12CrcError | kUSDHC_ForceEventEndBitError |
277          kUSDHC_ForceEventAutoCommand12IndexError | kUSDHC_ForceEventAutoCommand12NotIssued |
278          kUSDHC_ForceEventCommandTimeout | kUSDHC_ForceEventCommandCrcError | kUSDHC_ForceEventCommandEndBitError |
279          kUSDHC_ForceEventCommandIndexError | kUSDHC_ForceEventDataTimeout | kUSDHC_ForceEventDataCrcError |
280          kUSDHC_ForceEventDataEndBitError | kUSDHC_ForceEventAutoCommand12Error | kUSDHC_ForceEventCardInt |
281          kUSDHC_ForceEventDmaError | kUSDHC_ForceEventTuningError), /*!< All force event flags mask */
282 };
283 
284 /*! @brief Data transfer width */
285 typedef enum _usdhc_data_bus_width
286 {
287     kUSDHC_DataBusWidth1Bit = 0U, /*!< 1-bit mode */
288     kUSDHC_DataBusWidth4Bit = 1U, /*!< 4-bit mode */
289     kUSDHC_DataBusWidth8Bit = 2U, /*!< 8-bit mode */
290 } usdhc_data_bus_width_t;
291 
292 /*! @brief Endian mode */
293 typedef enum _usdhc_endian_mode
294 {
295     kUSDHC_EndianModeBig = 0U,         /*!< Big endian mode */
296     kUSDHC_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode */
297     kUSDHC_EndianModeLittle = 2U,      /*!< Little endian mode */
298 } usdhc_endian_mode_t;
299 
300 /*! @brief DMA mode */
301 typedef enum _usdhc_dma_mode
302 {
303     kUSDHC_DmaModeSimple = 0U, /*!< external DMA */
304     kUSDHC_DmaModeAdma1 = 1U,  /*!< ADMA1 is selected */
305     kUSDHC_DmaModeAdma2 = 2U,  /*!< ADMA2 is selected */
306     kUSDHC_ExternalDMA = 3U,   /*!< external dma mode select */
307 } usdhc_dma_mode_t;
308 
309 /*! @brief SDIO control flag mask */
310 enum _usdhc_sdio_control_flag
311 {
312     kUSDHC_StopAtBlockGapFlag = USDHC_PROT_CTRL_SABGREQ_MASK,     /*!< Stop at block gap */
313     kUSDHC_ReadWaitControlFlag = USDHC_PROT_CTRL_RWCTL_MASK,      /*!< Read wait control */
314     kUSDHC_InterruptAtBlockGapFlag = USDHC_PROT_CTRL_IABG_MASK,   /*!< Interrupt at block gap */
315     kUSDHC_ReadDoneNo8CLK = USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK, /*!< read done without 8 clk for block gap */
316     kUSDHC_ExactBlockNumberReadFlag = USDHC_PROT_CTRL_NON_EXACT_BLK_RD_MASK, /*!< Exact block number read */
317 };
318 
319 /*! @brief MMC card boot mode */
320 typedef enum _usdhc_boot_mode
321 {
322     kUSDHC_BootModeNormal = 0U,      /*!< Normal boot */
323     kUSDHC_BootModeAlternative = 1U, /*!< Alternative boot */
324 } usdhc_boot_mode_t;
325 
326 /*! @brief The command type */
327 typedef enum _usdhc_card_command_type
328 {
329     kCARD_CommandTypeNormal = 0U,  /*!< Normal command */
330     kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */
331     kCARD_CommandTypeResume = 2U,  /*!< Resume command */
332     kCARD_CommandTypeAbort = 3U,   /*!< Abort command */
333 } usdhc_card_command_type_t;
334 
335 /*!
336  * @brief The command response type.
337  *
338  * Define the command response type from card to host controller.
339  */
340 typedef enum _usdhc_card_response_type
341 {
342     kCARD_ResponseTypeNone = 0U, /*!< Response type: none */
343     kCARD_ResponseTypeR1 = 1U,   /*!< Response type: R1 */
344     kCARD_ResponseTypeR1b = 2U,  /*!< Response type: R1b */
345     kCARD_ResponseTypeR2 = 3U,   /*!< Response type: R2 */
346     kCARD_ResponseTypeR3 = 4U,   /*!< Response type: R3 */
347     kCARD_ResponseTypeR4 = 5U,   /*!< Response type: R4 */
348     kCARD_ResponseTypeR5 = 6U,   /*!< Response type: R5 */
349     kCARD_ResponseTypeR5b = 7U,  /*!< Response type: R5b */
350     kCARD_ResponseTypeR6 = 8U,   /*!< Response type: R6 */
351     kCARD_ResponseTypeR7 = 9U,   /*!< Response type: R7 */
352 } usdhc_card_response_type_t;
353 
354 /*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor */
355 #define USDHC_ADMA1_ADDRESS_ALIGN (4096U)
356 /*! @brief The alignment size for LENGTH field in ADMA1's descriptor */
357 #define USDHC_ADMA1_LENGTH_ALIGN (4096U)
358 /*! @brief The alignment size for ADDRESS field in ADMA2's descriptor */
359 #define USDHC_ADMA2_ADDRESS_ALIGN (4U)
360 /*! @brief The alignment size for LENGTH filed in ADMA2's descriptor */
361 #define USDHC_ADMA2_LENGTH_ALIGN (4U)
362 
363 /* ADMA1 descriptor table
364  * |------------------------|---------|--------------------------|
365  * | Address/page field     |Reserved |         Attribute        |
366  * |------------------------|---------|--------------------------|
367  * |31                    12|11      6|05  |04  |03|02 |01 |00   |
368  * |------------------------|---------|----|----|--|---|---|-----|
369  * | address or data length | 000000  |Act2|Act1| 0|Int|End|Valid|
370  * |------------------------|---------|----|----|--|---|---|-----|
371  *
372  *
373  * |------|------|-----------------|-------|-------------|
374  * | Act2 | Act1 |     Comment     | 31-28 | 27 - 12     |
375  * |------|------|-----------------|---------------------|
376  * |   0  |   0  | No op           | Don't care          |
377  * |------|------|-----------------|-------|-------------|
378  * |   0  |   1  | Set data length |  0000 | Data Length |
379  * |------|------|-----------------|-------|-------------|
380  * |   1  |   0  | Transfer data   | Data address        |
381  * |------|------|-----------------|---------------------|
382  * |   1  |   1  | Link descriptor | Descriptor address  |
383  * |------|------|-----------------|---------------------|
384  */
385 /*! @brief The bit shift for ADDRESS filed in ADMA1's descriptor */
386 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT (12U)
387 /*! @brief The bit mask for ADDRESS field in ADMA1's descriptor */
388 #define USDHC_ADMA1_DESCRIPTOR_ADDRESS_MASK (0xFFFFFU)
389 /*! @brief The bit shift for LENGTH filed in ADMA1's descriptor */
390 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U)
391 /*! @brief The mask for LENGTH field in ADMA1's descriptor */
392 #define USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
393 /*! @brief The maximum value of LENGTH filed in ADMA1's descriptor */
394 #define USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK - 3U)
395 
396 /*! @brief The mask for the control/status field in ADMA1 descriptor */
397 enum _usdhc_adma1_descriptor_flag
398 {
399     kUSDHC_Adma1DescriptorValidFlag = (1U << 0U),                      /*!< Valid flag */
400     kUSDHC_Adma1DescriptorEndFlag = (1U << 1U),                        /*!< End flag */
401     kUSDHC_Adma1DescriptorInterrupFlag = (1U << 2U),                   /*!< Interrupt flag */
402     kUSDHC_Adma1DescriptorActivity1Flag = (1U << 4U),                  /*!< Activity 1 flag */
403     kUSDHC_Adma1DescriptorActivity2Flag = (1U << 5U),                  /*!< Activity 2 flag */
404     kUSDHC_Adma1DescriptorTypeNop = (kUSDHC_Adma1DescriptorValidFlag), /*!< No operation */
405     kUSDHC_Adma1DescriptorTypeTransfer =
406         (kUSDHC_Adma1DescriptorActivity2Flag | kUSDHC_Adma1DescriptorValidFlag), /*!< Transfer data */
407     kUSDHC_Adma1DescriptorTypeLink = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorActivity2Flag |
408                                       kUSDHC_Adma1DescriptorValidFlag), /*!< Link descriptor */
409     kUSDHC_Adma1DescriptorTypeSetLength =
410         (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorValidFlag), /*!< Set data length */
411 };
412 
413 /* ADMA2 descriptor table
414  * |----------------|---------------|-------------|--------------------------|
415  * | Address field  |     Length    | Reserved    |         Attribute        |
416  * |----------------|---------------|-------------|--------------------------|
417  * |63            32|31           16|15         06|05  |04  |03|02 |01 |00   |
418  * |----------------|---------------|-------------|----|----|--|---|---|-----|
419  * | 32-bit address | 16-bit length | 0000000000  |Act2|Act1| 0|Int|End|Valid|
420  * |----------------|---------------|-------------|----|----|--|---|---|-----|
421  *
422  *
423  * | Act2 | Act1 |     Comment     | Operation                                                         |
424  * |------|------|-----------------|-------------------------------------------------------------------|
425  * |   0  |   0  | No op           | Don't care                                                        |
426  * |------|------|-----------------|-------------------------------------------------------------------|
427  * |   0  |   1  | Reserved        | Read this line and go to next one                                 |
428  * |------|------|-----------------|-------------------------------------------------------------------|
429  * |   1  |   0  | Transfer data   | Transfer data with address and length set in this descriptor line |
430  * |------|------|-----------------|-------------------------------------------------------------------|
431  * |   1  |   1  | Link descriptor | Link to another descriptor                                        |
432  * |------|------|-----------------|-------------------------------------------------------------------|
433  */
434 /*! @brief The bit shift for LENGTH field in ADMA2's descriptor */
435 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U)
436 /*! @brief The bit mask for LENGTH field in ADMA2's descriptor */
437 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
438 /*! @brief The maximum value of LENGTH field in ADMA2's descriptor */
439 #define USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK - 3U)
440 
441 /*! @brief ADMA1 descriptor control and status mask */
442 enum _usdhc_adma2_descriptor_flag
443 {
444     kUSDHC_Adma2DescriptorValidFlag = (1U << 0U),     /*!< Valid flag */
445     kUSDHC_Adma2DescriptorEndFlag = (1U << 1U),       /*!< End flag */
446     kUSDHC_Adma2DescriptorInterruptFlag = (1U << 2U), /*!< Interrupt flag */
447     kUSDHC_Adma2DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 mask */
448     kUSDHC_Adma2DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 mask */
449 
450     kUSDHC_Adma2DescriptorTypeNop = (kUSDHC_Adma2DescriptorValidFlag), /*!< No operation */
451     kUSDHC_Adma2DescriptorTypeReserved =
452         (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorValidFlag), /*!< Reserved */
453     kUSDHC_Adma2DescriptorTypeTransfer =
454         (kUSDHC_Adma2DescriptorActivity2Flag | kUSDHC_Adma2DescriptorValidFlag), /*!< Transfer type */
455     kUSDHC_Adma2DescriptorTypeLink = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorActivity2Flag |
456                                       kUSDHC_Adma2DescriptorValidFlag), /*!< Link type */
457 };
458 
459 /*! @brief dma transfer burst len config. */
460 typedef enum _usdhc_burst_len
461 {
462     kUSDHC_EnBurstLenForINCR = 0x01U,         /*!< enable burst len for INCR */
463     kUSDHC_EnBurstLenForINCR4816 = 0x02U,     /*!< enable burst len for INCR4/INCR8/INCR16 */
464     kUSDHC_EnBurstLenForINCR4816WRAP = 0x04U, /*!< enable burst len for INCR4/8/16 WRAP */
465 } usdhc_burst_len_t;
466 
467 /*! @brief Defines the adma1 descriptor structure. */
468 typedef uint32_t usdhc_adma1_descriptor_t;
469 
470 /*! @brief Defines the ADMA2 descriptor structure. */
471 typedef struct _usdhc_adma2_descriptor
472 {
473     uint32_t attribute;      /*!< The control and status field */
474     const uint32_t *address; /*!< The address field */
475 } usdhc_adma2_descriptor_t;
476 
477 /*!
478  * @brief USDHC capability information.
479  *
480  * Defines a structure to save the capability information of USDHC.
481  */
482 typedef struct _usdhc_capability
483 {
484     uint32_t sdVersion;      /*!< support SD card/sdio version */
485     uint32_t mmcVersion;     /*!< support emmc card version */
486     uint32_t maxBlockLength; /*!< Maximum block length united as byte */
487     uint32_t maxBlockCount;  /*!< Maximum block count can be set one time */
488     uint32_t flags;          /*!< Capability flags to indicate the support information(_usdhc_capability_flag) */
489 } usdhc_capability_t;
490 
491 /*! @brief Data structure to configure the MMC boot feature */
492 typedef struct _usdhc_boot_config
493 {
494     uint32_t ackTimeoutCount;      /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */
495     usdhc_boot_mode_t bootMode;    /*!< Boot mode selection. */
496     uint32_t blockCount;           /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */
497     bool enableBootAck;            /*!< Enable or disable boot ACK */
498     bool enableBoot;               /*!< Enable or disable fast boot */
499     bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period */
500 } usdhc_boot_config_t;
501 
502 /*! @brief Data structure to initialize the USDHC */
503 typedef struct _usdhc_config
504 {
505     uint32_t dataTimeout;           /*!< Data timeout value */
506     usdhc_endian_mode_t endianMode; /*!< Endian mode */
507     uint8_t readWatermarkLevel;     /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */
508     uint8_t writeWatermarkLevel;    /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */
509     uint8_t readBurstLen;           /*!< Read burst len */
510     uint8_t writeBurstLen;          /*!< Write burst len */
511 } usdhc_config_t;
512 
513 /*!
514  * @brief Card data descriptor
515  *
516  * Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card
517  * driver
518  * want to ignore the error event to read/write all the data not to stop read/write immediately when error event
519  * happen for example bus testing procedure for MMC card.
520  */
521 typedef struct _usdhc_data
522 {
523     bool enableAutoCommand12; /*!< Enable auto CMD12 */
524     bool enableAutoCommand23; /*!< Enable auto CMD23 */
525     bool enableIgnoreError;   /*!< Enable to ignore error event to read/write all the data */
526     bool executeTuning;       /*!< execute tuning flag */
527 
528     size_t blockSize;       /*!< Block size */
529     uint32_t blockCount;    /*!< Block count */
530     uint32_t *rxData;       /*!< Buffer to save data read */
531     const uint32_t *txData; /*!< Data buffer to write */
532 } usdhc_data_t;
533 
534 /*!
535  * @brief Card command descriptor
536  *
537  * Define card command-related attribute.
538  */
539 typedef struct _usdhc_command
540 {
541     uint32_t index;                          /*!< Command index */
542     uint32_t argument;                       /*!< Command argument */
543     usdhc_card_command_type_t type;          /*!< Command type */
544     usdhc_card_response_type_t responseType; /*!< Command response type */
545     uint32_t response[4U];                   /*!< Response for this command */
546     uint32_t responseErrorFlags;             /*!< response error flag, the flag which need to check
547                                                  the command reponse*/
548     uint32_t flags;                          /*!< Cmd flags */
549 } usdhc_command_t;
550 
551 /*! @brief ADMA configuration */
552 typedef struct _usdhc_adma_config
553 {
554     usdhc_dma_mode_t dmaMode; /*!< DMA mode */
555 
556     usdhc_burst_len_t burstLen; /*!< burst len config */
557 
558     uint32_t *admaTable;     /*!< ADMA table address, can't be null if transfer way is ADMA1/ADMA2 */
559     uint32_t admaTableWords; /*!< ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2 */
560 } usdhc_adma_config_t;
561 
562 /*! @brief Transfer state */
563 typedef struct _usdhc_transfer
564 {
565     usdhc_data_t *data;       /*!< Data to transfer */
566     usdhc_command_t *command; /*!< Command to send */
567 } usdhc_transfer_t;
568 
569 /*! @brief USDHC handle typedef */
570 typedef struct _usdhc_handle usdhc_handle_t;
571 
572 /*! @brief USDHC callback functions. */
573 typedef struct _usdhc_transfer_callback
574 {
575     void (*CardInserted)(void);  /*!< Card inserted occurs when DAT3/CD pin is for card detect */
576     void (*CardRemoved)(void);   /*!< Card removed occurs */
577     void (*SdioInterrupt)(void); /*!< SDIO card interrupt occurs */
578     void (*SdioBlockGap)(void);  /*!< SDIO card stopped at block gap occurs */
579     void (*TransferComplete)(USDHC_Type *base,
580                              usdhc_handle_t *handle,
581                              status_t status,
582                              void *userData); /*!< Transfer complete callback */
583     void (*ReTuning)(void);                   /*!< handle the re-tuning */
584 } usdhc_transfer_callback_t;
585 
586 /*!
587  * @brief USDHC handle
588  *
589  * Defines the structure to save the USDHC state information and callback function. The detailed interrupt status when
590  * sending a command or transfering data can be obtained from the interruptFlags field by using the mask defined in
591  * usdhc_interrupt_flag_t.
592  *
593  * @note All the fields except interruptFlags and transferredWords must be allocated by the user.
594  */
595 struct _usdhc_handle
596 {
597     /* Transfer parameter */
598     usdhc_data_t *volatile data;       /*!< Data to transfer */
599     usdhc_command_t *volatile command; /*!< Command to send */
600 
601     /* Transfer status */
602     volatile uint32_t interruptFlags;   /*!< Interrupt flags of last transaction */
603     volatile uint32_t transferredWords; /*!< Words transferred by DATAPORT way */
604 
605     /* Callback functions */
606     usdhc_transfer_callback_t callback; /*!< Callback function */
607     void *userData;                     /*!< Parameter for transfer complete callback */
608 };
609 
610 /*! @brief USDHC transfer function. */
611 typedef status_t (*usdhc_transfer_function_t)(USDHC_Type *base, usdhc_transfer_t *content);
612 
613 /*! @brief USDHC host descriptor */
614 typedef struct _usdhc_host
615 {
616     USDHC_Type *base;                   /*!< USDHC peripheral base address */
617     uint32_t sourceClock_Hz;            /*!< USDHC source clock frequency united in Hz */
618     usdhc_config_t config;              /*!< USDHC configuration */
619     usdhc_capability_t capability;      /*!< USDHC capability information */
620     usdhc_transfer_function_t transfer; /*!< USDHC transfer function */
621 } usdhc_host_t;
622 
623 /*************************************************************************************************
624  * API
625  ************************************************************************************************/
626 #if defined(__cplusplus)
627 extern "C" {
628 #endif
629 
630 /*!
631  * @name Initialization and deinitialization
632  * @{
633  */
634 
635 /*!
636  * @brief USDHC module initialization function.
637  *
638  * Configures the USDHC according to the user configuration.
639  *
640  * Example:
641    @code
642    usdhc_config_t config;
643    config.cardDetectDat3 = false;
644    config.endianMode = kUSDHC_EndianModeLittle;
645    config.dmaMode = kUSDHC_DmaModeAdma2;
646    config.readWatermarkLevel = 128U;
647    config.writeWatermarkLevel = 128U;
648    USDHC_Init(USDHC, &config);
649    @endcode
650  *
651  * @param base USDHC peripheral base address.
652  * @param config USDHC configuration information.
653  * @retval kStatus_Success Operate successfully.
654  */
655 void USDHC_Init(USDHC_Type *base, const usdhc_config_t *config);
656 
657 /*!
658  * @brief Deinitializes the USDHC.
659  *
660  * @param base USDHC peripheral base address.
661  */
662 void USDHC_Deinit(USDHC_Type *base);
663 
664 /*!
665  * @brief Resets the USDHC.
666  *
667  * @param base USDHC peripheral base address.
668  * @param mask The reset type mask(_usdhc_reset).
669  * @param timeout Timeout for reset.
670  * @retval true Reset successfully.
671  * @retval false Reset failed.
672  */
673 bool USDHC_Reset(USDHC_Type *base, uint32_t mask, uint32_t timeout);
674 
675 /* @} */
676 
677 /*!
678  * @name DMA Control
679  * @{
680  */
681 
682 /*!
683  * @brief Sets the ADMA descriptor table configuration.
684  *
685  * @param base USDHC peripheral base address.
686  * @param adma configuration
687  * @param data Data descriptor
688  * @param command flags
689  * @retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data.
690  * @retval kStatus_Success Operate successfully.
691  */
692 status_t USDHC_SetAdmaTableConfig(USDHC_Type *base,
693                                   usdhc_adma_config_t *dmaConfig,
694                                   usdhc_data_t *dataConfig,
695                                   uint32_t flags);
696 
697 /* @} */
698 
699 /*!
700  * @name Interrupts
701  * @{
702  */
703 
704 /*!
705  * @brief Enables the interrupt status.
706  *
707  * @param base USDHC peripheral base address.
708  * @param mask Interrupt status flags mask(_usdhc_interrupt_status_flag).
709  */
USDHC_EnableInterruptStatus(USDHC_Type * base,uint32_t mask)710 static inline void USDHC_EnableInterruptStatus(USDHC_Type *base, uint32_t mask)
711 {
712     base->INT_STATUS_EN |= mask;
713 }
714 
715 /*!
716  * @brief Disables the interrupt status.
717  *
718  * @param base USDHC peripheral base address.
719  * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag).
720  */
USDHC_DisableInterruptStatus(USDHC_Type * base,uint32_t mask)721 static inline void USDHC_DisableInterruptStatus(USDHC_Type *base, uint32_t mask)
722 {
723     base->INT_STATUS_EN &= ~mask;
724 }
725 
726 /*!
727  * @brief Enables the interrupt signal corresponding to the interrupt status flag.
728  *
729  * @param base USDHC peripheral base address.
730  * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag).
731  */
USDHC_EnableInterruptSignal(USDHC_Type * base,uint32_t mask)732 static inline void USDHC_EnableInterruptSignal(USDHC_Type *base, uint32_t mask)
733 {
734     base->INT_SIGNAL_EN |= mask;
735 }
736 
737 /*!
738  * @brief Disables the interrupt signal corresponding to the interrupt status flag.
739  *
740  * @param base USDHC peripheral base address.
741  * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag).
742  */
USDHC_DisableInterruptSignal(USDHC_Type * base,uint32_t mask)743 static inline void USDHC_DisableInterruptSignal(USDHC_Type *base, uint32_t mask)
744 {
745     base->INT_SIGNAL_EN &= ~mask;
746 }
747 
748 /* @} */
749 
750 /*!
751  * @name Status
752  * @{
753  */
754 
755 /*!
756  * @brief Gets the current interrupt status.
757  *
758  * @param base USDHC peripheral base address.
759  * @return Current interrupt status flags mask(_usdhc_interrupt_status_flag).
760  */
USDHC_GetInterruptStatusFlags(USDHC_Type * base)761 static inline uint32_t USDHC_GetInterruptStatusFlags(USDHC_Type *base)
762 {
763     return base->INT_STATUS;
764 }
765 
766 /*!
767  * @brief Clears a specified interrupt status.
768  * write 1 clears
769  * @param base USDHC peripheral base address.
770  * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag).
771  */
USDHC_ClearInterruptStatusFlags(USDHC_Type * base,uint32_t mask)772 static inline void USDHC_ClearInterruptStatusFlags(USDHC_Type *base, uint32_t mask)
773 {
774     base->INT_STATUS = mask;
775 }
776 
777 /*!
778  * @brief Gets the status of auto command 12 error.
779  *
780  * @param base USDHC peripheral base address.
781  * @return Auto command 12 error status flags mask(_usdhc_auto_command12_error_status_flag).
782  */
USDHC_GetAutoCommand12ErrorStatusFlags(USDHC_Type * base)783 static inline uint32_t USDHC_GetAutoCommand12ErrorStatusFlags(USDHC_Type *base)
784 {
785     return base->AUTOCMD12_ERR_STATUS;
786 }
787 
788 /*!
789  * @brief Gets the status of the ADMA error.
790  *
791  * @param base USDHC peripheral base address.
792  * @return ADMA error status flags mask(_usdhc_adma_error_status_flag).
793  */
USDHC_GetAdmaErrorStatusFlags(USDHC_Type * base)794 static inline uint32_t USDHC_GetAdmaErrorStatusFlags(USDHC_Type *base)
795 {
796     return base->ADMA_ERR_STATUS;
797 }
798 
799 /*!
800  * @brief Gets a present status.
801  *
802  * This function gets the present USDHC's status except for an interrupt status and an error status.
803  *
804  * @param base USDHC peripheral base address.
805  * @return Present USDHC's status flags mask(_usdhc_present_status_flag).
806  */
USDHC_GetPresentStatusFlags(USDHC_Type * base)807 static inline uint32_t USDHC_GetPresentStatusFlags(USDHC_Type *base)
808 {
809     return base->PRES_STATE;
810 }
811 
812 /* @} */
813 
814 /*!
815  * @name Bus Operations
816  * @{
817  */
818 
819 /*!
820  * @brief Gets the capability information.
821  *
822  * @param base USDHC peripheral base address.
823  * @param capability Structure to save capability information.
824  */
825 void USDHC_GetCapability(USDHC_Type *base, usdhc_capability_t *capability);
826 
827 /*!
828  * @brief force the card clock on.
829  *
830  * @param base USDHC peripheral base address.
831  * @param enable/disable flag.
832  */
USDHC_ForceClockOn(USDHC_Type * base,bool enable)833 static inline void USDHC_ForceClockOn(USDHC_Type *base, bool enable)
834 {
835     if (enable)
836     {
837         base->VEND_SPEC |= USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
838     }
839     else
840     {
841         base->VEND_SPEC &= ~USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
842     }
843 }
844 
845 /*!
846  * @brief Sets the SD bus clock frequency.
847  *
848  * @param base USDHC peripheral base address.
849  * @param srcClock_Hz USDHC source clock frequency united in Hz.
850  * @param busClock_Hz SD bus clock frequency united in Hz.
851  *
852  * @return The nearest frequency of busClock_Hz configured to SD bus.
853  */
854 uint32_t USDHC_SetSdClock(USDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz);
855 
856 /*!
857  * @brief Sends 80 clocks to the card to set it to the active state.
858  *
859  * This function must be called each time the card is inserted to ensure that the card can receive the command
860  * correctly.
861  *
862  * @param base USDHC peripheral base address.
863  * @param timeout Timeout to initialize card.
864  * @retval true Set card active successfully.
865  * @retval false Set card active failed.
866  */
867 bool USDHC_SetCardActive(USDHC_Type *base, uint32_t timeout);
868 
869 /*!
870  * @brief trigger a hardware reset.
871  *
872  * @param base USDHC peripheral base address.
873  * @param 1 or 0 level
874  */
USDHC_AssertHardwareReset(USDHC_Type * base,bool high)875 static inline void USDHC_AssertHardwareReset(USDHC_Type *base, bool high)
876 {
877     if (high)
878     {
879         base->SYS_CTRL |= USDHC_SYS_CTRL_IPP_RST_N_MASK;
880     }
881     else
882     {
883         base->SYS_CTRL &= ~USDHC_SYS_CTRL_IPP_RST_N_MASK;
884     }
885 }
886 
887 /*!
888  * @brief Sets the data transfer width.
889  *
890  * @param base USDHC peripheral base address.
891  * @param width Data transfer width.
892  */
USDHC_SetDataBusWidth(USDHC_Type * base,usdhc_data_bus_width_t width)893 static inline void USDHC_SetDataBusWidth(USDHC_Type *base, usdhc_data_bus_width_t width)
894 {
895     base->PROT_CTRL = ((base->PROT_CTRL & ~USDHC_PROT_CTRL_DTW_MASK) | USDHC_PROT_CTRL_DTW(width));
896 }
897 
898 /*!
899  * @brief Fills the the data port.
900  *
901  * This function is used to implement the data transfer by Data Port instead of DMA.
902  *
903  * @param base USDHC peripheral base address.
904  * @param data The data about to be sent.
905  */
USDHC_WriteData(USDHC_Type * base,uint32_t data)906 static inline void USDHC_WriteData(USDHC_Type *base, uint32_t data)
907 {
908     base->DATA_BUFF_ACC_PORT = data;
909 }
910 
911 /*!
912  * @brief Retrieves the data from the data port.
913  *
914  * This function is used to implement the data transfer by Data Port instead of DMA.
915  *
916  * @param base USDHC peripheral base address.
917  * @return The data has been read.
918  */
USDHC_ReadData(USDHC_Type * base)919 static inline uint32_t USDHC_ReadData(USDHC_Type *base)
920 {
921     return base->DATA_BUFF_ACC_PORT;
922 }
923 
924 /*!
925 * @brief send command function
926 *
927 * @param base USDHC peripheral base address.
928 * @param command configuration
929 */
930 void USDHC_SendCommand(USDHC_Type *base, usdhc_command_t *command);
931 
932 /*!
933  * @brief Enables or disables a wakeup event in low-power mode.
934  *
935  * @param base USDHC peripheral base address.
936  * @param mask Wakeup events mask(_usdhc_wakeup_event).
937  * @param enable True to enable, false to disable.
938  */
USDHC_EnableWakeupEvent(USDHC_Type * base,uint32_t mask,bool enable)939 static inline void USDHC_EnableWakeupEvent(USDHC_Type *base, uint32_t mask, bool enable)
940 {
941     if (enable)
942     {
943         base->PROT_CTRL |= mask;
944     }
945     else
946     {
947         base->PROT_CTRL &= ~mask;
948     }
949 }
950 
951 /*!
952  * @brief detect card insert status.
953  *
954  * @param base USDHC peripheral base address.
955  * @param enable/disable flag
956  */
USDHC_CardDetectByData3(USDHC_Type * base,bool enable)957 static inline void USDHC_CardDetectByData3(USDHC_Type *base, bool enable)
958 {
959     if (enable)
960     {
961         base->PROT_CTRL |= USDHC_PROT_CTRL_D3CD_MASK;
962     }
963     else
964     {
965         base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK;
966     }
967 }
968 
969 /*!
970  * @brief detect card insert status.
971  *
972  * @param base USDHC peripheral base address.
973  */
USDHC_DetectCardInsert(USDHC_Type * base)974 static inline bool USDHC_DetectCardInsert(USDHC_Type *base)
975 {
976     return (base->PRES_STATE & kUSDHC_CardInsertedFlag) ? true : false;
977 }
978 
979 /*!
980  * @brief Enables or disables the SDIO card control.
981  *
982  * @param base USDHC peripheral base address.
983  * @param mask SDIO card control flags mask(_usdhc_sdio_control_flag).
984  * @param enable True to enable, false to disable.
985  */
USDHC_EnableSdioControl(USDHC_Type * base,uint32_t mask,bool enable)986 static inline void USDHC_EnableSdioControl(USDHC_Type *base, uint32_t mask, bool enable)
987 {
988     if (enable)
989     {
990         base->PROT_CTRL |= mask;
991     }
992     else
993     {
994         base->PROT_CTRL &= ~mask;
995     }
996 }
997 /*!
998  * @brief Restarts a transaction which has stopped at the block GAP for the SDIO card.
999  *
1000  * @param base USDHC peripheral base address.
1001  */
USDHC_SetContinueRequest(USDHC_Type * base)1002 static inline void USDHC_SetContinueRequest(USDHC_Type *base)
1003 {
1004     base->PROT_CTRL |= USDHC_PROT_CTRL_CREQ_MASK;
1005 }
1006 
1007 /*!
1008  * @brief Configures the MMC boot feature.
1009  *
1010  * Example:
1011    @code
1012    usdhc_boot_config_t config;
1013    config.ackTimeoutCount = 4;
1014    config.bootMode = kUSDHC_BootModeNormal;
1015    config.blockCount = 5;
1016    config.enableBootAck = true;
1017    config.enableBoot = true;
1018    config.enableAutoStopAtBlockGap = true;
1019    USDHC_SetMmcBootConfig(USDHC, &config);
1020    @endcode
1021  *
1022  * @param base USDHC peripheral base address.
1023  * @param config The MMC boot configuration information.
1024  */
1025 void USDHC_SetMmcBootConfig(USDHC_Type *base, const usdhc_boot_config_t *config);
1026 
1027 /*!
1028  * @brief Forces generating events according to the given mask.
1029  *
1030  * @param base USDHC peripheral base address.
1031  * @param mask The force events mask(_usdhc_force_event).
1032  */
USDHC_SetForceEvent(USDHC_Type * base,uint32_t mask)1033 static inline void USDHC_SetForceEvent(USDHC_Type *base, uint32_t mask)
1034 {
1035     base->FORCE_EVENT = mask;
1036 }
1037 
1038 /*!
1039  * @brief select the usdhc output voltage
1040  *
1041  * @param base USDHC peripheral base address.
1042  * @param true 1.8V, false 3.0V
1043  */
UDSHC_SelectVoltage(USDHC_Type * base,bool en18v)1044 static inline void UDSHC_SelectVoltage(USDHC_Type *base, bool en18v)
1045 {
1046     if (en18v)
1047     {
1048         base->VEND_SPEC |= USDHC_VEND_SPEC_VSELECT_MASK;
1049     }
1050     else
1051     {
1052         base->VEND_SPEC &= ~USDHC_VEND_SPEC_VSELECT_MASK;
1053     }
1054 }
1055 
1056 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
1057 #else
1058                                                                    /*!
1059                                                                     * @brief check the SDR50 mode request tuning bit
1060                                                                     * When this bit set, user should call USDHC_StandardTuning function
1061                                                                     * @param base USDHC peripheral base address.
1062                                                                     */
USDHC_RequestTuningForSDR50(USDHC_Type * base)1063 static inline bool USDHC_RequestTuningForSDR50(USDHC_Type *base)
1064 {
1065     return base->HOST_CTRL_CAP & USDHC_HOST_CTRL_CAP_USE_TUNING_SDR50_MASK ? true : false;
1066 }
1067 
1068 /*!
1069  * @brief check the request re-tuning bit
1070  * When this bit is set, user should do manual tuning or standard tuning function
1071  * @param base USDHC peripheral base address.
1072  */
USDHC_RequestReTuning(USDHC_Type * base)1073 static inline bool USDHC_RequestReTuning(USDHC_Type *base)
1074 {
1075     return base->PRES_STATE & USDHC_PRES_STATE_RTR_MASK ? true : false;
1076 }
1077 
1078 /*!
1079  * @brief the SDR104 mode auto tuning enable and disable
1080  * This function should call after tuning function execute pass, auto tuning will handle
1081  * by hardware
1082  * @param base USDHC peripheral base address.
1083  * @param enable/disable flag
1084  */
USDHC_EnableAutoTuning(USDHC_Type * base,bool enable)1085 static inline void USDHC_EnableAutoTuning(USDHC_Type *base, bool enable)
1086 {
1087     if (enable)
1088     {
1089         base->MIX_CTRL |= USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK;
1090     }
1091     else
1092     {
1093         base->MIX_CTRL &= ~USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK;
1094     }
1095 }
1096 
1097 /*!
1098  * @brief the config the re-tuning timer for mode 1 and mode 3
1099  * This timer is used for standard tuning auto re-tuning,
1100  * @param base USDHC peripheral base address.
1101  * @param timer counter value
1102  */
USDHC_SetRetuningTimer(USDHC_Type * base,uint32_t counter)1103 static inline void USDHC_SetRetuningTimer(USDHC_Type *base, uint32_t counter)
1104 {
1105     base->HOST_CTRL_CAP &= ~USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING_MASK;
1106     base->HOST_CTRL_CAP |= USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING(counter);
1107 }
1108 
1109 /*!
1110  * @brief the auto tuning enbale for CMD/DATA line
1111  *
1112  * @param base USDHC peripheral base address.
1113  */
1114 void USDHC_EnableAutoTuningForCmdAndData(USDHC_Type *base);
1115 
1116 /*!
1117  * @brief manual tuning trigger or abort
1118  * User should handle the tuning cmd and find the boundary of the delay
1119  * then calucate a average value which will be config to the CLK_TUNE_CTRL_STATUS
1120  * This function should called before USDHC_AdjustDelayforSDR104 function
1121  * @param base USDHC peripheral base address.
1122  * @param tuning enable flag
1123  */
1124 void USDHC_EnableManualTuning(USDHC_Type *base, bool enable);
1125 
1126 /*!
1127  * @brief the SDR104 mode delay setting adjust
1128  * This function should called after USDHC_ManualTuningForSDR104
1129  * @param base USDHC peripheral base address.
1130  * @param delay setting configuration
1131  * @retval kStatus_Fail config the delay setting fail
1132  * @retval kStatus_Success config the delay setting success
1133  */
1134 status_t USDHC_AdjustDelayForManualTuning(USDHC_Type *base, uint32_t delay);
1135 
1136 /*!
1137  * @brief the enable standard tuning function
1138  * The standard tuning window and tuning counter use the default config
1139  * tuning cmd is send by the software, user need to check the tuning result
1140  * can be used for SDR50,SDR104,HS200 mode tuning
1141  * @param base USDHC peripheral base address.
1142  * @param tuning start tap
1143  * @param tuning step
1144  * @param enable/disable flag
1145  */
1146 void USDHC_EnableStandardTuning(USDHC_Type *base, uint32_t tuningStartTap, uint32_t step, bool enable);
1147 
1148 /*!
1149  * @brief Get execute std tuning status
1150  *
1151  * @param base USDHC peripheral base address.
1152  */
USDHC_GetExecuteStdTuningStatus(USDHC_Type * base)1153 static inline uint32_t USDHC_GetExecuteStdTuningStatus(USDHC_Type *base)
1154 {
1155     return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK);
1156 }
1157 
1158 /*!
1159  * @brief check std tuning result
1160  *
1161  * @param base USDHC peripheral base address.
1162  */
USDHC_CheckStdTuningResult(USDHC_Type * base)1163 static inline uint32_t USDHC_CheckStdTuningResult(USDHC_Type *base)
1164 {
1165     return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK);
1166 }
1167 
1168 /*!
1169  * @brief check tuning error
1170  *
1171  * @param base USDHC peripheral base address.
1172  */
USDHC_CheckTuningError(USDHC_Type * base)1173 static inline uint32_t USDHC_CheckTuningError(USDHC_Type *base)
1174 {
1175     return (base->CLK_TUNE_CTRL_STATUS &
1176             (USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK | USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK));
1177 }
1178 
1179 #endif
1180 /*!
1181  * @brief the enable/disable DDR mode
1182  *
1183  * @param base USDHC peripheral base address.
1184  * @param enable/disable flag
1185  * @param nibble position
1186  */
USDHC_EnableDDRMode(USDHC_Type * base,bool enable,uint32_t nibblePos)1187 static inline void USDHC_EnableDDRMode(USDHC_Type *base, bool enable, uint32_t nibblePos)
1188 {
1189     if (enable)
1190     {
1191         base->MIX_CTRL &= ~USDHC_MIX_CTRL_NIBBLE_POS_MASK;
1192         base->MIX_CTRL |= (USDHC_MIX_CTRL_DDR_EN_MASK | USDHC_MIX_CTRL_NIBBLE_POS(nibblePos));
1193     }
1194     else
1195     {
1196         base->MIX_CTRL &= ~USDHC_MIX_CTRL_DDR_EN_MASK;
1197     }
1198 }
1199 
1200 /*!
1201  * @brief the enable/disable HS400 mode
1202  *
1203  * @param base USDHC peripheral base address.
1204  * @param enable/disable flag
1205  */
1206 #if FSL_FEATURE_USDHC_HAS_HS400_MODE
USDHC_EnableHS400Mode(USDHC_Type * base,bool enable)1207 static inline void USDHC_EnableHS400Mode(USDHC_Type *base, bool enable)
1208 {
1209     if (enable)
1210     {
1211         base->MIX_CTRL |= USDHC_MIX_CTRL_HS400_MODE_MASK;
1212     }
1213     else
1214     {
1215         base->MIX_CTRL &= ~USDHC_MIX_CTRL_HS400_MODE_MASK;
1216     }
1217 }
1218 
1219 /*!
1220  * @brief reset the strobe DLL
1221  *
1222  * @param base USDHC peripheral base address.
1223  */
USDHC_ResetStrobeDLL(USDHC_Type * base)1224 static inline void USDHC_ResetStrobeDLL(USDHC_Type *base)
1225 {
1226     base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_RESET_MASK;
1227 }
1228 
1229 /*!
1230  * @brief enable/disable the strobe DLL
1231  *
1232  * @param base USDHC peripheral base address.
1233  * @param enable/disable flag
1234  */
USDHC_EnableStrobeDLL(USDHC_Type * base,bool enable)1235 static inline void USDHC_EnableStrobeDLL(USDHC_Type *base, bool enable)
1236 {
1237     if (enable)
1238     {
1239         base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK;
1240     }
1241     else
1242     {
1243         base->STROBE_DLL_CTRL &= ~USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK;
1244     }
1245 }
1246 
1247 /*!
1248  * @brief config the strobe DLL delay target and update interval
1249  *
1250  * @param base USDHC peripheral base address.
1251  * @param delay target
1252  * @param update interval
1253  */
USDHC_ConfigStrobeDLL(USDHC_Type * base,uint32_t delayTarget,uint32_t updateInterval)1254 static inline void USDHC_ConfigStrobeDLL(USDHC_Type *base, uint32_t delayTarget, uint32_t updateInterval)
1255 {
1256     base->STROBE_DLL_CTRL &= (USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_UPDATE_INT_MASK |
1257                               USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_DLY_TARGET_MASK);
1258 
1259     base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_UPDATE_INT(updateInterval) |
1260                              USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_DLY_TARGET(delayTarget);
1261 }
1262 
1263 /*!
1264  * @brief get the strobe DLL status
1265  *
1266  * @param base USDHC peripheral base address.
1267  */
USDHC_GetStrobeDLLStatus(USDHC_Type * base)1268 static inline uint32_t USDHC_GetStrobeDLLStatus(USDHC_Type *base)
1269 {
1270     return base->STROBE_DLL_STATUS;
1271 }
1272 
1273 #endif
1274 
1275 /* @} */
1276 
1277 /*!
1278  * @name Transactional
1279  * @{
1280  */
1281 
1282 /*!
1283  * @brief Transfers the command/data using a blocking method.
1284  *
1285  * This function waits until the command response/data is received or the USDHC encounters an error by polling the
1286  * status
1287  * flag.
1288  * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
1289  * the re-entry mechanism.
1290  *
1291  * @note There is no need to call the API 'USDHC_TransferCreateHandle' when calling this API.
1292  *
1293  * @param base USDHC peripheral base address.
1294  * @param adma configuration
1295  * @param transfer Transfer content.
1296  * @retval kStatus_InvalidArgument Argument is invalid.
1297  * @retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1298  * @retval kStatus_USDHC_SendCommandFailed Send command failed.
1299  * @retval kStatus_USDHC_TransferDataFailed Transfer data failed.
1300  * @retval kStatus_Success Operate successfully.
1301  */
1302 status_t USDHC_TransferBlocking(USDHC_Type *base, usdhc_adma_config_t *dmaConfig, usdhc_transfer_t *transfer);
1303 
1304 /*!
1305  * @brief Creates the USDHC handle.
1306  *
1307  * @param base USDHC peripheral base address.
1308  * @param handle USDHC handle pointer.
1309  * @param callback Structure pointer to contain all callback functions.
1310  * @param userData Callback function parameter.
1311  */
1312 void USDHC_TransferCreateHandle(USDHC_Type *base,
1313                                 usdhc_handle_t *handle,
1314                                 const usdhc_transfer_callback_t *callback,
1315                                 void *userData);
1316 
1317 /*!
1318  * @brief Transfers the command/data using an interrupt and an asynchronous method.
1319  *
1320  * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an
1321  * error.
1322  * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
1323  * the re-entry mechanism.
1324  *
1325  * @note Call the API 'USDHC_TransferCreateHandle' when calling this API.
1326  *
1327  * @param base USDHC peripheral base address.
1328  * @param handle USDHC handle.
1329  * @param adma configuration.
1330  * @param transfer Transfer content.
1331  * @retval kStatus_InvalidArgument Argument is invalid.
1332  * @retval kStatus_USDHC_BusyTransferring Busy transferring.
1333  * @retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed.
1334  * @retval kStatus_Success Operate successfully.
1335  */
1336 status_t USDHC_TransferNonBlocking(USDHC_Type *base,
1337                                    usdhc_handle_t *handle,
1338                                    usdhc_adma_config_t *dmaConfig,
1339                                    usdhc_transfer_t *transfer);
1340 
1341 /*!
1342  * @brief IRQ handler for the USDHC.
1343  *
1344  * This function deals with the IRQs on the given host controller.
1345  *
1346  * @param base USDHC peripheral base address.
1347  * @param handle USDHC handle.
1348  */
1349 void USDHC_TransferHandleIRQ(USDHC_Type *base, usdhc_handle_t *handle);
1350 
1351 /* @} */
1352 
1353 #if defined(__cplusplus)
1354 }
1355 #endif
1356 /*! @} */
1357 
1358 #endif /* _FSL_USDHC_H_*/
1359