打印

USB一样的报告描述符怎么就不一样的结果呢?

[复制链接]
4084|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
a_bb|  楼主 | 2009-9-24 19:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
整整2天了,问题依旧没解决,大侠、高手帮忙!
要使用自定义HID进行数据传输,从ST网站下载了最新的USB开发例程um0424(吃一堑长一智)。里面
有Custom_HID,拿来就用。我是在embest的开发板上进行的,使用RVMDK里的工程,用STM3210B-EVAL
选项编译下载运行正常。可是此例子每个报告符后面只带1个数据,必须扩展。
先将configdescriptor中的MaxPacketSize改为适当大小,比如0x40.然后将Reportdescriptor中4个LED
的配置都改为 0x95,0x02 ,再运行PC机的USB HID demonstrator,Input/Output report byte length都
自动改为3了,但再点击控制LED, bus hound却捕捉不到数据了! 数据无**常输出了。修改了ARM的
VID,PID等参数以匹配computer00的程序,以及computer00的Myusbhidtestapp程序中相应的ReportID和数据长度,点击以后,虽然显示有数据输出,但bus bound无捕获,2次点击后就显示
"数据正在发送中,暂时不能发送"了。显然数据没有真正发出。
上网找到computer00 "万利的STM32板实现的自定义USB HID设备",使用其中的Reportdescriptor(ReportID缺省为0),修改了
上位机的参数,发现仍旧没有输出。将长度改为1字节,即 0x95,0x01 OK,正常;改为0x95,0x02,也正常。
但...改为3以上就没有输出了。将完全相同的长字节的Reportdescriptor写到computer00的那个51板的程序中去,下载,同样的PC程序,正常。
看来Reportdescriptor和PC程序都没有问题,问题还是在ARM程序本身。可反复查看ARM程序,除了Reportdescriptor中修改长度,MaxPacketSize放到足够大,也看不到
其它的限制了,可程序怎么就能够限制上位机发长些的数据呢? 找到4月bmwlover02发的帖子“HID通讯字节限制问题",也没有解决问题。
通过ARM和51的对比试验,我认为问题还是在ARM程序本身。烦请香主也拿那个程序试试,将报告字节加长,试验是否能正常通讯?
还有就是此例程是新改版的,会不会里面新出了什么bug!我是不是又事最先吃螃蟹的人? 我是一朝被蛇咬,十年怕井绳了,可不愿意再当小白鼠。
烦请香主给我个老的例程,我用它再试试。当然,可能是我使用不当,也请香主指出,让我尽快解决问题。
在此谢谢 香主和computer00先
email: guangjingyang@yahoo.com.cn
沙发
香水城| | 2009-9-24 21:27 | 只看该作者
MaxPacketSize不能改,如果要改这个参数,需要改变所有固件程序中发送接收部分的长度。

使用特权

评论回复
板凳
香水城| | 2009-9-24 21:33 | 只看该作者
还是把你改过的Reportdescriptor贴出来看看吧,也说说你想得到什么效果。

还有另外一个疑问,你不是在做STM8S的项目吗?怎么又来这个STM32的USB?

使用特权

评论回复
地板
a_bb|  楼主 | 2009-9-25 08:36 | 只看该作者
还是把你改过的Reportdescriptor贴出来看看吧,也说说你想得到什么效果。

还有另外一个疑问,你不是在做STM8S的项目吗?怎么又来这个STM32的USB?
香水城 发表于 2009-9-24 21:33


项目的主机使用的是STM32,另外做了个辅助设备用STM8, NXP的代理希望我用他们的芯片,回了
const u8 ReportDescriptor[SIZ_REPORT_DESC] =
  {
    0x05, 0xFF,                    // USAGE_PAGE(User define)
    0x09, 0xFF,                    // USAGE(User define)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x05, 0x01,                    // USAGE_PAGE(1)
    0x19, 0x00,                    //   USAGE_MINIMUM(0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM(255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x40,                    //   REPORT_COUNT (64)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x02,                    // USAGE_PAGE(2)
    0x19, 0x00,                    //   USAGE_MINIMUM (0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM (255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x75, 0x40,                    //   REPORT_SIZE (64)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
  }; /* ReportDescriptor */

使用了computer00的ReportDescriptor ,最多带2字节数据
我要的效果就是 让每次报告能够带较多的数据字节,比如32字节

BTW, computer00是不是有处笔误 0x95,0x08, 0x75,0x40是不是应该为 0x95,0x40,0x75,0x08?

使用特权

评论回复
5
a_bb|  楼主 | 2009-9-25 08:48 | 只看该作者
MaxPacketSize不能改,如果要改这个参数,需要改变所有固件程序中发送接收部分的长度。
香水城 发表于 2009-9-24 21:27


不能修改,此程序还有什么用!
原程序如下
  /******************** Descriptor of Custom HID endpoints ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
    0x81,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x02,          /* wMaxPacketSize: 2 Bytes max */
    0x00,
    0x20,          /* bInterval: Polling Interval (32 ms) */
    /* 34 */
     
    0x07, /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
   /* Endpoint descriptor type */
    0x01, /* bEndpointAddress: */
   /* Endpoint Address (OUT) */
    0x03, /* bmAttributes: Interrupt endpoint */
    0x02, /* wMaxPacketSize: 2 Bytes max  */
    0x00,
    0x20, /* bInterval: Polling Interval (20 ms) */
    /* 41 */

对应 1字节reportID和1字节数据 此处 wMaxPacketSize: 2 Bytes max  没有
问题,但不可能每个程序都只有2字节长度,所以wMaxPacketSize 需要更改。其实在
computer00修改的万利程序里,就设为 0x40
从目前的实验现象上看,我也怀疑修改此值以后,下位机没有起到作用。
但我不知道,香主所说“需要改变所有固件程序中发送接收部分的长度。”具体指哪里?
告诉我,我来修改,实验!

使用特权

评论回复
6
icecut| | 2009-9-25 09:48 | 只看该作者
每个端口都有最大包长度.你看看别超了....

还有一个就是多字节可以重复接收但是1个字节悬

使用特权

评论回复
7
a_bb|  楼主 | 2009-9-25 09:58 | 只看该作者
最大长度包是 0x40。 32字节的书发32次,理论可行,但方法太笨了,应该可以一次发送

使用特权

评论回复
8
lxyppc| | 2009-9-25 10:36 | 只看该作者
/*-------------------------------------------------------------*/
/* --------------   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)
#define ENDP0_TXADDR        (0x58)

/* EP1  */
/* tx buffer base address */
#define ENDP1_TXADDR        (0x100)
#define ENDP1_RXADDR        (0x104)

官方的例子中ENDP1_TXADDR 在0x100,ENDP1_RXADDR在0x104,就这四个Byte你想怎么发?
P.S. 如果你想用ST库提供的例子来做项目,那我只能说“Good Luck”

使用特权

评论回复
9
lxyppc| | 2009-9-25 10:45 | 只看该作者
/*0001*/  /*******************************************************************************
|*0002*|  * Function Name  : CustomHID_Reset.
|*0003*|  * Description    : Custom HID reset routine.
|*0004*|  * Input          : None.
|*0005*|  * Output         : None.
|*0006*|  * Return         : None.
|*0007*|  *******************************************************************************/

/*0008*/  void CustomHID_Reset(void)
/*0009*/  {
/*0010*/    /* Set Joystick_DEVICE as not configured */
/*0011*/    pInformation->Current_Configuration = 0;
/*0012*/    pInformation->Current_Interface = 0;/*the default Interface*/
/*0013*/    
/*0014*/    /* Current Feature initialization */
/*0015*/    pInformation->Current_Feature = CustomHID_ConfigDescriptor[7];
/*0016*/    
/*0017*/    SetBTABLE(BTABLE_ADDRESS);
/*0018*/  
/*0019*/    /* Initialize Endpoint 0 */
/*0020*/    SetEPType(ENDP0, EP_CONTROL);
/*0021*/    SetEPTxStatus(ENDP0, EP_TX_STALL);
/*0022*/    SetEPRxAddr(ENDP0, ENDP0_RXADDR);
/*0023*/    SetEPTxAddr(ENDP0, ENDP0_TXADDR);
/*0024*/    Clear_Status_Out(ENDP0);
/*0025*/    SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
/*0026*/    SetEPRxValid(ENDP0);
/*0027*/  
/*0028*/    /* Initialize Endpoint 1 */
/*0029*/    SetEPType(ENDP1, EP_INTERRUPT);
/*0030*/    SetEPTxAddr(ENDP1, ENDP1_TXADDR);
/*0031*/    SetEPRxAddr(ENDP1, ENDP1_RXADDR);
/*0032*/    SetEPTxCount(ENDP1, 2);
/*0033*/    SetEPRxCount(ENDP1, 2);
/*0034*/    SetEPRxStatus(ENDP1, EP_RX_VALID);
/*0035*/    SetEPTxStatus(ENDP1, EP_TX_NAK);
/*0036*/  
/*0037*/    bDeviceState = ATTACHED;
/*0038*/    
/*0039*/    /* Set this device to response on default address */
/*0040*/    SetDeviceAddress(0);
/*0041*/  }

在CustomHID_Reset的第32、33行, 这里设置了发送缓冲的大小,USB Core是从这里读取实际发送或接收的数据长度的
别的地方的长度信息都是给Driver或Firmware看的,这里是芯片的USB Core要用的

使用特权

评论回复
10
a_bb|  楼主 | 2009-9-25 11:13 | 只看该作者
多谢 lxyppc, 修正了上面所说的参数后,通讯开始正常了。
下午,再仔细测试下,应该可以设置成可变的参数好些,这样只修改usb_desc办法就可以了
谢谢了

使用特权

评论回复
11
香水城| | 2009-9-25 11:16 | 只看该作者
回5楼:ConfigDescriptor中的MaxPacketSize,实际上是EndpointDescriptor的MaxPacketSize,它表示每个数据包的长度,也就是说你的数据缓冲区也要有相应的长度。

如果要修改ConfigDescriptor这个参数,就必须修改所有与其相关的数据缓冲区长度和处理函数的内容;如果只修改这个参数,而不改其它相关部分,程序当然不能正常工作,所以我在2楼说:MaxPacketSize不能改,如果要改这个参数,需要改变所有固件程序中发送接收部分的长度。

目前你修改了这个参数,如果没有修改下位机数据缓冲区长度,上位机发下来的数据将造成下位机数据缓冲区溢出,程序肯定要乱了。

你还是找我们在北京的FAE帮你解决一下吧。

使用特权

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

本版积分规则

35

主题

98

帖子

0

粉丝