1 #include "ameba_soc.h"
2
3 extern SDIOHCFG_TypeDef sdioh_config;
4
5 SRAM_NOCACHE_DATA_SECTION
6 SD_CardInfo card_info;
7
SDIOH_Pinmux(void)8 static void SDIOH_Pinmux(void)
9 {
10 u32 tmp;
11
12 /* SDIOH pinmux enable */
13 tmp = HAL_READ32(SYSTEM_CTRL_BASE, REG_HS_SDIO_CTRL);
14 tmp |= BIT_HS_SDIOH_PIN_EN;
15 HAL_WRITE32(SYSTEM_CTRL_BASE, REG_HS_SDIO_CTRL, tmp);
16
17 Pinmux_Config(_PB_20, PINMUX_FUNCTION_SDIOH); /* CMD */
18 Pinmux_Config(_PB_21, PINMUX_FUNCTION_SDIOH); /* CLK */
19 Pinmux_Config(_PB_22, PINMUX_FUNCTION_SDIOH); /* D0 */
20
21 PAD_PullCtrl(_PB_20, GPIO_PuPd_UP);
22 PAD_PullCtrl(_PB_21, GPIO_PuPd_UP);
23 PAD_PullCtrl(_PB_22, GPIO_PuPd_UP);
24
25 if(sdioh_config.sdioh_bus_width == SDIOH_BUS_WIDTH_4BIT) {
26 Pinmux_Config(_PB_18, PINMUX_FUNCTION_SDIOH); /* D2 */
27 Pinmux_Config(_PB_19, PINMUX_FUNCTION_SDIOH); /* D3 */
28 Pinmux_Config(_PB_23, PINMUX_FUNCTION_SDIOH); /* D1 */
29
30 PAD_PullCtrl(_PB_18, GPIO_PuPd_UP);
31 PAD_PullCtrl(_PB_19, GPIO_PuPd_UP);
32 PAD_PullCtrl(_PB_23, GPIO_PuPd_UP);
33 }
34
35 if(sdioh_config.sdioh_cd_pin != _PNC) { /* CD */
36 Pinmux_Config((u8)sdioh_config.sdioh_cd_pin, PINMUX_FUNCTION_SDIOH);
37 PAD_PullCtrl((u8)sdioh_config.sdioh_cd_pin, GPIO_PuPd_UP);
38 }
39
40 if(sdioh_config.sdioh_wp_pin != _PNC) { /* WP */
41 Pinmux_Config((u8)sdioh_config.sdioh_wp_pin, PINMUX_FUNCTION_SDIOH);
42 PAD_PullCtrl((u8)sdioh_config.sdioh_wp_pin, GPIO_PuPd_UP);
43 }
44 }
45
46 /**
47 * @brief Check SDIOH response is valid or not.
48 * @param resp_type: which can be a value of @ref SDIOH_Card_Response_Byte_Index.
49 * @param cmd: indicate the command of which the response to be checked
50 * @retval 0: response is valid
51 * others: response is invalid
52 */
CmdRespError(u8 resp_type,u8 cmd)53 static u32 CmdRespError(u8 resp_type, u8 cmd)
54 {
55 u32 ret = HAL_OK;
56 u16 err_status;
57 u8 resp_byte0, resp_byte1, resp_byte3, resp_byte4, t_cmd = cmd;
58
59 ret = SDIOH_CheckTxError(&err_status);
60 if (ret != HAL_OK) {
61 if(err_status & SDIOH_SD_CMD_RSP_TO_ERR)
62 return HAL_TIMEOUT;
63 else if (err_status & SDIOH_SD_TUNNING_PAT_COMP_ERR)
64 return HAL_ERR_HW;
65 else
66 return ret;
67 }
68
69 /* For R1, R6, R7 */
70 if((resp_type == SDIOH_RESP_R1) || (resp_type == SDIOH_RESP_R6) || (resp_type == SDIOH_RESP_R7)) {
71 if((cmd == SD_CMD_WrMulBlk) ||(cmd == SD_CMD_RdMulBlk))
72 t_cmd = SD_CMD_StopXsmission;
73
74 resp_byte0 = SDIOH_GetResponse(SDIO_RESP0);
75 resp_byte1 = SDIOH_GetResponse(SDIO_RESP1);
76 resp_byte3 = SDIOH_GetResponse(SDIO_RESP3);
77 resp_byte4 = SDIOH_GetResponse(SDIO_RESP4);
78
79 if((resp_byte0 & SDIOH_CMD_IDX_MASK) != t_cmd) {
80 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Command index error !!\r\n");
81 return HAL_ERR_UNKNOWN;
82 }
83
84 if(cmd == SD_CMD_AppCmd) {
85 if(!(resp_byte4 & SD_APP_CMD)) {
86 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "ACMD isn't expected !!\r\n");
87 return HAL_ERR_UNKNOWN;
88 }
89 } else if((cmd == SD_CMD_RdSingleBlk) || (cmd == SD_CMD_RdMulBlk)) {
90 if((resp_byte1 & SD_ADDRESS_ERROR) || (resp_byte1 & SD_BLOCK_LEN_ERROR))
91 return HAL_ERR_UNKNOWN;
92 } else if((cmd == SD_CMD_WrBlk) || (cmd == SD_CMD_WrMulBlk)) {
93 if((resp_byte1 & SD_ADDRESS_ERROR) || (resp_byte1 & SD_BLOCK_LEN_ERROR) || (resp_byte1 & SD_WP_VIOLATION))
94 return HAL_ERR_UNKNOWN;
95 }
96 }
97
98 /* For R7 */
99 if(resp_type == SDIOH_RESP_R7) {
100 // check the echo-back of check pattern
101 if(resp_byte4 != SDIOH_CMD8_CHK_PATN) {
102 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Check pattern error !!\r\n");
103 return HAL_ERR_UNKNOWN;
104 }
105 // check the VHS
106 if((resp_byte3 & 0xF) != SDIOH_CMD8_VHS) {
107 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Voltage accepted error !!\r\n");
108 return HAL_ERR_UNKNOWN;
109 }
110 }
111
112 return HAL_OK;
113 }
114
115 /**
116 * @brief Reset SD card.
117 * @param None.
118 * @retval 0: reset SD card successfully
119 * others: fail to reset SD card
120 */
SD_ResetCard(void)121 static u32 SD_ResetCard(void)
122 {
123 u32 ret;
124 SDIOH_CmdTypeDef cmd_attr;
125
126 /***** CMD0 *****/
127 cmd_attr.arg = 0;
128 cmd_attr.idx = SD_CMD_GoIdleSte;
129 cmd_attr.rsp_type = SDIOH_NO_RESP;
130 cmd_attr.rsp_crc_chk = DISABLE;
131 cmd_attr.data_present = SDIOH_NO_DATA;
132 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
133 if(ret != HAL_OK)
134 return ret;
135
136 // check if any errors
137 ret = CmdRespError(SDIOH_NO_RESP, SD_CMD_GoIdleSte);
138 if (ret != HAL_OK) {
139 return ret;
140 }
141
142 return HAL_OK;
143 }
144
145 /**
146 * @brief Sends SD Memory Card interface condition, which includes host supply voltage information
147 * and asks the card whether card supports voltage.
148 * @param voltage_mismatch: pointer to a variable to indicate SD card responds to CMD8 or not.
149 * @retval HAL_OK: SD card responds to CMD8 successfully
150 * HAL_TIMEOUT: SD card does not respond to CMD8
151 */
SD_VoltageCheck(u8 * voltage_mismatch)152 static u32 SD_VoltageCheck(u8 * voltage_mismatch)
153 {
154 /* To avoid gcc warnings */
155 ( void ) voltage_mismatch;
156
157 u32 ret;
158 SDIOH_CmdTypeDef cmd_attr;
159
160 /***** CMD8 *****/
161 cmd_attr.arg = (SDIOH_CMD8_VHS << 8) | SDIOH_CMD8_CHK_PATN;
162 cmd_attr.idx = SD_CMD_SendIfCond;
163 cmd_attr.rsp_type = SDIOH_RSP_6B;
164 cmd_attr.rsp_crc_chk = ENABLE;
165 cmd_attr.data_present = SDIOH_NO_DATA;
166 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
167 if(ret != HAL_OK)
168 return ret;
169
170 ret = CmdRespError(SDIOH_RESP_R7, SD_CMD_SendIfCond);
171 if(ret == HAL_TIMEOUT) {
172 //voltage_mismatch = 1; /* for Ver1.x SD card*/
173 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"voltage mismatch\n");
174 ret = HAL_OK;
175
176 } else if(ret == HAL_OK) {
177 //voltage_mismatch = 0;
178 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"voltage match\n");
179 }
180
181 return ret;
182 }
183
184 /**
185 * @brief Forces the card to stop transmission.
186 * @param None
187 * @retval HAL_OK: Transmission is stopped successfully
188 * Others: Fail to stop transmisstion
189 */
SD_StopTransfer(void)190 u32 SD_StopTransfer(void)
191 {
192 u32 ret;
193 SDIOH_CmdTypeDef cmd_attr;
194 SDIOH_TypeDef *psdioh = SDIOH_BASE;
195
196 /***** CMD12 *****/
197 cmd_attr.arg = 0;
198 cmd_attr.idx = SD_CMD_StopXsmission;
199 cmd_attr.rsp_type = SDIOH_RSP_6B;
200 cmd_attr.rsp_crc_chk = ENABLE;
201 cmd_attr.data_present = SDIOH_NO_DATA;
202 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
203 if(ret != HAL_OK)
204 return ret;
205
206 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_StopXsmission);
207 if (ret != HAL_OK) {
208 return ret;
209 }
210
211 // stop the transfer & the transfer state machine returns to idle state
212 psdioh->CARD_STOP = SDIOH_TARGET_MODULE_SD;
213
214 return HAL_OK;
215 }
216
217 /**
218 * @brief Get operating condition register(OCR) value in response.
219 * @param voltage_mismatch: indicate voltage mismatch or not when check voltage.
220 * @retval HAL_OK: Get OCR successfully
221 * Others: Fail to get OCR
222 */
223 #if defined(SDIO) && (SDIO == SD)
224
SD_GetOCR(u8 voltage_mismatch)225 static u32 SD_GetOCR(u8 voltage_mismatch)
226 {
227 u32 ret;
228 SDIOH_CmdTypeDef cmd_attr;
229 u32 retry = 100;
230
231 while(retry--) {
232 // Normal ACMD41 (CMD55)
233 cmd_attr.arg = 0;
234 cmd_attr.idx = SD_CMD_AppCmd;
235 cmd_attr.rsp_type = SDIOH_RSP_6B;
236 cmd_attr.rsp_crc_chk = ENABLE;
237 cmd_attr.data_present = SDIOH_NO_DATA;
238 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
239 if(ret != HAL_OK)
240 return ret;
241
242 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_AppCmd);
243 if(ret != HAL_OK)
244 break;
245
246 // Normal ACMD41 (CMD41)
247 #ifdef SDIOH_SUPPORT_SD30
248 if (voltage_mismatch)
249 cmd_attr.arg = (SD_SUPPORT_SDSC_ONLY << 30) | (SD_MAX_PERFORM << 28) | (SD_USE_CUR_VOL << 24) | SDIOH_OCR_VDD_WIN; // 3.3V
250 else
251 cmd_attr.arg = (SD_SUPPORT_SDHC_SDXC << 30) | (SD_MAX_PERFORM << 28) | (SD_SWITCH_18V << 24) | SDIOH_OCR_VDD_WIN; // 1.8V
252 #else
253 if(voltage_mismatch)
254 cmd_attr.arg = (SD_SUPPORT_SDSC_ONLY << 30) | SDIOH_OCR_VDD_WIN;
255 else
256 cmd_attr.arg = (SD_SUPPORT_SDHC_SDXC << 30) | SDIOH_OCR_VDD_WIN;
257 #endif
258
259 cmd_attr.idx = SD_CMD_SdSendOpCond;
260 cmd_attr.rsp_type = SDIOH_RSP_6B;
261 cmd_attr.rsp_crc_chk = DISABLE;
262 cmd_attr.data_present = SDIOH_NO_DATA;
263 ret = SDIOH_SendCommand(&cmd_attr , SDIOH_CMD_CPLT_TIMEOUT);
264 if(ret != HAL_OK)
265 return ret;
266
267 ret = CmdRespError(SDIOH_RESP_R3, SD_CMD_SdSendOpCond);
268 if (ret != HAL_OK) {
269 return ret;
270 }
271
272 // check if initialization is complete, Card power up status bit, OCR bit31
273 if(SDIOH_GetResponse(SDIO_RESP1) & BIT7) {
274 break;
275 }
276
277 DelayUs(10000);
278 }
279
280 if(ret != HAL_OK) {
281 return ret;
282 }
283 if(!retry) {
284 return HAL_TIMEOUT;
285 }
286
287 // check CCS(Card Capacity Status) bit, OCR bit30
288 if(SDIOH_GetResponse(SDIO_RESP1) & BIT6) {
289 card_info.is_sdhc_sdxc = 1;
290 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "This is a SDHC/SDXC card...\r\n");
291
292 #ifdef SDIOH_SUPPORT_SD30
293 // check S18A(Switching to 1.8V Accepted) bit, OCR bit24
294 if(SDIOH_GetResponse(SDIO_RESP1) & BIT0) {
295 ret = SD_VoltageSwitch();
296 if (ret != HAL_OK)
297 return ret;
298 }else {
299 card_info.sig_level = SDIOH_SIG_VOL_33;
300 card_info.bus_spd = SD_SPEED_DS;
301 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Keep 3.3V...\r\n");
302 }
303 #else
304 card_info.sig_level = SDIOH_SIG_VOL_33;
305 card_info.bus_spd = SD_SPEED_DS;
306 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Keep 3.3V...\r\n");
307 #endif
308 } else {
309 card_info.is_sdhc_sdxc = 0;
310 card_info.sig_level = SDIOH_SIG_VOL_33;
311 card_info.bus_spd = SD_SPEED_DS;
312 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "This is a SDSC card...\r\n");
313 }
314
315 return HAL_OK;
316 }
317
318 #else
319
SD_GetOCR(u8 voltage_mismatch)320 static SD_RESULT SD_GetOCR(u8 voltage_mismatch)
321 {
322
323 u32 ret, cnt = 1000;
324 SDIOH_CmdTypeDef cmd_attr;
325 u8 resp_byte1;
326
327 card_info.is_sdhc_sdxc = 1;
328
329 resp_byte1 = SDIOH_GetResponse(SDIO_RESP1);
330
331 do{
332 cmd_attr.arg = 0x40FF8080;
333 cmd_attr.idx = EMMC_CMD_SendOpCond;
334 cmd_attr.rsp_type = SDIOH_RSP_6B;
335 cmd_attr.rsp_crc_chk = DISABLE;
336 cmd_attr.data_present = SDIOH_DATA_EXIST;
337 ret = SDIOH_SendCommand(&cmd_attr , SDIOH_CMD_CPLT_TIMEOUT);
338
339 if(ret != HAL_OK)
340 return ret;
341
342 ret = CmdRespError(SDIOH_RESP_R3, EMMC_CMD_SendOpCond);
343 if(ret != HAL_OK)
344 return ret;
345
346 resp_byte1 = SDIOH_GetResponse(SDIO_RESP1);
347
348 DelayMs(1);
349
350 if(resp_byte1&BIT7) {
351 return HAL_OK;
352 }
353 }while(cnt--);
354
355 return HAL_ERR_UNKNOWN;
356
357 }
358
359 #endif
360 /**
361 * @brief Asks any card to send the CID numbers on the CMD line (any card that is connected to the host will respond)
362 * @param None.
363 * @retval HAL_OK: Get CID successfully
364 * Others: Fail to get CID
365 */
SD_GetCID(void)366 static u32 SD_GetCID(void)
367 {
368 u32 ret;
369 SDIOH_DmaCtl dma_cfg;
370 SDIOH_CmdTypeDef cmd_attr;
371 u8* pbuf = card_info.dma_buf;
372
373 /***** CMD2 *****/
374 _memset((void *)(pbuf), 0, SDIOH_C6R2_BUF_LEN);
375 dma_cfg.op = SDIOH_DMA_READ;
376 dma_cfg.start_addr = ((u32)(pbuf))/8;
377 dma_cfg.blk_cnt = 1;
378 dma_cfg.type = SDIOH_DMA_R2;
379 SDIOH_DMAConfig(&dma_cfg);
380
381 cmd_attr.arg = 0;
382 cmd_attr.idx = SD_CMD_AllSendCid;
383 cmd_attr.rsp_type = SDIOH_RSP_17B;
384 cmd_attr.rsp_crc_chk = ENABLE;
385 cmd_attr.data_present = SDIOH_NO_DATA;
386 ret = SDIOH_SendCommand(&cmd_attr, 0);
387 if(ret != HAL_OK)
388 return ret;
389
390 ret = SDIOH_WaitDMADone(SDIOH_XFER_CPLT_TIMEOUT);
391 if (ret != HAL_OK) {
392 return ret;
393 }
394
395 //DCache_Invalidate((u32)pbuf, SDIOH_C6R2_BUF_LEN);
396
397 ret = CmdRespError(SDIOH_RESP_R2, SD_CMD_AllSendCid);
398 if (ret != HAL_OK) {
399 return ret;
400 }
401 #if defined(SDIO) && (SDIO == EMMC)
402 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Manufacturer ID:%d\r\n", pbuf[1]);
403 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "OEM/Application ID:%x\r\n", pbuf[3]);
404 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Product name:%x%x%x%x%x%x\r\n", pbuf[4], pbuf[5], pbuf[6], pbuf[7], pbuf[8], pbuf[9]);
405 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Product serial number:%02X%02X%02X%02X\r\n", pbuf[11], pbuf[12], pbuf[13], pbuf[14]);
406 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Manufacturing date:%d/%d\r\n", 2013+(pbuf[15]&0xf) ,pbuf[15]>>4);
407 #else
408 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Manufacturer ID:%d\r\n", pbuf[1]);
409 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "OEM/Application ID:%c%c\r\n", pbuf[2], pbuf[3]);
410 //DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Product name:%c%c%c%c%c\r\n", pbuf[4], pbuf[5], pbuf[6], pbuf[7], pbuf[8]);
411 //DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Product serial number:%02X%02X%02X%02X\r\n", pbuf[10], pbuf[11], pbuf[12], pbuf[13]);
412 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Manufacturing date:%d/%d\r\n", 2000 + (((pbuf[14] & 0xF) << 4) | (pbuf[15] >> 4)), pbuf[15] & 0xF);
413 #endif
414 return HAL_OK;
415 }
416
417 /**
418 * @brief Ask the card to publish a new relative address (RCA)
419 * @param None.
420 * @retval HAL_OK: Get RCA successfully
421 * Others: Fail to get RCA
422 */
SD_GetRCA(void)423 static u32 SD_GetRCA(void)
424 {
425 u32 ret;
426 SDIOH_CmdTypeDef cmd_attr;
427
428 /***** CMD3 *****/
429 cmd_attr.arg = 0;
430 cmd_attr.idx = SD_CMD_SendRelAddr;
431 cmd_attr.rsp_type = SDIOH_RSP_6B;
432 cmd_attr.rsp_crc_chk = ENABLE;
433 cmd_attr.data_present = SDIOH_NO_DATA;
434 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
435 if(ret != HAL_OK)
436 return ret;
437
438 ret = CmdRespError(SDIOH_RESP_R6, SD_CMD_SendRelAddr);
439 if (ret != HAL_OK) {
440 return ret;
441 }
442
443 // get RCA
444 card_info.rca = (SDIOH_GetResponse(SDIO_RESP1) << 8) | (SDIOH_GetResponse(SDIO_RESP2));
445 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "RCA = %04X\r\n", card_info.rca);
446
447 return HAL_OK;
448 }
449
450 /**
451 * @brief Ask the Addressed card sends its card-specific data (CSD) on the CMD line.
452 * @param None.
453 * @retval HAL_OK: Get CSD successfully
454 * Others: Fail to get CSD
455 */
SD_GetCSD(void)456 static u32 SD_GetCSD(void)
457 {
458 u32 ret;
459 SDIOH_DmaCtl dma_cfg;
460 SDIOH_CmdTypeDef cmd_attr;
461 u8* pbuf = card_info.dma_buf;
462 u32 c_size, n;
463
464 /***** CMD9 *****/
465 _memset((void *)(pbuf), 0, SDIOH_C6R2_BUF_LEN);
466 dma_cfg.op = SDIOH_DMA_READ;
467 dma_cfg.start_addr = ((u32)(pbuf))/8;
468 dma_cfg.blk_cnt = 1;
469 dma_cfg.type = SDIOH_DMA_R2;
470 SDIOH_DMAConfig(&dma_cfg);
471
472 cmd_attr.arg = (card_info.rca) << 16;
473 cmd_attr.idx = SD_CMD_SendCsd;
474 cmd_attr.rsp_type = SDIOH_RSP_17B;
475 cmd_attr.rsp_crc_chk = ENABLE;
476 cmd_attr.data_present = SDIOH_NO_DATA;
477 ret = SDIOH_SendCommand(&cmd_attr, 0);
478 if(ret != HAL_OK)
479 return ret;
480
481 ret = SDIOH_WaitDMADone( SDIOH_XFER_CPLT_TIMEOUT);
482 if (ret != HAL_OK) {
483 return ret;
484 }
485
486 //DCache_Invalidate((u32)pbuf, SDIOH_C6R2_BUF_LEN);
487
488 ret = CmdRespError(SDIOH_RESP_R2, SD_CMD_SendCsd);
489 if (ret != HAL_OK) {
490 return ret;
491 }
492
493 _memcpy (card_info.csd, pbuf + 1, SDIOH_CSD_LEN);
494
495 #if defined(SDIO) && (SDIO == SD)
496 if(card_info.csd[0] >> 6) {
497 c_size = (((card_info.csd[7] & 0x3F) << 16) | (card_info.csd[8] << 8) | (card_info.csd[9]))+1;
498 card_info.capaticy = c_size << 9; //KB
499
500 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "CSD Version:2.0\r\n");
501 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "User data area capacity: %d GB\r\n", card_info.capaticy / 1024 / 1024);
502
503 } else {
504 c_size = (((card_info.csd[6] & 0x3) << 10) | (card_info.csd[7] << 2) | (card_info.csd[8] >> 6)) + 1;
505 n = ((((card_info.csd[9] & 0x3) << 1) |(card_info.csd[10] >> 7))+2) + (card_info.csd[5] & 0xF);
506
507 card_info.capaticy = (u32)(c_size << (n - 10)); //KB
508
509 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "CSD Version:1.0\r\n");
510 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "User data area capacity: %d MB\r\n", card_info.capaticy /1024);
511 }
512 #endif
513
514 card_info.read_bl_len = 1 << (card_info.csd[5] & 0xF);
515 card_info.write_bl_len = 1 << (((card_info.csd[12] & 0x3) << 2) | (card_info.csd[13] >> 6));
516
517 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Max. read data block length: %d Bytes\r\n", card_info.read_bl_len);
518 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Max. write data block length: %d Bytes\r\n", card_info.write_bl_len);
519
520 return HAL_OK;
521 }
522
523 /**
524 * @brief Select/Deselect the SD card.
525 * @param select: can be _TRUE or _FALSE.
526 * @retval HAL_OK: Select/Deselect card successfully
527 * Others: Fail to Select/Deselect card
528 */
SD_SelectDeselect(u8 select)529 static u32 SD_SelectDeselect(u8 select)
530 {
531 u32 ret;
532 SDIOH_CmdTypeDef cmd_attr;
533
534 /***** CMD7 *****/
535 if (select == _TRUE) {
536 cmd_attr.arg = (card_info.rca) << 16;
537 cmd_attr.idx = SD_CMD_SelDeselCard;
538 cmd_attr.rsp_type = SDIOH_RSP_6B;
539 cmd_attr.rsp_crc_chk = ENABLE;
540 cmd_attr.data_present = SDIOH_NO_DATA;
541 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
542 if(ret != HAL_OK)
543 return ret;
544
545 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SelDeselCard);
546 if (ret != HAL_OK) {
547 return ret;
548 }
549 } else {
550 // address 0 deselects all
551 cmd_attr.arg = 0;
552 cmd_attr.idx = SD_CMD_SelDeselCard;
553 cmd_attr.rsp_type = SDIOH_NO_RESP;
554 cmd_attr.rsp_crc_chk = DISABLE;
555 cmd_attr.data_present = SDIOH_NO_DATA;
556 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
557 if(ret != HAL_OK)
558 return ret;
559
560 // check if any errors
561 ret = CmdRespError(SDIOH_NO_RESP, SD_CMD_SelDeselCard);
562 if (ret != HAL_OK) {
563 return ret;
564 }
565 }
566
567 return HAL_OK;
568 }
569
570 /**
571 * @brief Set the bus width of the SD card.
572 * @param bus_width: can be one of the @ref SDIOH_Bus_Width
573 * @retval HAL_OK: Set bus width successfully
574 * Others: Fail to set bus width
575 */
SD_SetBusWidth(u8 bus_width)576 static u32 SD_SetBusWidth(u8 bus_width)
577 {
578 u32 ret, wid_arg_4bit, wid_arg_1bit;
579 SDIOH_CmdTypeDef cmd_attr;
580
581 if (bus_width > SDIOH_BUS_WIDTH_4BIT) {
582 return HAL_ERR_PARA;
583 }
584
585 if (SDIOH_GetBusWidth() == bus_width) {
586 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Current SD bus width is already the specified setting...\r\n");
587 return HAL_OK;
588 }
589
590 #if defined(SDIO) && (SDIO == SD)
591 /***** ACMD6 (CMD55) *****/
592 cmd_attr.arg = (card_info.rca) << 16;
593 cmd_attr.idx = SD_CMD_AppCmd;
594 cmd_attr.rsp_type = SDIOH_RSP_6B;
595 cmd_attr.rsp_crc_chk = ENABLE;
596 cmd_attr.data_present = SDIOH_NO_DATA;
597 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
598 if(ret != HAL_OK)
599 return ret;
600
601 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_AppCmd);
602 if (ret != HAL_OK) {
603 return ret;
604 }
605 wid_arg_4bit = 0x2;
606 wid_arg_1bit = 0x0;
607 #else
608 wid_arg_4bit = 0x03B70100; //EXT_CSD register B7 byte: 01, 4bit mode; 00, 1bit mode
609 wid_arg_1bit = 0x03B70000;
610 #endif
611 /***** ACMD6 (CMD6) *****/
612 if(bus_width == SDIOH_BUS_WIDTH_4BIT) {
613 cmd_attr.arg = wid_arg_4bit; // 4-bit bus
614 } else {
615 cmd_attr.arg = wid_arg_1bit; // 1-bit bus
616 }
617 cmd_attr.idx = SD_CMD_SetBusWidth;
618 cmd_attr.rsp_type = SDIOH_RSP_6B;
619 cmd_attr.rsp_crc_chk = ENABLE;
620 cmd_attr.data_present = SDIOH_NO_DATA;
621 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
622 if(ret != HAL_OK)
623 return ret;
624
625 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SetBusWidth);
626 if (ret != HAL_OK) {
627 return ret;
628 }
629
630 // Host also selects the specified mode
631 SDIOH_SetBusWidth(bus_width);
632
633 return HAL_OK;
634 }
635
636 /**
637 * @brief Get the SD Configuration Register (SCR).
638 * @param None
639 * @retval HAL_OK: Get SCR successfully
640 * Others: Fail to get SCR
641 */
SD_GetSCR(void)642 static u32 SD_GetSCR(void)
643 {
644 u32 ret;
645 SDIOH_DmaCtl dma_cfg;
646 SDIOH_CmdTypeDef cmd_attr;
647 u8* pbuf = card_info.dma_buf;
648
649 /***** ACMD51 (CMD55) *****/
650 cmd_attr.arg = (card_info.rca) << 16;
651 cmd_attr.idx = SD_CMD_AppCmd;
652 cmd_attr.rsp_type = SDIOH_RSP_6B;
653 cmd_attr.rsp_crc_chk = ENABLE;
654 cmd_attr.data_present = SDIOH_NO_DATA;
655 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
656 if(ret != HAL_OK)
657 return ret;
658
659 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_AppCmd);
660 if (ret != HAL_OK) {
661 return ret;
662 }
663
664 /***** ACMD51 (CMD51) *****/
665 _memset((void *)(pbuf), 0, SDIOH_C6R2_BUF_LEN);
666 dma_cfg.op = SDIOH_DMA_READ;
667 dma_cfg.start_addr = ((u32)(pbuf))/8;
668 dma_cfg.blk_cnt = 1;
669 dma_cfg.type = SDIOH_DMA_64B;
670 SDIOH_DMAConfig(&dma_cfg);
671
672 cmd_attr.arg = 0;
673 cmd_attr.idx = SD_CMD_SendScr;
674 cmd_attr.rsp_type = SDIOH_RSP_6B;
675 cmd_attr.rsp_crc_chk = ENABLE;
676 cmd_attr.data_present = SDIOH_DATA_EXIST;
677 ret = SDIOH_SendCommand(&cmd_attr, 0);
678 if(ret != HAL_OK)
679 return ret;
680
681 ret = SDIOH_WaitDMADone( SDIOH_XFER_CPLT_TIMEOUT);
682 if (ret != HAL_OK) {
683 ret = SD_StopTransfer();
684 if (ret != HAL_OK) {
685 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Stop transmission error !!\r\n");
686 }
687
688 return HAL_ERR_UNKNOWN;
689 }
690
691 //DCache_Invalidate((u32)pbuf, SDIOH_C6R2_BUF_LEN);
692
693 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SendScr);
694 if (ret != HAL_OK) {
695 return ret;
696 }
697
698 switch (pbuf[0] & 0xF) {
699 case 2:
700 if(pbuf[2] >> 7) {
701 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "SD specification version: 3.0X\r\n");
702 card_info.sd_spec_ver = SD_SPEC_V300;
703 } else {
704 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "SD specification version: 2.00\r\n");
705 card_info.sd_spec_ver = SD_SPEC_V200;
706 }
707 break;
708 case 1:
709 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "SD specification version: 1.10\r\n");
710 card_info.sd_spec_ver = SD_SPEC_V110;
711 break;
712 case 0:
713 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "SD specification version: 1.01\r\n");
714 card_info.sd_spec_ver = SD_SPEC_V101;
715 break;
716 default:
717 DBG_PRINTF(MODULE_SDIO, LEVEL_WARN,"SD specification version: Unknown\r\n");
718 card_info.sd_spec_ver = 0xFF;
719 }
720
721 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "Data status after erase: %d\r\n", pbuf[1] >> 7);
722
723 return HAL_OK;
724 }
725
726 /**
727 * @brief Checks switchable function (mode 0) and switch card function (mode 1).
728 * @param mode: can be a value of @ref SD_CMD6_operation_mode
729 * @param speed: can be a value of @SD_CMD6_Function_Group1
730 * @param buf_32align: pointer to a buffer to save the switch function status
731 * @retval HAL_OK: Check/Set function successfully
732 * Others: Fail to get check/Set function
733 */
SD_SwitchFunction(u8 mode,u8 speed,u8 * buf_32align)734 static u32 SD_SwitchFunction(u8 mode, u8 speed, u8 *buf_32align)
735 {
736 u32 ret;
737 SDIOH_DmaCtl dma_cfg;
738 SDIOH_CmdTypeDef cmd_attr;
739
740 if ((buf_32align == NULL) || (((u32)buf_32align) & 0x1F)) {
741 return HAL_ERR_PARA;
742 }
743
744 /***** CMD6 *****/
745 _memset((void *)buf_32align, 0, SDIOH_C6R2_BUF_LEN);
746 dma_cfg.op = SDIOH_DMA_READ;
747 dma_cfg.start_addr = ((u32)buf_32align)/8;
748 dma_cfg.blk_cnt = 1;
749 dma_cfg.type = SDIOH_DMA_64B;
750 SDIOH_DMAConfig(&dma_cfg);
751
752 cmd_attr.arg = (mode << 31) | (0xF << 20) | (0xF << 16) | (0xF << 12) | (0xF << 8) | (0xF << 4) | speed;
753 cmd_attr.idx = SD_CMD_SwitchFunc;
754 cmd_attr.rsp_type = SDIOH_RSP_6B;
755 cmd_attr.rsp_crc_chk = ENABLE;
756 cmd_attr.data_present = SDIOH_DATA_EXIST;
757 ret = SDIOH_SendCommand(&cmd_attr, 0);
758 if(ret != HAL_OK)
759 return ret;
760
761 ret = SDIOH_WaitDMADone( SDIOH_XFER_CPLT_TIMEOUT);
762 if (ret != HAL_OK) {
763 ret = SD_StopTransfer();
764 if (ret != HAL_OK) {
765 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Stop transmission error !!\r\n");
766 }
767
768 return HAL_ERR_UNKNOWN;
769 }
770
771 DCache_Invalidate((u32)buf_32align, SDIOH_C6R2_BUF_LEN);
772
773 // check if any errors
774 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SwitchFunc);
775 if (ret != HAL_OK) {
776 return ret;
777 }
778
779 return HAL_OK;
780 }
781
782 /**
783 * @brief SD card interrupt handler.
784 * @param None
785 * @retval None
786 */
SD_IRQHandler(void)787 static void SD_IRQHandler (void)
788 {
789 SDIOH_TypeDef *psdioh = SDIOH_BASE;
790 volatile u32 tmp1;
791 volatile u8 tmp2 = 0;
792
793 tmp1 = SDIOH_GetISR();
794 if(tmp1)
795 SDIOH_INTClearPendingBit(tmp1);
796
797 if(psdioh->CARD_INT_PEND & SDIOH_SDMMC_INT_PEND) {
798 tmp2 = psdioh->CARD_EXIST;
799
800 if(tmp2 & SDIOH_SD_EXIST) {
801 if(tmp2 & SDIOH_SD_WP)
802 card_info.sd_status = SD_PROTECTED;
803 else
804 card_info.sd_status = SD_INSERT;
805
806 DBG_8195A("Card Detect\n");
807 } else {
808 card_info.sd_status = SD_NODISK;
809
810 DBG_8195A("Card Remove\n");
811 }
812
813 psdioh->CARD_INT_PEND |= SDIOH_SDMMC_INT_PEND;
814 }
815
816 __DSB();
817 }
818
819
820
SD_GetEXTCSD(u8 * pbuf)821 SD_RESULT SD_GetEXTCSD(u8 *pbuf)
822 {
823 u32 ret, start;
824 SDIOH_DmaCtl dma_cfg;
825 SDIOH_CmdTypeDef cmd_attr;
826
827 /***** CMD8 *****/
828 dma_cfg.op = SDIOH_DMA_READ;
829 dma_cfg.start_addr = ((u32)(pbuf))/8;
830 dma_cfg.blk_cnt = 1;
831 dma_cfg.type = SDIOH_DMA_NORMAL;
832 SDIOH_DMAConfig(&dma_cfg);
833
834 cmd_attr.arg = 0;
835 cmd_attr.idx = EMMC_CMD_SendExtCsd;
836 cmd_attr.rsp_type = SDIOH_RSP_6B;
837 cmd_attr.rsp_crc_chk = ENABLE;
838 cmd_attr.data_present = SDIOH_DATA_EXIST;
839 ret = SDIOH_SendCommand(&cmd_attr, 100);
840 if(ret != HAL_OK){
841 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Send CMD8 error !!\r\n");
842 return ret;
843 }
844
845 ret = SDIOH_WaitDMADone(SDIOH_READ_TIMEOUT);
846
847 if (ret != HAL_OK) {
848 ret = SD_StopTransfer();
849 if (ret != HAL_OK)
850 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Stop transmission error !!\r\n");
851
852 return HAL_ERR_UNKNOWN;
853 }
854
855 //DCache_Invalidate((u32)card_info.ext_csd, SD_BLOCK_SIZE);
856
857 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SendIfCond);
858
859 return ret;
860 }
861
862 /**
863 * @brief To read one block from the SD card.
864 * @param ReadAddr: The start address to begin to read from the card.
865 * @param readbuff: The buffer to read data blocks (must be 32-Byte alignment).
866 * @retval HAL_OK: Read data successfully
867 * Others: Fail to read data
868 */
SD_ReadBlock(uint8_t * readbuff,uint32_t ReadAddr)869 u32 SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr)
870 {
871 u32 ret, start;
872 SDIOH_DmaCtl dma_cfg;
873 SDIOH_CmdTypeDef cmd_attr;
874
875 assert_param((readbuff != NULL) && ((((u32)readbuff) & 0x1F) == 0));
876
877 if (card_info.is_sdhc_sdxc)
878 start = (u32)(ReadAddr/SD_BLOCK_SIZE); // unit: block
879 else
880 start = (u32)ReadAddr;
881
882 /***** CMD17 *****/
883 dma_cfg.op = SDIOH_DMA_READ;
884 dma_cfg.start_addr = ((u32)readbuff)/8;
885 dma_cfg.blk_cnt = 1;
886 dma_cfg.type = SDIOH_DMA_NORMAL;
887 SDIOH_DMAConfig(&dma_cfg);
888
889 cmd_attr.arg = start;
890 cmd_attr.idx = SD_CMD_RdSingleBlk;
891 cmd_attr.rsp_type = SDIOH_RSP_6B;
892 cmd_attr.rsp_crc_chk = ENABLE;
893 cmd_attr.data_present = SDIOH_DATA_EXIST;
894 ret = SDIOH_SendCommand(&cmd_attr, 0);
895 if(ret != HAL_OK){
896 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Send CMD17 error !!\r\n");
897 return ret;
898 }
899
900 ret = SDIOH_WaitDMADone(SDIOH_READ_TIMEOUT);
901
902 if (ret != HAL_OK) {
903 ret = SD_StopTransfer();
904 if (ret != HAL_OK)
905 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Stop transmission error !!\r\n");
906
907 return HAL_ERR_UNKNOWN;
908 }
909
910 DCache_Invalidate((u32)readbuff, SD_BLOCK_SIZE);
911
912 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_RdSingleBlk);
913
914 return ret;
915 }
916
917 /**
918 * @brief To read multi-block from the SD card.
919 * @param ReadAddr: The start address to begin to read from the card.
920 * @param readbuff: The buffer to read data blocks (must be 32-Byte alignment).
921 * @param NumberOfBlocks: the number of blocks to be read
922 * @retval HAL_OK: Read data successfully
923 * Others: Fail to read data
924 */
SD_ReadMultiBlocks(uint8_t * readbuff,uint32_t ReadAddr,uint32_t NumberOfBlocks)925 u32 SD_ReadMultiBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint32_t NumberOfBlocks)
926 {
927 u32 ret, start;
928 SDIOH_DmaCtl dma_cfg;
929 SDIOH_CmdTypeDef cmd_attr;
930
931 assert_param(NumberOfBlocks > 1);
932 assert_param((readbuff != NULL) && ((((u32)readbuff) & 0x1F) == 0));
933
934 if (card_info.is_sdhc_sdxc)
935 start = (u32)(ReadAddr/SD_BLOCK_SIZE); // unit: block
936 else
937 start = (u32)ReadAddr;
938
939 /***** CMD18 *****/
940 dma_cfg.op = SDIOH_DMA_READ;
941 dma_cfg.start_addr = ((u32)readbuff)/8;
942 dma_cfg.blk_cnt = NumberOfBlocks;
943 dma_cfg.type = SDIOH_DMA_NORMAL;
944 SDIOH_DMAConfig(&dma_cfg);
945
946 cmd_attr.arg = start;
947 cmd_attr.idx = SD_CMD_RdMulBlk;
948 cmd_attr.rsp_type = SDIOH_RSP_6B;
949 cmd_attr.rsp_crc_chk = ENABLE;
950 cmd_attr.data_present = SDIOH_DATA_EXIST;
951 ret = SDIOH_SendCommand(&cmd_attr, 0);
952 if(ret != HAL_OK)
953 return ret;
954
955 ret = SDIOH_WaitDMADone(SDIOH_READ_TIMEOUT * NumberOfBlocks);
956 if (ret != HAL_OK) {
957 return ret;
958 }
959
960 DCache_Invalidate((u32)readbuff, NumberOfBlocks * SD_BLOCK_SIZE);
961
962 ret = CmdRespError(SDIOH_RESP_R1 , SD_CMD_RdMulBlk);
963
964 return ret;
965
966 }
967
968 /**
969 * @brief To write one block to the SD card.
970 * @param WriteAddr: The start address to begin writing to the card.
971 * @param writebuff: The buffer to write data blocks (must be 32-Byte alignment).
972 * @retval HAL_OK: Write data successfully
973 * Others: Fail to write data
974 */
SD_WriteBlock(uint8_t * writebuff,uint32_t WriteAddr)975 u32 SD_WriteBlock(uint8_t *writebuff, uint32_t WriteAddr)
976 {
977 u32 ret, start;
978 SDIOH_DmaCtl dma_cfg;
979 SDIOH_CmdTypeDef cmd_attr;
980 assert_param((writebuff != NULL) && ((((u32)writebuff) & 0x1F) == 0));
981
982 if (card_info.is_sdhc_sdxc)
983 start = (u32)(WriteAddr/SD_BLOCK_SIZE); // unit: block
984 else
985 start = (u32)WriteAddr;
986
987 /***** CMD24 *****/
988 DCache_Clean((u32)writebuff, SD_BLOCK_SIZE);
989
990 dma_cfg.op = SDIOH_DMA_WRITE;
991 dma_cfg.start_addr = ((u32)writebuff)/8;
992 dma_cfg.blk_cnt = 1;
993 dma_cfg.type = SDIOH_DMA_NORMAL;
994 SDIOH_DMAConfig(&dma_cfg);
995
996 cmd_attr.arg = start;
997 cmd_attr.idx = SD_CMD_WrBlk;
998 cmd_attr.rsp_type = SDIOH_RSP_6B;
999 cmd_attr.rsp_crc_chk = ENABLE;
1000 cmd_attr.data_present = SDIOH_DATA_EXIST;
1001 ret = SDIOH_SendCommand(&cmd_attr, 0);
1002 if(ret != HAL_OK)
1003 return ret;
1004
1005 ret = SDIOH_WaitDMADone(SDIOH_WRITE_TIMEOUT);
1006 if (ret != HAL_OK) {
1007 ret = SD_StopTransfer();
1008 if (ret != HAL_OK)
1009 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Stop transmission error !!\r\n");
1010
1011 return HAL_ERR_UNKNOWN;
1012 }
1013
1014 // check if any errors
1015 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_WrBlk);
1016
1017 return ret;
1018
1019 }
1020
1021 /**
1022 * @brief To write multi-block to the SD card.
1023 * @param WriteAddr: The start address to begin writing to the card.
1024 * @param NumberOfBlocks: The block count.
1025 * @param writebuff: The buffer to write data blocks (must be 32-Byte alignment).
1026 * @retval HAL_OK: Write data successfully
1027 * Others: Fail to write data
1028 */
SD_WriteMultiBlocks(uint8_t * writebuff,uint32_t WriteAddr,uint32_t NumberOfBlocks)1029 u32 SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint32_t NumberOfBlocks)
1030 {
1031 u32 start, ret;
1032 SDIOH_DmaCtl dma_cfg;
1033 SDIOH_CmdTypeDef cmd_attr;
1034
1035 assert_param(NumberOfBlocks > 1);
1036 assert_param((writebuff != NULL) && ((((u32)writebuff) & 0x1F) == 0));
1037
1038 if (card_info.is_sdhc_sdxc)
1039 start = (u32)(WriteAddr/SD_BLOCK_SIZE); // unit: block
1040 else
1041 start = (u32)WriteAddr;
1042 #if defined(SDIO) && (SDIO == SD)
1043 /***** ACMD23 (CMD55) *****/
1044 cmd_attr.arg = (card_info.rca) << 16;
1045 cmd_attr.idx = SD_CMD_AppCmd;
1046 cmd_attr.rsp_type = SDIOH_RSP_6B;
1047 cmd_attr.rsp_crc_chk = ENABLE;
1048 cmd_attr.data_present = SDIOH_NO_DATA;
1049 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
1050 if(ret != HAL_OK)
1051 return ret;
1052
1053 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_AppCmd);
1054 if (ret != HAL_OK) {
1055 return ret;
1056 }
1057
1058 /***** ACMD23 (CMD23) *****/
1059 cmd_attr.arg = NumberOfBlocks;
1060 cmd_attr.idx = SD_CMD_SetWrBlkEraseCnt;
1061 cmd_attr.rsp_type = SDIOH_RSP_6B;
1062 cmd_attr.rsp_crc_chk = ENABLE;
1063 cmd_attr.data_present = SDIOH_NO_DATA;
1064 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
1065 if(ret != HAL_OK)
1066 return ret;
1067
1068 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SetWrBlkEraseCnt);
1069 if (ret != HAL_OK) {
1070 return ret;
1071 }
1072 #endif
1073 DCache_Clean((u32)writebuff, NumberOfBlocks * SD_BLOCK_SIZE);
1074
1075 /***** CMD25 *****/
1076 dma_cfg.op = SDIOH_DMA_WRITE;
1077 dma_cfg.start_addr = ((u32)writebuff)/8;
1078 dma_cfg.blk_cnt = NumberOfBlocks;
1079 dma_cfg.type = SDIOH_DMA_NORMAL;
1080 SDIOH_DMAConfig(&dma_cfg);
1081
1082 cmd_attr.arg = start;
1083 cmd_attr.idx = SD_CMD_WrMulBlk;
1084 cmd_attr.rsp_type = SDIOH_RSP_6B;
1085 cmd_attr.rsp_crc_chk = ENABLE;
1086 cmd_attr.data_present = SDIOH_DATA_EXIST;
1087 ret = SDIOH_SendCommand(&cmd_attr, 0);
1088 if(ret != HAL_OK)
1089 return ret;
1090
1091 ret = SDIOH_WaitDMADone(SDIOH_WRITE_TIMEOUT * NumberOfBlocks);
1092 if (ret != HAL_OK) {
1093 return ret;
1094 }
1095
1096 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_WrMulBlk);
1097
1098 return ret;
1099
1100 }
1101
1102 /**
1103 * @brief To erase data in the SD card.
1104 * @param startaddr: The start address to begin erasing.
1105 * @param endaddr: The end address to begin erasing.
1106 * @retval HAL_OK: Erase data successfully
1107 * Others: Fail to Erase data.
1108 */
SD_Erase(uint32_t startaddr,uint32_t endaddr)1109 u32 SD_Erase(uint32_t startaddr, uint32_t endaddr)
1110 {
1111 SDIOH_CmdTypeDef cmd_attr;
1112 u32 start, end, ret, blk_cnt, start_cmd, end_cmd;
1113 #if defined(SDIO) && (SDIO == EMMC)
1114 start_cmd = EMMC_CMD_EraseAddrSt;
1115 end_cmd = EMMC_CMD_EraseAddrEd;
1116 #else
1117 start_cmd = SD_CMD_EraseBlkSt;
1118 end_cmd = SD_CMD_EraseBlkEd;
1119 #endif
1120
1121 assert_param(startaddr <= endaddr);
1122
1123 if (card_info.is_sdhc_sdxc) {
1124 start = (u32)(startaddr/SD_BLOCK_SIZE);
1125 end = (u32)(endaddr/SD_BLOCK_SIZE); // unit: block
1126 } else {
1127 start = (u32)startaddr;
1128 end = (u32)endaddr;
1129 }
1130
1131 blk_cnt = endaddr/SD_BLOCK_SIZE - startaddr/SD_BLOCK_SIZE + 1;
1132
1133 /***** CMD32 *****/
1134 cmd_attr.arg = start;
1135 cmd_attr.idx = start_cmd;
1136 cmd_attr.rsp_type = SDIOH_RSP_6B;
1137 cmd_attr.rsp_crc_chk = ENABLE;
1138 cmd_attr.data_present = SDIOH_NO_DATA;
1139 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
1140 if(ret != HAL_OK){
1141 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Send CMD32 error !!\r\n");
1142 }
1143
1144 ret = CmdRespError(SDIOH_RESP_R1, start_cmd);
1145 if (ret != HAL_OK) {
1146 return ret;
1147 }
1148
1149 /***** CMD33 *****/
1150 cmd_attr.arg = end;
1151 cmd_attr.idx = end_cmd;
1152 cmd_attr.rsp_type = SDIOH_RSP_6B;
1153 cmd_attr.rsp_crc_chk = ENABLE;
1154 cmd_attr.data_present = SDIOH_NO_DATA;
1155 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
1156 if(ret != HAL_OK){
1157 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Send CMD33 error !!\r\n");
1158 }
1159
1160 ret = CmdRespError(SDIOH_RESP_R1, end_cmd);
1161 if (ret != HAL_OK) {
1162 return ret;
1163 }
1164
1165 /***** CMD38 *****/
1166 cmd_attr.arg = 0;
1167 cmd_attr.idx = SD_CMD_Erase;
1168 cmd_attr.rsp_type = SDIOH_RSP_6B;
1169 cmd_attr.rsp_crc_chk = ENABLE;
1170 cmd_attr.data_present = SDIOH_NO_DATA;
1171 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_ERASE_TIMEOUT * blk_cnt);
1172 if(ret != HAL_OK){
1173 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Send CMD38 error !!\r\n");
1174 return ret;
1175 }
1176
1177 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_Erase);
1178 return ret;
1179 }
1180
1181 /**
1182 * @brief To get the current state of the SD card.
1183 * @param None.
1184 * @retval Current state of SD card, which is one of the @ref SD_Card_States values.
1185 */
SD_GetCardStatus(void)1186 u8 SD_GetCardStatus(void)
1187 {
1188 u32 ret;
1189 u8 state;
1190 SDIOH_CmdTypeDef cmd_attr;
1191
1192 /***** CMD13 *****/
1193 cmd_attr.arg = (card_info.rca) << 16;
1194 cmd_attr.idx = SD_CMD_SendSts;
1195 cmd_attr.rsp_type = SDIOH_RSP_6B;
1196 cmd_attr.rsp_crc_chk = ENABLE;
1197 cmd_attr.data_present = SDIOH_NO_DATA;
1198 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
1199 if(ret != HAL_OK)
1200 return ret;
1201
1202 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SendSts);
1203 if (ret != HAL_OK) {
1204 return SD_CARD_ERROR;
1205 }
1206
1207 // get card's current state
1208 state = (SDIOH_GetResponse(SDIO_RESP3) >> 1) & 0xF;
1209 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"card_curr_ste = %d\r\n", state);
1210
1211 return state;
1212 }
1213
1214 /**
1215 * @brief To get the SD status from the SD card.
1216 * @param buf_32align: The buffer to store the SD status (must be 32-Byte alignment).
1217 * @retval HAL_OK: Get SD status successfully
1218 * Others: Fail to get SD status.
1219 */
SD_GetSDStatus(u8 * buf_32align)1220 u32 SD_GetSDStatus(u8 *buf_32align)
1221 {
1222 u32 ret;
1223 SDIOH_DmaCtl dma_cfg;
1224 SDIOH_CmdTypeDef cmd_attr;
1225
1226 assert_param((buf_32align != NULL) && ((((u32)buf_32align) & 0x1F) == 0));
1227
1228 /***** ACMD13 (CMD55) *****/
1229 cmd_attr.arg = (card_info.rca) << 16;
1230 cmd_attr.idx = SD_CMD_AppCmd;
1231 cmd_attr.rsp_type = SDIOH_RSP_6B;
1232 cmd_attr.rsp_crc_chk = ENABLE;
1233 cmd_attr.data_present = SDIOH_NO_DATA;
1234 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
1235 if(ret != HAL_OK)
1236 return ret;
1237
1238 ret= CmdRespError(SDIOH_RESP_R1, SD_CMD_AppCmd);
1239 if (ret != HAL_OK) {
1240 return ret;
1241 }
1242
1243 /***** ACMD13 (CMD13) *****/
1244 _memset((void *)buf_32align, 0, SDIOH_C6R2_BUF_LEN);
1245 dma_cfg.op = SDIOH_DMA_READ;
1246 dma_cfg.start_addr = ((u32)buf_32align)/8;
1247 dma_cfg.blk_cnt = 1;
1248 dma_cfg.type = SDIOH_DMA_64B;
1249 SDIOH_DMAConfig(&dma_cfg);
1250
1251 cmd_attr.arg = 0;
1252 cmd_attr.idx = SD_CMD_SendSts;
1253 cmd_attr.rsp_type = SDIOH_RSP_6B;
1254 cmd_attr.rsp_crc_chk = ENABLE;
1255 cmd_attr.data_present = SDIOH_DATA_EXIST;
1256 ret = SDIOH_SendCommand(&cmd_attr, 0);
1257 if(ret != HAL_OK)
1258 return ret;
1259
1260 ret = SDIOH_WaitDMADone(SDIOH_XFER_CPLT_TIMEOUT);
1261 if (ret != HAL_OK) {
1262 ret = SD_StopTransfer();
1263 if (ret != HAL_OK) {
1264 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Stop transmission error !!\r\n");
1265 }
1266
1267 return HAL_ERR_UNKNOWN;
1268 }
1269
1270 DCache_Invalidate((u32)buf_32align, SDIOH_C6R2_BUF_LEN);
1271
1272 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SendSts);
1273
1274 return ret;
1275 }
1276
1277 /**
1278 * @brief To switch the SD bus speed.
1279 * @param speed: can be SD_SPEED_DS or SD_SPEED_HS of @ref SD_access_mode
1280 * @retval HAL_OK: switch speed successfully
1281 * Others: Fail to switch speed.
1282 */
1283 #if defined(SDIO) && (SDIO == SD)
1284
SD_SwitchBusSpeed(u8 speed)1285 u32 SD_SwitchBusSpeed(u8 speed)
1286 {
1287 u32 ret;
1288 u8 sw_spd, support_spd;
1289 u8* pbuf = card_info.dma_buf;
1290
1291 assert_param(speed <= SD_SPEED_HS);
1292
1293 if ((card_info.bus_spd) == speed) {
1294 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"Current SD bus speed is already the specified setting.\r\n");
1295 return HAL_OK;
1296 }
1297
1298 /* Get spec version to check if card supports CMD6 which was added in version 1.10 */
1299 ret = SD_GetSCR();
1300 if (ret != HAL_OK)
1301 return ret;
1302
1303 if((card_info.sd_spec_ver) >= SD_SPEC_V110) {
1304 /* get the supported speed modes */
1305 ret = SD_SwitchFunction(SD_CMD6_CHECK_MODE, SD_KEEP_CUR_SPEED, pbuf);
1306 if (ret != HAL_OK)
1307 return ret;
1308
1309 sw_spd = speed;
1310
1311 support_spd = pbuf[13];
1312 if(support_spd & (1 << sw_spd)) {
1313 if((pbuf[16] & 0xF) == sw_spd) {
1314 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"SD card's current speed mode is already the specified setting !!\r\n");
1315 } else {
1316 /* check if the specified speed can be switched */
1317 ret = SD_SwitchFunction(SD_CMD6_CHECK_MODE, sw_spd, pbuf);
1318
1319 if (ret != HAL_OK)
1320 return ret;
1321
1322 if((pbuf[16] & 0xF) == sw_spd) {
1323 /* Switch to the specified speed */
1324 ret = SD_SwitchFunction(SD_CMD6_SWITCH_MODE, sw_spd, pbuf);
1325
1326 if (ret != HAL_OK)
1327 return ret;
1328
1329 if((pbuf[16] & 0xF) == sw_spd) {
1330 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"SD card changes to the specified speed mode successfully\r\n");
1331 if(speed == SD_SPEED_DS) {
1332 SDIOH_SwitchSpeed(SDIOH_CLK_DIV4, SDIOH_SD20_MODE); // 25 MHz
1333 card_info.bus_spd = SD_SPEED_DS;
1334 } else if (speed == SD_SPEED_HS) {
1335 SDIOH_SwitchSpeed(SDIOH_CLK_DIV2, SDIOH_SD20_MODE); // 50 MHz
1336 card_info.bus_spd = SD_SPEED_HS;
1337 }
1338 } else {
1339 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "The switch request is canceled !!\r\n");
1340 return HAL_ERR_UNKNOWN;
1341 }
1342 } else {
1343 DBG_PRINTF(MODULE_SDIO, LEVEL_WARN, "The specified speed mode can't be switched !!\r\n");
1344 return HAL_ERR_UNKNOWN;
1345 }
1346 }
1347 } else {
1348 DBG_PRINTF(MODULE_SDIO, LEVEL_WARN, "This card doesn't support the specified speed mode !!\r\n");
1349 return HAL_ERR_HW;
1350 }
1351 } else {
1352 DBG_PRINTF(MODULE_SDIO, LEVEL_WARN,"This card doesn't support CMD6 and can't switch the bus speed !!\r\n");
1353 return HAL_ERR_HW;
1354 }
1355 return HAL_OK;
1356 }
1357
1358 #else
SD_SwitchBusSpeed(u8 speed)1359 SD_RESULT SD_SwitchBusSpeed(u8 speed)
1360 {
1361 u32 ret;
1362 SDIOH_CmdTypeDef cmd_attr;
1363
1364 if ((card_info.bus_spd) == speed) {
1365 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"Current SD bus speed is already the specified setting.\r\n");
1366 return HAL_OK;
1367 }
1368
1369 /***** CMD6 (CMD6) *****/
1370 if(speed == SD_SPEED_HS) {
1371 cmd_attr.arg = 0x03B90100; //EXT_CSD register B9 byte: 01, high speed mode;
1372 } else {
1373 cmd_attr.arg = 0x03B90000;
1374 }
1375 cmd_attr.idx = SD_CMD_SetBusWidth;
1376 cmd_attr.rsp_type = SDIOH_RSP_6B;
1377 cmd_attr.rsp_crc_chk = ENABLE;
1378 cmd_attr.data_present = SDIOH_NO_DATA;
1379 ret = SDIOH_SendCommand(&cmd_attr, SDIOH_CMD_CPLT_TIMEOUT);
1380 if(ret != HAL_OK)
1381 return ret;
1382
1383 ret = CmdRespError(SDIOH_RESP_R1, SD_CMD_SetBusWidth);
1384 if (ret != HAL_OK) {
1385 return ret;
1386 }
1387
1388 // Host also selects the specified mode
1389 if(speed == SD_SPEED_DS) {
1390 SDIOH_SwitchSpeed(SDIOH_CLK_DIV4, SDIOH_SD20_MODE); // 25 MHz
1391 card_info.bus_spd = SD_SPEED_DS;
1392 } else if (speed == SD_SPEED_HS) {
1393 SDIOH_SwitchSpeed(SDIOH_CLK_DIV2, SDIOH_SD20_MODE); // 50 MHz
1394 card_info.bus_spd = SD_SPEED_HS;
1395 }
1396 return HAL_OK;
1397 }
1398
1399 #endif
1400
1401 /****************************** The following functions are for FATFS call **************************************/
1402 /**
1403 * @brief To get the current state of the SDIOH and card.
1404 * @param None.
1405 * @retval SD_OK: SD card is initialized.
1406 * SD_NODISK: SD card is removed.
1407 * SD_INSERT: SD card is inserted.
1408 * SD_INITERR: SD card is init fail.
1409 * SD_PROTECTED: SD card is write-protected.
1410 * SD_ERROR: Some errors occur.
1411 */
SD_Status(void)1412 SD_RESULT SD_Status(void)
1413 {
1414 return card_info.sd_status;
1415 }
1416
1417 /**
1418 * @brief To write blocks of data to the SD card.
1419 * @param sector: the start index of blocks to write to.
1420 * @param data: pointer to data buffer. If the address of data buffer is 32-byte alinged,
1421 * the write performance would be higher.
1422 * @param count: specify how many blocks to be written.
1423 * @retval SD_OK: Success to write blocks.
1424 * SD_ERROR: Fail to write blocks.
1425 */
SD_WriteBlocks(u32 sector,const u8 * data,u32 count)1426 SD_RESULT SD_WriteBlocks(u32 sector,const u8 *data,u32 count)
1427 {
1428 u8 res, i = 0;
1429 u8 *ptr;
1430
1431 if((u32)data & 0x1F) { /* Not 32-byte aligned */
1432 ptr = pvPortMalloc(SD_BLOCK_SIZE + 0x1F);
1433 if(ptr == NULL) {
1434 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR,"Allocate buffer error !!\r\n");
1435 return SD_ERROR;
1436 }
1437 ptr = (u8*)(((((u32)ptr-1) >> 5) + 1) << 5); /*next 32-byte aligned*/
1438
1439 do {
1440 _memcpy(ptr, data + i * SD_BLOCK_SIZE, SD_BLOCK_SIZE);
1441
1442 res = SD_WriteBlock(ptr, (sector + i) * SD_BLOCK_SIZE);
1443 if(res != HAL_OK)
1444 break;
1445
1446 } while(++i < count);
1447
1448 vPortFree(ptr);
1449
1450 } else { /*32-byte aligned */
1451
1452 if(count == 1)
1453 res = SD_WriteBlock((uint8_t *)data, sector * SD_BLOCK_SIZE);
1454 else
1455 res = SD_WriteMultiBlocks((uint8_t *)data, sector * SD_BLOCK_SIZE, count);
1456 }
1457
1458 if(res == HAL_OK)
1459 return SD_OK;
1460
1461 return SD_ERROR;
1462 }
1463
1464 /**
1465 * @brief To read blocks of data from the SD card.
1466 * @param sector: the start index of blocks to read from.
1467 * @param data: pointer to data buffer. If the address of data buffer is 32-byte alinged,
1468 * the read performance would be higher.
1469 * @param count: specify how many blocks to be read.
1470 * @retval SD_OK: Success to read blocks.
1471 * SD_ERROR: Fail to read blocks.
1472 */
SD_ReadBlocks(u32 sector,u8 * data,u32 count)1473 SD_RESULT SD_ReadBlocks(u32 sector,u8 *data,u32 count)
1474 {
1475 u8 res, i = 0;
1476 u8 *ptr;
1477
1478 if((u32)data & 0x1F) { /* Not 32-byte aligned */
1479 ptr = pvPortMalloc(SD_BLOCK_SIZE + 0x1F);
1480 if(ptr == NULL) {
1481 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR,"Allocate buffer error !!\r\n");
1482 return SD_ERROR;
1483 }
1484 ptr = (u8*)(((((u32)ptr-1) >> 5) + 1) << 5); /*next 32-byte aligned*/
1485
1486 do {
1487 res = SD_ReadBlock(ptr, (sector + i) * SD_BLOCK_SIZE);
1488 if(res != HAL_OK)
1489 break;
1490
1491 _memcpy(data + i * SD_BLOCK_SIZE, ptr, SD_BLOCK_SIZE);
1492
1493 } while(++i < count);
1494
1495 vPortFree(ptr);
1496
1497 } else { /*32-byte aligned */
1498
1499 if(count == 1)
1500 res = SD_ReadBlock(data, sector * SD_BLOCK_SIZE);
1501 else
1502 res = SD_ReadMultiBlocks(data, sector * SD_BLOCK_SIZE, count);
1503 }
1504
1505 if(res == HAL_OK)
1506 return SD_OK;
1507
1508 return SD_ERROR;
1509 }
1510
1511 /**
1512 * @brief To get the capacity of the SD card.
1513 * @param sector_count: the capacity in blocks.
1514 * @retval SD_OK: Success to get capacity.
1515 * SD_ERROR: Fail to get capacity.
1516 */
SD_GetCapacity(u32 * sector_count)1517 SD_RESULT SD_GetCapacity(u32* sector_count)
1518 {
1519 if (card_info.capaticy == 0)
1520 SD_GetCSD();
1521
1522 *sector_count = card_info.capaticy * (1024 / SD_BLOCK_SIZE); //capacity in block counts
1523
1524 if(*sector_count)
1525 return SD_OK;
1526 return SD_ERROR;
1527 }
1528
1529 /**
1530 * @brief To initialize the SD memory card.
1531 * @param None.
1532 * @retval SD_OK: Initialize SD card successfully
1533 * Others: Fail to initialize SD card
1534 */
SD_Init(void)1535 SD_RESULT SD_Init(void)
1536 {
1537 u32 ret;
1538 u8 voltage_mismatch;
1539
1540 _memset(&card_info, 0, sizeof(SD_CardInfo));
1541 card_info.sd_status = SD_NODISK;
1542
1543 /* Configure pinmux */
1544 SDIOH_Pinmux();
1545
1546 /* Initialize SDIOH */
1547 SDIOH_Init(sdioh_config.sdioh_bus_width);
1548 #if defined(SDIO) &&(SDIO == EMMC)
1549 card_info.sd_status = SD_INSERT;
1550 #else
1551 InterruptRegister((IRQ_FUN)SD_IRQHandler, SDIO_HOST_IRQ, NULL, 5);
1552 InterruptEn(SDIO_HOST_IRQ, 5);
1553 #endif
1554 /* Initialize SD card */
1555 if(card_info.sd_status == SD_INSERT) {
1556 do {
1557 /* Card Identification */
1558 ret = SD_ResetCard();
1559 if (ret != HAL_OK)
1560 break;
1561
1562 #if defined(SDIO) && (SDIO == SD)
1563 ret = SD_VoltageCheck(&voltage_mismatch);
1564 if (ret != HAL_OK)
1565 break;
1566 #endif
1567 ret = SD_GetOCR(voltage_mismatch);
1568 if (ret != HAL_OK)
1569 break;
1570
1571 ret = SD_GetCID();
1572 if (ret != HAL_OK)
1573 break;
1574
1575 ret = SD_GetRCA();
1576 if (ret != HAL_OK)
1577 break;
1578
1579 /* switch to non-initial mode */
1580 ret = SDIOH_InitialModeCmd(DISABLE, card_info.sig_level);
1581 if (ret != HAL_OK) {
1582 break;
1583 } else {
1584 if(card_info.sig_level == SDIOH_SIG_VOL_18)
1585 card_info.bus_spd = SD_SPEED_SDR12;
1586 else
1587 card_info.bus_spd = SD_SPEED_DS;
1588 }
1589
1590 ret = SD_GetCSD();
1591 if (ret != HAL_OK)
1592 break;
1593
1594 ret = SD_SelectDeselect(_TRUE);
1595 if (ret != HAL_OK)
1596 break;
1597
1598 if(sdioh_config.sdioh_bus_width == SDIOH_BUS_WIDTH_4BIT) {
1599 ret = SD_SetBusWidth(SDIOH_BUS_WIDTH_4BIT);
1600 if (ret != HAL_OK)
1601 break;
1602 }
1603
1604 if(sdioh_config.sdioh_bus_speed == SD_SPEED_HS) {
1605 ret = SD_SwitchBusSpeed(SD_SPEED_HS);
1606 if (ret != HAL_OK)
1607 break;
1608
1609 }
1610
1611 } while(0);
1612
1613 if(ret == HAL_OK) {
1614 card_info.sd_status = SD_OK;
1615 DBG_PRINTF(MODULE_SDIO, LEVEL_INFO,"SD card is initialized\r\n");
1616 } else {
1617 card_info.sd_status = SD_INITERR;
1618 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR,"Init FAIL, ret: %d\n", ret);
1619 }
1620 } else if (card_info.sd_status == SD_PROTECTED) {
1621 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR,"Card is write protected !!\r\n");
1622
1623 } else if (card_info.sd_status == SD_NODISK) {
1624 DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR,"Card is removed\r\n");
1625 return SD_INITERR;
1626 }
1627
1628 return card_info.sd_status;
1629 }
1630
1631 /**
1632 * @brief To de-initialize the SDIO host controller.
1633 * @param None.
1634 * @retval SD_OK: SDIO host controller is de-initialize successfully.
1635 */
SD_DeInit(void)1636 SD_RESULT SD_DeInit(void)
1637 {
1638 SDIOH_DeInit();
1639 RCC_PeriphClockCmd(APBPeriph_SDIOH, APBPeriph_SDIOH_CLOCK, DISABLE);
1640
1641 InterruptUnRegister(SDIO_HOST_IRQ);
1642 InterruptDis(SDIO_HOST_IRQ);
1643
1644 return SD_OK;
1645 }
1646
1647