⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mc_operations.c

📁 基于STR710 spi接口的MMC/SD卡(SPI模式)驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "config.h"


const UWORD32 time_unit[8] = {1000000000,100000000,10000000,/* 超时时间单位表(单位:0.000000001ns)  */
							 1000000,100000,10000,1000,100};
							 
const UWORD8 time_value[16] = {0,10,12,13,15,20,25,30,		/* 超时时间表  */
                              35,40,45,50,55,60,70,80};
                             
const UWORD8 r2w_fator[8] = {1,2,4,8,16,32,64,128}; 		/* 超时时间因数表  */  

/*********************************************************************************************************
** 函数名称: mc_hadware_init
** 功能描述: MMC/SD硬件接口初始化
** 
** 参    数: None 
**          
** 返 回 值:  None
**         
** 作   者: 罗辉联
** 日   期: 2006年6月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void mc_hadware_init(void)
{

	MC_WRITE_PROTECTED_CFG();				/* 配置MC的WP管脚GPIO1_14为输入模式 	*/
				
    MC_CARD_INSERTED_CFG();					/* 配置MC的INSERT管脚GPIO1_15为输入模式 */
	   
    MC_MISO_PIN_CONFIG();					/* 配置SPI接口       					*/	
    MC_MISO_PIN_LOW();
	MC_MOSI_PIN_CONFIG();	
	MC_MOSI_PIN_LOW();
	MC_SCLK_PIN_CONFIG();	
	MC_SCLK_PIN_LOW();


	MC_CS_CFG();							/* 配置MC的CS管脚为推拉输出 			*/
	
	MC_CLK_400K();							/* 配置BSPI波特率为400k       			*/

	mc_port_init();							/* 初始化SPI接口       					*/
		
}

/*********************************************************************************************************
** 函数名称: mc_software_active
** 功能描述: MMC/SD软件激活
** 
** 参    数: None 
**          
** 返 回 值: error type
**         
** 作   者: 罗辉联
** 日   期: 2006年6月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
UWORD8 mc_software_active(void)
{
	UWORD8 param[4] = {0,0,0,0},resp[5] = {0,0,0,0,0},ret = 0;
	UWORD32 i = 0;

 	do 
    {										/* 发出CMD1, 查询卡的状态 */
        ret = mc_send_command(CMD1, param, CMD1_R, resp);
        if (ret != MC_SUCCESS)
        {
            MC_SEND_TRACE("mc_send_command CMD1 return value fail: %d", ret);
            goto MC_SOFTWARE_ACTIVE_END;
		
        }
       // else
        	;//MC_SEND_TRACE("mc_send_command CMD1 return value success, CMD1 send times:%d ", i);
        	
        i ++;
        													/* 如果响应R1的最低位Idle位为1,则继续循环 */
    }while (((resp[0] & MSK_IDLE) == MSK_IDLE) && (i <= MC_IDLE_WAIT_MAX));
    															    
    if (i >= MC_IDLE_WAIT_MAX)
    {
    	MC_SEND_TRACE("CMD1 resposne timeout error: %d", i);	
        ret = MC_ERR_TIMEOUT_WAITIDLE;						/* 超时,返回错误 */	
        goto MC_SOFTWARE_ACTIVE_END;
    }
	
    ret = mc_send_command(CMD55, param, CMD55_R, resp);		/* 通知SD/MMC下面将发送应用命令*/
   
    if (ret != MC_SUCCESS)
    	goto MC_SOFTWARE_ACTIVE_END;
       	
    ret = mc_send_command(ACMD41, param, ACMD41_R, resp);	/* 激活内部初始化命令 */
    
    if (ret != MC_SUCCESS)
    {	
    	MC_SEND_TRACE("CMD41 resposne value: %d", ret);
    	ret = MC_ERR_UNKNOWN_CARD;
    	goto MC_SOFTWARE_ACTIVE_END;
    }
    
    if ((resp[0] & 0xFE) == 0)		
    {		
		mc_info.card_type = SD_CARD;						/* 是SD卡  */
    }
    else
    {
    	mc_info.card_type = MMC_CARD;						/* 是MMC卡  */
    }

MC_SOFTWARE_ACTIVE_END:
	MC_SEND_TRACE("mc_software_active return value: %d", ret);
	return ret;

}
/*********************************************************************************************************
** 函数名称: mc_cal_time_out
** 功能描述: MMC/SD操作超时计算
** 
** 参    数: None 
**          
** 返 回 值: error type
**         
** 作   者: 罗辉联
** 日   期: 2006年6月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
MC_RESULT_T mc_cal_time_out(UWORD8 *csdbuf)
{
	
	UWORD32 tmp;
	UWORD8 time_u,time_v,fator;
	
	mc_info.timeout_read = READ_TIMEOUT_100MS;							/* 默认读超时为100ms */
	mc_info.timeout_write = WRITE_TIMEOUT_250MS;						/* 默认写超时为250ms */
	mc_info.timeout_erase = WRITE_TIMEOUT_250MS;
		
	time_u = (csdbuf[TAAC_POS] & TAAC_MSK);								/* 读超时时间单位  */
	time_v = (csdbuf[TAAC_POS] & NSAC_MSK) >> 3;						/* 读超时时间值    */
	fator = (csdbuf[R2WFACTOR_POS] & R2WFACTOR_MSK) >> 2;				/* 读超时时间因数  */
	
	if(time_v == 0)	
		return MC_ERR_CARD_PARAM;												/* 卡参数有错误  */
	
	tmp = SPI_CLOCK * time_value[time_v] / 10 / time_unit[time_u];		/* TACC * f (单位 unit: clock) */
	tmp = tmp + csdbuf[NSAC_POS] * 100;									/* TACC * f + NSAC * 100 (单位 unit: clock) */
	
																		/* 计算得到的超时值 */
	mc_info.timeout_read = tmp;
	mc_info.timeout_write = tmp * r2w_fator[fator];						/* (TACC * f + NSAC * 100) * R2WFACTOR (单位 unit:clock)*/
	
	if (mc_info.card_type == SD_CARD)
	{
		mc_info.timeout_read  = mc_info.timeout_read * 100 / 8;			/* 实际值为计算值的100倍 */
		mc_info.timeout_write = mc_info.timeout_write * 100 / 8;
		if (mc_info.timeout_read > READ_TIMEOUT_100MS)					/* 取计算值与默认值中的最小值 */
			mc_info.timeout_read = READ_TIMEOUT_100MS;
		
		if (mc_info.timeout_write > WRITE_TIMEOUT_250MS)
			mc_info.timeout_write = WRITE_TIMEOUT_250MS;
	}
	else
	{
		mc_info.timeout_read  = mc_info.timeout_read * 10 / 8;			/* 实际值为计算值的10倍 */
		mc_info.timeout_write = mc_info.timeout_write * 10 / 8;
	}
	
	mc_info.timeout_erase = mc_info.timeout_write;
	
	
	return MC_SUCCESS;	
}
/*********************************************************************************************************
** 函数名称: mc_get_card_info
** 功能描述:  获得MMC/SD相关信息
** 
** 参    数: None 
**          
** 返 回 值: error type
**         
** 作   者: 罗辉联
** 日   期: 2006年6月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
MC_RESULT_T mc_get_card_info(void)
{
	UWORD32 tmp;
	UWORD8 csdbuf[16],ret;

	ret = mc_read_csd(16, csdbuf);	 								    /* 读CSD寄存器     */
	
	if (ret != MC_SUCCESS)	
		return ret;	
		
	mc_cal_time_out(csdbuf);											/* 计算超时时间值  */
		
													
	mc_info.block_len = 1 << (csdbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK);/* 计算块的最大长度  */		  			
	
																		/* 计算卡中块的个数 */
	mc_info.block_num = ((csdbuf[C_SIZE_POS1] & C_SIZE_MSK1) << 10) +
	      			 (csdbuf[C_SIZE_POS2] << 2) +
	 	 			((csdbuf[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1;		/* (C_SIZE + 1)*/
		 	  															
	tmp = ((csdbuf[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) +   
	      ((csdbuf[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2;		/* (C_SIZE_MULT + 2) */
    	
    																	/* 获得卡中块的数量 */														
	mc_info.block_num = mc_info.block_num * (1 << tmp);					/* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
																			
																		/* 计算擦除的单位(单位: 块) */	
	if (mc_info.card_type == MMC_CARD)
	{					    
		tmp  = ((csdbuf[ERASE_GRP_SIZE_POS] & ERASE_GRP_SIZE_MSK) >> 2) + 1;  /* (ERASE_GRP_SIZE + 1)  */ 
		
		tmp *= ((csdbuf[ERASE_GRP_MULTI_POS1] & ERASE_GRP_MULTI_MSK1) << 3) +
		       ((csdbuf[ERASE_GRP_MULTI_POS2] & ERASE_GRP_MULTI_MSK2) >> 5) + 1;	
	}
	else																/*calculate the size of sector */
		tmp = ((csdbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) +  			
	          ((csdbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1;	/* SD: SECTOR_SIZE */
	
	mc_info.erase_unit = tmp;	    									/* 擦除单位(块) */ 
	
	return MC_SUCCESS;													/* 返回执行成功  */
}


/*********************************************************************************************************
** 函数名称: mc_initialize
** 功能描述: MMC/SD总的初始化
** 
** 参    数: None 
**          
** 返 回 值: error type
**         
** 作   者: 罗辉联
** 日   期: 2006年6月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 
** 日   期: 
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
UWORD8 mc_initialize(void)
{
	WORD8  ret = 0;
	UWORD8 recbuf[4] = {0};
		
	mc_hadware_init();											/* MMC/SD硬件接口初始化 		 */
	
	if (MC_CARD_INSERTED_STATUS() != 1)							/* 检查卡是否插入 				 */
    {
    	ret = MC_ERR_NO_CARD;   
    	goto MC_SD_ERR;
    }
    
    															/* MC SD初始化步骤 				  */
    MC_CS_ENABLE();												/* 1.置CS为低 					  */ 
    mc_delay(200);												/* 2.至少延时CLK 此处延时320 CLK */ 
    MC_CS_DISABLE();											/* 3.置CS为高  				  */
    mc_delay(4);												/* 4.延时4(8 clock) 			  */
    
    ms_sleep(100);												/* 5.等待一定的时间后在操作SD/MMC */
    
    ret = mc_reset();											/* 6.发出CMDO命令复位SD卡 		  */
    if (ret != MC_SUCCESS)
        goto MC_SD_ERR;								
	
	ret =mc_software_active();									/* 7.激活卡进入初始化过程.  */
	if(ret != MC_SUCCESS)
		goto MC_SD_ERR;	
		
	mc_read_ocr(4,recbuf);										/* 8.读OCR寄存器,查询卡支持的电压值 */
    
//    MC_SEND_TRACE("among SD_ReadOCR, after send CMD58, recbuf[0] value:%d",recbuf[0]);	
//    MC_SEND_TRACE("among SD_ReadOCR, after send CMD58, recbuf[1] value:%d",recbuf[1]);	
//    MC_SEND_TRACE("among SD_ReadOCR, after send CMD58, recbuf[2] value:%d",recbuf[2]);
//    MC_SEND_TRACE("among SD_ReadOCR, after send CMD58, recbuf[3] value:%d",recbuf[3]);
    
    if((recbuf[1] & MSK_OCR_33) != MSK_OCR_33)
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -