SD_Error SDIO_SendDataCommand(SDIO_CmdInitType *SDIO_CmdInitStruct, SDIO_DataInitType* SDIO_DataInitStruct, u32 *buf)
{
SD_Error errorstatus = SD_OK;
u32 count;
u32 timeout = SDIO_DATATIMEOUT;
int tlen;
if(NULL == buf)
{
return SD_INVALID_PARAMETER;
}
SDIO1->DTCTRL = 0x0; //数据控制寄存器清零(关DMA)
SDIO_DataConfig(SDIO1, SDIO_DataInitStruct);
SDIO_SendCommand(SDIO1, SDIO_CmdInitStruct); //发送CMD17+从addr地址出读取数据,短响应
errorstatus = CmdResp1Error(SDIO_CmdInitStruct->SDIO_CmdIdx); //等待R1响应
if(errorstatus != SD_OK) //响应错误
{
return errorstatus;
}
tlen = SDIO_DataInitStruct->SDIO_DataLen;
if(DeviceMode == SD_POLLING_MODE) /* 轮询模式 */
{
if (SDIO_DataInitStruct->SDIO_TransferDir == SDIO_TransferDir_ToSDIO)
{
while(!(SDIO1->STS & (SDIO_INTR_STS_READ_MASK)))
{
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_RXBUF_H) != RESET)
{
for(count = 0; count < 8; count++, buf++)
{
*buf = SDIO1->BUF;
}
timeout = 0X7FFFFF;
}
else
{
if(timeout == 0) //超时
{
SD_Init();
return SD_DATA_TIMEOUT;
}
timeout--;
}
}
while(SDIO_GetFlagStatus(SDIO1, SDIO_**_RXBUF) != RESET)
{
*buf = SDIO1->BUF;
buf++;
}
}
else
{
while(!(SDIO1->STS & SDIO_INTR_STS_WRITE_MASK))
{
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_TXBUF_H) != RESET)
{
for(count = 0; count < 8 && tlen > 0; count++, buf++, tlen -= 4)
{
SDIO1->BUF = *buf;
}
timeout = 0X3FFFFFFF;
}
else
{
if(timeout == 0) //超时
{
SD_Init();
return SD_DATA_TIMEOUT;
}
timeout--;
}
}
}
if(SDIO_GetFlagStatus(SDIO1, SDIO_**_DTTIMEOUT) != RESET) //数据超时
{
SDIO_ClearFlag(SDIO1, SDIO_**_DTTIMEOUT);
return SD_DATA_TIMEOUT;
}
else if(SDIO_GetFlagStatus(SDIO1, SDIO_**_DTFAIL) != RESET) //CRC错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_DTFAIL);
return SD_DATA_FAIL;
}
else if(SDIO_GetFlagStatus(SDIO1, SDIO_**_RXERRO) != RESET) //上溢错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_RXERRO);
return SD_RX_OVERRUN;
}
else if(SDIO_GetFlagStatus(SDIO1, SDIO_**_TXERRU) != RESET) //下溢错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_TXERRU);
return SD_TX_UNDERRUN;
}
else if(SDIO_GetFlagStatus(SDIO1, SDIO_**_SBITERR) != RESET) //起始位错误
{
SDIO_ClearFlag(SDIO1, SDIO_**_SBITERR);
return SD_START_BIT_ERR;
}
if(StopCondition == 1 && SDIO_GetFlagStatus(SDIO1, SDIO_**_DTCMPL) != RESET) //接收结束
{
SDIO_CmdInitStruct->SDIO_Argu = 0; //发送CMD12+结束传输
SDIO_CmdInitStruct->SDIO_CmdIdx = SD_CMD_STOP_TRANSMISSION;
SDIO_CmdInitStruct->SDIO_Resp = SDIO_Rsp_Short;
SDIO_CmdInitStruct->SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStruct->SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(SDIO1, SDIO_CmdInitStruct);
errorstatus = CmdResp1Error(SD_CMD_STOP_TRANSMISSION); //等待R1响应
if(errorstatus != SD_OK)
{
return errorstatus;
}
}
SDIO_ClearFlag(SDIO1, SDIO_STATIC_FLAGS); //清除所有标记
}
else if(DeviceMode == SD_DMA_MODE) /* DMA模式 */
{
if (SDIO_DataInitStruct->SDIO_TransferDir == SDIO_TransferDir_ToSDIO)
{
SD_DMA_Config(buf, tlen, DMA_DIR_PERIPHERALSRC);
SDIO1->INTEN |= SDIO_INTR_STS_READ_MASK;
}
else
{
SD_DMA_Config(buf, tlen, DMA_DIR_PERIPHERALDST);
SDIO1->INTEN |= SDIO_INTR_STS_WRITE_MASK;
}
TransferError = SD_OK;
TransferEnd = 0; //传输结束标置位,在中断服务置1
SDIO1->DTCTRL |= 1 << 3;
while(!(SDIO1->STS & SDIO1->INTEN) && timeout)
{
timeout--;
if (TransferEnd)
{
break;
}
}
if(timeout == 0)
{
SD_Init();
return SD_DATA_TIMEOUT;
}
if(TransferError != SD_OK)
{
errorstatus = TransferError;
}
}
return errorstatus;
}
|