/*************************************************************************************************************************
* 函数 : SDIO_Error SD_WriteMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, const u8 *pBlockBuff, u16 NumberOfBlocks)
* 功能 : 写SD卡多个块
* 参数 : pHandle:句柄;BlockAddr:块地址;BlockBuff:块缓冲区地址NumberOfBlocks:块数量
* 返回 : SD_OK:成功,其它见SD Card Error code.
* 依赖 : 底层寄存器操作函数
* 作者 : cp1300@139.com
* 时间 : 2018-03-30
* 最后修改时间 : 2018-03-30
* 说明 : 写SD卡多个(大于1个)块
**************************************************************************************************************************/
SDIO_Error SD_WriteMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, const u8 *pBlockBuff, u16 NumberOfBlocks)
{
SDIO_Error errorstatus = SDIO_OK;
u32 cardstatus = 0;
u32 ReadLen = 0;
u32 timeout;
if (pBlockBuff == NULL)
{
errorstatus = SDIO_INVALID_PARAMETER;
return(errorstatus);
}
//限制读取的块数量
if(NumberOfBlocks > pHandle->MaxTransBlockCount)
{
DEBUG("限制一次读取%d块,当前一次读取%d\r\n", pHandle->MaxTransBlockCount, NumberOfBlocks);
NumberOfBlocks = pHandle->MaxTransBlockCount;
}
//地址检查
if(pHandle->CardType != SD_HIGH_CAPACITY_SD_CARD)
{
BlockAddr <<= 9; //小容量卡,转换为字节单位
}
//检查
timeout = 100; //超时100ms`
do
{
//发送CMD13,SDIO_SEND_STATUS,读 Card_Status 寄存器,参数,RCA地址,短返回,R1;
pHandle->pInterface->SDIO_SendCommand(CMD13, (u32) pHandle->RCA << 16, SDIO_Response_Short);
errorstatus = pHandle->pInterface->SDIO_CmdResp1Error(); //获取回复
if (errorstatus != SDIO_OK) //命令发送错误,返回
{
pHandle->pInterface->SDIO_ClearDataTrans(); //清除数据传输
DEBUG("CMD13 error (%d)!\r\n",errorstatus);
return(errorstatus);
}
pHandle->pInterface->SDIO_GetResponse(SDIO_RESP_Short, &cardstatus); //获取响应的状态
if((cardstatus & 0x00000100) == 0) //没有准备好
{
SYS_DelayMS(1); //延时
}
else //READY_FOR_DATA位有效,卡已经准备好写入了
{
break;
}
timeout --;
}
while (timeout);
if (timeout == 0)
{
DEBUG("等待卡写入超时,错误:%d(状态0x%X)\r\n",errorstatus,cardstatus);
return(SDIO_ERROR);
}
pHandle->pInterface->SDIO_ClearDataTrans(); //清除数据传输
//发送CMD25,SDIO_WRITE_MULT_BLOCK,参数:字节地址(大容量卡为块地址),短返回,R1
pHandle->pInterface->SDIO_SendCommand(CMD25, BlockAddr, SDIO_Response_Short);
errorstatus = pHandle->pInterface->SDIO_CmdResp1Error(); //获取回复
if (errorstatus != SDIO_OK) //命令发送错误,返回
{
pHandle->pInterface->SDIO_ClearDataTrans(); //清除数据传输
DEBUG("CMD25 error (%d)!\r\n",errorstatus);
return(errorstatus);
}
//开始传输-写入数据
pHandle->pInterface->SDIO_SetAndStartDataTrans((u8 *)pBlockBuff, FALSE, pHandle->SDIO_BlockSize, pHandle->SDCardInfo.CardBlockSize*NumberOfBlocks);
//等待传输完成
errorstatus = pHandle->pInterface->SDIO_WaitTransComplete(FALSE, &ReadLen, 100*NumberOfBlocks);//SDIO等待传输完成(等待读取或写入数据完成)(超时:100ms*NumberOfBlocks)
if(errorstatus == SDIO_OK && ReadLen != (pHandle->SDCardInfo.CardBlockSize*NumberOfBlocks))
{
DEBUG("写入数据错误,需要写入:%dB,实际写入:%dB\r\n", pHandle->SDCardInfo.CardBlockSize, ReadLen);
}
//发送CMD12 SDIO_STOP_TRANSMISSION命令,终止读取;参数:0,短响应,R1
pHandle->pInterface->SDIO_SendCommand(CMD12, 0, SDIO_Response_Short);
errorstatus = pHandle->pInterface->SDIO_CmdResp1Error(); //获取回复
if (errorstatus != SDIO_OK) //命令发送错误,返回
{
pHandle->pInterface->SDIO_ClearDataTrans(); //清除数据传输
DEBUG("CMD12 error (%d)!\r\n",errorstatus);
return(errorstatus);
}
//读取卡编程状态,等待写入完成
errorstatus = SD_WaitProgrammingFinish(pHandle, 100); //等待编程完成
return(errorstatus);
}
|