1 /*
2  * Copyright 2021 MindMotion Microelectronics Co., Ltd.
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef __HAL_SDIO_H__
9 #define __HAL_SDIO_H__
10 
11 #include "hal_common.h"
12 
13 /*!
14  * @addtogroup SDIO
15  * @{
16  */
17 
18 /*!
19  * @brief SDIO driver version number.
20  */
21 #define SDIO_DRIVER_VERSION 0u /*!< sdio_0. */
22 
23 /*!
24  * @brief Card command return type .
25  */
26 typedef enum
27 {
28     SDIO_RespType_R1, /*!< 32 bit + 8 bit CRC. */
29     SDIO_RespType_R2, /*!< 128 bit + 8 bit CRC, for CID and CSD. */
30     SDIO_RespType_R3, /*!< 32 bit + 8 bit CRC, for OCR. */
31     SDIO_RespType_R6, /*!< 32 bit + 8 bit CRC, for RCA. */
32     SDIO_RespType_R7, /*!< 32 bit + 8 bit CRC, for card interface condition. */
33 } SDIO_RespType_Type;
34 
35 /*!
36 * @brief SDIO data bus width.
37 */
38 typedef enum
39 {
40     SDIO_DataBusWidth_1b = 0u, /*!< 1-bit data bus. */
41     SDIO_DataBusWidth_4b = 1u, /*!< 4-bit data bus. */
42 } SDIO_DataBusWidth_Type;
43 
44 /*!
45 * @brief SDIO base clock source.
46 */
47 typedef enum
48 {
49     SDIO_BaseClkSrc_1MHz   = 0u, /*!< Select 1MHz clock as the clock source of SDIO module. */
50     SDIO_BaseClkSrc_BusClk = 1u, /*!< Select bus clock as the clock source of SDIO module. */
51 } SDIO_BaseClkSrc_Type;
52 
53 /*!
54  * @brief The divider from base clock to port clk line speed.
55 */
56 typedef enum
57 {
58     SDIO_ClkLineSpeedDiv_Div2  = 0u, /*!< SDIO clk command line clock freq's divider as 2. */
59     SDIO_ClkLineSpeedDiv_Div4  = 1u, /*!< SDIO clk command line clock freq's divider as 4. */
60     SDIO_ClkLineSpeedDiv_Div6  = 2u, /*!< SDIO clk command line clock freq's divider as 6. */
61     SDIO_ClkLineSpeedDiv_Div8  = 3u, /*!< SDIO clk command line clock freq's divider as 8. */
62     SDIO_ClkLineSpeedDiv_Div10 = 4u, /*!< SDIO clk command line clock freq's divider as 10. */
63     SDIO_ClkLineSpeedDiv_Div12 = 5u, /*!< SDIO clk command line clock freq's divider as 12. */
64     SDIO_ClkLineSpeedDiv_Div14 = 6u, /*!< SDIO clk command line clock freq's divider as 14. */
65     SDIO_ClkLineSpeedDiv_Div16 = 7u, /*!< SDIO clk command line clock freq's divider as 16. */
66 } SDIO_ClkLineSpeedDiv_Type;
67 
68 /*!
69  * @brief This type of structure instance is used to keep the settings when calling the @ref SDIO_Init() to initialize the SDIO module.
70  */
71 typedef struct
72 {
73     uint32_t                  BusClkHz;        /*!< SDIO module clock freq. */
74     SDIO_BaseClkSrc_Type      BaseClkSrc;      /*!< Select the SDIO base clock source.  */
75     SDIO_ClkLineSpeedDiv_Type ClkLineSpeedDiv; /*!< Select the divider from base clock to port clk line speed. */
76 } SDIO_Init_Type;
77 
78 /*!
79  * @addtogroup SDIO_STATUS
80  * @{
81  */
82 #define SDIO_STATUS_CMD_DONE                     (1u << 0u)  /*!< Status flag when SDIO sent a command to bus. */
83 #define SDIO_STATUS_DAT_DONE                     (1u << 1u)  /*!< Status flag when SDIO sent a word of data to bus. */
84 #define SDIO_STATUS_DAT_CRC_ERR                  (1u << 2u)  /*!< Status flag when SDIO found a data crc error. */
85 #define SDIO_STATUS_CMD_CRC_ERR                  (1u << 3u)  /*!< Status flag when SDIO found a command crc error. */
86 #define SDIO_STATUS_DAT_MULTI_BLOCKS_DONE        (1u << 4u)  /*!< Status flag when SDIO sent multiple blocks of data. */
87 #define SDIO_STATUS_DAT_MULTI_BLOCKS_TIMEOUT     (1u << 5u)  /*!< Status flag when SDIO found a timeout of sending multiple blocks of data. */
88 #define SDIO_STATUS_CMD_NCR_TIMEOUT              (1u << 6u)  /*!< Status flag when SDIO found a command ncr timeout issue. */
89 #define SDIO_STATUS_CRC_CRC_ERR                  (1u << 7u)  /*!< Status flag when SDIO found a crc issue. */
90 #define SDIO_STATUS_DAT0_BUSY                    (1u << 8u)  /*!< Status flag when SDIO checked the data0 line is busy. */
91 #define SDIO_STATUS_DAT_BUF_FULL                 (1u << 9u)  /*!< Status flag when SDIO fifo buffer is full. */
92 #define SDIO_STATUS_DAT_BUF_EMPTY                (1u << 10u) /*!< Status flag when SDIO fifo buffer is empty. */
93 /*!
94  * @}
95  */
96 
97 /*!
98  * @addtogroup SDIO_INT
99  * @{
100  */
101 #define SDIO_INT_CMD_DONE                        (1u << 0u) /*!< Interrupt enable when SDIO sent a command to bus. */
102 #define SDIO_INT_DAT_DONE                        (1u << 1u) /*!< Interrupt enable when SDIO sent a word of data to bus. */
103 #define SDIO_INT_DAT_CRC_ERR                     (1u << 2u) /*!< Interrupt enable when SDIO found a data crc error. */
104 #define SDIO_INT_CMD_CRC_ERR                     (1u << 3u) /*!< Interrupt enable when SDIO found a command crc error. */
105 #define SDIO_INT_DAT_MULTI_BLOCKS_DONE           (1u << 4u) /*!< Interrupt enable when SDIO sent multiple blocks of data. */
106 #define SDIO_INT_DAT_MULTI_BLOCKS_TIMEOUT        (1u << 5u) /*!< Interrupt enable when SDIO found a timeout of sending multiple blocks of data. */
107 #define SDIO_INT_CMD_NCR_TIMEOUT                 (1u << 6u) /*!< Interrupt enable when SDIO found a command ncr timeout issue. */
108 #define SDIO_INT_CRC_CRC_ERR                     (1u << 7u) /*!< Interrupt enable when SDIO found a crc issue. */
109 #define SDIO_INT_DAT0_BUSY                       (1u << 8u) /*!< Interrupt enable when SDIO checked the data0 line is busy. */
110 /*!
111  * @}
112  */
113 
114 /*!
115  * @addtogroup SDIO_CMD_FLAG
116  * @{
117  */
118 #define SDIO_CMD_FLAG_READ_BLOCK                 (1u << 0u) /*!< SDIO command flag of reading block. */
119 #define SDIO_CMD_FLAG_WRITE_BLOCK                (1u << 1u) /*!< SDIO command flag of writing block. */
120 #define SDIO_CMD_FLAG_READ_CID_CSD               (1u << 2u) /*!< SDIO command flag of reading CID and CSD. */
121 #define SDIO_CMD_FLAG_WRITE_BLOCKS               (1u << 5u) /*!< SDIO command flag of writing multiple blocks. */
122 #define SDIO_CMD_FLAG_READ_BLOCKS                (1u << 6u) /*!< SDIO command flag of reading multiple blocks. */
123 #define SDIO_CMD_FLAG_ENABLE_DATA_XFER           (1u << 7u) /*!< SDIO command flag of starting the data transfer. */
124 /*!
125  * @}
126  */
127 
128 /*!
129  * @brief Initialize the SDIO module.
130  *
131  * @param SDIOx SDIO instance.
132  * @param init  Pointer to the initialization structure. See to @ref SDIO_Init_Type.
133  * @return None.
134  */
135 void     SDIO_Init(SDIO_Type * SDIOx, SDIO_Init_Type * init);
136 
137 /*!
138  * @brief Enable the SDIO module.
139  *
140  * @param SDIOx SDIO instance.
141  * @param enable 'true' to enable the module, 'false' to disable the module.
142  * @return None.
143  */
144 void     SDIO_Enable(SDIO_Type * SDIOx, bool enable);
145 
146 /*!
147  * @brief Setup the data bus width of the SDIO module.
148  *
149  * @param SDIOx SDIO instance.
150  * @param width SDIO data bus width. See to @ref SDIO_DataBusWidth_Type.
151  * @return None.
152  */
153 void     SDIO_SetDataBusWidth(SDIO_Type *SDIOx, SDIO_DataBusWidth_Type width);
154 
155 /*!
156  * @brief Get the status of the SDIO module.
157  *
158  * @param SDIOx SDIO instance.
159  * @return SDIO module status, see to @ref SDIO_STATUS.
160  */
161 uint32_t SDIO_GetStatus(SDIO_Type * SDIOx);
162 
163 /*!
164  * @brief Clear the status of the SDIO module.
165  *
166  * @param SDIOx SDIO instance.
167  * @param flags Indicate the flags to be cleared. See to @ref SDIO_STATUS.
168  * @return SDIO module status, see to @ref SDIO_STATUS.
169  */
170 void     SDIO_ClearStatus(SDIO_Type * SDIOx, uint32_t flags);
171 
172 /*!
173  * @brief Enable interrupts of the SDIO module.
174  *
175  * @param SDIOx SDIO instance.
176  * @param interrupts Interrupt code masks. See to @ref SDIO_INT.
177  * @param enable 'true' to enable the indicated interrupts, 'false' to disable the indicated interrupts.
178  * @return None.
179  */
180 void     SDIO_EnableInterrupts(SDIO_Type * SDIOx, uint32_t interrupts, bool enable);
181 
182 /*!
183  * @brief Execute the SD command through the SDIO module.
184  *
185  * @param SDIOx SDIO instance.
186  * @param cmd_index SD command index number.
187  * @param param SD commamd parameter.
188  * @param cmd_flags SD command option flags. See to @ref SDIO_CMD_FLAG.
189  * @return None.
190  */
191 void     SDIO_ExecuteCmd(SDIO_Type * SDIOx, uint8_t cmd_index, uint32_t param, uint32_t cmd_flags);
192 
193 /*!
194  * @brief Send data when executing the SD command through the SDIO module.
195  *
196  * @param SDIOx SDIO instance.
197  * @param cmd_flags SD command option flags. See to @ref SDIO_CMD_FLAG.
198  * @return None.
199  */
200 void     SDIO_ExecuteData(SDIO_Type * SDIOx, uint32_t cmd_flags);
201 
202 /*!
203  * @brief Receive the return type at the end of executing SD command.
204  *
205  * @param SDIOx SDIO instance.
206  * @param resp_type SD command return type. See to @ref SDIO_RespType_Type.
207  * @param resp Pointer to a buffer, which would be used to keep the return value.
208  * @return None.
209  */
210 void     SDIO_RequestResp(SDIO_Type * SDIOx, SDIO_RespType_Type resp_type, uint32_t *resp);
211 
212 /*!
213  * @brief Put data into the FIFO inside the SDIO module.
214  *
215  * @param SDIOx SDIO instance.
216  * @param dat Data word to be put into the FIFO.
217  * @return None.
218  */
219 void     SDIO_PutFifoData(SDIO_Type * SDIOx, uint32_t dat);
220 
221 /*!
222  * @brief Get data from the FIFO inside the SDIO module.
223  *
224  * @param SDIOx SDIO instance.
225  * @return Data word from the FIFO.
226  */
227 uint32_t SDIO_GetFifoData(SDIO_Type * SDIOx);
228 
229 /*!
230  * @brief Clear all data of the FIFO inside the SDIO module.
231  *
232  * @param SDIOx SDIO instance.
233  * @return None.
234  */
235 void     SDIO_ClearFifoData(SDIO_Type * SDIOx);
236 
237 /*!
238  * @brief Setup the data direction of data transfer.
239  *
240  * @param SDIOx SDIO instance.
241  * @param write 'true' to setup as write, 'false' to setup as read.
242  * @return None.
243  */
244 void     SDIO_SwitchFifoWrite(SDIO_Type * SDIOx, bool write);
245 
246 /*!
247  * @brief Setup the watermark of the FIFO inside the SDIO module.
248  *
249  * @param SDIOx SDIO instance.
250  * @param word_cnt Indicated the watermark value.
251  * @return None.
252  */
253 void     SDIO_SetFifoWatermark(SDIO_Type * SDIOx, uint32_t word_cnt);
254 
255 /*!
256  * @brief Enable the DMA of SDIO module
257  *
258  * @param SDIOx SDIO instance.
259  * @param enable 'true' to enable the DMA, while 'false' to disable.
260  * @return None.
261  */
262 void     SDIO_EnableFifoDMA(SDIO_Type * SDIOx, bool enable);
263 
264 /*!
265  * @brief Setup count number for the read multiple block operation.
266  *
267  * @param SDIOx SDIO instance.
268  * @param blk_cnt Indicated the count number of blocks.
269  * @return None.
270  */
271 void     SDIO_SetMultiBlockCount(SDIO_Type * SDIOx, uint32_t blk_cnt);
272 
273 /*!
274  * @brief Enable the wait operation when reading the FIFO.
275  *
276  * @param SDIOx SDIO instance.
277  * @param enable 'true' to enable the wait operation, 'false' to disable this function.
278  * @return None.
279  */
280 void     SDIO_EnableFifoReadWait(SDIO_Type * SDIOx, bool enable);
281 
282 /*!
283  * @}
284  */
285 
286 #endif /* __HAL_SDIO_H__ */
287 
288