打印
[应用相关]

STM32 USB双缓冲IN端点的疑问

[复制链接]
6791|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
九把刀|  楼主 | 2008-12-19 21:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32的USB双缓冲方式到底应该如何使用, 超级迷糊...

参考STR910双缓冲代码, 编写了一个STM32的双缓冲应用, 简单的测试了一下, 功能到是正常的. 就是对双缓冲的原理还不是特别明白.  

OUT端点倒是觉得理解的差不多了. 但是对于IN端点, 正确的操作到底应该如何的...

在那个代码中, USB初始化时设置DTOG_TX=0, SW_BUF=1, 在往缓冲区中写第一个数据包后, 会切换SW_BUF(即1->0).

那么此时, DTOG_TX便与SW_BUF都为0了. 按照数据手册中的说明, 在SW_BUF和DTOG_TX为相同值时, 端点为NAK状态.

可数据却可以正常上传, 这是为何???
沙发
香水城| | 2008-12-19 23:09 | 只看该作者

请参考这个帖子

记得这个帖子的楼主发表过他的源程序,你找找看。
相关链接:https://bbs.21ic.com/club/bbs/list.asp?boardid=49&t=3031280

使用特权

评论回复
板凳
九把刀|  楼主 | 2008-12-19 23:25 | 只看该作者

谢谢香大侠的回复.

我现在发现有两种方式都是可以正常传输的. <针对IN端点>

方式一
1. 在端点初始化时, 设置DTOG_TX=0, SW_BUF=1
   
2. 在主程序中写第一个数据包到缓冲区, 并切换SW_BUF(即1->0)

3. 在端点IN中断程序中写余下的数据包到缓冲区, 并一次切换SW_BUF. 
   (IN端点每中断一次, 便写一个数据包, 根据SW_BUF的状态决定是写入到BUF0还是BUF1)

方式二:
1. 在端点初始化时, 设置DTOG_TX=0, SW_BUF=0 (与上面的方式不同)
   
2. 在主程序中连着两个数据包到缓冲区(分别写到BUF0和BUF1), 并切换SW_BUF两次

3. 在端点IN中断程序中写余下的数据包到缓冲区, 并切换一次SW_BUF. 
   (IN端点每中断一次, 便写一个数据包, 根据SW_BUF的状态决定是写入到BUF0还是BUF1)


我测试了这两种方式, 发现都能正常传送数据... 

到底哪一种是正确可靠的?

使用特权

评论回复
地板
STARM| | 2013-6-18 10:34 | 只看该作者
方式二:
1. 在端点初始化时, 设置DTOG_TX=0, SW_BUF=0 (与上面的方式不同)
   
2. 在主程序中连着两个数据包到缓冲区(分别写到BUF0和BUF1), 并切换SW_BUF两次

并切换SW_BUF两次之后, 不是和 DTOG_TX 一样, 两者都是 0 吗, 数据发不出去吧 ?

因为2个标志位相同它就会发NAK

使用特权

评论回复
5
gongxd126com| | 2014-3-13 20:36 | 只看该作者
同问

使用特权

评论回复
6
一无所有aaa| | 2014-4-22 16:29 | 只看该作者
求双传冲代码

使用特权

评论回复
7
一无所有aaa| | 2014-4-22 16:29 | 只看该作者
求STM32双缓冲代码

使用特权

评论回复
8
abswzp| | 2015-10-9 08:57 | 只看该作者
STARM 发表于 2013-6-18 10:34
方式二:
1. 在端点初始化时, 设置DTOG_TX=0, SW_BUF=0 (与上面的方式不同)
   

不会发不出去,第1次切换SW_BUF时,usb硬件就开始工作了,很快就会把buf0里的数据发完,与此同时,你的程序正在往buf1里拷贝数据.按照usb48M的时钟速度,应该还没等你拷贝完成,usb早就把buf0发送到pc里了,这之后你才将SW_BUF进行第2次切换

使用特权

评论回复
9
abswzp| | 2015-10-9 11:04 | 只看该作者
本帖最后由 abswzp 于 2015-10-9 11:11 编辑

在stm32给的例子,STM32_USB-FS-Device_Lib_V4.0.0中的Audio_Speaker端点1就是双缓冲的,自己找下,配置源码给你截取一段

usb_prop.c里void Virtual_Com_Port_Reset(void)函数
  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_ISOCHRONOUS);
  SetEPDblBuffAddr(ENDP1, ENDP1_BUF0Addr, ENDP1_BUF1Addr);
  SetEPDblBuffCount(ENDP1, EP_DBUF_OUT, 0x40);
  ClearDTOG_RX(ENDP1);
  ClearDTOG_TX(ENDP1);
  ToggleDTOG_TX(ENDP1);
  SetEPRxStatus(ENDP1, EP_RX_VALID);
  SetEPTxStatus(ENDP1, EP_TX_DIS);

  SetEPRxValid(ENDP0);
  /* Set this device to response on default address */
  SetDeviceAddress(0);

  bDeviceState = ATTACHED;

  In_Data_Offset = 0;
  Out_Data_Offset = 0;

usb_endp.c
void EP1_OUT_Callback(void)
{
    uint16_t Data_Len;       /* data length*/

    if (GetENDPOINT(ENDP1) & EP_DTOG_TX)
    {
        /*read from ENDP1_BUF0Addr buffer*/
        Data_Len = GetEPDblBuf0Count(ENDP1);
        PMAToUserBufferCopy(Stream_Buff, ENDP1_BUF0Addr, Data_Len);
    }
    else
    {
        /*read from ENDP1_BUF1Addr buffer*/
        Data_Len = GetEPDblBuf1Count(ENDP1);
        PMAToUserBufferCopy(Stream_Buff, ENDP1_BUF1Addr, Data_Len);
    }
    FreeUserBuffer(ENDP1, EP_DBUF_OUT);
    In_Data_Offset += Data_Len;
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

44

帖子

0

粉丝