1 /*!
2  * @file        apm32f10x_sdio.h
3  *
4  * @brief       This file contains all the functions prototypes for the SDIO firmware library
5  *
6  * @version     V1.0.4
7  *
8  * @date        2022-12-01
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be useful and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Define to prevent recursive inclusion */
27 #ifndef __APM32F10X_SDIO_H
28 #define __APM32F10X_SDIO_H
29 
30 /* Includes */
31 #include "apm32f10x.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /** @addtogroup APM32F10x_StdPeriphDriver
38   @{
39 */
40 
41 /** @addtogroup SDIO_Driver SDIO Driver
42   @{
43 */
44 
45 /** @defgroup SDIO_Enumerations Enumerations
46   @{
47 */
48 
49 /**
50  * @brief    SDIO clock edge
51  */
52 typedef enum
53 {
54     SDIO_CLOCK_EDGE_RISING        = 0x00000000,
55     SDIO_CLOCK_EDGE_FALLING       = 0x00002000
56 } SDIO_CLOCK_EDGE_T;
57 
58 /**
59  * @brief    SDIO clock bypass
60  */
61 typedef enum
62 {
63     SDIO_CLOCK_BYPASS_DISABLE     = 0x00000000,
64     SDIO_CLOCK_BYPASS_ENABLE      = 0x00000400
65 } SDIO_CLOCK_BYPASS_T;
66 
67 /**
68  * @brief    SDIO clock power save
69  */
70 typedef enum
71 {
72     SDIO_CLOCK_POWER_SAVE_DISABLE = 0x00000000,
73     SDIO_CLOCK_POWER_SAVE_ENABLE  = 0x00000200
74 } SDIO_CLOCK_POWER_SAVE_T;
75 
76 /**
77  * @brief    SDIO bus wide
78  */
79 typedef enum
80 {
81     SDIO_BUS_WIDE_1B = 0x00000000,
82     SDIO_BUS_WIDE_4B = 0x00000800,
83     SDIO_BUS_WIDE_8B = 0x00001000
84 } SDIO_BUS_WIDE_T;
85 
86 /**
87  * @brief    SDIO hardware flow control
88  */
89 typedef enum
90 {
91     SDIO_HARDWARE_FLOW_CONTROL_DISABLE = 0x00000000,
92     SDIO_HARDWARE_FLOW_CONTROL_ENABLE  = 0x00004000
93 } SDIO_HARDWARE_FLOW_CONTROL_T;
94 
95 /**
96  * @brief    SDIO power state
97  */
98 typedef enum
99 {
100     SDIO_POWER_STATE_OFF = 0x00000000,
101     SDIO_POWER_STATE_ON  = 0x00000003
102 } SDIO_POWER_STATE_T;
103 
104 /**
105  * @brief    SDIO interrupt sources
106  */
107 typedef enum
108 {
109     SDIO_INT_COMRESP    = 0x00000001,
110     SDIO_INT_DBDR       = 0x00000002,
111     SDIO_INT_CMDRESTO   = 0x00000004,
112     SDIO_INT_DATATO     = 0x00000008,
113     SDIO_INT_TXUDRER    = 0x00000010,
114     SDIO_INT_RXOVRER    = 0x00000020,
115     SDIO_INT_CMDRES     = 0x00000040,
116     SDIO_INT_CMDSENT    = 0x00000080,
117     SDIO_INT_DATAEND    = 0x00000100,
118     SDIO_INT_SBE        = 0x00000200,
119     SDIO_INT_DBCP       = 0x00000400,
120     SDIO_INT_CMDACT     = 0x00000800,
121     SDIO_INT_TXACT      = 0x00001000,
122     SDIO_INT_RXACT      = 0x00002000,
123     SDIO_INT_TXFHF      = 0x00004000,
124     SDIO_INT_RXFHF      = 0x00008000,
125     SDIO_INT_TXFF       = 0x00010000,
126     SDIO_INT_RXFF       = 0x00020000,
127     SDIO_INT_TXFE       = 0x00040000,
128     SDIO_INT_RXFE       = 0x00080000,
129     SDIO_INT_TXDA       = 0x00100000,
130     SDIO_INT_RXDA       = 0x00200000,
131     SDIO_INT_SDIOINT    = 0x00400000,
132     SDIO_INT_ATAEND     = 0x00800000
133 } SDIO_INT_T;
134 
135 /**
136  * @brief    SDIO response
137  */
138 typedef enum
139 {
140     SDIO_RESPONSE_NO    = 0x00000000,
141     SDIO_RESPONSE_SHORT = 0x00000040,
142     SDIO_RESPONSE_LONG  = 0x000000C0
143 } SDIO_RESPONSE_T;
144 
145 /**
146  * @brief    SDIO wait interrupt state
147  */
148 typedef enum
149 {
150     SDIO_WAIT_NO        = 0x00000000,
151     SDIO_WAIT_INT       = 0x00000100,
152     SDIO_WAIT_PEND      = 0x00000200
153 } SDIO_WAIT_T;
154 
155 /**
156  * @brief    SDIO CPSM state
157  */
158 typedef enum
159 {
160     SDIO_CPSM_DISABLE   = 0x00000000,
161     SDIO_CPSM_ENABLE    = 0x00000400
162 } SDIO_CPSM_T;
163 
164 /**
165  * @brief    SDIO response registers
166  */
167 typedef enum
168 {
169     SDIO_RES1 = 0x00000000,
170     SDIO_RES2 = 0x00000004,
171     SDIO_RES3 = 0x00000008,
172     SDIO_RES4 = 0x0000000C
173 } SDIO_RES_T;
174 
175 /**
176  * @brief    SDIO data block size
177  */
178 typedef enum
179 {
180     SDIO_DATA_BLOCKSIZE_1B     = 0x00000000,
181     SDIO_DATA_BLOCKSIZE_2B     = 0x00000010,
182     SDIO_DATA_BLOCKSIZE_4B     = 0x00000020,
183     SDIO_DATA_BLOCKSIZE_8B     = 0x00000030,
184     SDIO_DATA_BLOCKSIZE_16B    = 0x00000040,
185     SDIO_DATA_BLOCKSIZE_32B    = 0x00000050,
186     SDIO_DATA_BLOCKSIZE_64B    = 0x00000060,
187     SDIO_DATA_BLOCKSIZE_128B   = 0x00000070,
188     SDIO_DATA_BLOCKSIZE_256B   = 0x00000080,
189     SDIO_DATA_BLOCKSIZE_512B   = 0x00000090,
190     SDIO_DATA_BLOCKSIZE_1024B  = 0x000000A0,
191     SDIO_DATA_BLOCKSIZE_2048B  = 0x000000B0,
192     SDIO_DATA_BLOCKSIZE_496B   = 0x000000C0,
193     SDIO_DATA_BLOCKSIZE_8192B  = 0x000000D0,
194     SDIO_DATA_BLOCKSIZE_16384B = 0x000000E0
195 } SDIO_DATA_BLOCKSIZE_T;
196 
197 /**
198  * @brief    SDIO transfer direction
199  */
200 typedef enum
201 {
202     SDIO_TRANSFER_DIR_TO_CARD   = 0x00000000,
203     SDIO_TRANSFER_DIR_TO_SDIO   = 0x00000002
204 } SDIO_TRANSFER_DIR_T;
205 
206 /**
207  * @brief    SDIO transfer type
208  */
209 typedef enum
210 {
211     SDIO_TRANSFER_MODE_BLOCK   = 0x00000000,
212     SDIO_TRANSFER_MODE_STREAM  = 0x00000004
213 } SDIO_TRANSFER_MODE_T;
214 
215 /**
216  * @brief    SDIO DPSM state
217  */
218 typedef enum
219 {
220     SDIO_DPSM_DISABLE          = 0x00000000,
221     SDIO_DPSM_ENABLE           = 0x00000001
222 } SDIO_DPSM_T;
223 
224 /**
225  * @brief    SDIO flag
226  */
227 typedef enum
228 {
229     SDIO_FLAG_COMRESP   = 0x00000001,
230     SDIO_FLAG_DBDR      = 0x00000002,
231     SDIO_FLAG_CMDRESTO  = 0x00000004,
232     SDIO_FLAG_DATATO    = 0x00000008,
233     SDIO_FLAG_TXUDRER   = 0x00000010,
234     SDIO_FLAG_RXOVRER   = 0x00000020,
235     SDIO_FLAG_CMDRES    = 0x00000040,
236     SDIO_FLAG_CMDSENT   = 0x00000080,
237     SDIO_FLAG_DATAEND   = 0x00000100,
238     SDIO_FLAG_SBE       = 0x00000200,
239     SDIO_FLAG_DBCP      = 0x00000400,
240     SDIO_FLAG_CMDACT    = 0x00000800,
241     SDIO_FLAG_TXACT     = 0x00001000,
242     SDIO_FLAG_RXACT     = 0x00002000,
243     SDIO_FLAG_TXFHF     = 0x00004000,
244     SDIO_FLAG_RXFHF     = 0x00008000,
245     SDIO_FLAG_TXFF      = 0x00010000,
246     SDIO_FLAG_RXFF      = 0x00020000,
247     SDIO_FLAG_TXFE      = 0x00040000,
248     SDIO_FLAG_RXFE      = 0x00080000,
249     SDIO_FLAG_TXDA      = 0x00100000,
250     SDIO_FLAG_RXDA      = 0x00200000,
251     SDIO_FLAG_SDIOINT   = 0x00400000,
252     SDIO_FLAG_ATAEND    = 0x00800000
253 } SDIO_FLAG_T;
254 
255 /**
256  * @brief    SDIO read wait mode
257  */
258 typedef enum
259 {
260     SDIO_READ_WAIT_MODE_CLK   = 0x00000001,
261     SDIO_READ_WAIT_MODE_DATA2 = 0x00000000
262 } SDIO_READ_WAIT_MODE_T;
263 
264 /**@} end of group SDIO_Enumerations */
265 
266 
267 /** @defgroup SDIO_Macros Macros
268   @{
269 */
270 
271 /* ------------ SDIO registers bit address in the alias region ----------- */
272 #define SDIO_OFFSET                (SDIO_BASE - PERIPH_BASE)
273 
274 /* --- CLKCTRL Register --- */
275 
276 /* Alias word address of CLKEN bit */
277 #define CLKCTRL_OFFSET            (SDIO_OFFSET + 0x04)
278 #define CLKEN_BitNumber            0x08
279 #define CLKCTRL_CLKEN_BB          (PERIPH_BB_BASE + (CLKCTRL_OFFSET * 32) + (CLKEN_BitNumber * 4))
280 
281 /* --- CMD Register --- */
282 
283 /* Alias word address of SDIOSC bit */
284 #define CMD_OFFSET                (SDIO_OFFSET + 0x0C)
285 #define SDIOSC_BitNumber           0x0B
286 #define CMD_SDIOSC_BB             (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSC_BitNumber * 4))
287 
288 /* Alias word address of CMDCPEN bit */
289 #define CMDCPEN_BitNumber          0x0C
290 #define CMD_CMDCPEN_BB            (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (CMDCPEN_BitNumber * 4))
291 
292 /* Alias word address of INTEN bit */
293 #define INTEN_BitNumber            0x0D
294 #define CMD_INTEN_BB              (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (INTEN_BitNumber * 4))
295 
296 /* Alias word address of ATACMD bit */
297 #define ATACMD_BitNumber           0x0E
298 #define CMD_ATACMD_BB             (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BitNumber * 4))
299 
300 /* --- DCTRL Register --- */
301 
302 /* Alias word address of DMAEN bit */
303 #define DCTRL_OFFSET              (SDIO_OFFSET + 0x2C)
304 #define DMAEN_BitNumber            0x03
305 #define DCTRL_DMAEN_BB            (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BitNumber * 4))
306 
307 /* Alias word address of RWSTR bit */
308 #define RWSTR_BitNumber            0x08
309 #define DCTRL_RWSTR_BB            (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTR_BitNumber * 4))
310 
311 /* Alias word address of RWSTOP bit */
312 #define RWSTOP_BitNumber           0x09
313 #define DCTRL_RWSTOP_BB           (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BitNumber * 4))
314 
315 /* Alias word address of RDWAIT bit */
316 #define RDWAIT_BitNumber           0x0A
317 #define DCTRL_RDWAIT_BB           (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RDWAIT_BitNumber * 4))
318 
319 /* Alias word address of SDIOF bit */
320 #define SDIOF_BitNumber            0x0B
321 #define DCTRL_SDIOF_BB            (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOF_BitNumber * 4))
322 
323 /**@} end of group SDIO_Macros */
324 
325 /** @defgroup SDIO_Structures Structures
326   @{
327 */
328 
329 /**
330  * @brief    SDIO Configure structure definition
331  */
332 typedef struct
333 {
334     SDIO_CLOCK_EDGE_T            clockEdge;
335     SDIO_CLOCK_BYPASS_T          clockBypass;
336     SDIO_CLOCK_POWER_SAVE_T      clockPowerSave;
337     SDIO_BUS_WIDE_T              busWide;
338     SDIO_HARDWARE_FLOW_CONTROL_T hardwareFlowControl;
339     uint8_t                      clockDiv;
340 } SDIO_Config_T;
341 
342 /**
343  * @brief    SDIO CMD Configure structure definition
344  */
345 typedef struct
346 {
347     uint32_t                     argument;
348     uint32_t                     cmdIndex;
349     SDIO_RESPONSE_T              response;
350     SDIO_WAIT_T                  wait;
351     SDIO_CPSM_T                  CPSM;
352 } SDIO_CmdConfig_T;
353 
354 /**
355  * @brief    SDIO Data Configure structure definition
356  */
357 typedef struct
358 {
359     uint32_t                     dataTimeOut;
360     uint32_t                     dataLength;
361     SDIO_DATA_BLOCKSIZE_T        dataBlockSize;
362     SDIO_TRANSFER_DIR_T          transferDir;
363     SDIO_TRANSFER_MODE_T         transferMode;
364     SDIO_DPSM_T                  DPSM;
365 } SDIO_DataConfig_T;
366 
367 /**@} end of group SDIO_Structures */
368 
369 /** @defgroup SDIO_Functions Functions
370   @{
371 */
372 
373 /* SDIO reset and configuration */
374 void SDIO_Reset(void);
375 void SDIO_Config(SDIO_Config_T* sdioConfig);
376 void SDIO_ConfigStructInit(SDIO_Config_T* sdioConfig);
377 void SDIO_EnableClock(void);
378 void SDIO_DisableClock(void);
379 void SDIO_ConfigPowerState(SDIO_POWER_STATE_T powerState);
380 uint32_t SDIO_ReadPowerState(void);
381 
382 /* DMA */
383 void SDIO_EnableDMA(void);
384 void SDIO_DisableDMA(void);
385 
386 /* Command */
387 void SDIO_TxCommand(SDIO_CmdConfig_T* cmdConfig);
388 void SDIO_TxCommandStructInit(SDIO_CmdConfig_T* cmdconfig);
389 uint8_t SDIO_ReadCommandResponse(void);
390 uint32_t SDIO_ReadResponse(SDIO_RES_T res);
391 
392 /* SDIO data configuration */
393 void SDIO_ConfigData(SDIO_DataConfig_T* dataConfig);
394 void SDIO_ConfigDataStructInit(SDIO_DataConfig_T* dataConfig);
395 uint32_t SDIO_ReadDataCounter(void);
396 void SDIO_WriteData(uint32_t data);
397 uint32_t SDIO_ReadData(void);
398 uint32_t SDIO_ReadFIFOCount(void);
399 
400 /* SDIO mode */
401 void SDIO_EnableStartReadWait(void);
402 void SDIO_DisableStartReadWait(void);
403 void SDIO_EnableStopReadWait(void);
404 void SDIO_DisableStopReadWait(void);
405 void SDIO_ConfigSDIOReadWaitMode(SDIO_READ_WAIT_MODE_T readWaitMode);
406 void SDIO_EnableSDIO(void);
407 void SDIO_DisableSDIO(void);
408 void SDIO_EnableTxSDIOSuspend(void);
409 void SDIO_DisableTxSDIOSuspend(void);
410 void SDIO_EnableCommandCompletion(void);
411 void SDIO_DisableCommandCompletion(void);
412 void SDIO_EnableCEATAInterrupt(void);
413 void SDIO_DisableCEATAInterrupt(void);
414 void SDIO_EnableTxCEATA(void);
415 void SDIO_DisableTxCEATA(void);
416 
417 /* Interrupt and flags */
418 void SDIO_EnableInterrupt(uint32_t interrupt);
419 void SDIO_DisableInterrupt(uint32_t interrupt);
420 uint8_t SDIO_ReadStatusFlag(SDIO_FLAG_T flag);
421 void SDIO_ClearStatusFlag(uint32_t flag);
422 uint8_t SDIO_ReadIntFlag(SDIO_INT_T flag);
423 void SDIO_ClearIntFlag(uint32_t flag);
424 
425 /**@} end of group SDIO_Functions */
426 /**@} end of group SDIO_Driver */
427 /**@} end of group APM32F10x_StdPeriphDriver */
428 
429 #ifdef __cplusplus
430 }
431 #endif
432 
433 #endif /*__APM32F10X_SDIO_H */
434