Beispiel #1
0
/********************************************************************************************************************
** 函数名称: U8_T SD_SendCmd()						Name:	  U8_T SD_SendCmd()
** 功能描述: 向卡发送命令,并取得响应				Function: send command to the card,and get a response
** 输   入: U8_T cmd	    : 命令字				Input:	  U8_T cmd	    : command byte	
			 U8_T *param	: 命令参数,长度为4字节			  U8_T *param	: command parameter,length is 4 bytes  
			 U8_T resptype : 响应类型						  U8_T resptype: response type
			 U8_T *resp	: 响应,长度为1-5字节			  U8_T *resp	: response,length is 1-5 bytes
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
********************************************************************************************************************/
U8_T SD_SendCmd(U8_T cmd, U8_T *param, U8_T resptype, U8_T *resp)
{
	S8_T i;
	U8_T tmp,rlen;
    
	SPI_CS_Assert();
   
    SPI_SendByte((cmd & 0x3F) | 0x40);				 /* 发送命令头和命令字 send command header and word */
    
    for (i = 3; i >= 0; i--)
        SPI_SendByte(param[i]);						 /* 发送参数 send parameters */
    
	if(cmd == CMD8)
		SPI_SendByte(CMD8_CRC);
	else if(cmd == CMD0)
		SPI_SendByte(0x95);							 /* CRC校验码,只用于第1个命令 CRC,only used for the first command */
	else
		SPI_SendByte(0x00);
    
    rlen = 0;
    switch (resptype)								 /* 根据不同的命令,得到不同的响应长度 */
    {												 /* according various command,get the various response length */
  		case R1:
   	 	case R1B: rlen = 1;  break;
       		 
    	case R2:  rlen = 2;	 break;
       		 
   		case R3:
		case R7:  rlen = 5;	 break;
       		 
    	default:  SPI_SendByte(0xFF);	
      		      SPI_CS_Deassert();						 
        	      return SD_ERR_CMD_RESPTYPE;		 /* 返回命令响应类型错误 return error of command response type */
    		      break;
    }
    
    i = 0;				
    do 												 /* 等待响应,响应的开始位为0 */
    {												 /* Wait for a response,a response is a start bit(zero) */ 
        tmp = SPI_RecByte();
        i++;
    }while (((tmp & 0x80) != 0) && (i < SD_CMD_TIMEOUT));
    
    if (i >= SD_CMD_TIMEOUT)
    {				
        SPI_CS_Deassert();
        return SD_ERR_CMD_TIMEOUT;					 /* 返回命令超时 return response timeout of command */
    }
    
    for (i = rlen - 1; i >= 0; i--)
    {
        resp[i] = tmp;
        tmp = SPI_RecByte();					 	 /* 循环的最后发送8clock  at the last recycle,clock out 8 clock */
    }

	SPI_CS_Deassert();

    return SD_NO_ERR;								 /* 返回执行成功 return perform sucessfully */
}
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res;

   if (pdrv)
    {   
        return RES_PARERR;  
    }
    //FATFS目前版本仅需处理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三个命令
    switch(cmd)
    {
    case CTRL_SYNC:
        SPI_CS_Assert();

        if(SD_ResetSD() == SD_NO_ERR)
        {
            res = RES_OK;
        }
        else
        {
            res = RES_ERROR;
        }
        SPI_CS_Deassert();
        break;
         
    case GET_BLOCK_SIZE:
        *(WORD*)buff = 512;
        res = RES_OK;
        break;
 
    case GET_SECTOR_COUNT:
        *(DWORD*)buff = SD_GetCardInfo();
        res = RES_OK;
        break;
    default:
        res = RES_PARERR;
        break;
    }
 
    return res;

}