我想使用SDIO接口作为普通的通信接口与FPGA进行通信,只使用SDIO数据接口,不使用SDIO通信协议,但是在进行测试时发现使用SDIO + DMA下发数据时会发生SDIO_FLAG_DCRCFAIL,SDIO和DMA都不会产生结束传输中断,想请教一下问题出在哪里,应该如何解决?
[mw_shl_code=applescript,true]void do_SDIO_init(void)
{
GPIO_InitTypeDef stGPIOInit;
NVIC_InitTypeDef NVIC_InitStructure;
SDIO_InitTypeDef SDIO_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组2 2bit抢占优先级 2bit从优先级
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn; //选择中断线0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级为 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //响应优先级为 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //中断使能
NVIC_Init(&NVIC_InitStructure);
/* SDIO 引脚分配
SDIO_CK PC12
SDIO_CMD PD2
SDIO_D0 PC8
SDIO_D1 PC9
SDIO_D2 PC10
SDIO_D3 PC11
SDIO_D4 PB8
SDIO_D5 PB9
SDIO_D6 PC6
SDIO_D7 PC7
*/
stGPIOInit.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
stGPIOInit.GPIO_Mode = GPIO_Mode_AF_PP;
stGPIOInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_BANK_C,&stGPIOInit);
stGPIOInit.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
stGPIOInit.GPIO_Mode = GPIO_Mode_AF_PP;
stGPIOInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_BANK_B,&stGPIOInit);
stGPIOInit.GPIO_Pin = GPIO_Pin_2;
stGPIOInit.GPIO_Mode = GPIO_Mode_AF_PP;
stGPIOInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_BANK_D,&stGPIOInit);
/* 寄存器复位 */
SDIO_DeInit( );
//SDIO_CK = HCLK/(2+CLK_DIV)
SDIO_InitStruct.SDIO_ClockDiv = SDIO_CLK_DIV_400KHz;//SDIO_CLK_DIV_1MHz; //时钟分频
SDIO_InitStruct.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
SDIO_InitStruct.SDIO_ClockBypass = SDIO_ClockBypass_Disable; //关闭旁路 如果开启旁路则会使用系统时钟 HCLK
SDIO_InitStruct.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; //开启省电模式后总线空闲时关闭sdclk时钟,逻辑不允许时钟关闭
SDIO_InitStruct.SDIO_BusWide = SDIO_BusWide_8b; //使用8位数据总线模式
SDIO_InitStruct.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Enable; //硬件流控,开启后,在fifo不能进行发送和接收数据时,数据传输暂停
SDIO_Init(&SDIO_InitStruct);
SDIO_SetPowerState(SDIO_PowerState_ON); //SDIO控制器供电
SDIO_ClockCmd(ENABLE); //SDIO时钟使能
}
[/mw_shl_code]
[mw_shl_code=c,true]void SDIO_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize )
{
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit(&DMA_InitStructure);//初始化 结构体
DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);//清除DMA CH4标志位
DMA_Cmd(SDIO_DMA_CH, DISABLE);//关闭DMA通道
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SDIO->FIFO; //DMA 的外设基址为SDIO的FIFO
DMA_InitStructure.DMA_BufferSize = BufferSize; //buffer size应该设置为多少?
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferDST;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向是从外设读入 外设为数据源
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //读过程中 外设的地址不自增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //读过程中 内存地址自增
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //不循环
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //通道优先级高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非存储器至存储器模式
DMA_Init(SDIO_DMA_CH, &DMA_InitStructure);
DMA_Cmd(SDIO_DMA_CH, ENABLE);
}
[/mw_shl_code]
[mw_shl_code=c,true]
void drvSDIOSendData(u16 regaddr, u8* pu8writebuff,euSDIO_BLK_SIZE euBlkSize,u32 u32BlkNum)
{
u32 timeout = 0xFFF;
int ii = 0;
u32 u32BlkLen = (u32)pow(2,(euBlkSize>>4)&0x0F);
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLength = u32BlkLen*u32BlkNum; //u32BlkSize * u32BlkNum;
SDIO_DataInitStructure.SDIO_DataBlockSize = euBlkSize;
SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard; //SDIO主机 --> 卡
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable; //启动发送
SDIO_DataConfig(&SDIO_DataInitStructure);
//允许中断 发送下溢 块CRC校验错误 数据发送超时 数据发送结束 起始位错误
SDIO_ITConfig(SDIO_IT_TXUNDERR|/*SDIO_IT_DCRCFAIL|*/SDIO_IT_DTIMEOUT|SDIO_IT_DATAEND|SDIO_IT_STBITERR, ENABLE);
SDIO_DMACmd(ENABLE); //使能DMA
SDIO_DMA_TxConfig((uint32_t *)pu8writebuff, u32BlkLen * u32BlkNum);
while(timeout)
{
if((SDIO_GetITStatus(SDIO_FLAG_DATAEND) == !RESET))
{
printf("data end
");
}
if((SDIO_GetITStatus(SDIO_FLAG_DBCKEND) == !RESET))
{
printf("block end
");
}
if((SDIO_GetITStatus(SDIO_FLAG_TXACT) == !RESET))
{
printf("block end
");
}
timeout--;
}
printf("time out
");
if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
printf("001
");
}
else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
printf("00data count is %d
",DMA_GetCurrDataCounter(SDIO_DMA_CH));
printf("002
");
}
else if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);
printf("003
");
}
else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_STBITERR);
printf("004
");
}
}
[/mw_shl_code][mw_shl_code=applescript,true]void main()
{
u32 mm = 1;
SystemInit();
RCCInit();
do_SDIO_init();
printf("Hello wrollld
");
do_ADC_Init();
for(xx = 0;xx < sizeof(aa);xx++)
{
aa[xx] = xx;
}
while (1)
{//TT是一个u32的数组,大小为128.
drvSDIOSendData(0,(u8*)TT,SDIO_BLK_512_Byte,1);
delay_us(1000);
}
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
有点汗颜了,今天又进行了一些测试,发现流控的开启和关闭又不会对数据发送产生影响了,鬼知道我昨天干了什么,打扰原子哥了,多谢多谢!
一周热门 更多>