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