1 /*!
2  * @file        apm32f4xx_sdio.h
3  *
4  * @brief       This file contains all the functions prototypes for the SDIO firmware
5  *              library.
6  *
7  * @version     V1.0.2
8  *
9  * @date        2022-06-23
10  *
11  * @attention
12  *
13  *  Copyright (C) 2021-2022 Geehy Semiconductor
14  *
15  *  You may not use this file except in compliance with the
16  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
17  *
18  *  The program is only for reference, which is distributed in the hope
19  *  that it will be usefull and instructional for customers to develop
20  *  their software. Unless required by applicable law or agreed to in
21  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
22  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
23  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
24  *  and limitations under the License.
25  */
26 
27 /* Define to prevent recursive inclusion */
28 #ifndef __APM32F4XX_SDIO_H
29 #define __APM32F4XX_SDIO_H
30 
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34 
35 /* Includes */
36 #include "apm32f4xx.h"
37 
38 /** @addtogroup APM32F4xx_StdPeriphDriver
39   @{
40 */
41 
42 /** @addtogroup SDIO_Driver
43   @{
44 */
45 
46 /** @defgroup SDIO_Enumerations
47   @{
48 */
49 
50 /**
51  * @brief SDIO clock edge
52  */
53 typedef enum
54 {
55     SDIO_CLOCK_EDGE_RISING, /*!< Select rising edge of SDIOCLK to generate SDIO_CLK */
56     SDIO_CLOCK_EDGE_FALLING /*!< Select falling edge of SDIOCLK to generate SDIO_CLK */
57 } SDIO_CLOCK_EDGE_T;
58 
59 /**
60  * @brief SDIO clock bypass
61  */
62 typedef enum
63 {
64     SDIO_CLOCK_BYPASS_DISABLE,  /*!< Disable divider bypass */
65     SDIO_CLOCK_BYPASS_ENABLE    /*!< Enable divider bypass */
66 } SDIO_CLOCK_BYPASS_T;
67 
68 /**
69  * @brief    SDIO clock power save
70  */
71 typedef enum
72 {
73     SDIO_CLOCK_POWER_SAVE_DISABLE,  /*!< Disable power saving mode */
74     SDIO_CLOCK_POWER_SAVE_ENABLE    /*!< Enable power saving mode */
75 } SDIO_CLOCK_POWER_SAVE_T;
76 
77 /**
78  * @brief SDIO bus wide
79  */
80 typedef enum
81 {
82     SDIO_BUS_WIDE_1B,   /*!< 1-bit wide bus mode */
83     SDIO_BUS_WIDE_4B,   /*!< 4-bit wide bus mode */
84     SDIO_BUS_WIDE_8B    /*!< 8-bit wide bus mode */
85 } SDIO_BUS_WIDE_T;
86 
87 /**
88  * @brief SDIO hardware flow control
89  */
90 typedef enum
91 {
92     SDIO_HARDWARE_FLOW_CONTROL_DISABLE, /*!< Disable hardware flow control */
93     SDIO_HARDWARE_FLOW_CONTROL_ENABLE   /*!< Enable hardware flow control */
94 } SDIO_HARDWARE_FLOW_CONTROL_T;
95 
96 /**
97  * @brief SDIO power state
98  */
99 typedef enum
100 {
101     SDIO_POWER_STATE_OFF = 0x00,    /*!< Power off */
102     SDIO_POWER_STATE_ON  = 0x03     /*!< Power on */
103 } SDIO_POWER_STATE_T;
104 
105 /**
106  * @brief SDIO response
107  */
108 typedef enum
109 {
110     SDIO_RESPONSE_NO    = (uint8_t)0x00,    /*!< No response */
111     SDIO_RESPONSE_SHORT = (uint8_t)0x01,    /*!< Short response */
112     SDIO_RESPONSE_LONG  = (uint8_t)0x03     /*!< Long response */
113 } SDIO_RESPONSE_T;
114 
115 /**
116  * @brief SDIO wait interrupt state
117  */
118 typedef enum
119 {
120     SDIO_WAIT_NO   = (uint8_t)0x00, /*!< No wait */
121     SDIO_WAIT_INT  = (uint8_t)0x01, /*!< Wait interrupt request */
122     SDIO_WAIT_PEND = (uint8_t)0x02  /*!< Wait CmdPend */
123 } SDIO_WAIT_T;
124 
125 /**
126  * @brief SDIO CPSM state
127  */
128 typedef enum
129 {
130     SDIO_CPSM_DISABLE,  /*!< Disable CPSM */
131     SDIO_CPSM_ENABLE    /*!< Enable CPSM */
132 } SDIO_CPSM_T;
133 
134 /**
135  * @brief SDIO response registers
136  */
137 typedef enum
138 {
139     SDIO_RES1 = ((uint8_t)0x00),    /*!< Response Register 1 */
140     SDIO_RES2 = ((uint8_t)0x04),    /*!< Response Register 2 */
141     SDIO_RES3 = ((uint8_t)0x08),    /*!< Response Register 3 */
142     SDIO_RES4 = ((uint8_t)0x0C)     /*!< Response Register 4 */
143 } SDIO_RES_T;
144 
145 /**
146  * @brief SDIO data block size
147  */
148 typedef enum
149 {
150     SDIO_DATA_BLOCKSIZE_1B,     /*!< block size = 1 byte */
151     SDIO_DATA_BLOCKSIZE_2B,     /*!< block size = 2 bytes */
152     SDIO_DATA_BLOCKSIZE_4B,     /*!< block size = 4 bytes */
153     SDIO_DATA_BLOCKSIZE_8B,     /*!< block size = 8 bytes */
154     SDIO_DATA_BLOCKSIZE_16B,    /*!< block size = 16 bytes */
155     SDIO_DATA_BLOCKSIZE_32B,    /*!< block size = 32 bytes */
156     SDIO_DATA_BLOCKSIZE_64B,    /*!< block size = 64 bytes */
157     SDIO_DATA_BLOCKSIZE_128B,   /*!< block size = 128 bytes */
158     SDIO_DATA_BLOCKSIZE_256B,   /*!< block size = 256 bytes */
159     SDIO_DATA_BLOCKSIZE_512B,   /*!< block size = 512 bytes */
160     SDIO_DATA_BLOCKSIZE_1024B,  /*!< block size = 1024 bytes */
161     SDIO_DATA_BLOCKSIZE_2048B,  /*!< block size = 2048 bytes */
162     SDIO_DATA_BLOCKSIZE_4096B,  /*!< block size = 4096 bytes */
163     SDIO_DATA_BLOCKSIZE_8192B,  /*!< block size = 8192 bytes */
164     SDIO_DATA_BLOCKSIZE_16384B  /*!< block size = 16384 bytes */
165 } SDIO_DATA_BLOCKSIZE_T;
166 
167 /**
168  * @brief SDIO transfer direction
169  */
170 typedef enum
171 {
172     SDIO_TRANSFER_DIR_TO_CARD,  /*!< Controller to SD card */
173     SDIO_TRANSFER_DIR_TO_SDIO   /*!< SD card to controller */
174 } SDIO_TRANSFER_DIR_T;
175 
176 /**
177  * @brief SDIO transfer type
178  */
179 typedef enum
180 {
181     SDIO_TRANSFER_MODE_BLOCK,   /*!< Block data mode */
182     SDIO_TRANSFER_MODE_STREAM   /*!< Stream data mode */
183 } SDIO_TRANSFER_MODE_T;
184 
185 /**
186  * @brief SDIO DPSM state
187  */
188 typedef enum
189 {
190     SDIO_DPSM_DISABLE,  /*!< Disable DPSM */
191     SDIO_DPSM_ENABLE    /*!< Enable DPSM */
192 } SDIO_DPSM_T;
193 
194 /**
195  * @brief SDIO flag
196  */
197 typedef enum
198 {
199     SDIO_FLAG_COMRESP  = ((uint32_t)0x00000001),    /*!< Command response received (CRC check failed) flag */
200     SDIO_FLAG_DBDR     = ((uint32_t)0x00000002),    /*!< Data block sent/received (CRC check failed) flag */
201     SDIO_FLAG_CMDRESTO = ((uint32_t)0x00000004),    /*!< Command response timeout flag */
202     SDIO_FLAG_DATATO   = ((uint32_t)0x00000008),    /*!< Data timeout flag */
203     SDIO_FLAG_TXUDRER  = ((uint32_t)0x00000010),    /*!< Transmit FIFO underrun error flag */
204     SDIO_FLAG_RXOVRER  = ((uint32_t)0x00000020),    /*!< Received FIFO overrun error flag */
205     SDIO_FLAG_CMDRES   = ((uint32_t)0x00000040),    /*!< Command response received (CRC check passed) flag */
206     SDIO_FLAG_CMDSENT  = ((uint32_t)0x00000080),    /*!< Command sent (no response required) flag */
207     SDIO_FLAG_DATAEND  = ((uint32_t)0x00000100),    /*!< Data end (data counter is zero) flag */
208     SDIO_FLAG_SBE      = ((uint32_t)0x00000200),    /*!< Start bit not detected on all data signals in wide bus mode flag */
209     SDIO_FLAG_DBCP     = ((uint32_t)0x00000400),    /*!< Data block sent/received (CRC check passed) flag */
210     SDIO_FLAG_CMDACT   = ((uint32_t)0x00000800),    /*!< Command transfer in progress flag */
211     SDIO_FLAG_TXACT    = ((uint32_t)0x00001000),    /*!< Data transmit in progress flag */
212     SDIO_FLAG_RXACT    = ((uint32_t)0x00002000),    /*!< Data receive in progress flag */
213     SDIO_FLAG_TXFHF    = ((uint32_t)0x00004000),    /*!< Transmit FIFO Half Empty flag */
214     SDIO_FLAG_RXFHF    = ((uint32_t)0x00008000),    /*!< Receive FIFO Half Full flag */
215     SDIO_FLAG_TXFF     = ((uint32_t)0x00010000),    /*!< Transmit FIFO full flag */
216     SDIO_FLAG_RXFF     = ((uint32_t)0x00020000),    /*!< Receive FIFO full flag */
217     SDIO_FLAG_TXFE     = ((uint32_t)0x00040000),    /*!< Transmit FIFO empty flag */
218     SDIO_FLAG_RXFE     = ((uint32_t)0x00080000),    /*!< Receive FIFO empty flag */
219     SDIO_FLAG_TXDA     = ((uint32_t)0x00100000),    /*!< Data available in transmit FIFO flag */
220     SDIO_FLAG_RXDA     = ((uint32_t)0x00200000),    /*!< Data available in receive FIFO flag */
221     SDIO_FLAG_SDIOINT  = ((uint32_t)0x00400000),    /*!< SD I/O interrupt received flag */
222     SDIO_FLAG_ATAEND   = ((uint32_t)0x00800000)     /*!< CE-ATA command completion signal received for CMD61 flag */
223 } SDIO_FLAG_T;
224 
225 /**
226  * @brief SDIO interrupt sources
227  */
228 typedef enum
229 {
230     SDIO_INT_COMRESP  = ((uint32_t)0x00000001), /*!< Command response received (CRC check failed) interrupt */
231     SDIO_INT_DBDR     = ((uint32_t)0x00000002), /*!< Data block sent/received (CRC check failed) interrupt */
232     SDIO_INT_CMDRESTO = ((uint32_t)0x00000004), /*!< Command response timeout interrupt */
233     SDIO_INT_DATATO   = ((uint32_t)0x00000008), /*!< Data timeout interrupt */
234     SDIO_INT_TXUDRER  = ((uint32_t)0x00000010), /*!< Transmit FIFO underrun error interrupt */
235     SDIO_INT_RXOVRER  = ((uint32_t)0x00000020), /*!< Received FIFO overrun error interrupt */
236     SDIO_INT_CMDRES   = ((uint32_t)0x00000040), /*!< Command response received (CRC check passed) interrupt */
237     SDIO_INT_CMDSENT  = ((uint32_t)0x00000080), /*!< Command sent (no response required) interrupt */
238     SDIO_INT_DATAEND  = ((uint32_t)0x00000100), /*!< Data end (data counter, SDIDCOUNT, is zero) interrupt */
239     SDIO_INT_SBE      = ((uint32_t)0x00000200), /*!< Start bit not detected on all data signals in wide bus mode interrupt */
240     SDIO_INT_DBCP     = ((uint32_t)0x00000400), /*!< Data block sent/received (CRC check passed) interrupt */
241     SDIO_INT_CMDACT   = ((uint32_t)0x00000800), /*!< Command transfer in progress interrupt */
242     SDIO_INT_TXACT    = ((uint32_t)0x00001000), /*!< Data transmit in progress interrupt */
243     SDIO_INT_RXACT    = ((uint32_t)0x00002000), /*!< Data receive in progress interrupt */
244     SDIO_INT_TXFHF    = ((uint32_t)0x00004000), /*!< Transmit FIFO Half Empty interrupt */
245     SDIO_INT_RXFHF    = ((uint32_t)0x00008000), /*!< Receive FIFO Half Full interrupt */
246     SDIO_INT_TXFF     = ((uint32_t)0x00010000), /*!< Transmit FIFO full interrupt */
247     SDIO_INT_RXFF     = ((uint32_t)0x00020000), /*!< Receive FIFO full interrupt */
248     SDIO_INT_TXFE     = ((uint32_t)0x00040000), /*!< Transmit FIFO empty interrupt */
249     SDIO_INT_RXFE     = ((uint32_t)0x00080000), /*!< Receive FIFO empty interrupt */
250     SDIO_INT_TXDA     = ((uint32_t)0x00100000), /*!< Data available in transmit FIFO interrupt */
251     SDIO_INT_RXDA     = ((uint32_t)0x00200000), /*!< Data available in receive FIFO interrupt */
252     SDIO_INT_SDIOINT  = ((uint32_t)0x00400000), /*!< SD I/O interrupt received interrupt */
253     SDIO_INT_ATAEND   = ((uint32_t)0x00800000)  /*!< CE-ATA command completion signal received for CMD61 interrupt */
254 } SDIO_INT_T;
255 
256 /**
257  * @brief SDIO read wait mode
258  */
259 typedef enum
260 {
261     SDIO_READ_WAIT_MODE_DATA2,  /*!< Read Wait control using SDIO_DATA2 */
262     SDIO_READ_WAIT_MODE_CLK     /*!< Read Wait control by stopping SDIOCLK */
263 } SDIO_READ_WAIT_MODE_T;
264 
265 /**@} end of group SDIO_Enumerations*/
266 
267 /** @addtogroup SDIO_Structure Data Structure
268   @{
269 */
270 
271 /**
272  * @brief SDIO Config structure definition
273  */
274 typedef struct
275 {
276     SDIO_CLOCK_EDGE_T            clockEdge;           /*!< Specifies the clock transition on which the bit capture is made */
277     SDIO_CLOCK_BYPASS_T          clockBypass;         /*!< Specifies whether the SDIO Clock divider bypass is enabled or disabled */
278     SDIO_CLOCK_POWER_SAVE_T      clockPowerSave;      /*!< Specifies whether SDIO Clock output is enabled or disabled when the bus is idle */
279     SDIO_BUS_WIDE_T              busWide;             /*!< Specifies the SDIO bus width */
280     SDIO_HARDWARE_FLOW_CONTROL_T hardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled */
281     uint8_t                      clockDiv;            /*!< This parameter can be a value between 0x00 and 0xFF */
282 } SDIO_Config_T;
283 
284 /**
285  * @brief SDIO Command Config structure definition
286  */
287 typedef struct
288 {
289     uint32_t           argument; /*!< Specifies the SDIO command argument which is sentto a card as part of a command message.
290                                         If a command contains an argument, it must be loaded into this register before writing
291                                         the command to the command register */
292     uint32_t           cmdIndex; /*!< It must be lower than 0x40 */
293     SDIO_RESPONSE_T    response; /*!< SDIO response */
294     SDIO_WAIT_T        wait;     /*!< Specifies whether SDIO wait for interrupt request */
295     SDIO_CPSM_T        CPSM;     /*!< Specifies whether SDIO Command path state machine (CPSM) */
296 } SDIO_CmdConfig_T;
297 
298 /**
299  * @brief SDIO Data Config
300  */
301 typedef struct
302 {
303     uint32_t              dataTimeOut;      /*!< SDIO data timeout period */
304     uint32_t              dataLength;       /*!< SDIO data length */
305     SDIO_DATA_BLOCKSIZE_T dataBlockSize;    /*!< SDIO data block size */
306     SDIO_TRANSFER_DIR_T   transferDir;      /*!< SDIO transfer direction */
307     SDIO_TRANSFER_MODE_T  transferMode;     /*!< SDIO transfer type */
308     SDIO_DPSM_T           DPSM;             /*!< Specifies whether SDIO Data path state machine(DPSM) */
309 } SDIO_DataConfig_T;
310 
311 /**@} end of group SDIO_Structure*/
312 
313 /** @defgroup SDIO_Functions
314   @{
315 */
316 
317 /* SDIO reset and configuration */
318 void SDIO_Reset(void);
319 void SDIO_Config(SDIO_Config_T* sdioConfig);
320 void SDIO_ConfigStructInit(SDIO_Config_T* sdioConfig);
321 void SDIO_EnableClock(void);
322 void SDIO_DisableClock(void);
323 void SDIO_ConfigPowerState(SDIO_POWER_STATE_T powerState);
324 uint32_t SDIO_ReadPowerState(void);
325 
326 /* DMA */
327 void SDIO_EnableDMA(void);
328 void SDIO_DisableDMA(void);
329 
330 /* Command */
331 void SDIO_TxCommand(SDIO_CmdConfig_T *cmdConfig);
332 void SDIO_TxCommandStructInit(SDIO_CmdConfig_T* cmdconfig);
333 uint8_t SDIO_ReadCommandResponse(void);
334 uint32_t SDIO_ReadResponse(SDIO_RES_T res);
335 
336 /* SDIO data configuration */
337 void SDIO_ConfigData(SDIO_DataConfig_T* dataConfig);
338 void SDIO_ConfigDataStructInit(SDIO_DataConfig_T* dataConfig);
339 uint32_t SDIO_ReadDataCounter(void);
340 void SDIO_WriteData(uint32_t data);
341 uint32_t SDIO_ReadData(void);
342 uint32_t SDIO_ReadFIFOCount(void);
343 
344 /* SDIO mode */
345 void SDIO_EnableStartReadWait(void);
346 void SDIO_DisableStartReadWait(void);
347 void SDIO_EnableStopReadWait(void);
348 void SDIO_DisableStopReadWait(void);
349 void SDIO_ConfigSDIOReadWaitMode(SDIO_READ_WAIT_MODE_T readWaitMode);
350 void SDIO_EnableSDIO(void);
351 void SDIO_DisableSDIO(void);
352 void SDIO_EnableTxSDIOSuspend(void);
353 void SDIO_DisableTxSDIOSuspend(void);
354 void SDIO_EnableCommandCompletion(void);
355 void SDIO_DisableCommandCompletion(void);
356 void SDIO_EnableCEATAInterrupt(void);
357 void SDIO_DisableCEATAInterrupt(void);
358 void SDIO_EnableTxCEATA(void);
359 void SDIO_DisableTxCEATA(void);
360 
361 /* Interrupt and flags */
362 void SDIO_EnableInterrupt(uint32_t interrupt);
363 void SDIO_DisableInterrupt(uint32_t interrupt);
364 uint8_t SDIO_ReadStatusFlag(SDIO_FLAG_T flag);
365 void SDIO_ClearStatusFlag(uint32_t flag);
366 uint8_t SDIO_ReadIntFlag(SDIO_INT_T flag);
367 void SDIO_ClearIntFlag(uint32_t flag);
368 
369 #ifdef __cplusplus
370 }
371 #endif
372 
373 #endif /* __APM32F4XX_SDIO_H */
374 
375 /**@} end of group SDIO_Enumerations */
376 /**@} end of group SDIO_Driver */
377 /**@} end of group APM32F4xx_StdPeriphDriver */
378