1 /*********************************************************************************************************//**
2  * @file    ht32f1xxxx_sdio.c
3  * @version $Rev:: 2459         $
4  * @date    $Date:: 2021-08-13 #$
5  * @brief   This file provides all the SDIO firmware functions.
6  *************************************************************************************************************
7  * @attention
8  *
9  * Firmware Disclaimer Information
10  *
11  * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
12  *    code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
13  *    proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
14  *    other intellectual property laws.
15  *
16  * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
17  *    code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
18  *    other than HOLTEK and the customer.
19  *
20  * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
21  *    only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
22  *    the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
23  *    the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
24  *
25  * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
26  ************************************************************************************************************/
27 
28 /* Includes ------------------------------------------------------------------------------------------------*/
29 #include "ht32f1xxxx_sdio.h"
30 
31 /** @addtogroup HT32F1xxxx_Peripheral_Driver HT32F1xxxx Peripheral Driver
32   * @{
33   */
34 
35 /** @defgroup SDIO SDIO
36   * @brief SDIO driver modules
37   * @{
38   */
39 
40 
41 /* Global functions ----------------------------------------------------------------------------------------*/
42 /** @defgroup SDIO_Exported_Functions SDIO exported functions
43   * @{
44   */
45 /*********************************************************************************************************//**
46  * @brief Deinitialize the SDIO peripheral registers to their default reset values.
47  * @retval None
48  ************************************************************************************************************/
SDIO_DeInit(void)49 void SDIO_DeInit(void)
50 {
51   RSTCU_PeripReset_TypeDef RSTCUReset = {{0}};
52 
53   RSTCUReset.Bit.SDIO = 1;
54   RSTCU_PeripReset(RSTCUReset, ENABLE);
55 }
56 
57 /*********************************************************************************************************//**
58  * @brief Initialize the SDIO peripheral according to the specified parameters in the SDIO_InitStruct.
59  * @param SDIO_InitStruct: pointer to a SDIO_InitTypeDef structure.
60  * @retval None
61  ************************************************************************************************************/
SDIO_Init(SDIO_InitTypeDef * SDIO_InitStruct)62 void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct)
63 {
64   u32 t;
65 
66   /* Check the parameters                                                                                   */
67   Assert_Param(IS_SDIO_CLOC_DIV(SDIO_InitStruct->SDIO_ClockDiv));
68   Assert_Param(IS_SDIO_CLOCK_PERIOD(SDIO_InitStruct->SDIO_ClockPeriod));
69   Assert_Param(IS_SDIO_CLOCK_POWER_SAVE(SDIO_InitStruct->SDIO_ClockPowerSave));
70   Assert_Param(IS_SDIO_BUS_WIDE(SDIO_InitStruct->SDIO_BusWide));
71   Assert_Param(IS_SDIO_BUS_MODE(SDIO_InitStruct->SDIO_BusMode));
72 
73   /* Disable the SDIO clock and wait for a while                                                            */
74   SDIO_ClockCmd(DISABLE);
75   for (t = 500; t > 0; t--);
76 
77   /* Configure SDIO bus and clock                                                                           */
78   HT_SDIO->CR = SDIO_InitStruct->SDIO_BusWide | SDIO_InitStruct->SDIO_BusMode;
79 
80   HT_SDIO->CLKCR = SDIO_InitStruct->SDIO_ClockPeriod | SDIO_InitStruct->SDIO_ClockPowerSave |
81                    ((SDIO_InitStruct->SDIO_ClockDiv - 1) << 8);
82 
83   /* Enable SDIO bus clock                                                                                  */
84   SDIO_ClockCmd(ENABLE);
85 }
86 
87 /*********************************************************************************************************//**
88  * @brief Enable or disable the SDIO Clock.
89  * @param Cmd: This parameter can be ENABLE or DISABLE.
90  * @retval None
91  ************************************************************************************************************/
SDIO_ClockCmd(ControlStatus Cmd)92 void SDIO_ClockCmd(ControlStatus Cmd)
93 {
94   /* Check the parameters                                                                                   */
95   Assert_Param(IS_CONTROL_STATUS(Cmd));
96 
97   if (Cmd != DISABLE)
98   {
99     BitBand((u32)&HT_SDIO->CLKCR, 2) = Cmd;
100   }
101   else
102   {
103     BitBand((u32)&HT_SDIO->CLKCR, 2) = Cmd;
104   }
105 }
106 
107 /*********************************************************************************************************//**
108  * @brief Initialize the SDIO command according to the specified parameters in the SDIO_CmdInitStruct.
109  * @param SDIO_CmdInitStruct: pointer to a SDIO_CmdInitTypeDef structure.
110  * @retval None
111  ************************************************************************************************************/
SDIO_SendCommand(SDIO_CmdInitTypeDef * SDIO_CmdInitStruct)112 void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct)
113 {
114   /* Check the parameters                                                                                   */
115   Assert_Param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->SDIO_CmdIndex));
116   Assert_Param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->SDIO_Response));
117   Assert_Param(IS_SDIO_DATA_PRESENT(SDIO_CmdInitStruct->SDIO_DatPresent));
118   Assert_Param(IS_SDIO_CMD_IDX_CHK(SDIO_CmdInitStruct->SDIO_CmdIdxChk));
119   Assert_Param(IS_SDIO_CMD_CRC_CHK(SDIO_CmdInitStruct->SDIO_CmdCrcChk));
120 
121   HT_SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument;
122 
123   HT_SDIO->CMD = SDIO_CmdInitStruct->SDIO_CmdIndex   | SDIO_CmdInitStruct->SDIO_Response  |
124                  SDIO_CmdInitStruct->SDIO_DatPresent | SDIO_CmdInitStruct->SDIO_CmdIdxChk |
125                  SDIO_CmdInitStruct->SDIO_CmdCrcChk;
126 }
127 
128 /*********************************************************************************************************//**
129  * @brief Return response received from the card for the last command.
130  * @param SDIO_RESP: Specify the SDIO response register.
131  *   This parameter can be one of the following values:
132  *     @arg SDIO_RESP1 : Response Register 1
133  *     @arg SDIO_RESP2 : Response Register 2
134  *     @arg SDIO_RESP3 : Response Register 3
135  *     @arg SDIO_RESP4 : Response Register 4
136  * @retval The Corresponding response register value.
137  ************************************************************************************************************/
SDIO_GetResponse(u32 SDIO_RESP)138 u32 SDIO_GetResponse(u32 SDIO_RESP)
139 {
140   /* Check the parameters                                                                                   */
141   Assert_Param(IS_SDIO_RESP(SDIO_RESP));
142 
143   return(rw((u32)&HT_SDIO->RESP0 + SDIO_RESP));
144 }
145 
146 /*********************************************************************************************************//**
147  * @brief Initialize the SDIO data path according to the specified parameters in the SDIO_DataInitStruct.
148  * @param SDIO_DataInitStruct: pointer to a SDIO_DataInitTypeDef structure.
149  * @retval None
150  ************************************************************************************************************/
SDIO_DataConfig(SDIO_DataInitTypeDef * SDIO_DataInitStruct)151 void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct)
152 {
153   /* Check the parameters                                                                                   */
154   Assert_Param(IS_SDIO_DATA_BLOCK_COUNT(SDIO_DataInitStruct->SDIO_DataBlockCount));
155   Assert_Param(IS_SDIO_DATA_BLOCK_SIZE(SDIO_DataInitStruct->SDIO_DataBlockSize));
156   Assert_Param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->SDIO_TransferMode));
157   Assert_Param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->SDIO_TransferDir));
158   Assert_Param(IS_SDIO_DATA_TIMEOUT(SDIO_DataInitStruct->SDIO_DataTimeOut));
159 
160   /* configure DPSM                                                                                         */
161   RESET_DPSM();
162   HT_SDIO->BLKCNT  = SDIO_DataInitStruct->SDIO_DataBlockCount;
163   HT_SDIO->BLKSIZE = SDIO_DataInitStruct->SDIO_DataBlockSize;
164   HT_SDIO->TMR     = SDIO_DataInitStruct->SDIO_TransferMode | SDIO_DataInitStruct->SDIO_TransferDir;
165   HT_SDIO->TMOCR   = SDIO_DataInitStruct->SDIO_DataTimeOut;
166 }
167 
168 /*********************************************************************************************************//**
169  * @brief Read one data word from FIFO.
170  * @return Data received
171  ************************************************************************************************************/
SDIO_ReadData(void)172 u32 SDIO_ReadData(void)
173 {
174   return HT_SDIO->DR;
175 }
176 
177 /*********************************************************************************************************//**
178  * @brief Write one data word to FIFO.
179  * @param Data: 32-bit data word to write.
180  * @retval None
181  ************************************************************************************************************/
SDIO_WriteData(u32 Data)182 void SDIO_WriteData(u32 Data)
183 {
184   HT_SDIO->DR = Data;
185 }
186 
187 /*********************************************************************************************************//**
188  * @brief Return the number of words left to be written to or read from FIFO.
189  * @return Remaining number of words.
190  ************************************************************************************************************/
SDIO_GetFIFOCount(void)191 u32 SDIO_GetFIFOCount(void)
192 {
193   return (HT_SDIO->PSR >> 20);
194 }
195 
196 /*********************************************************************************************************//**
197  * @brief Enable the SDIO's flag.
198  * @param SDIO_FLAG: specify the flag to enable.
199  *   This parameter can be one of the following values:
200  *     @arg SDIO_FLAG_CMD_SEND      :
201  *     @arg SDIO_FLAG_TRANS_END     :
202  *     @arg SDIO_FLAG_BUF_OVERFLOW  :
203  *     @arg SDIO_FLAG_BUF_UNDERFLOW :
204  *     @arg SDIO_FLAG_BUF_HALF      :
205  *     @arg SDIO_FLAG_BUF_FULL      :
206  *     @arg SDIO_FLAG_BUF_EMPTY     :
207  *     @arg SDIO_FLAG_CMD_TIMEOUT   :
208  *     @arg SDIO_FLAG_CMD_CRCERR    :
209  *     @arg SDIO_FLAG_CMD_IDXERR    :
210  *     @arg SDIO_FLAG_DATA_TIMEOUT  :
211  *     @arg SDIO_FLAG_DATA_CRCERR   :
212  *     @arg SDIO_FLAG_CARD_INT      :
213  * @param NewState: This parameter can be ENABLE or DISABLE.
214  * @retval None
215  ************************************************************************************************************/
SDIO_FlagConfig(u32 SDIO_FLAG,ControlStatus NewState)216 void SDIO_FlagConfig(u32 SDIO_FLAG, ControlStatus NewState)
217 {
218   /* Check the parameters                                                                                   */
219   Assert_Param(IS_SDIO_FLAG(SDIO_FLAG));
220   Assert_Param(IS_CONTROL_STATUS(NewState));
221 
222   if (NewState != DISABLE)
223   {
224     HT_SDIO->SER |= (SDIO_FLAG);
225   }
226   else
227   {
228     HT_SDIO->SER &= ~(SDIO_FLAG);
229   }
230 }
231 
232 /*********************************************************************************************************//**
233  * @brief Check whether the specified SDIO flag is set or not.
234  * @param SDIO_FLAG: specify the flag to check.
235  *   This parameter can be one of the following values:
236  *     @arg SDIO_FLAG_CMD_SEND      :
237  *     @arg SDIO_FLAG_TRANS_END     :
238  *     @arg SDIO_FLAG_BUF_OVERFLOW  :
239  *     @arg SDIO_FLAG_BUF_UNDERFLOW :
240  *     @arg SDIO_FLAG_BUF_HALF      :
241  *     @arg SDIO_FLAG_BUF_FULL      :
242  *     @arg SDIO_FLAG_BUF_EMPTY     :
243  *     @arg SDIO_FLAG_CMD_TIMEOUT   :
244  *     @arg SDIO_FLAG_CMD_CRCERR    :
245  *     @arg SDIO_FLAG_CMD_IDXERR    :
246  *     @arg SDIO_FLAG_DATA_TIMEOUT  :
247  *     @arg SDIO_FLAG_DATA_CRCERR   :
248  *     @arg SDIO_FLAG_CARD_INT      :
249  * @retval SET or RESET
250  ************************************************************************************************************/
SDIO_GetFlagStatus(u32 SDIO_FLAG)251 FlagStatus SDIO_GetFlagStatus(u32 SDIO_FLAG)
252 {
253   /* Check the parameters                                                                                   */
254   Assert_Param(IS_SDIO_FLAG(SDIO_FLAG));
255 
256   if (HT_SDIO->SR & (SDIO_FLAG))
257   {
258     return SET;
259   }
260   else
261   {
262     return RESET;
263   }
264 }
265 
266 /*********************************************************************************************************//**
267  * @brief Clear the SDIO's pending flags.
268  * @param SDIO_FLAG: specify the flag to clear.
269  *   This parameter can be one of the following values:
270  *     @arg SDIO_FLAG_CMD_SEND      :
271  *     @arg SDIO_FLAG_TRANS_END     :
272  *     @arg SDIO_FLAG_BUF_OVERFLOW  :
273  *     @arg SDIO_FLAG_BUF_UNDERFLOW :
274  *     @arg SDIO_FLAG_BUF_HALF      :
275  *     @arg SDIO_FLAG_BUF_FULL      :
276  *     @arg SDIO_FLAG_BUF_EMPTY     :
277  *     @arg SDIO_FLAG_ERR           :
278  *     @arg SDIO_FLAG_CMD_TIMEOUT   :
279  *     @arg SDIO_FLAG_CMD_CRCERR    :
280  *     @arg SDIO_FLAG_CMD_ENDERR    :
281  *     @arg SDIO_FLAG_CMD_IDXERR    :
282  *     @arg SDIO_FLAG_DATA_TIMEOUT  :
283  *     @arg SDIO_FLAG_DATA_CRCERR   :
284  *     @arg SDIO_FLAG_DATA_ENDERR   :
285  *     @arg SDIO_FLAG_CARD_INT      :
286  *     @arg SDIO_FLAG_DAT_ERR       :
287  *     @arg SDIO_FLAG_CMD_ERR       :
288  * @retval SET or RESET
289  ************************************************************************************************************/
SDIO_ClearFlag(u32 SDIO_FLAG)290 void SDIO_ClearFlag(u32 SDIO_FLAG)
291 {
292   /* Check the parameters                                                                                   */
293   Assert_Param(IS_SDIO_FLAG(SDIO_FLAG));
294 
295   HT_SDIO->SR = (SDIO_FLAG);
296 
297   if (SDIO_FLAG & SDIO_FLAG_BUF_OVERFLOW)
298   {
299     HT_SDIO->SER &= ~(SDIO_FLAG_BUF_OVERFLOW);
300     HT_SDIO->SER |= (SDIO_FLAG_BUF_OVERFLOW);
301   }
302   if (SDIO_FLAG & SDIO_FLAG_BUF_UNDERFLOW)
303   {
304     HT_SDIO->SER &= ~(SDIO_FLAG_BUF_UNDERFLOW);
305     HT_SDIO->SER |= (SDIO_FLAG_BUF_UNDERFLOW);
306   }
307 }
308 
309 /*********************************************************************************************************//**
310  * @brief Clear the SDIO's pending flags.
311  * @param SDIO_INT: specify the flag to clear.
312  *   This parameter can be one of the following values:
313  *     @arg SDIO_INT_CMD_SEND      :
314  *     @arg SDIO_INT_TRANS_END     :
315  *     @arg SDIO_INT_BUF_OVERFLOW  :
316  *     @arg SDIO_INT_BUF_UNDERFLOW :
317  *     @arg SDIO_INT_BUF_HALF      :
318  *     @arg SDIO_INT_BUF_FULL      :
319  *     @arg SDIO_INT_BUF_EMPTY     :
320  *     @arg SDIO_INT_CMD_TIMEOUT   :
321  *     @arg SDIO_INT_CMD_CRCERR    :
322  *     @arg SDIO_INT_CMD_IDXERR    :
323  *     @arg SDIO_INT_DATA_TIMEOUT  :
324  *     @arg SDIO_INT_DATA_CRCERR   :
325  *     @arg SDIO_INT_CARD_INT      :
326  * @param NewState: This parameter can be ENABLE or DISABLE.
327  * @retval SET or RESET
328  ************************************************************************************************************/
SDIO_IntConfig(u32 SDIO_INT,ControlStatus NewState)329 void SDIO_IntConfig(u32 SDIO_INT, ControlStatus NewState)
330 {
331   /* Check the parameters                                                                                   */
332   Assert_Param(IS_SDIO_INT(SDIO_INT));
333   Assert_Param(IS_CONTROL_STATUS(NewState));
334 
335   if (NewState != DISABLE)
336   {
337     HT_SDIO->IER |= (SDIO_INT);
338   }
339   else
340   {
341     HT_SDIO->IER &= ~(SDIO_INT);
342   }
343 }
344 /**
345   * @}
346   */
347 
348 
349 /**
350   * @}
351   */
352 
353 /**
354   * @}
355   */
356