查看: 1357|回复: 2
打印 上一主题 下一主题

如何使用STM32 USB的控制端点进行数据传输(HID)

[复制链接]
跳转到指定楼层
沙发
发表于 2015-5-27 16:16:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位好!USB在几个项目上用过,不过使用控制端点去传数据还没试过,目前有一项目由于是硬件平台升级(51升级至STM32),上位机及动态库要使用原来的。

原来的平台是做的无驱产品(HID),但不是常见的中断传输方式,而是使用的控制传输,为了加快开发速度,直接使用STM32的官方USB库里的CustomHID例子来修改。

现在的问题的,在参考网上一例子,增加了对Set Report与Get Report设备请求响应,但因为在上位机下发一条Get Report请求后,USB设备会很讯速地往PC发空数据包(因为此时下位机还没处理完数据),这样如何让PC等待一下?让下位机在接收到Get Report请求后(也就是我们自定义的协议里的数据请求),先处理完数据后,把数据填充到发送缓冲区,再允许USB向PC发送数据?

如果直接在Get Report请求响应函数里加入数据处理的部分是可以的,只是此时还在USB中断里,有时候数据处理要花一点时间,所以还是希望在此处设置一标志位,通知收到请求了,然后在主循环里根据命令去处理数据,完后填充发送缓冲区,然后允许发送。

看完上面的问题描述后,关键点就在于:怎么设置STM32的USB(以及在程序的哪个位置设置),让它在接收到来自PC的Get Report请求后,要得到允许后再往PC发送数据?

由于对官方USB库的流程还不是很熟悉,所以弄了几天还没确定插入控制的位置。

谢谢各位!转载

回复

使用道具 举报

板凳
 楼主| 发表于 2015-5-27 16:16:43 | 只看该作者

USB的协议不允许你这样做,协议要求收到Get Report请求后,设备必须马上响应这个请求,发送回数据。

你这个问题的一种正确做法是:在你向上位机发出的数据包中包含一个判断数据是否过期的域(例如,可以是数据包的序号),当下位机还没有准备好时,收到Get Report请求时发送旧的数据,上位机判断出是旧数据时丢弃它。

当然还可以使用附加的自定义协议,上位机先发送一个Get Report请求,查询下位机是否准备好发送真实数据,如果下位机没有准备好则上位机等待一会儿再查询。
转载
回复 支持 反对

使用道具 举报

地板
 楼主| 发表于 2015-5-27 16:17:12 | 只看该作者
谢谢__STM32__朋友的回复:)
但是上位机是不能修改的,因为要与原来的产品兼容,只升级硬件,软件不用作任何更改。所以你说的两种方式,都不可行。

不知道原来的产品是如何做的?(没有原始资料)

一个正常的通讯流程是这样的:
1,CTL(SET_REPORT)
2, DO(上位机发下来的命令)

3,CTL(GET_REPORT)
4,DI(回应命令)

5,CTL(SET_REPORT)
6,DO(上位机发下来的命令)

7,CTL(GET_REPORT)
8,DI(回应命令)
....
....

可以看出,1234和5678分别是一组完整的“问-答”通讯。按照你的EDN博客提到一篇文章《以HID的SET REPORT为例说明如何使用STM32的USB库支持控制端点0》提到,在Process_Status_IN()里处理或设置一个标志,现在设置标志不可行(还没到主循环处理就已经回发了),直接把处理的函数放到这里,倒是能插进这个USB响应流程里了,只是因为此时还处于中断,感觉不是很妥。或者把整个USB的中断的内容放到大循环里(因为别的动作都是根据从USB接收到的命令进行的,没有自主动作的操作),检查状态然后去执行?

另外再请教一下:它个GetReport响应稍微慢一些都不行吗?不能发一个NAK或STALL暂停一下?(试过不行,不过可能也是流程没对)。另在“DataStageIn()”这个函数里,是不是已经是启动真正的发送了?转载
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表