打印

stm32f103c8t6 usb端点1无法发送数据

[复制链接]
6868|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cgha|  楼主 | 2009-6-25 17:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

从3.01 版本cunstom hid例子修改成bulk传输,pc驱动用libusb-win32,将ADC数据通过USB上传到PC,能正常枚举,装驱动,但是PC在发送BULK IN 后,设备端无反应。
以下为USB部分设置:
SetEPType(ENDP1, EP_BULK);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxCount(ENDP1, 64);    //2*3*8
SetEPTxStatus(ENDP1, EP_TX_VALID);  //设置端点发送有效
    //SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxStatus(ENDP1, EP_RX_DIS);  //设置端点接收关闭

SetEPType(ENDP2, EP_BULK);  //设置端点2传输模式批量传输
SetEPRxAddr(ENDP2, ENDP2_RXADDR);
SetEPRxCount(ENDP2, 64);
SetEPRxStatus(ENDP2, EP_RX_VALID);
SetEPTxStatus(ENDP2, EP_TX_DIS);  //端点关闭发送


void EP1_IN_Callback(void)
{
    static uint16_t i=0;
    
    if(Ready2Transfer)
    {
        GPIO_WriteBit(GPIO_LED, GPIO_LED2_PIN, Bit_SET);
        UserToPMABufferCopy(Send_Buffer+i*64, GetEPTxAddr(ENDP1), 64);
        SetEPTxValid(ENDP1);  //发送数据
        i++;
        if(i==4)
        {
            i=0;
            Ready2Transfer = 0;
            //May also need ZLP here! depend on the pc driver
        }
    }
   //delay();
}
 
#define EP_NUM     (2)
/*-------------------------------------------------------------*/
/* --------------   Buffer Description Table  -----------------*/
/*-------------------------------------------------------------*/
/* buffer table base address */
/* buffer table base address */
#define BTABLE_ADDRESS      (0x00) //描述表在分组缓冲区中的位置
/* EP0  */
/* rx/tx buffer base address */
#define ENDP0_RXADDR        (0x18) //0x00~0x17被描述表给占用,0x18~0x1ff作为真正端点数据缓冲区
#define ENDP0_TXADDR        (0x58)
/* EP1  */
/* tx buffer base address */
#define ENDP1_TXADDR        (0x100)
#define ENDP2_RXADDR        (0x180)
//#define  EP1_IN_Callback   NOP_Process
沙发
cgha|  楼主 | 2009-6-25 17:12 | 只看该作者

USB端点描述符已改成BULK

使用特权

评论回复
板凳
cgha|  楼主 | 2009-6-25 17:23 | 只看该作者

是忘了设置SetEPTxCount了。设置了就好了

使用特权

评论回复
地板
vigia| | 2009-6-25 18:00 | 只看该作者

为什么不用BULK的例子改,而用HID的例子改呢?

SetEPTxStatus(ENDP1, EP_TX_VALID);  //设置端点发送有效
这句话是不能随便写的,一旦设置了有效,在USB驱动发送了IN的请求后,设备立即将buff中的数据上传,然后产生EP1_IN_Callback的中断。

所以正确的做法是

初始化时SetEPTxStatus(ENDP1, EP_TX_NAK);

在main函数中:
UserToPMABufferCopy(Send_Buffer, GetEPTxAddr(ENDP1), 64);
SetEPTxValid(ENDP1);  //发送数据
注意:
SetEPTxValid(ENDP1); 这句话和SetEPTxStatus(ENDP1, EP_TX_VALID); 是完全一样的意思。


在void EP1_IN_Callback(void)中
检测是不是数据都发完了,如果没有,继续
UserToPMABufferCopy(Send_Buffer+i*64, GetEPTxAddr(ENDP1), 64);
SetEPTxValid(ENDP1);  //发送数据

对了,还要设置发送长度寄存器

使用特权

评论回复
5
vigia| | 2009-6-25 18:03 | 只看该作者

晕,没看到三楼的回复

好了?

我不信^_^

看看我4楼的回复吧,你在EP1_IN_Callback()函数里反复发是没意思的,那是中断处理函数,在每个成功的IN传输之后都会调用的。在这个函数里一次只能发64个字节。

使用特权

评论回复
6
cgha|  楼主 | 2009-6-25 22:31 | 只看该作者

多谢vigia大虾指点。

那如果发送完毕之后是否需要重新将端点状态设置为SetEPTxStatus(ENDP1, EP_TX_NAK);

使用特权

评论回复
7
cgha|  楼主 | 2009-6-25 22:38 | 只看该作者

应该不会啊

那为什么我不设置tx_count,设备端不对主机的In_tokin做回应呢?

使用特权

评论回复
8
vigia| | 2009-6-26 09:38 | 只看该作者

RX

tx_count设的是发送数据长度寄存器,如果不设的话是0,发送的数据就是0字节。

发送完毕软件不用把端点设成NAK。硬件在每次成功的传输之后都会把端点的状态设为NAK。只需在下次要发送的时候设成VALID就行。

使用特权

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

本版积分规则

561

主题

719

帖子

0

粉丝