1、周立功的SD卡驱动,发送CMD,填充的4字节参数需要颠倒过来的,这点从计算CRC时可以看出,不知这样设计的道理是什么?
2、发送CMD接收应答时,将接收的数据也颠倒过来了,响应为1字节时没问题,响应为多字节时,如发送CMD58命令式,判断应答判断的是resp[0],这不就会产生bug吗?颠倒了应该判断resp[4]吧?
以下为周立功SD驱动发送CMD命令源码:
/********************************************************************************************************************
** 函数名称: INT8U SD_SendCmd() Name: INT8U SD_SendCmd()
** 功能描述: 向卡发送命令,并取得响应 Function: send command to the card,and get a response
** 输 入: INT8U cmd : 命令字 Input: INT8U cmd : command byte
INT8U *param : 命令参数,长度为4字节 INT8U *param : command parameter,length is 4 bytes
INT8U resptype : 响应类型 INT8U resptype: response type
INT8U *resp : 响应,长度为1-5字节 INT8U *resp : response,length is 1-5 bytes
** 输 出: 0: 正确 >0: 错误码 Output: 0: right >0: error code
********************************************************************************************************************/
uint8 SD_SendCmd(uint8 cmd, uint8 *param, uint8 resptype, uint8 *resp)
{
int32 i,rlen; //所有SD卡命令都是6字节长
uint8 tmp;
SPI_CS_Assert(); //片选SPI从机
SPI_SendByte((cmd & 0x3F) | 0x40); /* 发送命令头和命令字 send command header and word */
//起始位为0(bit47),传输位为1(bit46)
for (i = 0; i < 4; i++)
SPI_SendByte(param[i]); /* 发送参数 send parameters */
#if SD_CRC_EN
tmp = SD_GetCmdByte6((cmd & 0x3F) | 0x40, param);
SPI_SendByte(tmp);
#else
SPI_SendByte(0x95); /* CRC校验码,只用于第1个命令 CRC,only used for the first command */
#endif
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: rlen = 5; break;
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 */
}
|