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

📄 mc_commands.c

📁 基于STR710 spi接口的MMC/SD卡(SPI模式)驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
;********************************************************************************************************/
UWORD8 mc_get_write_nblock(UWORD32 *blocknum)
{
    UWORD8  param[4];
    UWORD8  resp;
    UWORD8  ret;
    
    ret = mc_send_command(CMD55, param, CMD55_R, &resp);	  	 /* 后续命令为一个应用命令 */
    if (ret != MC_SUCCESS) 								 
    	 return ret;
    	 
    if (resp != 0)
    	 return MC_ERR_CMD_RESP;    	
    											
    ret = mc_send_command(ACMD22, param, ACMD22_R, &resp);  	 /* 读取正确写入的块数命令 */
    if (ret != MC_SUCCESS)								 
    	 return ret;											    
    		 														
    if (resp != 0)
    	 return MC_ERR_CMD_RESP;							 	/* 响应错误 */
    		
    ret = mc_read_block_data(4, param);						 	/* 读块数 */
    if (ret != MC_SUCCESS)
    	 return ret;
    	
    *blocknum = (param[0] << 24) + (param[1] << 16) + (param[2] << 8) + param[3];	
    													 		/* 转换为32位  */
    
    return MC_SUCCESS;    								 		/* 返回执行成功 */		
}


		/*********************************************************
		
		    			数据传输函数
		
		**********************************************************/
/*********************************************************************************************************
;** 函数名称: UWORD8 mc_read_register()	
;** 功能描述: 从SD卡读取数据	
;** 
;** 参    数: UWORD32 len	  : 长度			
;**			  UWORD8 *recbuf: 接收缓冲区	
;** 返 回 值: 0:   正确    >0:   错误码
;**         
;** 作   者: 邓国强
;** 日   期: 2006年5月29日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
UWORD8 mc_read_register(UWORD32 len, UWORD8 *recbuf)
{	
    UWORD32  i = 0;
    UWORD8   resp,tmp;
    
    MC_CS_ENABLE();
    do{    											/* 等待数据起始令牌  */
        resp = mc_receive_byte();
        i++;
    }while((resp == 0xFF) && (i < MC_READREG_TIMEOUT));    
    
    if (i >= MC_READREG_TIMEOUT)
    {
        MC_CS_DISABLE();
        return MC_ERR_TIMEOUT_READ;					/* 超时, 返回错误  */
    }
    
    if (resp != MC_TOK_READ_STARTBLOCK)				
    {												/* 不是收到数据起始令牌  */
        recbuf[0] = resp;							
        i = 1;										/* 还有len - 1个字节要接收  */
    }
    else
        i = 0;										/* 收到数据起始令牌,还有len个字节要接收  */
    	
    for (; i < len; i++)				
        recbuf[i] = mc_receive_byte();				/* 接收数据  */
	

    tmp = mc_receive_byte();
    i = mc_receive_byte();
    i = (tmp << 8) + i;    							/* 读取16位CRC  */	
    
    #if MC_CRC_EN 
    if (i != mc_get_crc16(recbuf, len))
    {												/* CRC校验错误  */
        mc_send_byte(0xff);
        MC_CS_DISABLE();		
        return MC_ERR_DATA_CRC16;					/* 返回RCR16错误   */				
    }    
    #endif   
    mc_send_byte(0xff);                             /* 返回之前发送8个clock   */
    MC_CS_DISABLE();	
    
    return MC_SUCCESS;
}	

/*********************************************************************************************************
;** 函数名称: UWORD8 mc_read_block_data()			
;** 功能描述: 从卡中读取数据块		
;** 
;** 参    数: UWORD32 len    : 长度			
;**			  UWORD8 *recbuf : 接收缓冲区	
;** 返 回 值: 0:   正确    >0:   错误码
;**         
;** 作   者: 邓国强
;** 日   期: 2006年5月29日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
UWORD8 mc_read_block_data(UWORD32 len, UWORD8 *recbuf)
{
    UWORD8 tmp,tmprec;
    UWORD32 i = 0,timeout;
    
	timeout = mc_info.timeout_read;						/* 等待接收数据开始令牌最长时间  */

    
    MC_CS_ENABLE();    
    do
    { 											    	/* 等待接收数据开始令牌0xFE  */
	 tmp = mc_receive_byte();
        i++;
    }while((tmp == 0xFF) && (i < timeout));
    

    if (i >= timeout)
    {
        MC_CS_DISABLE();
        return MC_ERR_TIMEOUT_READ;						/* 返回读超时错误码   */
    }
    
    if (tmp != MC_TOK_READ_STARTBLOCK)					/* 块读开始令牌错误  */
    {
        tmp = 0xff;
        mc_send_byte(0xff);
	 MC_CS_DISABLE();
        return MC_ERR_DATA_START_TOK;
    }
    
    for (i = 0; i < len; i++)					
        recbuf[i] = mc_receive_byte();					/* 接收数据  */

    tmprec = mc_receive_byte();
    i = mc_receive_byte();
    i = (tmprec << 8) + i;    							/* 读取16位CRC  */	

#if MC_CRC_EN 
    if (i != mc_get_crc16(recbuf, len))
    {	
        tmprec = 0xff;							
        mc_send_byte(0xff);   							/* CRC校验错误  */
	 MC_CS_DISABLE();		
    	 return MC_ERR_DATA_CRC16;						/* 返回RCR16错误  */				
    }    
#endif   

    tmp = 0xff;
    mc_send_byte(0xff);
    MC_CS_DISABLE();	
    
    return MC_SUCCESS;									/* 返回函数执行成功 */
}

/*********************************************************************************************************
;** 函数名称: UWORD8 mc_write_block_data()		
;** 功能描述: 向卡写数据块			
;** 
;** 参    数: UWORD8 bmulti  : 是否为多块操作1:是0:否	
;**			  UWORD32 len    : 长度
;**                  UWORD8 *sendbuf: 发送缓冲区					
;** 返 回 值: 0:   正确    >0:   错误码
;**         
;** 作   者: 邓国强
;** 日   期: 2006年5月29日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
UWORD8 mc_write_block_data(UWORD8 bmulti, UWORD32 len, UWORD8 *sendbuf)
{
    UWORD16 i;
    UWORD8 tmp;
    
    MC_CS_ENABLE();   
    				
    mc_send_byte(0xFF);								/* 开始发送数据之前发送8个clock  */
    
    if (bmulti == 1)				
        mc_send_byte(MC_TOK_WRITE_STARTBLOCK_M);	/* 写多块开始令牌  */
    else
	 	mc_send_byte(MC_TOK_WRITE_STARTBLOCK);		/* 写单块开始令牌  */	
	 		
	 	
    for (i = 0; i < len; i++)
        mc_send_byte(sendbuf[i]);					/* 发送数据  */
        
#if MC_CRC_EN	
    i = mc_get_crc16(sendbuf,len);					/* 计算CRC16  */
#endif
    
    
    mc_send_byte((i >> 8) & 0xFF);           		/* 发送CRC16校验码  */
    mc_send_byte(i & 0xFF);


    tmp = mc_receive_byte();
    if ((tmp & MC_RESP_DATA_MSK) != MC_RESP_DATA_ACCETPTED)	
    {	
        
        mc_send_byte(0xFF);							/* 返回之前发送8个clock   */
	 	MC_CS_DISABLE();
        return MC_ERR_DATA_RESP;					/* 数据响应错误  */
    }
    
    MC_CS_DISABLE();  
       		
    if (mc_wait_busy(MC_WAIT_WRITE) != MC_SUCCESS)			
    	return MC_ERR_TIMEOUT_WRITE;				/* 写入超时 */
    else
    	return MC_SUCCESS; 							/* 写入正确  */
 }

/*********************************************************************************************************
;** 函数名称:void SD_StopMultiToken()		
;** 功能描述:发送多块写停止令牌		
;** 
;** 参    数: NONE
;**			 				
;** 返 回 值: none
;**         
;** 作   者: 邓国强
;** 日   期: 2006年5月29日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
void mc_stop_multi_token(void)
{
    UWORD8 tmp[2];
    
    MC_CS_ENABLE();
    tmp[0] = 0xff;                                /* 先发送8个clock  */
    tmp[1] = MC_TOK_STOP_MULTI;                   /* 发送停止数据传输令牌  */
    mc_send_byte(tmp[0]);
    mc_send_byte(tmp[1]);
	
    tmp[0] = mc_receive_byte();
    MC_CS_DISABLE();
}

/*********************************************************************************************************
;** 函数名称: void mc_wait_busy()			
;** 功能描述: 查询SD卡是否处于忙状态		
;** 
;** 参    数: UWORD8 waittype: 超时类型			
;**			 				
;** 返 回 值: 0: 未超时  >0: 错误码		
;**         
;** 作   者: 邓国强
;** 日   期: 2006年5月29日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
UWORD8 mc_wait_busy(UWORD8 waittype)
{
    UWORD32 timeout, i = 0;
    volatile UWORD8 tmp;
    
    if (waittype == MC_WAIT_WRITE)
    {
    	timeout = mc_info.timeout_write;				/* 等待类型为写操作  */
    }
    else if (waittype == MC_WAIT_READ)
    	timeout = mc_info.timeout_read;   				/* 等待类型为擦除操作  */
    else
    	timeout = mc_info.timeout_erase;
   

    MC_CS_ENABLE();
    do
    { 													/* 等待忙结束  */
        tmp = mc_receive_byte();
        i++;
    }while ((tmp != 0xFF) && (i < timeout));			/* 忙时收到的值为0  */    


    if(i < timeout) 
        tmp = MC_SUCCESS;								/* 返回0,表示没超时  */
    else 
        tmp = MC_ERR_TIMEOUT_WAIT;						/* 返回错误码,表示超时  */
    
    mc_send_byte(0xFF);
    MC_CS_DISABLE();	
    							
    return tmp;											/* 返回执行结果 */
}

/*********************************************************************************************************
;** 函数名称:void mc_spi_delay()			
;** 功能描述: SPI总线延时		
;** 
;** 参    数: UWORD8 value: 延时值,不超过255			
;**			 				
;** 返 回 值: none
;**         
;** 作   者: 邓国强
;** 日   期: 2006年5月29日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
void mc_delay(UWORD16 value)
{
    UWORD16 i;

    for (i = 0; i < value; i++)
    {
	 	mc_send_byte(0xFF);					 	/* 发送0xFF */
    }
        
}



⌨️ 快捷键说明

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