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

📄 sdcmd.c

📁 SmartARM2400系列开发板全套资料
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			sdcmd.c
** Last modified Date:	2007-5-19
** Last Version:		V2.0
** Descriptions:		SD/MMC 软件包: SD/MMC卡SPI模式和SD模式支持的命令 
**						
**
**------------------------------------------------------------------------------------------------------
** Created by:			Ming Yuan Zheng
** Created date:		2005-1-6
** Version:				V1.0
** Descriptions:		SD/MMC 读写模块: 物理层 ---- SD卡SPI模式支持的命令 
**
**------------------------------------------------------------------------------------------------------
** Modified by:			Ming Yuan Zheng
** Modified date:		2005-3-11
** Version:				V2.0	
** Descriptions:		增加了对MMC卡的支持,并使用本模块既可以运行于前后台系统,也可运行于uCOS-II中.
**
**------------------------------------------------------------------------------------------------------
** Modified by:         Ming Yuan Zheng
** Modified date:       2007-5-19
** Version:	            V3.0
** Descriptions:        1. 对原来SPI模式下的函数名进行修改, 改为以 SpiCmd_ 为开头, 数据流函数以 SdSpi_ 为开头
**
**                      2. 增加了对SD总线模式的支持, 函数名以 SdCmd_ 为开头
**
********************************************************************************************************/

#include "sdconfig.h"


			/*********************************************

			 本文件实现 SD/MMC 卡 SD模式下的各 CMD 和 ACMD

			**********************************************/

#if SDBUS_MODE_EN

static void word_to_byte(INT32U value, INT8U *pdst);

#define OCR_WITHOUT_BUSY		0x00FF8000
#define OCR_WITH_BUSY			0x80000000


/*************
    CMD 0 
*************/
/*******************************************************************************************************************
** 函数名称: SdCmd_Go_Idle_State()				
**
** 功能描述: CMD0, 复位所有卡, 使卡进入Idle状态		
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体 
**	
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdCmd_Go_Idle_State(sd_struct *sds)
{
	return (SdHal_SendCmd(sds, CMD0, 0, CMD0_R, 0, 0));			/* 发送 CMD0 并取得响应 */
}


/*************
    CMD 1 
*************/
/*******************************************************************************************************************
** 函数名称: SdCmd_Send_OP_Cond()				
**
** 功能描述: CMD1(仅用于MMC卡), 使卡退出Idle状态, 进入Ready状态(通过判断MMC卡的OCR寄存器值)		
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体 
**	
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdCmd_Send_OP_Cond(sd_struct *sds)
{
	INT32U OCRVal;
	INT8U ret;
	INT32U count = 0;

 	do 
    {	
		ret = SdHal_SendCmd(sds, CMD1, OCR_WITHOUT_BUSY, CMD1_R, &OCRVal, 1);	/* 发送 CMD1 并取得响应 */
		if (ret != SD_NO_ERR)
			return ret;

        if (count >= SD_IDLE_WAIT_MAX)
            return SD_ERR_TIMEOUT_WAITIDLE;									    /* 超时,返回错误码 */
     	
      	count ++;

    }while ((OCRVal & OCR_WITH_BUSY) == 0x00000000);
	
    if ((OCRVal & MSK_OCR_33) != MSK_OCR_33)
        return SD_ERR_VOL_NOTSUSP;											    /* 卡不支3.2V ~ 3.3V电压 */			
	
	return SD_NO_ERR;
}


/*************
    CMD 55 
*************/
/*******************************************************************************************************************
** 函数名称: SdCmd_Send_ACMD()				
**
** 功能描述: CMD55(仅用于SD卡), 在发送所有 ACMDxx 命令之前, 必须先发送本命令		
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体 
**	
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
**
** 注	 意: 在未使用 Set_Relative_Addr 命令取得卡的RCA地址之前, sds->RCA为0.
********************************************************************************************************************/
INT8U SdCmd_Send_ACMD(sd_struct *sds)
{
	INT32U argument;	
	INT32U devstatus = 0;
	INT8U ret;

	if (sds->card_type == CARDTYPE_SD)									/* 根据卡型取不同的参数 */
		argument = sds->RCA;											
	else
		argument = 0x00000000;	
				  
	ret = SdHal_SendCmd(sds, CMD55, argument, CMD55_R, &devstatus, 1);	/* 发送 CMD55 并取得响应 */	
	if (ret != SD_NO_ERR)
		return ret;
		
	if (devstatus & CARD_STATUS_ACMD_ENABLE)						
		return SD_NO_ERR;											    /* 支持 CMD55 命令 */
		
	return SD_ERR_CMD_NOTSUSP;										    /* 不支持该命令 */
}


/*************
    ACMD 41 
*************/
/*******************************************************************************************************************
** 函数名称: SdCmd_SD_App_OP_Cond()				
**
** 功能描述: ACMD41(仅用于SD卡), 使卡退出Idle状态, 并进入Ready状态(通过判断SD卡的OCR寄存器值)		
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体
**           
**	
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
**
** 注	 意: 在未使用 Set_Relative_Addr 命令取得卡的RCA地址之前, sds->RCA为0.
********************************************************************************************************************/
INT8U SdCmd_SD_App_OP_Cond(sd_struct *sds)
{
	INT8U ret;
	INT32U OCRVal, count = 0;

 	do 
    {	
       	ret = SdCmd_Send_ACMD(sds);                                               /* 先发送 CMD55 命令 */
		if (ret != SD_NO_ERR)
			return ret;
           
		ret = SdHal_SendCmd(sds, ACMD41, OCR_WITHOUT_BUSY, ACMD41_R, &OCRVal, 1); /* 发送 ACMD41 并取得响应 */
		if (ret != SD_NO_ERR)
			return ret;

        if (count >= SD_IDLE_WAIT_MAX)
            return SD_ERR_TIMEOUT_WAITIDLE;									      /* 超时,返回错误码 */
     	
      	count ++;

    }while ((OCRVal & OCR_WITH_BUSY) == 0x00000000);
	
    if ((OCRVal & MSK_OCR_33) != MSK_OCR_33)
        return SD_ERR_VOL_NOTSUSP;											      /* 卡不支3.2V ~ 3.3V电压 */			
	
	return SD_NO_ERR;	
}


/*************
    CMD 2
*************/
/*******************************************************************************************************************
** 函数名称: SdCmd_All_Send_CID()				
**
** 功能描述: 获取所有卡的CID寄存器内容	
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体
**           INT8U cidlen    : CID 寄存器长度, 固定为16字节
**	
** 输   出: INT8U *cidbuf   : CID 寄存器内容, 长度为16字节
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
**
** 注	 意: 该命令的Argument域不必关心
********************************************************************************************************************/
INT8U SdCmd_All_Send_CID(sd_struct *sds, INT8U cidlen, INT8U *cidbuf)
{
	INT8U ret;
	INT32U resp[4];
	
	if ((cidlen < 16) || (cidbuf == 0))
	    return SD_ERR_USER_PARAM;
		
	ret = SdHal_SendCmd(sds, CMD2, 0, CMD2_R, resp, 4);
	if (ret != SD_NO_ERR)
		return ret;	
	
	word_to_byte(*resp, cidbuf);                            /* 从响应内容中取得CID寄存器内容 */
	word_to_byte(*(resp + 1), cidbuf + 4);
	word_to_byte(*(resp + 2), cidbuf + 8);
	word_to_byte(*(resp + 3), cidbuf + 12);
			
	return SD_NO_ERR;
}


/*****************************
    CMD 3: 设置卡的地址 RCA 
******************************/
/*******************************************************************************************************************
** 函数名称: SdCmd_Set_Relative_Addr()				
**
** 功能描述: CMD3, 获取卡的RCA地址, 然后保存到sds结构体中		
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体
**	
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
**
** 注	 意: 该函数将给 sds->RCA 成员赋值
********************************************************************************************************************/
INT8U SdCmd_Set_Relative_Addr(sd_struct *sds)
{	
	INT32U argument;
	INT32U resp;
	INT8U ret;

	/* 如果是一张SD卡, 使用SET_RELATIVE_ADDR用于从卡获取地址并在RCA中使用该值, 
	   如果是一张MMC卡, 使用默认的RCA地址 0x00010000. */
	if (sds->card_type == CARDTYPE_SD)
	{
		argument = 0;
	}
	else			
	{	/* 如果是未知的或MMC卡, 固定RCA地址 */
		argument = 0x00010000;
	}

	ret = SdHal_SendCmd(sds, CMD3, argument, CMD3_R, &resp, 1);
	if (ret != 0)
		return ret;
	
	if (sds->card_type == CARDTYPE_SD)
	{
	    /* 卡应处于 IDENT 状态 */	
	    if ((resp & CARD_STATUS_CURRENT_STATE) == CARD_STATUS_IDENT)
	    	sds->RCA = resp & 0xFFFF0000;
	    else
	        return SD_ERR_CURRENT_STATE;
	}
	else
	    sds->RCA = argument;    
	    
	return SD_NO_ERR;		
}


/********************************************
    CMD 9, 仅在CMD3发送后才可发送, 获取 CSD 
*********************************************/
/*******************************************************************************************************************
** 函数名称: SdCmd_Send_CSD()				
**
** 功能描述: CMD9, 获取卡的CSD寄存器值		
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体
**           INT8U csdlen    : CSD 寄存器长度
**	
** 输   出: INT8U *csdbuf   : CSD寄存器内容, bit127 在csdbuf[0] 
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
**
** 注	 意: 该命令需要 sds->RCA 作为命令参数
********************************************************************************************************************/
INT8U SdCmd_Send_CSD(sd_struct *sds, INT8U csdlen, INT8U *csdbuf)
{	
	INT8U ret;
	INT32U resp[4];
	
	if ((csdlen < 16) || (csdbuf == 0))
	    return SD_ERR_USER_PARAM;	
	
	ret = SdHal_SendCmd(sds, CMD9, sds->RCA, CMD9_R, resp, 4);
	if (ret != SD_NO_ERR)
		return ret;
		
	word_to_byte(*resp, csdbuf);                            /* 从响应内容中取得CSD寄存器内容 */
	word_to_byte(*(resp + 1), csdbuf + 4);
	word_to_byte(*(resp + 2), csdbuf + 8);
	word_to_byte(*(resp + 3), csdbuf + 12);
	
	return SD_NO_ERR;
}


/**********************************************************
    CMD 7: 选择卡, 使卡在 Stand-by 与 Transfer 之间切换
***********************************************************/
/*******************************************************************************************************************
** 函数名称: SdCmd_Select_Card()				
**
** 功能描述: CMD7, 使卡在 Stand-by 与 Transfer 之间切换	
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体
**	        
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
**
** 注	 意: 该命令需要 sds->RCA 作为命令参数
********************************************************************************************************************/
INT8U SdCmd_Select_Card(sd_struct *sds)
{
	INT32U resp;
	INT8U ret;

	ret = SdHal_SendCmd(sds, CMD7, sds->RCA, CMD7_R, &resp, 1);
	if (ret != SD_NO_ERR)
		return ret;
	
	return SD_NO_ERR;
}


/**********************************************************
    CMD 7: 取消选择卡, 使卡在 Stand-by 与 Transfer 之间切换
***********************************************************/
/*******************************************************************************************************************
** 函数名称: SdCmd_Select_Card()				
**
** 功能描述: CMD7, 使卡在 Stand-by 与 Transfer 之间切换	
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体
**	         INT32U RCA      : 卡的RCA地址
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
**
** 注	 意: 该命令的命令参数为RCA, 取值为0
********************************************************************************************************************/
INT8U SdCmd_Deselect_Card(sd_struct *sds, INT32U RCA)
{
	INT32U resp;
	INT8U ret;

	ret = SdHal_SendCmd(sds, CMD7, RCA, CMD0_R, &resp, 1);

⌨️ 快捷键说明

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