发现STM32 USB固件库一处BUG

文 号

840248

1 回复 / 430 浏览


ry7740kptv1 个月前 -2017-10-26 18:42840248 0阶

STM32 USB提供双缓冲接收方式,以解决对时序和速度要求较高的场合,如使用同步传输的音/视频流、接近线速的Bulk传输等。最近在用F103C8T6做声卡,在调试时发现收到的数据总是最后一对采样错误,导致声音播放时有毛刺。反复找问题和调试无果,遂怀疑芯片有问题,更换后仍无果。最后一统乱试发现,判断当前用户使用的缓冲区的标志位反了,具体如下:

voidEP3_OUT_Callback(void)
{
  if(GetENDPOINT(ENDP3) & EP_DTOG_TX){ //先判断本次接收到的数据是放在哪块缓冲区的
    FreeUserBuffer(ENDP3,EP_DBUF_OUT); //先释放用户对缓冲区的占有,这样的话USB的下一个接收过程可以立刻进行,同时用户并行进行下面处理
    count_out=GetEPDblBuf0Count(ENDP3);//读取接收到的字节数
    PMAToUserBufferCopy(buffer_out,ENDP3_BUF0Addr,count_out);
  }else{
    FreeUserBuffer(ENDP3,EP_DBUF_OUT);
    count_out=GetEPDblBuf1Count(ENDP3);
    PMAToUserBufferCopy(buffer_out,ENDP3_BUF1Addr,count_out);
  }
}

以上是搬运的网上的一个例程,可以看到通过判断端点的EP_DTOG_RX/EP_DTOG_TX标志位来确定当前用户所使用的缓冲区,此例程是接收方向的双缓冲中断处理函数,当EP_DTOG_TX标志位置1时表示使用用户使用BUFF0而USB IP核使用BUFF1,反之用户使用BUFF1而USB使用BUFF0。我在编写声卡的程序时也按照此思路,接收方向判断EP_DTOG_TX来交换Buffer,但此时收到的数据总有错误。而无意中将EP_DTOG_TX改为EP_DTOG_RX,则问题消失,数据正常,播放声音正常。遂仔细翻阅STM32器件手册,发现:

278336

即对于接收方向上使用EP_DTOG_RX判断缓冲区而发送方向用EP_DTOG_TX(从宏定义字面意思上也能看懂的~),但这里并没有说明接收方向和发送方向是以谁为参考,即对于OUT端点是当做接收方向(对单片机)还是发送方向(对主机)。但仔细看下OUT端点,使用的缓冲区均以RX结尾,也就是说理论上应该是和DTOG_RX对应的。如果确实是这样,那么网上的例程应该全是错误的,按照他们的写法根本收不到正确的数据。但确实是改为RX后,声卡工作正常了,Debug Watch看到数据流也正确了。

待有空写一个Bulk传输的例程来验证下再来跟大家分享!


iSee1 个月前 -2017-10-28 12:32840283 1阶
确实不能迷信芯片厂家的固件库,我曾经也在华邦的W90P710芯片固件库的串行模块部分发现BUG,调试了好久才发现问题。

返回 电子技术
返回 本页顶部

想参与大家的讨论?现在就 登陆 或者 注册


nkc Development Server https://github.com/lovetheory/nkc2

科创研究院 (c)2005-2016

蜀ICP备11004945号-2 川公网安备51010802000058号