1 
2 /**
3  * @file xmc_sdmmc.h
4  * @date 2019-05-07
5  *
6  * @cond
7  *********************************************************************************************************************
8  * XMClib v2.1.24 - XMC Peripheral Driver Library
9  *
10  * Copyright (c) 2015-2019, Infineon Technologies AG
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
14  * following conditions are met:
15  *
16  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
17  * disclaimer.
18  *
19  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
20  * disclaimer in the documentation and/or other materials provided with the distribution.
21  *
22  * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
23  * products derived from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
34  * Infineon Technologies AG dave@infineon.com).
35  *********************************************************************************************************************
36  *
37  * Change History
38  * --------------
39  *
40  * 2015-02-20:
41  *     - Initial version
42  *     - Documentation updates
43  *
44  * 2015-06-20:
45  *     - Removed version macros and declaration of GetDriverVersion API <br>
46  *
47  * 2016-01-16:
48  *     - Added the following APIs to the XMC_SDMMC low level driver <br>
49  *         1) XMC_SDMMC_EnableDelayCmdDatLines <br>
50  *         2) XMC_SDMMC_DisableDelayCmdDatLines <br>
51  *         3) XMC_SDMMC_SetDelay <br>
52  *         4) XMC_SDMMC_EnableHighSpeed <br>
53  *         5) XMC_SDMMC_DisableHighSpeed <br>
54  *
55  * 2016-04-07:
56  *     - Added XMC_SDMMC_COMMAND_RESPONSE_t <br>
57  *
58  * 2016-07-11:
59  *     - Adjust masks for the following functions: <br>
60  *       1) XMC_SDMMC_SetBusVoltage <br>
61  *       2) XMC_SDMMC_SetDataLineTimeout <br>
62  *       3) XMC_SDMMC_SDClockFreqSelect <br>
63  *
64  * 2017-02-14:
65  *     - Added: <br>
66  *       1) XMC_SDMMC_SetCardDetectionStatus() <br>
67  *       2) XMC_SDMMC_SetCardDetectionSource() <br>
68  *
69  * 2018-08-29:
70  *     - XMC_SDMMC_SetCardDetectionStatus() and XMC_SDMMC_SetCardDetectionSource()
71  *       Changed for XMC43/XMC47/XMC48 to use SDMMC Write Protection and Card Detection Control register instead of the test register of SDMMC host controller
72  *     - Added for XMC43/XMC47/XMC48:
73  *       1) XMC_SDMMC_SetWriteProtectionSource()
74  *       2) XMC_SDMMC_SetWriteProtectionStatus()
75  *
76  * 2019-05-07:
77  *     - Fix compilation issues on XMC45
78  *     - Fix compilation warnings
79  *
80  * @endcond
81  */
82 
83 #ifndef XMC_SDMMC_H
84 #define XMC_SDMMC_H
85 
86 /*******************************************************************************
87  * HEADER FILES
88  *******************************************************************************/
89 
90 #include "xmc_common.h"
91 
92 #if defined (SDMMC)
93 
94 #if (UC_SERIES != XMC45)
95 #define SDMMC_CON_WPSEL_Pos  0
96 #define SDMMC_CON_WPSEL_Msk  0x00000001UL
97 #define SDMMC_CON_WPSVAL_Pos 4
98 #define SDMMC_CON_WPSVAL_Msk 0x00000010UL
99 #define SDMMC_CON_CDSEL_Pos  16
100 #define SDMMC_CON_CDSEL_Msk  0x00010000UL
101 #define SDMMC_CON_CDSVAL_Pos 20
102 #define SDMMC_CON_CDSVAL_Msk 0x00100000UL
103 #endif
104 
105 /**
106  * @addtogroup XMClib XMC Peripheral Library
107  * @{
108  */
109 
110 /**
111  * @addtogroup SDMMC
112  * @brief Secure Digital/Multi Media Card (SDMMC) driver for the XMC4500 microcontroller
113  *
114  * The SDMMC peripheral provides an interface between SD/SDIO/MMC cards and the AHB. It handles
115  * the SD/SDIO protocol at transmission level. It automatically packs data and checks for CRC,
116  * start/end bits and format correctness. For SD cards, a maximum transfer rate of 24MB/sec is
117  * supported and for MMC cards, 48MB/sec.
118  *
119  * The peripheral can be used for applications that require large storage memory; e.g. Data logging,
120  * firmware updates or an embedded database.
121  *
122  * The SDMMC low level driver provides functions to configure and initialize the SDMMC hardware
123  * peripheral.
124  * @{
125  */
126 
127 /*******************************************************************************
128  * MACROS
129  *******************************************************************************/
130 
131 /**
132  * A convenient symbol for the SDMMC peripheral base address
133  */
134 #if defined (SDMMC)
135 # define XMC_SDMMC ((XMC_SDMMC_t *)SDMMC_BASE)
136 #else
137 # error 'SDMMC' base peripheral pointer not defined
138 #endif
139 
140 /*
141  * Check for valid ACMD errors <br>
142  *
143  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
144  */
145 #define XMC_SDMMC_CHECK_MODULE_PTR(p) ((p) == XMC_SDMMC)
146 
147 /*
148  * Check for valid ACMD errors <br>
149  *
150  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
151  */
152 #define XMC_SDMMC_CHECK_ACMD_ERR(v)\
153   ((v == XMC_SDMMC_ACMD12_NOT_EXEC_ERR) ||\
154    (v == XMC_SDMMC_ACMD_TIMEOUT_ERR)    ||\
155    (v == XMC_SDMMC_ACMD_CRC_ERR)        ||\
156    (v == XMC_SDMMC_ACMD_END_BIT_ERR)    ||\
157    (v == XMC_SDMMC_ACMD_IND_ERR)        ||\
158    (v == XMC_SDMMC_CMD_NOT_ISSUED_BY_ACMD12_ERR))
159 
160 /*
161  * Check for valid SDCLK divider frequency <br>
162  *
163  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
164  */
165 #define XMC_SDMMC_CHECK_SDCLK_FREQ(f)\
166   ((f == XMC_SDMMC_CLK_DIV_1)           ||\
167    (f == XMC_SDMMC_CLK_DIV_2)           ||\
168    (f == XMC_SDMMC_CLK_DIV_4)           ||\
169    (f == XMC_SDMMC_CLK_DIV_8)           ||\
170    (f == XMC_SDMMC_CLK_DIV_16)          ||\
171    (f == XMC_SDMMC_CLK_DIV_32)          ||\
172    (f == XMC_SDMMC_CLK_DIV_64)          ||\
173    (f == XMC_SDMMC_CLK_DIV_128)         ||\
174    (f == XMC_SDMMC_CLK_DIV_256))
175 
176 /*
177  * Check for valid bus voltage levels <br>
178  *
179  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
180  */
181 #define XMC_SDMMC_CHECK_BUS_VOLTAGE(v)\
182   (v == XMC_SDMMC_BUS_VOLTAGE_3_3_VOLTS)
183 
184 /*
185  * Check for valid data timeout counter values <br>
186  *
187  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
188  */
189 #define XMC_SDMMC_CHECK_DAT_TIMEOUT_COUNTER(c)\
190   ((c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_13) ||\
191    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_14) ||\
192    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_15) ||\
193    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_16) ||\
194    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_17) ||\
195    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_18) ||\
196    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_19) ||\
197    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_20) ||\
198    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_21) ||\
199    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_22) ||\
200    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_23) ||\
201    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_24) ||\
202    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_25) ||\
203    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_26) ||\
204    (c == XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_27))
205 
206 /*
207  * Valid number of data lines <br>
208  *
209  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
210  */
211 #define XMC_SDMMC_CHECK_DATA_LINES(l)\
212   ((l == XMC_SDMMC_DATA_LINES_1)        ||\
213    (l == XMC_SDMMC_DATA_LINES_4)        ||\
214    (l == XMC_SDMMC_DATA_LINES_8))
215 
216 /*
217  * Check data transfer dir: Host to card and vice-versa <br>
218  *
219  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
220  */
221 #define XMC_SDMMC_CHECK_DATA_TRANSFER_DIR(d)\
222   ((d == XMC_SDMMC_DATA_TRANSFER_HOST_TO_CARD)   ||\
223    (d == XMC_SDMMC_DATA_TRANSFER_CARD_TO_HOST))
224 
225 /*
226  * Min and max number of delay elements <br>
227  *
228  * This macro is used in the LLD for assertion checks (XMC_ASSERT).
229  */
230 #define XMC_SDMMC_MIN_DELAY_ELEMENTS (0U)
231 #define XMC_SDMMC_MAX_DELAY_ELEMENTS (15U)
232 
233 /*******************************************************************************
234  * ENUMS
235  *******************************************************************************/
236 
237 /**
238  * Number of data lines for SDMMC data transfer
239  */
240 typedef enum XMC_SDMMC_DATA_LINES
241 {
242   XMC_SDMMC_DATA_LINES_1 = 0x00U, /**< Single data line mode */
243   XMC_SDMMC_DATA_LINES_4 = 0x02U, /**< 4-bit mode */
244   XMC_SDMMC_DATA_LINES_8 = 0x20U  /**< SD 8-bit mode */
245 } XMC_SDMMC_DATA_LINES_t;
246 
247 /**
248  * Valid SD clock frequency divider selection
249  */
250 typedef enum XMC_SDMMC_SDCLK_FREQ_SEL
251 {
252   XMC_SDMMC_CLK_DIV_1   = 0x00U, /**< Base clock (10 Mhz -> 63 Mhz) */
253   XMC_SDMMC_CLK_DIV_2   = 0x01U, /**< Base clock divided by 2 */
254   XMC_SDMMC_CLK_DIV_4   = 0x02U, /**< Base clock divided by 4 */
255   XMC_SDMMC_CLK_DIV_8   = 0x04U, /**< Base clock divided by 8 */
256   XMC_SDMMC_CLK_DIV_16  = 0x08U, /**< Base clock divided by 16 */
257   XMC_SDMMC_CLK_DIV_32  = 0x10U, /**< Base clock divided by 32 */
258   XMC_SDMMC_CLK_DIV_64  = 0x20U, /**< Base clock divided by 64 */
259   XMC_SDMMC_CLK_DIV_128 = 0x40U, /**< Base clock divided by 128 */
260   XMC_SDMMC_CLK_DIV_256 = 0x80U  /**< Base clock divided by 256 */
261 } XMC_SDMMC_SDCLK_FREQ_SEL_t;
262 
263 /**
264  * Status return values for the SDMMC low level driver
265  */
266 typedef enum XMC_SDMMC_STATUS
267 {
268   XMC_SDMMC_STATUS_SUCCESS       = 0U, /**< Operation successful */
269   XMC_SDMMC_STATUS_CMD_LINE_BUSY,      /**< Command line busy */
270   XMC_SDMMC_STATUS_DAT_LINE_BUSY       /**< Data line busy */
271 } XMC_SDMMC_STATUS_t;
272 
273 /**
274  * SDMMC events (Normal and error events)
275  */
276 typedef enum XMC_SDMMC_EVENT
277 {
278   XMC_SDMMC_CMD_COMPLETE       = 0x01U, /**< Command complete event */
279   XMC_SDMMC_TX_COMPLETE        = 0x02U, /**< Transmit complete event */
280   XMC_SDMMC_BLOCK_GAP_EVENT    = 0x04U, /**< Block gap event */
281   XMC_SDMMC_BUFFER_WRITE_READY = 0x10U, /**< Buffer write ready event */
282   XMC_SDMMC_BUFFER_READ_READY  = 0x20U, /**< Buffer read ready event */
283   XMC_SDMMC_CARD_INS           = 0x40U, /**< Card insert event */
284   XMC_SDMMC_CARD_REMOVAL       = 0x80U, /**< Card removal event */
285   XMC_SDMMC_CARD_INT           = 0x100U, /**< Card INT event */
286   XMC_SDMMC_CARD_ERR           = 0x8000U, /**< Card error interrupt */
287   XMC_SDMMC_CMD_TIMEOUT_ERR    = ((uint32_t)0x01 << 16U),   /**< Command time-out error */
288   XMC_SDMMC_CMD_CRC_ERR        = ((uint32_t)0x02U << 16U),  /**< Command CRC error */
289   XMC_SDMMC_CMD_END_BIT_ERR    = ((uint32_t)0x04U << 16U),  /**< Command end bit error */
290   XMC_SDMMC_CMD_IND_ERR        = ((uint32_t)0x08U << 16U),  /**< Command index error */
291   XMC_SDMMC_DATA_TIMEOUT_ERR   = ((uint32_t)0x10U << 16U),  /**< Data time-out error */
292   XMC_SDMMC_DATA_CRC_ERR       = ((uint32_t)0x20U << 16U),  /**< Data CRC error */
293   XMC_SDMMC_DATA_END_BIT_ERR   = ((uint32_t)0x40U << 16U),  /**< Data end bit error */
294   XMC_SDMMC_CURRENT_LIMIT_ERR  = ((uint32_t)0x80U << 16U),  /**< Current limit error */
295   XMC_SDMMC_ACMD_ERR           = ((uint32_t)0x100U << 16U), /**< ACMD error */
296   XMC_SDMMC_TARGET_RESP_ERR    = ((uint32_t)0x1000U << 16U) /**< Target response error */
297 } XMC_SDMMC_EVENT_t;
298 
299 /**
300  * SDMMC wakeup events
301  */
302 typedef enum XMC_SDMMC_WAKEUP_EVENT
303 {
304   XMC_SDMMC_WAKEUP_EN_CARD_INT = SDMMC_WAKEUP_CTRL_WAKEUP_EVENT_EN_INT_Msk, /**< Wakeup on card interrupt */
305   XMC_SDMMC_WAKEUP_EN_CARD_INS = SDMMC_WAKEUP_CTRL_WAKEUP_EVENT_EN_INS_Msk, /**< Wakeup on SD card insertion */
306   XMC_SDMMC_WAKEUP_EN_CARD_REM = SDMMC_WAKEUP_CTRL_WAKEUP_EVENT_EN_REM_Msk  /**< Wakeup SD card removal */
307 } XMC_SDMMC_WAKEUP_EVENT_t;
308 
309 /**
310  * SDMMC software reset modes
311  */
312 typedef enum XMC_SDMMC_SW_RESET
313 {
314   XMC_SDMMC_SW_RESET_ALL    = SDMMC_SW_RESET_SW_RST_ALL_Msk,      /**< Software reset all */
315   XMC_SDMMC_SW_RST_CMD_LINE = SDMMC_SW_RESET_SW_RST_CMD_LINE_Msk, /**< Software reset command line */
316   XMC_SDMMC_SW_RST_DAT_LINE = SDMMC_SW_RESET_SW_RST_DAT_LINE_Msk  /**< Software reset data line */
317 } XMC_SDMMC_SW_RESET_t;
318 
319 /**
320  * CMD12 response errors of Auto CMD12
321  */
322 typedef enum XMC_SDMMC_ACMD_ERR
323 {
324   XMC_SDMMC_ACMD12_NOT_EXEC_ERR = SDMMC_ACMD_ERR_STATUS_ACMD12_NOT_EXEC_ERR_Msk, /**< ACMD12 not executed error */
325   XMC_SDMMC_ACMD_TIMEOUT_ERR    = SDMMC_ACMD_ERR_STATUS_ACMD_TIMEOUT_ERR_Msk,    /**< ACMD timeout error */
326   XMC_SDMMC_ACMD_CRC_ERR        = SDMMC_ACMD_ERR_STATUS_ACMD_CRC_ERR_Msk,        /**< ACMD CRC error */
327   XMC_SDMMC_ACMD_END_BIT_ERR    = SDMMC_ACMD_ERR_STATUS_ACMD_END_BIT_ERR_Msk,    /**< ACMD end bit error */
328   XMC_SDMMC_ACMD_IND_ERR        = SDMMC_ACMD_ERR_STATUS_ACMD_IND_ERR_Msk,        /**< ACMD IND error */
329   XMC_SDMMC_CMD_NOT_ISSUED_BY_ACMD12_ERR = SDMMC_ACMD_ERR_STATUS_CMD_NOT_ISSUED_BY_ACMD12_ERR_Msk /**< CMD not issued by ACMD12 */
330 } XMC_SDMMC_ACMD_ERR_t;
331 
332 /**
333  * SDMMC response types
334  */
335 typedef enum XMC_SDMMC_RESPONSE_TYPE
336 {
337   XMC_SDMMC_RESPONSE_TYPE_NO_RESPONSE = 0U, /**< No response */
338   XMC_SDMMC_RESPONSE_TYPE_R1,               /**< Response type: R1 */
339   XMC_SDMMC_RESPONSE_TYPE_R1b,              /**< Response type: R1b */
340   XMC_SDMMC_RESPONSE_TYPE_R2,               /**< Response type: R2 */
341   XMC_SDMMC_RESPONSE_TYPE_R3,               /**< Response type: R3 */
342   XMC_SDMMC_RESPONSE_TYPE_R6,               /**< Response type: R6 */
343   XMC_SDMMC_RESPONSE_TYPE_R7                /**< Response type: R7 */
344 } XMC_SDMMC_RESPONSE_TYPE_t;
345 
346 /**
347 * Command response selection
348 */
349 typedef enum XMC_SDMMC_COMMAND_RESPONSE
350 {
351   XMC_SDMMC_COMMAND_RESPONSE_NONE = 0, /**< No Response */
352   XMC_SDMMC_COMMAND_RESPONSE_LONG = 1, /**< Response length 136 */
353   XMC_SDMMC_COMMAND_RESPONSE_SHORT = 2, /**< Response length 48 */
354   XMC_SDMMC_COMMAND_RESPONSE_SHORT_BUSY = 3, /**< Response length 48 check Busy after response */
355 } XMC_SDMMC_COMMAND_RESPONSE_t;
356 
357 /**
358  * Types of SDMMC commands
359  */
360 typedef enum XMC_SDMMC_COMMAND_TYPE
361 {
362   XMC_SDMMC_COMMAND_TYPE_NORMAL  = 0U, /**< Command normal */
363   XMC_SDMMC_COMMAND_TYPE_SUSPEND,      /**< Command suspend */
364   XMC_SDMMC_COMMAND_TYPE_RESUME,       /**< Command resume */
365   XMC_SDMMC_COMMAND_TYPE_ABORT         /**< Command abort */
366 } XMC_SDMMC_COMMAND_TYPE_t;
367 
368 /**
369  * SDMMC transfer modes
370  */
371 typedef enum XMC_SDMMC_TRANSFER_MODE_TYPE
372 {
373   XMC_SDMMC_TRANSFER_MODE_TYPE_SINGLE        = 0x00U, /**< Transfer mode type: single */
374   XMC_SDMMC_TRANSFER_MODE_TYPE_INFINITE      = 0x20U, /**< Transfer mode type: infinite */
375   XMC_SDMMC_TRANSFER_MODE_TYPE_MULTIPLE      = 0x22U, /**< Transfer mode type: multiple */
376   XMC_SDMMC_TRANSFER_MODE_TYPE_STOP_MULTIPLE = 0x22U  /**< Transfer mode type: multiple stop */
377 } XMC_SDMMC_TRANSFER_MODE_TYPE_t;
378 
379 /**
380  * Auto command transfer modes
381  */
382 typedef enum XMC_SDMMC_TRANSFER_MODE_AUTO_CMD
383 {
384   XMC_SDMMC_TRANSFER_MODE_AUTO_CMD_DISABLED = 0x00U, /**< ACMD mode disabled */
385   XMC_SDMMC_TRANSFER_MODE_AUTO_CMD_12                /**< ACMD12 mode */
386 } XMC_SDMMC_TRANSFER_MODE_AUTO_CMD_t;
387 
388 /**
389  * SDMMC bus voltage level
390  */
391 typedef enum XMC_SDMMC_BUS_VOLTAGE
392 {
393   XMC_SDMMC_BUS_VOLTAGE_3_3_VOLTS = 0x07U /**< 3.3V */
394 } XMC_SDMMC_BUS_VOLTAGE_t;
395 
396 /**
397  * Data line timeout counter values
398  */
399 typedef enum XMC_SDMMC_DAT_TIMEOUT_COUNTER
400 {
401   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_13 = 0U, /**< SDCLK * (2 ^ 13) */
402   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_14 = 1U, /**< SDCLK * (2 ^ 14) */
403   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_15 = 2U, /**< SDCLK * (2 ^ 15) */
404   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_16 = 3U, /**< SDCLK * (2 ^ 16) */
405   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_17 = 4U, /**< SDCLK * (2 ^ 17) */
406   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_18 = 5U, /**< SDCLK * (2 ^ 18) */
407   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_19 = 6U, /**< SDCLK * (2 ^ 19) */
408   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_20 = 7U, /**< SDCLK * (2 ^ 20) */
409   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_21 = 8U, /**< SDCLK * (2 ^ 21) */
410   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_22 = 9U, /**< SDCLK * (2 ^ 22) */
411   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_23 = 10U, /**< SDCLK * (2 ^ 23) */
412   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_24 = 11U, /**< SDCLK * (2 ^ 24) */
413   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_25 = 12U, /**< SDCLK * (2 ^ 25) */
414   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_26 = 13U, /**< SDCLK * (2 ^ 26) */
415   XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_27 = 14U, /**< SDCLK * (2 ^ 27) */
416 } XMC_SDMMC_DAT_TIMEOUT_COUNTER_t;
417 
418 /**
419  * SDMMC data transfer direction
420  */
421 typedef enum XMC_SDMMC_DATA_TRANSFER_DIR
422 {
423   XMC_SDMMC_DATA_TRANSFER_HOST_TO_CARD = 0U, /**< Host to card */
424   XMC_SDMMC_DATA_TRANSFER_CARD_TO_HOST       /**< Card to host */
425 } XMC_SDMMC_DATA_TRANSFER_DIR_t;
426 
427 /**
428  * SDMMC card detection signal source
429  */
430 typedef enum XMC_SDMMC_CD_SOURCE
431 {
432 #if UC_SERIES == XMC45 || defined(DOXYGEN)
433   XMC_SDMMC_CD_SOURCE_PIN = 0 << SDMMC_HOST_CTRL_CARD_DET_SIGNAL_DETECT_Pos, /**< P1.10 input pin selected */
434   XMC_SDMMC_CD_SOURCE_SW = 1 << SDMMC_HOST_CTRL_CARD_DET_SIGNAL_DETECT_Pos   /**< Software is selected */
435 #else
436   XMC_SDMMC_CD_SOURCE_PIN = 0 << SDMMC_CON_CDSEL_Pos, /**< P1.10 input pin selected */
437   XMC_SDMMC_CD_SOURCE_SW = 1 << SDMMC_CON_CDSEL_Pos   /**< Software is selected */
438 #endif
439 } XMC_SDMMC_CD_SOURCE_t;
440 
441 /**
442  * Used to set the SDMMC card detection status when the card detection status source input is set to software
443  */
444 typedef enum XMC_SDMMC_CD_STATUS
445 {
446 #if UC_SERIES == XMC45 || defined(DOXYGEN)
447   XMC_SDMMC_CD_STATUS_NO_CARD = 0 << SDMMC_HOST_CTRL_CARD_DETECT_TEST_LEVEL_Pos, /**< No card detected */
448   XMC_SDMMC_CD_STATUS_INSERTED = 1 << SDMMC_HOST_CTRL_CARD_DETECT_TEST_LEVEL_Pos /**< Card detected */
449 #else
450   XMC_SDMMC_CD_STATUS_NO_CARD = 0 << SDMMC_CON_CDSVAL_Pos,  /**< No card detected */
451   XMC_SDMMC_CD_STATUS_INSERTED = 1 << SDMMC_CON_CDSVAL_Pos  /**< Card detected */
452 #endif
453 } XMC_SDMMC_CD_STATUS_t;
454 
455 #if UC_SERIES != XMC45 || defined(DOXYGEN)
456 /**
457  * SDMMC card write protection signal source
458  * @note Only available for XMC4300, XMC4800 and XMC4700 series
459  */
460 typedef enum XMC_SDMMC_WP_SOURCE
461 {
462   XMC_SDMMC_WP_SOURCE_PIN = 0 << SDMMC_CON_WPSEL_Pos, /**< P1.1 input pin selected */
463   XMC_SDMMC_WP_SOURCE_SW = 1 << SDMMC_CON_WPSEL_Pos   /**< Software is selected */
464 } XMC_SDMMC_WP_SOURCE_t;
465 
466 /**
467  * Used to set the SDMMC card protection status when the card protection status source input is set to software
468  * @note Only available for XMC4300, XMC4800 and XMC4700 series
469  */
470 typedef enum XMC_SDMMC_WP_STATUS
471 {
472   XMC_SDMMC_WP_STATUS_NO_WRITE_PROTECTION = 0 << SDMMC_CON_WPSVAL_Pos, /**< No write protection */
473   XMC_SDMMC_WP_STATUS_WRITE_PROTECTION = 1 << SDMMC_CON_WPSVAL_Pos     /**< Write protection active */
474 } XMC_SDMMC_WP_STATUS_t;
475 #endif
476 
477 /*******************************************************************************
478  * DATA STRUCTURES
479  *******************************************************************************/
480 
481 /**
482  * SDMMC device structure <br>
483  *
484  * The structure represents a collection of all hardware registers used
485  * to configure the SDMMC peripheral on the XMC4500 microcontroller. The
486  * registers can be accessed with ::XMC_SDMMC.
487  */
488 typedef struct
489 {
490   __I  uint32_t  RESERVED0;
491   __IO uint16_t  BLOCK_SIZE;
492   __IO uint16_t  BLOCK_COUNT;
493   __IO uint32_t  ARGUMENT1;
494   __IO uint16_t  TRANSFER_MODE;
495   __IO uint16_t  COMMAND;
496   __I  uint32_t  RESPONSE[4];
497   __IO uint32_t  DATA_BUFFER;
498   __I  uint32_t  PRESENT_STATE;
499   __IO uint8_t   HOST_CTRL;
500   __IO uint8_t   POWER_CTRL;
501   __IO uint8_t   BLOCK_GAP_CTRL;
502   __IO uint8_t   WAKEUP_CTRL;
503   __IO uint16_t  CLOCK_CTRL;
504   __IO uint8_t   TIMEOUT_CTRL;
505   __IO uint8_t   SW_RESET;
506   __IO uint16_t  INT_STATUS_NORM;
507   __IO uint16_t  INT_STATUS_ERR;
508   __IO uint16_t  EN_INT_STATUS_NORM;
509   __IO uint16_t  EN_INT_STATUS_ERR;
510   __IO uint16_t  EN_INT_SIGNAL_NORM;
511   __IO uint16_t  EN_INT_SIGNAL_ERR;
512   __I  uint16_t  ACMD_ERR_STATUS;
513   __I  uint16_t  RESERVED1[9];
514   __O  uint16_t  FORCE_EVENT_ACMD_ERR_STATUS;
515   __O  uint16_t  FORCE_EVENT_ERR_STATUS;
516   __I  uint32_t  RESERVED2[8];
517   __O  uint32_t  DEBUG_SEL;
518   __I  uint32_t  RESERVED3[30];
519   __IO uint32_t  SPI;
520   __I  uint32_t  RESERVED4[2];
521   __I  uint16_t  SLOT_INT_STATUS;
522 } XMC_SDMMC_t;
523 
524 /* Anonymous structure/union guard start */
525 #if defined (__CC_ARM)
526   #pragma push
527   #pragma anon_unions
528 #elif defined (__TASKING__)
529   #pragma warning 586
530 #endif
531 
532 /**
533  * Present state of the SDMMC host controller <br>
534  *
535  * The structure presents a convenient way to obtain the SDMMC peripheral's
536  * present state information (for example, the write protect pin level). The
537  * XMC_SDMMC_GetPresentState() API can be used to populate the structure
538  * with the state of the SD host controller.
539  */
540 typedef union XMC_SDMMC_PRESENT_STATE
541 {
542   struct
543   {
544     uint32_t command_inihibit_cmd    : 1; /**< Command: Inhibit command */
545   uint32_t command_inihibit_dat    : 1; /**< Command: Inhibit data */
546   uint32_t dat_line_active     : 1; /**< Data line active */
547   uint32_t             : 5;
548   uint32_t write_transfer_active   : 1; /**< Write transfer active */
549   uint32_t read_transfer_active    : 1; /**< Read transfer active */
550   uint32_t buffer_write_enable   : 1; /**< Buffer write enable */
551   uint32_t buffer_read_enable    : 1; /**< Buffer read enable */
552   uint32_t             : 4;
553   uint32_t card_inserted       : 1; /**< Card inserted */
554   uint32_t card_state_stable     : 1; /**< Card state stable */
555   uint32_t card_detect_pin_level   : 1; /**< Card detect pin level */
556   uint32_t write_protect_pin_level : 1; /**< Write protect pin level */
557   uint32_t dat_3_0_pin_level     : 4; /**< Data 3_0 pin level */
558   uint32_t cmd_line_level          : 1; /**< Command line level */
559   uint32_t dat7_4_pin_level        : 4; /**< Data 7_4 pin level */
560   uint32_t                         : 3;
561   };
562   uint32_t b32;
563 } XMC_SDMMC_PRESENT_STATE_t;
564 
565 /**
566  * SDMMC transfer mode configuration
567  */
568 typedef struct XMC_SDMMC_TRANSFER_MODE
569 {
570   uint32_t block_size;
571   uint32_t num_blocks;
572   XMC_SDMMC_TRANSFER_MODE_TYPE_t type;
573   XMC_SDMMC_TRANSFER_MODE_AUTO_CMD_t auto_cmd;
574   XMC_SDMMC_DATA_TRANSFER_DIR_t direction;
575 } XMC_SDMMC_TRANSFER_MODE_t;
576 
577 /**
578  * Represent an SDMMC command <br>
579  *
580  * The structure holds the configuration for an SDMMC command. The SDMMC
581  * COMMAND register is a 16-bit register which is responsible for enabling
582  * configuration parameters like command type, response type, index check
583  * enable (and a few more). Once SDMMC.COMMAND is configured, the
584  * XMC_SDMMC_SendCommand() function can be used to send the command.
585  */
586 typedef union XMC_SDMMC_COMMAND
587 {
588   struct
589   {
590     uint16_t response_type_sel : 2; /**< Response type select ::XMC_SDMMC_COMMAND_RESPONSE_t */
591     uint16_t                   : 1;
592     uint16_t crc_check_en      : 1; /**< Command CRC check enable */
593     uint16_t index_check_en    : 1; /**< Command index check enable */
594     uint16_t dat_present_sel   : 1; /**< Data present select */
595     uint16_t cmd_type          : 2; /**< Command type ::XMC_SDMMC_COMMAND_TYPE_t */
596     uint16_t cmd_index         : 6; /**< Command index */
597     uint16_t                   : 2;
598   };
599   uint16_t cmd;
600 } XMC_SDMMC_COMMAND_t;
601 
602 /* Anonymous structure/union guard end */
603 #if defined (__CC_ARM)
604   #pragma pop
605 #elif defined (__TASKING__)
606   #pragma warning restore
607 #endif
608 
609 /**
610  * Card response structure
611  */
612 typedef struct XMC_SDMMC_RESPONSE
613 {
614   uint32_t response_0;
615   uint32_t response_2;
616   uint32_t response_4;
617   uint32_t response_6;
618 } XMC_SDMMC_RESPONSE_t;
619 
620 /**
621  * SDMMC configuration data structure <br>
622  *
623  * The structure is used to configure the bus width and the clock divider.
624  */
625 typedef struct XMC_SDMMC_CONFIG
626 {
627   uint8_t bus_width; /**< SDMMC bus width */
628   XMC_SDMMC_SDCLK_FREQ_SEL_t clock_divider; /**< SDMMC clock divider */
629 } XMC_SDMMC_CONFIG_t;
630 
631 /*******************************************************************************
632  * API PROTOTYPES
633  *******************************************************************************/
634 
635 #ifdef __cplusplus
636 extern "C" {
637 #endif
638 
639 /**
640  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
641  * @return bool
642  *
643  * \par<b>Description: </b><br>
644  * Get power status of the SDMMC peripheral <br>
645  *
646  * \par
647  * The function checks the SD_BUS_POWER bit-field of the POWER_CTRL register and returns
648  * a boolean value - "on" or "off".
649  */
650 bool XMC_SDMMC_GetPowerStatus(XMC_SDMMC_t *const sdmmc);
651 
652 /**
653  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
654  * @return None
655  *
656  * \par<b>Description: </b><br>
657  * Enable SDMMC peripheral <br>
658  *
659  * \par
660  * The function de-asserts the peripheral reset. The peripheral needs to be initialized.
661  */
662 void XMC_SDMMC_Enable(XMC_SDMMC_t *const sdmmc);
663 
664 /**
665  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
666  * @return None
667  *
668  * \par<b>Description: </b><br>
669  * Disable SDMMC peripheral <br>
670  *
671  * \par
672  * The function asserts the peripheral reset.
673  */
674 void XMC_SDMMC_Disable(XMC_SDMMC_t *const sdmmc);
675 
676 /**
677  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
678  * @param config A pointer to a constant XMC_SDMMC_CONFIG_t structure containing the
679  *               bus width and clock divider configuration
680  * @return ::XMC_SDMMC_STATUS_SUCCESS
681  *
682  * \par<b>Description: </b><br>
683  * Initialize the SDMMC peripheral <br>
684  *
685  * \par
686  * The function enables the SDMMC peripheral, sets the internal clock divider register
687  * and sets the bus width.
688  */
689 XMC_SDMMC_STATUS_t XMC_SDMMC_Init(XMC_SDMMC_t *const sdmmc, const XMC_SDMMC_CONFIG_t *config);
690 
691 /**
692  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
693  * @param event A valid SDMMC event (XMC_SDMMC_EVENT_t) or a valid combination of
694  *              logically OR'd events
695  * @return None
696  *
697  * \par<b>Description: </b><br>
698  * Enable SDMMC normal and error event(s) <br>
699  *
700  * \par
701  * The function first sets the bit-fields of EN_INT_STATUS_NORM and EN_INT_STATUS_ERR
702  * registers to enable interrupt status for requested normal/error SDMMC events. It then
703  * sets the bit-fields of EN_INT_SIGNAL_NORM and EN_INT_SIGNAL_ERR to enable the
704  * interrupt generation for the requested events.
705  */
706 void XMC_SDMMC_EnableEvent(XMC_SDMMC_t *const sdmmc, uint32_t event);
707 
708 /**
709  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
710  * @param event A valid SDMMC event (XMC_SDMMC_EVENT_t) or a valid combination of
711  *              logically OR'd events
712  * @return None
713  *
714  * \par<b>Description: </b><br>
715  * Disable normal and error SDMMC event(s) <br>
716  *
717  * \par
718  * The function disables the interrupt generation for the requested events by clearing
719  * the bit-fields of EN_INT_SIGNAL_NORM and EN_INT_SIGNAL_ERR registers.
720  *
721  * \par<b>Note:</b><br>
722  * The XMC_SDMMC_DisableEvent() function doesn't reset the the interrupt status. One
723  * may still use XMC_SDMMC_GetEvent() to check the status of requested events even if
724  * the interrupt generation is already disabled.
725  */
726 void XMC_SDMMC_DisableEvent(XMC_SDMMC_t *const sdmmc, uint32_t event);
727 
728 /**
729  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
730  * @param event A valid SDMMC event (XMC_SDMMC_EVENT_t) or a valid combination of
731  *              logically OR'd events
732  * @return None
733  *
734  * \par<b>Description: </b><br>
735  * Clear SDMMC event(s) <br>
736  *
737  * \par
738  * The function clears requested normal/error events by settings the bit-fields of
739  * the INT_STATUS register. Please check SDMMC_INT_STATUS_NORM in the XMC45000
740  * manual for more details.
741  */
742 void XMC_SDMMC_ClearEvent(XMC_SDMMC_t *const sdmmc, uint32_t event);
743 
744 /**
745  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
746  * @param event A valid SDMMC event (XMC_SDMMC_EVENT_t)
747  * @return bool
748  *
749  * \par<b>Description: </b><br>
750  * Get SDMMC event status <br>
751  *
752  * \par
753  * The function returns the status of a single requested (normal/error) event by
754  * reading the appropriate bit-fields of the INT_STATUS register.
755  */
756 bool XMC_SDMMC_GetEvent(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_EVENT_t event);
757 
758 /**
759  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
760  * @param event A valid SDMMC event (XMC_SDMMC_EVENT_t) or a valid combination of
761  *              logically OR'd events
762  * @return None
763  *
764  * \par<b>Description: </b><br>
765  * Enable event status <br>
766  *
767  * \par
768  * The function sets the bit-fields of EN_INT_STATUS_NORM and EN_INT_STATUS_ERR
769  * registers to enable interrupt status for requested normal/error SDMMC events.
770  */
771 void XMC_SDMMC_EnableEventStatus(XMC_SDMMC_t *const sdmmc, uint32_t event);
772 
773 /**
774  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
775  * @param event A valid SDMMC event (XMC_SDMMC_EVENT_t) or a valid combination of
776  *              logically OR'd events
777  * @return None
778  *
779  * \par<b>Description: </b><br>
780  * Disable event status <br>
781  *
782  * \par
783  * The function resets the bit-fields of EN_INT_STATUS_NORM and EN_INT_STATUS_ERR
784  * registers to disable interrupt status for requested normal/error SDMMC events.
785  */
786 void XMC_SDMMC_DisableEventStatus(XMC_SDMMC_t *const sdmmc, uint32_t event);
787 
788 /**
789  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
790  * @param event A valid SDMMC event (::XMC_SDMMC_EVENT_t) or a valid combination of
791  *              logically OR'd events
792  * @return None
793  *
794  * \par<b>Description: </b><br>
795  * Trigger SDMMC error events <br>
796  *
797  * \par
798  * The SDMMC peripheral supports triggering of following error events: <br>
799  *
800  * ::XMC_SDMMC_CMD_TIMEOUT_ERR, ::XMC_SDMMC_CMD_CRC_ERR, ::XMC_SDMMC_CMD_END_BIT_ERR,
801  * ::XMC_SDMMC_CMD_IND_ERR, ::XMC_SDMMC_DATA_TIMEOUT_ERR, ::XMC_SDMMC_DATA_CRC_ERR,
802  * ::XMC_SDMMC_DATA_END_BIT_ERR, ::XMC_SDMMC_CURRENT_LIMIT_ERR, ::XMC_SDMMC_ACMD_ERR,
803  * ::XMC_SDMMC_TARGET_RESP_ERR
804  *
805  * For triggering Auto CMD12 error, see XMC_SDMMC_TriggerACMDErr()
806  */
XMC_SDMMC_TriggerEvent(XMC_SDMMC_t * const sdmmc,uint32_t event)807 __STATIC_INLINE void XMC_SDMMC_TriggerEvent(XMC_SDMMC_t *const sdmmc, uint32_t event)
808 {
809   XMC_ASSERT("XMC_SDMMC_TriggerEvent: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
810 
811   sdmmc->FORCE_EVENT_ERR_STATUS |= (uint16_t)(event >> 16U);
812 }
813 
814 /**
815  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
816  * @param source A valid SDMMC card detection signal source (::XMC_SDMMC_CD_SOURCE_t)
817  * @return None
818  *
819  * \par<b>Description: </b><br>
820  * Selects source for card detection
821  */
XMC_SDMMC_SetCardDetectionSource(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_CD_SOURCE_t source)822 __STATIC_INLINE void XMC_SDMMC_SetCardDetectionSource(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_CD_SOURCE_t source)
823 {
824   XMC_ASSERT("XMC_SDMMC_SetCardDetectionSource: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
825 
826 #if UC_SERIES == XMC45
827   sdmmc->HOST_CTRL |= (sdmmc->HOST_CTRL & (uint32_t)~SDMMC_HOST_CTRL_CARD_DET_SIGNAL_DETECT_Msk) | source;
828 #else
829   XMC_UNUSED_ARG(sdmmc);
830   *(uint32_t *)SDMMC_CON = (*(uint32_t *)SDMMC_CON & (uint32_t)~SDMMC_CON_CDSEL_Msk) | source;
831 #endif
832 
833 }
834 
835 
836 /**
837  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
838  * @param status A valid SDMMC card detection status (::XMC_SDMMC_CD_STATUS_t)
839  * @return None
840  *
841  * \par<b>Description: </b><br>
842  * Sets the card detection status indicating whether card is inserted or not.
843  * Generates (card ins or card removal) interrupt when the normal interrupt is enabled.
844  * @note Only valid if SDMMC card detection signal source is set to XMC_SDMMC_CD_SOURCE_SW <br>
845  *
846  */
XMC_SDMMC_SetCardDetectionStatus(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_CD_STATUS_t status)847 __STATIC_INLINE void XMC_SDMMC_SetCardDetectionStatus(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_CD_STATUS_t status)
848 {
849   XMC_ASSERT("XMC_SDMMC_SetCardDetectionStatus: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
850 
851 #if UC_SERIES == XMC45
852   sdmmc->HOST_CTRL |= (sdmmc->HOST_CTRL & (uint32_t)~SDMMC_HOST_CTRL_CARD_DETECT_TEST_LEVEL_Msk) | status;
853 #else
854   XMC_UNUSED_ARG(sdmmc);
855   *(uint32_t *)SDMMC_CON = (*(uint32_t *)SDMMC_CON & (uint32_t)~SDMMC_CON_CDSVAL_Msk) | status;
856 #endif
857 }
858 
859 #if (UC_SERIES != XMC45) || defined(DOXYGEN)
860 /**
861  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
862  * @param source A valid SDMMC card detection signal source (::XMC_SDMMC_WP_SOURCE_t)
863  * @return None
864  *
865  * \par<b>Description: </b><br>
866  * Selects input for card write protection status
867  */
XMC_SDMMC_SetWriteProtectionSource(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_WP_SOURCE_t source)868 __STATIC_INLINE void XMC_SDMMC_SetWriteProtectionSource(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_WP_SOURCE_t source)
869 {
870   XMC_ASSERT("XMC_SDMMC_SetWriteProtectionSource: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
871   XMC_UNUSED_ARG(sdmmc);
872 
873 #if UC_SERIES != XMC45
874   *(uint32_t *)SDMMC_CON = (*(uint32_t *)SDMMC_CON & (uint32_t)~SDMMC_CON_WPSEL_Msk) | source;
875 #endif
876 }
877 
878 /**
879  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
880  * @param status A valid SDMMC card detection status (::XMC_SDMMC_WP_STATUS_t)
881  * @return None
882  *
883  * \par<b>Description: </b><br>
884  * Sets the card write protection status indicating whether card is write protected or not.
885  * @note Only valid if SDMMC card detection signal source is set to XMC_SDMMC_WP_SOURCE_SW <br>
886  *
887  */
XMC_SDMMC_SetWriteProtectionStatus(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_WP_STATUS_t status)888 __STATIC_INLINE void XMC_SDMMC_SetWriteProtectionStatus(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_WP_STATUS_t status)
889 {
890   XMC_ASSERT("XMC_SDMMC_SetWriteProtectionStatus: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
891   XMC_UNUSED_ARG(sdmmc);
892 
893 #if UC_SERIES != XMC45
894   *(uint32_t *)SDMMC_CON = (*(uint32_t *)SDMMC_CON & (uint32_t)~SDMMC_CON_WPSVAL_Msk) | status;
895 #endif
896 }
897 #endif
898 
899 /**
900  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
901  * @return bool
902  *
903  * \par<b>Description: </b><br>
904  * Check if any error event has occured <br>
905  *
906  * \par
907  * The function can typically be used for writing an error interrupt recovery routine.
908  * Should any error be indicated (If XMC_SDMMC_IsAnyErrorEvent() returns true), the
909  * routine may then clear the event after indicating the error event and reset the
910  * SDMMC command and data lines.
911  */
XMC_SDMMC_IsAnyErrorEvent(XMC_SDMMC_t * const sdmmc)912 __STATIC_INLINE bool XMC_SDMMC_IsAnyErrorEvent(XMC_SDMMC_t *const sdmmc)
913 {
914   XMC_ASSERT("XMC_SDMMC_IsAnyErrorEvent: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
915 
916   return (bool)(sdmmc->INT_STATUS_ERR);
917 }
918 
919 /**
920  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
921  * @param event A valid SDMMC wakeup event (::XMC_SDMMC_WAKEUP_EVENT_t) or a valid combination
922  *              of logically OR'd wakeup events
923  * @return None
924  *
925  * \par<b>Description: </b><br>
926  * Enable wakeup event(s) <br>
927  *
928  * \par
929  * The function enables SDMMC wakeup events by setting appropriate bit-fields of the WAKEUP_CTRL
930  * register. <br>
931  *
932  * List of supported wakeup events -> Wakeup on: <br>
933  * 1) Card interrupt <br>
934  * 2) SD card insertion <br>
935  * 3) SD card removal <br>
936  */
XMC_SDMMC_EnableWakeupEvent(XMC_SDMMC_t * const sdmmc,uint32_t event)937 __STATIC_INLINE void XMC_SDMMC_EnableWakeupEvent(XMC_SDMMC_t *const sdmmc, uint32_t event)
938 {
939   XMC_ASSERT("XMC_SDMMC_EnableWakeupEvent: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
940 
941   sdmmc->WAKEUP_CTRL |= (uint8_t)event;
942 }
943 
944 /**
945  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
946  * @param event A valid SDMMC wakeup event (::XMC_SDMMC_WAKEUP_EVENT_t) or a valid combination
947  *              of logically OR'd wakeup events
948  * @return None
949  *
950  * \par<b>Description: </b><br>
951  * Disable wakeup event(s) <br>
952  *
953  * \par
954  * The function disables SDMMC wakeup events by clearing appropriate bit-fields of the WAKEUP_CTRL
955  * register. <br>
956  *
957  * List of supported wakeup events -> Wakeup on: <br>
958  * 1) Card interrupt <br>
959  * 2) SD card insertion <br>
960  * 3) SD card removal <br>
961  */
XMC_SDMMC_DisableWakeupEvent(XMC_SDMMC_t * const sdmmc,uint32_t event)962 __STATIC_INLINE void XMC_SDMMC_DisableWakeupEvent(XMC_SDMMC_t *const sdmmc, uint32_t event)
963 {
964   XMC_ASSERT("XMC_SDMMC_DisableWakeupEvent: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
965 
966   sdmmc->WAKEUP_CTRL &= (uint8_t)~event;
967 }
968 
969 /**
970  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
971  * @param error A valid SDMMC ACMD error (::XMC_SDMMC_ACMD_ERR_t)
972  * @return bool
973  *
974  * \par<b>Description: </b><br>
975  * Get status of Auto CMD12 errors <br>
976  *
977  * \par
978  * The function detects the presence of an Auto CMD12 error. A boolean is returned to
979  * indicate if an error is detected.
980  */
XMC_SDMMC_GetACMDErrStatus(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_ACMD_ERR_t error)981 __STATIC_INLINE bool XMC_SDMMC_GetACMDErrStatus(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_ACMD_ERR_t error)
982 {
983   XMC_ASSERT("XMC_SDMMC_GetACMDErrStatus: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
984   XMC_ASSERT("XMC_SDMMC_GetACMDErrStatus: Invalid ACMD response error", XMC_SDMMC_CHECK_ACMD_ERR(error));
985 
986   return (bool)(sdmmc->ACMD_ERR_STATUS & (uint16_t)error);
987 }
988 
989 /**
990  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
991  * @param error A valid SDMMC ACMD error (::XMC_SDMMC_ACMD_ERR_t) or a valid combination
992  *              of logically OR'd ACMD error events
993  * @return None
994  *
995  * \par<b>Description: </b><br>
996  * Triggers Auto CMD12 error(s) <br>
997  *
998  * \par
999  * This function triggers Auto CMD12 error(s) by setting appropriate bit-fields of the
1000  * FORCE_EVENT_ACMD_ERR_STATUS register.
1001  *
1002  * \par<b>Related APIs: </b><br>
1003  * XMC_SDMMC_TriggerEvent()
1004  */
XMC_SDMMC_TriggerACMDErr(XMC_SDMMC_t * const sdmmc,uint32_t error)1005 __STATIC_INLINE void XMC_SDMMC_TriggerACMDErr(XMC_SDMMC_t *const sdmmc, uint32_t error)
1006 {
1007   XMC_ASSERT("XMC_SDMMC_TriggerACMDErr: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1008 
1009   sdmmc->FORCE_EVENT_ACMD_ERR_STATUS |= (uint16_t)error;
1010 }
1011 
1012 /**
1013  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1014  * @return uint32_t The value held in the SDMMC FIFO
1015  *
1016  * \par<b>Description: </b><br>
1017  * Use this function to read a single word (32 bits) from the SDMMC FIFO. <br>
1018  */
XMC_SDMMC_ReadFIFO(XMC_SDMMC_t * const sdmmc)1019 __STATIC_INLINE uint32_t XMC_SDMMC_ReadFIFO(XMC_SDMMC_t *const sdmmc)
1020 {
1021   XMC_ASSERT("XMC_SDMMC_ReadFIFO: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1022 
1023   return (sdmmc->DATA_BUFFER);
1024 }
1025 
1026 /**
1027  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1028  * @param data Pointer to a data word (32 bits) that needs to be written to the FIFO
1029  * @return None
1030  *
1031  * \par<b>Description: </b><br>
1032  * Use this function to write a single word (32 bits) to the SDMMC FIFO. <br>
1033  */
XMC_SDMMC_WriteFIFO(XMC_SDMMC_t * const sdmmc,uint32_t * data)1034 __STATIC_INLINE void XMC_SDMMC_WriteFIFO(XMC_SDMMC_t *const sdmmc, uint32_t *data)
1035 {
1036   XMC_ASSERT("XMC_SDMMC_WriteFIFO: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1037 
1038   sdmmc->DATA_BUFFER = *data;
1039 }
1040 
1041 /**
1042  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1043  * @return None
1044  *
1045  * \par<b>Description: </b><br>
1046  * Enable SDMMC bus power <br>
1047  *
1048  * \par
1049  * The function sets the SD_BUS_POWER bit-field in the POWER_CTRL register, enabling the
1050  * bus power. It may be invoked after enabling the SD clock (XMC_SDMMC_SDClockEnable()).
1051  */
XMC_SDMMC_BusPowerOn(XMC_SDMMC_t * const sdmmc)1052 __STATIC_INLINE void XMC_SDMMC_BusPowerOn(XMC_SDMMC_t *const sdmmc)
1053 {
1054   XMC_ASSERT("XMC_SDMMC_BusPowerOn: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1055 
1056   sdmmc->POWER_CTRL |= (uint8_t)(SDMMC_POWER_CTRL_SD_BUS_POWER_Msk);
1057 }
1058 
1059 /**
1060  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1061  * @return None
1062  *
1063  * \par<b>Description: </b><br>
1064  * Disable SDMMC bus power <br>
1065  *
1066  * \par
1067  * The function resets the SD_BUS_POWER bit-field in the POWER_CTRL register, disabling the
1068  * bus power.
1069  */
XMC_SDMMC_BusPowerOff(XMC_SDMMC_t * const sdmmc)1070 __STATIC_INLINE void XMC_SDMMC_BusPowerOff(XMC_SDMMC_t *const sdmmc)
1071 {
1072   XMC_ASSERT("XMC_SDMMC_BusPowerOff: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1073 
1074   sdmmc->POWER_CTRL &= (uint8_t)~SDMMC_POWER_CTRL_SD_BUS_POWER_Msk;
1075 }
1076 
1077 /**
1078  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1079  * @return None
1080  *
1081  * \par<b>Description: </b><br>
1082  * Enable the internal SDMMC clock <br>
1083  *
1084  * \par
1085  * The function enables the internal clock of the SDMMC peripheral. To check if the
1086  * clock is stable, use XMC_SDMMC_GetClockStability().
1087  *
1088  * \par<b>Note: </b><br>
1089  * Invoke XMC_SDMMC_Init() before using this function.
1090  */
XMC_SDMMC_Start(XMC_SDMMC_t * const sdmmc)1091 __STATIC_INLINE void XMC_SDMMC_Start(XMC_SDMMC_t *const sdmmc)
1092 {
1093   XMC_ASSERT("XMC_SDMMC_Start: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1094 
1095   /* Enable internal clock */
1096   sdmmc->CLOCK_CTRL |= (uint16_t)SDMMC_CLOCK_CTRL_INTERNAL_CLOCK_EN_Msk;
1097 }
1098 
1099 /**
1100  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1101  * @return bool
1102  *
1103  * \par<b>Description: </b><br>
1104  * Check internal clock stability <br>
1105  *
1106  * \par
1107  * Use this function to check the internal SDMMC clock stability. The function returns a
1108  * boolean value indicating internal clock stability (true = stable)
1109  */
XMC_SDMMC_GetClockStability(XMC_SDMMC_t * const sdmmc)1110 __STATIC_INLINE bool XMC_SDMMC_GetClockStability(XMC_SDMMC_t *const sdmmc)
1111 {
1112   XMC_ASSERT("XMC_SDMMC_GetClockStability: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1113 
1114   /* Return clock stability */
1115   return (bool)(sdmmc->CLOCK_CTRL & SDMMC_CLOCK_CTRL_INTERNAL_CLOCK_STABLE_Msk);
1116 }
1117 
1118 /**
1119  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1120  * @return None
1121  *
1122  * \par<b>Description: </b><br>
1123  * Disable internal SDMMC clock <br>
1124  *
1125  * \par
1126  * The function disables the internal clock of the SDMMC peripheral. The SDMMC registers
1127  * can still be read and written even if the internal clock is disabled.
1128  */
XMC_SDMMC_Stop(XMC_SDMMC_t * const sdmmc)1129 __STATIC_INLINE void XMC_SDMMC_Stop(XMC_SDMMC_t *const sdmmc)
1130 {
1131   XMC_ASSERT("XMC_SDMMC_Stop: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1132 
1133   sdmmc->CLOCK_CTRL &= (uint16_t)~SDMMC_CLOCK_CTRL_INTERNAL_CLOCK_EN_Msk;
1134 }
1135 
1136 /**
1137  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1138  * @return None
1139  *
1140  * \par<b>Description: </b><br>
1141  * Enable the SD clock <br>
1142  *
1143  * \par
1144  * The function sets the SDCLOCK_EN bit-field of the CLOCK_CTRL register, enabling the
1145  * SD clock. It can be invoked after the internal clock has achieved stability. SD card
1146  * initialization process may then follow.
1147  */
XMC_SDMMC_SDClockEnable(XMC_SDMMC_t * const sdmmc)1148 __STATIC_INLINE void XMC_SDMMC_SDClockEnable(XMC_SDMMC_t *const sdmmc)
1149 {
1150   XMC_ASSERT("XMC_SDMMC_SDClockEnable: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1151 
1152   sdmmc->CLOCK_CTRL |= (uint16_t)SDMMC_CLOCK_CTRL_SDCLOCK_EN_Msk;
1153 }
1154 
1155 /**
1156  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1157  * @return None
1158  *
1159  * \par<b>Description: </b><br>
1160  * Disable the SD clock <br>
1161  *
1162  * \par
1163  * The function resets the SDCLOCK_EN bit-field of the CLOCK_CTRL register, disabling the
1164  * SD clock. It can be used alongside a SD card information reset routine (if required).
1165  */
XMC_SDMMC_SDClockDisable(XMC_SDMMC_t * const sdmmc)1166 __STATIC_INLINE void XMC_SDMMC_SDClockDisable(XMC_SDMMC_t *const sdmmc)
1167 {
1168   XMC_ASSERT("XMC_SDMMC_SDClockDisable: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1169 
1170   sdmmc->CLOCK_CTRL &= (uint16_t)~SDMMC_CLOCK_CTRL_SDCLOCK_EN_Msk;
1171 }
1172 
1173 /**
1174  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1175  * @param reset_mode Reset mode or a bitwise combination of modes
1176  * @return None
1177  *
1178  * \par<b>Description: </b><br>
1179  * Set SDMMC software reset request <br>
1180  *
1181  * \par
1182  * The function sets in the SDMMC SW_RESET register: <br>
1183  * 1) bit 0 to reset all <br>
1184  * 2) bit 1 to reset CMD line <br>
1185  * 3) bit 2 reset DAT line <br>
1186  *
1187  * It is typically used to reset the SD HOST controller's registers.
1188  */
XMC_SDMMC_SetSWReset(XMC_SDMMC_t * const sdmmc,uint32_t reset_mode)1189 __STATIC_INLINE void XMC_SDMMC_SetSWReset(XMC_SDMMC_t *const sdmmc, uint32_t reset_mode)
1190 {
1191   XMC_ASSERT("XMC_SDMMC_SetSWReset: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1192 
1193   sdmmc->SW_RESET |= (uint8_t)reset_mode;
1194 }
1195 
1196 /**
1197  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1198  * @return Software reset status
1199  *
1200  * \par<b>Description: </b><br>
1201  * Get SDMMC software reset status <br>
1202  *
1203  * \par
1204  * The SD host takes some time to reset its registers after invoking XMC_SDMMC_SetSWReset().
1205  * Since XMC_SDMMC_SetSWReset() is a non-blocking function, XMC_SDMMC_GetSWResetStatus() has
1206  * been provided to check the software reset status. The return value needs to be masked
1207  * with the reset mode (XMC_SDMMC_SW_RESET_t) to get a specific software reset status value.
1208  */
XMC_SDMMC_GetSWResetStatus(XMC_SDMMC_t * const sdmmc)1209 __STATIC_INLINE uint32_t XMC_SDMMC_GetSWResetStatus(XMC_SDMMC_t *const sdmmc)
1210 {
1211   XMC_ASSERT("XMC_SDMMC_GetSWResetStatus: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1212 
1213   return (uint32_t)(sdmmc->SW_RESET);
1214 }
1215 
1216 /**
1217  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1218  * @return XMC_SDMMC_PRESENT_STATE_t A structure storing the present state of the host controller
1219  *
1220  * \par<b>Description: </b><br>
1221  * Get the present state of the SDMMC host controller <br>
1222  *
1223  * \par
1224  * Get the values of each bit-field in SDMMC_PRESENT_STATE register
1225  * The function call populates an instance of the XMC_SDMMC_PRESENT_STATE_t structure with
1226  * the state of the SD host controller and returns it to the caller.
1227  */
XMC_SDMMC_GetPresentState(const XMC_SDMMC_t * const sdmmc)1228 __STATIC_INLINE XMC_SDMMC_PRESENT_STATE_t XMC_SDMMC_GetPresentState(const XMC_SDMMC_t *const sdmmc)
1229 {
1230   XMC_SDMMC_PRESENT_STATE_t result;
1231 
1232   XMC_ASSERT("XMC_SDMMC_GetPresentState: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1233 
1234   result.b32 = (uint32_t)sdmmc->PRESENT_STATE;
1235 
1236   return result;
1237 }
1238 
1239 /**
1240  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1241  * @return bool SDMMC command line status
1242  *
1243  * \par<b>Description: </b><br>
1244  * Check if the command line is busy <br>
1245  *
1246  * \par
1247  * The function reads the SDMMC PRESENT_STATE register and returns "true" if the command
1248  * line is busy ("false" otherwise). The command line must be free before sending an SDMMC
1249  * command with XMC_SDMMC_SendCommand().
1250  */
XMC_SDMMC_IsCommandLineBusy(XMC_SDMMC_t * const sdmmc)1251 __STATIC_INLINE bool XMC_SDMMC_IsCommandLineBusy(XMC_SDMMC_t *const sdmmc)
1252 {
1253   XMC_ASSERT("XMC_SDMMC_IsCommandLineBusy: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1254 
1255   return (bool)(sdmmc->PRESENT_STATE & SDMMC_PRESENT_STATE_COMMAND_INHIBIT_CMD_Msk);
1256 }
1257 
1258 /**
1259  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1260  * @return bool SDMMC data line status
1261  *
1262  * \par<b>Description: </b><br>
1263  * Check if the data line is busy <br>
1264  *
1265  * \par
1266  * The function reads the SDMMC PRESENT_STATE register and returns "true" if the data
1267  * line is busy ("false" otherwise). The data line must be free before sending an SDMMC
1268  * command with XMC_SDMMC_SendCommand().
1269  */
XMC_SDMMC_IsDataLineBusy(XMC_SDMMC_t * const sdmmc)1270 __STATIC_INLINE bool XMC_SDMMC_IsDataLineBusy(XMC_SDMMC_t *const sdmmc)
1271 {
1272   XMC_ASSERT("XMC_SDMMC_IsDataLineBusy: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1273 
1274   return (bool)(sdmmc->PRESENT_STATE & SDMMC_PRESENT_STATE_COMMAND_INHIBIT_DAT_Msk);
1275 }
1276 
1277 /**
1278  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1279  * @return bool Status of all data lines
1280  *
1281  * \par<b>Description: </b><br>
1282  * Check if all data line are high <br>
1283  *
1284  * \par
1285  * The function reads the SDMMC PRESENT_STATE register and returns "true" if all data
1286  * lines are high. It can be used to handle SDMMC error conditions. For example, if an
1287  * error event (XMC_SDMMC_IsAnyErrorEvent()) is detected and all data lines are high,
1288  * the user code can conclude that the error is of a "recoverable" type.
1289  */
XMC_SDMMC_IsAllDataLinesHigh(XMC_SDMMC_t * const sdmmc)1290 __STATIC_INLINE bool XMC_SDMMC_IsAllDataLinesHigh(XMC_SDMMC_t *const sdmmc)
1291 {
1292   XMC_ASSERT("XMC_SDMMC_IsAllDataLinesHigh: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1293 
1294   return ((((sdmmc->PRESENT_STATE & SDMMC_PRESENT_STATE_DAT_3_0_PIN_LEVEL_Msk) >>
1295         SDMMC_PRESENT_STATE_DAT_3_0_PIN_LEVEL_Pos) == 0x0FU) ? true : false);
1296 }
1297 
1298 /**
1299  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1300  * @param command A pointer to a constant of type XMC_SDMMC_COMMAND_t, pointing to the command configuration
1301  * @param arg Command argument
1302  * @return ::XMC_SDMMC_STATUS_SUCCESS
1303  *
1304  * \par<b>Description: </b><br>
1305  * Send normal SDMMC command <br>
1306  *
1307  * \par
1308  * Use this function to send a normal SDMMC command. This non-blocking function sets the
1309  * ARGUMENT1 and COMMAND registers. It is the user's responsibility to check if the command
1310  * and data lines are busy (XMC_SDMMC_IsDataLineBusy(), XMC_SDMMC_IsCommandLineBusy()).
1311  */
1312 XMC_SDMMC_STATUS_t XMC_SDMMC_SendCommand(XMC_SDMMC_t *const sdmmc, const XMC_SDMMC_COMMAND_t *command, uint32_t arg);
1313 
1314 /**
1315  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1316  * @return uint32_t SDMMC command response
1317  *
1318  * \par<b>Description: </b><br>
1319  * Get card response (no Auto command) <br>
1320  *
1321  * \par
1322  * This function returns [39:8] bits of the card response. The others are checked automatically
1323  * by the peripheral. This function can be used with response type R1, R1b, R3, R4, R5, R5b, R6
1324  * but it doesn't support the retrieving of R1 of Auto CMD 23 and R1b of Auto CMD 12. To get
1325  * these responses, use XMC_SDMMC_GetAutoCommandResponse().
1326  */
XMC_SDMMC_GetCommandResponse(XMC_SDMMC_t * const sdmmc)1327 __STATIC_INLINE uint32_t XMC_SDMMC_GetCommandResponse(XMC_SDMMC_t *const sdmmc)
1328 {
1329   XMC_ASSERT("XMC_SDMMC_GetCommandResponse: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1330 
1331   return (sdmmc->RESPONSE[0]);
1332 }
1333 
1334 /**
1335  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1336  * @return uint32_t Auto command response value
1337  *
1338  * \par<b>Description: </b><br>
1339  * Get card response of Auto commands <br>
1340  *
1341  * \par
1342  * This function returns card response [39:8] bits of auto commands: R1 of Auto CMD 23 and
1343  * R1b of Auto CMD 12.
1344  */
XMC_SDMMC_GetAutoCommandResponse(const XMC_SDMMC_t * const sdmmc)1345 __STATIC_INLINE uint32_t XMC_SDMMC_GetAutoCommandResponse(const XMC_SDMMC_t *const sdmmc)
1346 {
1347   XMC_ASSERT("XMC_SDMMC_GetAutoCommandResponse: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1348 
1349   return (sdmmc->RESPONSE[3]);
1350 }
1351 
1352 /**
1353  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1354  * @param response Pointer to structure type XMC_SDMMC_RESPONSE_t to store the full response
1355  * @return None
1356  *
1357  * \par<b>Description: </b><br>
1358  * Get card R2 response <br>
1359  *
1360  * \par
1361  * The R2 response is 120 bits wide. The function reads all peripheral registers and store in
1362  * the response data structure.
1363  */
1364 void XMC_SDMMC_GetR2Response(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_RESPONSE_t *const response);
1365 
1366 /**
1367  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1368  * @param transfer_mode Transfer mode configuration
1369  * @return None
1370  *
1371  * \par<b>Description: </b><br>
1372  * Configure data transfer mode <br>
1373  *
1374  * \par
1375  * The function configures block size, block count, type of data transfer, response type
1376  * and sets the auto command configuration. Use this function to configure a multi-block
1377  * SDMMC transfer.
1378  */
1379 void XMC_SDMMC_SetDataTransferMode(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_TRANSFER_MODE_t *const transfer_mode);
1380 
1381 /**
1382  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1383  * @return uint32_t Number of blocks that need to be transferred
1384  *
1385  * \par<b>Description: </b><br>
1386  * Get the number of blocks that need to be transferred <br>
1387  *
1388  * \par
1389  * This function is valid only for multiple block transfers. The host controller
1390  * decrements the block count after each block transfer and stops when the count reaches
1391  * zero. It can only be accessed when no transaction is happening (i.e after a transaction
1392  * has stopped). This function returns an invalid value during the transfer. <br>
1393  *
1394  * When saving transfer context as a result of the suspend command, the number of blocks
1395  * yet to be transferred can be determined by using this function.
1396  */
XMC_SDMMC_GetTransferBlocksNum(XMC_SDMMC_t * const sdmmc)1397 __STATIC_INLINE uint32_t XMC_SDMMC_GetTransferBlocksNum(XMC_SDMMC_t *const sdmmc)
1398 {
1399   XMC_ASSERT("XMC_SDMMC_GetTransferBlocksNum: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1400 
1401   return (uint32_t)(sdmmc->BLOCK_COUNT);
1402 }
1403 
1404 /**
1405  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1406  * @param enabled "true" to enable read wait control, "false" to disable read wait control.
1407  * @return None
1408  *
1409  * \par<b>Description: </b><br>
1410  * Configure read wait control <br>
1411  *
1412  * \par
1413  * The read wait function is optional for SDIO cards. If the card supports read wait and
1414  * XMC_SDMMC_GetTransferBlocksNum() is executed, the SDMMC peripheral will stop read data
1415  * using DAT[2] line. If this feature is not enabled the peripheral has to stop the SD
1416  * clock to hold read data, restricting commands generation. <br>
1417  *
1418  * When the host driver detects an SD card insertion, it sets this bit according to the
1419  * CCCR of the SDIO card. If the card does not support read wait, this feature shall
1420  * never be enabled otherwise a DAT line conflict may occur. If this feature is disabled,
1421  * Suspend/Resume cannot be supported.
1422  */
XMC_SDMMC_SetReadWaitControl(XMC_SDMMC_t * const sdmmc,bool enabled)1423 __STATIC_INLINE void XMC_SDMMC_SetReadWaitControl(XMC_SDMMC_t *const sdmmc, bool enabled)
1424 {
1425   XMC_ASSERT("XMC_SDMMC_SetReadWaitControl: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1426 
1427   sdmmc->BLOCK_GAP_CTRL = (uint8_t)((sdmmc->BLOCK_GAP_CTRL & (uint8_t)~SDMMC_BLOCK_GAP_CTRL_READ_WAIT_CTRL_Msk) |
1428                                     (uint8_t)((uint8_t)enabled << SDMMC_BLOCK_GAP_CTRL_READ_WAIT_CTRL_Pos));
1429 }
1430 
1431 /**
1432  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1433  * @param enabled "true" to set stop at block gap, "false" for transfer
1434  * @return None
1435  *
1436  * \par<b>Description: </b><br>
1437  * Stop at block gap request <br>
1438  *
1439  * \par
1440  * The function is used to terminate a transaction execution at the next block gap for
1441  * non-DMA transfers.
1442  */
XMC_SDMMC_SetStopAtBlockGap(XMC_SDMMC_t * const sdmmc,bool enabled)1443 __STATIC_INLINE void XMC_SDMMC_SetStopAtBlockGap(XMC_SDMMC_t *const sdmmc, bool enabled)
1444 {
1445   XMC_ASSERT("XMC_SDMMC_SetStopAtBlockGap: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1446 
1447   sdmmc->BLOCK_GAP_CTRL = (uint8_t)((sdmmc->BLOCK_GAP_CTRL & (uint8_t)~SDMMC_BLOCK_GAP_CTRL_STOP_AT_BLOCK_GAP_Msk) |
1448                                     (uint8_t)((uint8_t)enabled << SDMMC_BLOCK_GAP_CTRL_STOP_AT_BLOCK_GAP_Pos));
1449 }
1450 
1451 /**
1452  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1453  * @param enabled "true" to restart transaction, "false" is ignored
1454  * @return None
1455  *
1456  * \par<b>Description: </b><br>
1457  * Issue a continue request <br>
1458  *
1459  * \par
1460  * The function is used to restart a transaction which was stopped using the "Stop at
1461  * block gap" request. (XMC_SDMMC_SetStopAtBlockGap())
1462  */
XMC_SDMMC_SetContinueRequest(XMC_SDMMC_t * const sdmmc,bool enabled)1463 __STATIC_INLINE void XMC_SDMMC_SetContinueRequest(XMC_SDMMC_t *const sdmmc, bool enabled)
1464 {
1465   XMC_ASSERT("XMC_SDMMC_SetContinueRequest: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1466 
1467   sdmmc->BLOCK_GAP_CTRL = ((sdmmc->BLOCK_GAP_CTRL & (uint8_t)~SDMMC_BLOCK_GAP_CTRL_CONTINUE_REQ_Msk) |
1468                            (uint8_t)((uint8_t)enabled << SDMMC_BLOCK_GAP_CTRL_CONTINUE_REQ_Pos));
1469 }
1470 
1471 /**
1472  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1473  * @return bool
1474  *
1475  * \par<b>Description: </b><br>
1476  * Get continue request <br>
1477  *
1478  * \par
1479  * The function returns the status of the BLOCK_GAP_CTRL.CONTINUE_REQ bit-field. It
1480  * returns "true" if the transaction is restarted after a "stop at block gap" request.
1481  */
XMC_SDMMC_GetContinueRequest(XMC_SDMMC_t * const sdmmc)1482 __STATIC_INLINE bool XMC_SDMMC_GetContinueRequest(XMC_SDMMC_t *const sdmmc)
1483 {
1484   XMC_ASSERT("XMC_SDMMC_GetContinueRequest: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1485 
1486   return (bool)(sdmmc->BLOCK_GAP_CTRL & (uint8_t)(1U << SDMMC_BLOCK_GAP_CTRL_CONTINUE_REQ_Pos));
1487 }
1488 
1489 /**
1490  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1491  * @param config A pointer to the SDMMC configuration structure (::XMC_SDMMC_CONFIG_t)
1492  * @return None
1493  *
1494  * \par<b>Description: </b><br>
1495  * Enable interrupt at block gap <br>
1496  *
1497  * \par
1498  * The function sets the BLOCK_GAP_CTRL.INT_AT_BLOCK_GAP bit-field to enable interrupt
1499  * at block gap for a multi-block transfer. This bit is only valid in a 4-bit mode of
1500  * the SDIO card.
1501  */
XMC_SDMMC_EnableInterruptAtBlockGap(XMC_SDMMC_t * const sdmmc,const XMC_SDMMC_CONFIG_t * config)1502 __STATIC_INLINE void XMC_SDMMC_EnableInterruptAtBlockGap(XMC_SDMMC_t *const sdmmc, const XMC_SDMMC_CONFIG_t *config)
1503 {
1504   XMC_ASSERT("XMC_SDMMC_EnableInterruptAtBlockGap: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1505   XMC_ASSERT("XMC_SDMMC_EnableInterruptAtBlockGap: This operation is only valid in 4-bit mode",
1506              (config->bus_width == XMC_SDMMC_DATA_LINES_1));
1507 
1508   XMC_UNUSED_ARG(config);
1509   sdmmc->BLOCK_GAP_CTRL |= (uint8_t)SDMMC_BLOCK_GAP_CTRL_INT_AT_BLOCK_GAP_Msk;
1510 }
1511 
1512 /**
1513  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1514  * @param config A pointer to the SDMMC configuration structure (::XMC_SDMMC_CONFIG_t)
1515  * @return None
1516  *
1517  * \par<b>Description: </b><br>
1518  * Disable interrupt at block gap <br>
1519  *
1520  * \par
1521  * The function resets the BLOCK_GAP_CTRL.INT_AT_BLOCK_GAP bit-field to disable interrupt
1522  * at block gap. This bit is only valid in a 4-bit mode of the SDIO card.
1523  */
XMC_SDMMC_DisableInterruptAtBlockGap(XMC_SDMMC_t * const sdmmc,const XMC_SDMMC_CONFIG_t * config)1524 __STATIC_INLINE void XMC_SDMMC_DisableInterruptAtBlockGap(XMC_SDMMC_t *const sdmmc,
1525                                                           const XMC_SDMMC_CONFIG_t *config)
1526 
1527 {
1528   XMC_ASSERT("XMC_SDMMC_EnableInterruptAtBlockGap: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1529   XMC_ASSERT("XMC_SDMMC_EnableInterruptAtBlockGap: This operation is only valid in 4-bit mode",
1530              (config->bus_width == XMC_SDMMC_DATA_LINES_1));
1531 
1532   XMC_UNUSED_ARG(config);
1533   sdmmc->BLOCK_GAP_CTRL &= (uint8_t)~SDMMC_BLOCK_GAP_CTRL_INT_AT_BLOCK_GAP_Msk;
1534 }
1535 
1536 /**
1537  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1538  * @param clk Desired clock frequency (::XMC_SDMMC_SDCLK_FREQ_SEL_t)
1539  * @return None
1540  *
1541  * \par<b>Description: </b><br>
1542  * Set SD clock frequency <br>
1543  *
1544  * \par
1545  * The function sets the CLOCK_CTRL register to configure the frequency of the SD clock
1546  * pin. The register is programmed with the divisor of the base clock frequency (clk).
1547  *
1548  * The following settings are permitted (8-bit divided clock mode): <br>
1549  * 00H: base clock (10MHz->63MHz) <br>
1550  * 01H: base clock divided by 2   <br>
1551  * 10H: base clock divided by 32  <br>
1552  * 02H: base clock divided by 4   <br>
1553  * 04H: base clock divided by 8   <br>
1554  * 08H: base clock divided by 16  <br>
1555  * 20H: base clock divided by 64  <br>
1556  * 40H: base clock divided by 128 <br>
1557  * 80H: base clock divided by 256 <br>
1558  *
1559  * \par<b>Note: </b><br>
1560  * The internal clock should be disabled before updating frequency clock select. Please
1561  * see section 2.2.14 -> "Clock Control Register" in the SD HOST specification for more
1562  * information.
1563  */
XMC_SDMMC_SDClockFreqSelect(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_SDCLK_FREQ_SEL_t clk)1564 __STATIC_INLINE void XMC_SDMMC_SDClockFreqSelect(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_SDCLK_FREQ_SEL_t clk)
1565 {
1566   XMC_ASSERT("XMC_SDMMC_SDClockFreqSelect: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1567   XMC_ASSERT("XMC_SDMMC_SDClockFreqSelect: Invalid clock frequency selection", XMC_SDMMC_CHECK_SDCLK_FREQ(clk));
1568 
1569   sdmmc->CLOCK_CTRL = (uint16_t)((sdmmc->CLOCK_CTRL & (uint32_t)~SDMMC_CLOCK_CTRL_SDCLK_FREQ_SEL_Msk) |
1570                                  (uint32_t)(clk << SDMMC_CLOCK_CTRL_SDCLK_FREQ_SEL_Pos));
1571 }
1572 
1573 /**
1574  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1575  * @param bus_voltage Desired bus voltage (::XMC_SDMMC_BUS_VOLTAGE_t)
1576  * @return None
1577  *
1578  * \par<b>Description: </b><br>
1579  * Set SDMMC bus voltage <br>
1580  *
1581  * \par
1582  * The function sets the CLOCK_CTRL register to configure the bus voltage. Currently,
1583  * 3.3 volts is the supported voltage level. This function is relevant within the host
1584  * controller initialization routine.
1585  */
XMC_SDMMC_SetBusVoltage(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_BUS_VOLTAGE_t bus_voltage)1586 __STATIC_INLINE void XMC_SDMMC_SetBusVoltage(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_BUS_VOLTAGE_t bus_voltage)
1587 {
1588   XMC_ASSERT("XMC_SDMMC_SetBusVoltage: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1589   XMC_ASSERT("XMC_SDMMC_SetBusVoltage: Invalid bus voltage", XMC_SDMMC_CHECK_BUS_VOLTAGE(bus_voltage));
1590 
1591   sdmmc->POWER_CTRL = (uint8_t)((sdmmc->POWER_CTRL & (uint32_t)~SDMMC_POWER_CTRL_SD_BUS_VOLTAGE_SEL_Msk) |
1592                                 (uint32_t)(bus_voltage << SDMMC_POWER_CTRL_SD_BUS_VOLTAGE_SEL_Pos));
1593 }
1594 
1595 /**
1596  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1597  * @param timeout Data line timeout value
1598  * @return None
1599  *
1600  * \par<b>Description: </b><br>
1601  * Set data line timeout <br>
1602  *
1603  * \par
1604  * Use the function to set the interval by which the data line timeouts are detected. The
1605  * timeout clock frequency is generated by dividing the SD clock (TMCLK) by the timeout argument.
1606  * This function must be called before setting the bus voltage (XMC_SDMMC_SetBusVoltage()).
1607  */
XMC_SDMMC_SetDataLineTimeout(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_DAT_TIMEOUT_COUNTER_t timeout)1608 __STATIC_INLINE void XMC_SDMMC_SetDataLineTimeout(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_DAT_TIMEOUT_COUNTER_t timeout)
1609 {
1610   XMC_ASSERT("XMC_SDMMC_SetDataLineTimeout: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1611   XMC_ASSERT("XMC_SDMMC_SetDataLineTimeout: Invalid timeout", XMC_SDMMC_CHECK_DAT_TIMEOUT_COUNTER(timeout));
1612 
1613   sdmmc->TIMEOUT_CTRL = (uint8_t)((sdmmc->TIMEOUT_CTRL & (uint32_t)~SDMMC_TIMEOUT_CTRL_DAT_TIMEOUT_CNT_VAL_Msk) |
1614                                   (uint32_t)(timeout << SDMMC_TIMEOUT_CTRL_DAT_TIMEOUT_CNT_VAL_Pos));
1615 }
1616 
1617 /**
1618  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1619  * @param lines Number of data lines to use  (::XMC_SDMMC_DATA_LINES_t)
1620  * @return None
1621  *
1622  * \par<b>Description: </b><br>
1623  * Set data transfer width <br>
1624  *
1625  * \par
1626  * Use the function to set the data transfer width. Before using this function, an ACMD6
1627  * command (with R1 response type) must be sent to switch the bus width.
1628  */
XMC_SDMMC_SetDataTransferWidth(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_DATA_LINES_t lines)1629 __STATIC_INLINE void XMC_SDMMC_SetDataTransferWidth(XMC_SDMMC_t *const sdmmc, XMC_SDMMC_DATA_LINES_t lines)
1630 {
1631   XMC_ASSERT("XMC_SDMMC_SetDataTransferWidth: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1632   XMC_ASSERT("XMC_SDMMC_SetDataTransferWidth: Invalid no. of data lines", XMC_SDMMC_CHECK_DATA_LINES(lines));
1633 
1634   sdmmc->HOST_CTRL &= (uint8_t)~(XMC_SDMMC_DATA_LINES_1 | XMC_SDMMC_DATA_LINES_4 | XMC_SDMMC_DATA_LINES_8);
1635   sdmmc->HOST_CTRL |= (uint8_t)lines;
1636 }
1637 
1638 /**
1639  * @param sdmmc A constant pointer to XMC_SDMMC_t, pointing to the SDMMC base address
1640  * @param dir Transfer direction (::XMC_SDMMC_DATA_TRANSFER_DIR_t)
1641  * @return None
1642  *
1643  * \par<b>Description: </b><br>
1644  * Set data transfer direction <br>
1645  *
1646  * \par
1647  * Use the function to set the data transfer direction: host to card OR card to host. It
1648  * is typically used to configure block operations (read/write) on the SD card. For
1649  * example, XMC_SDMMC_DATA_TRANSFER_HOST_TO_CARD must be used for a write block operation.
1650  */
XMC_SDMMC_SetDataTransferDirection(XMC_SDMMC_t * const sdmmc,XMC_SDMMC_DATA_TRANSFER_DIR_t dir)1651 __STATIC_INLINE void XMC_SDMMC_SetDataTransferDirection(XMC_SDMMC_t *const sdmmc,
1652                                                         XMC_SDMMC_DATA_TRANSFER_DIR_t dir)
1653 {
1654   XMC_ASSERT("XMC_SDMMC_SetDataTransferDirection: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1655   XMC_ASSERT("XMC_SDMMC_SetDataTransferDirection: Invalid direction", XMC_SDMMC_CHECK_DATA_TRANSFER_DIR(dir));
1656 
1657   sdmmc->TRANSFER_MODE = (uint16_t)((sdmmc->TRANSFER_MODE & (uint16_t)~SDMMC_TRANSFER_MODE_TX_DIR_SELECT_Msk) |
1658                                   (uint16_t)((uint16_t)dir << SDMMC_TRANSFER_MODE_TX_DIR_SELECT_Pos));
1659 }
1660 
1661 /**
1662  * @param None
1663  * @return None
1664  *
1665  * \par<b>Description: </b><br>
1666  * Enable delay on the command/data out lines <br>
1667  *
1668  * \par
1669  * Use the function to enable delay on the command/data out lines. Invoke this function
1670  * before selecting the number of delay elements.
1671  */
XMC_SDMMC_EnableDelayCmdDatLines(void)1672 __STATIC_INLINE void XMC_SDMMC_EnableDelayCmdDatLines(void)
1673 {
1674   SCU_GENERAL->SDMMCDEL |= (uint32_t)SCU_GENERAL_SDMMCDEL_TAPEN_Msk;
1675 }
1676 
1677 /**
1678  * @param None
1679  * @return None
1680  *
1681  * \par<b>Description: </b><br>
1682  * Disable delay on the command/data out lines <br>
1683  *
1684  * \par
1685  * Use the function to disable delay on the command/data out lines.
1686  */
XMC_SDMMC_DisableDelayCmdDatLines(void)1687 __STATIC_INLINE void XMC_SDMMC_DisableDelayCmdDatLines(void)
1688 {
1689   SCU_GENERAL->SDMMCDEL &= (uint32_t)~SCU_GENERAL_SDMMCDEL_TAPEN_Msk;
1690 }
1691 
1692 /**
1693  * @param tapdel Number of delay elements to select
1694  * @return None
1695  *
1696  * \par<b>Description: </b><br>
1697  * Set number of delay elements on the command/data out lines <br>
1698  *
1699  * \par
1700  * Use the function to set the number of delay elements on the command/data out lines.
1701  * The function writes the delay value to the SDMMC delay control register (SDMMCDEL)
1702  * within the realm of the SCU peripheral. A delay of tapdel + 1 is considered as the
1703  * final selected number of delay elements.
1704  */
XMC_SDMMC_SetDelay(uint8_t tapdel)1705 __STATIC_INLINE void XMC_SDMMC_SetDelay(uint8_t tapdel)
1706 {
1707   SCU_GENERAL->SDMMCDEL = (uint32_t)((SCU_GENERAL->SDMMCDEL & (uint32_t)~SCU_GENERAL_SDMMCDEL_TAPDEL_Msk) |
1708                                   (uint32_t)(tapdel << SCU_GENERAL_SDMMCDEL_TAPDEL_Pos));
1709 }
1710 
1711 /**
1712  * @param None
1713  * @return None
1714  *
1715  * \par<b>Description: </b><br>
1716  * High speed enable <br>
1717  *
1718  * \par
1719  * Use the function to enable high speed operation. The default is a normal speed operation.
1720  * Once enabled, the host controller outputs command and data lines at the rising edge of the
1721  * SD clock (up to 50 MHz for SD).
1722  */
XMC_SDMMC_EnableHighSpeed(XMC_SDMMC_t * const sdmmc)1723 __STATIC_INLINE void XMC_SDMMC_EnableHighSpeed(XMC_SDMMC_t *const sdmmc)
1724 {
1725   XMC_ASSERT("XMC_SDMMC_EnableHighSpeed: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1726 
1727   sdmmc->HOST_CTRL |= (uint8_t)SDMMC_HOST_CTRL_HIGH_SPEED_EN_Msk;
1728 }
1729 
1730 /**
1731  * @param None
1732  * @return None
1733  *
1734  * \par<b>Description: </b><br>
1735  * High speed disable <br>
1736  *
1737  * \par
1738  * Use the function to disable high speed operation. The host controller will switch back
1739  * to a normal speed mode. In this mode, the host controller outputs command and data lines
1740  * at 25 MHz for SD.
1741  */
XMC_SDMMC_DisableHighSpeed(XMC_SDMMC_t * const sdmmc)1742 __STATIC_INLINE void XMC_SDMMC_DisableHighSpeed(XMC_SDMMC_t *const sdmmc)
1743 {
1744   XMC_ASSERT("XMC_SDMMC_DisableHighSpeed: Invalid module pointer", XMC_SDMMC_CHECK_MODULE_PTR(sdmmc));
1745 
1746   sdmmc->HOST_CTRL &= (uint8_t)~SDMMC_HOST_CTRL_HIGH_SPEED_EN_Msk;
1747 }
1748 
1749 #ifdef __cplusplus
1750 }
1751 #endif
1752 
1753 /**
1754  * @}
1755  */
1756 
1757 /**
1758  * @}
1759  */
1760 
1761 #endif /* #if defined (SDMMC) */
1762 
1763 #endif
1764