本帖最后由 yang_alex 于 2018-5-19 00:44 编辑
沁恒针对USB HOST应用提供的代码文件如下两个:
1、USBHOST.C: CH554 USB主机控制传输函数定义,主要是设备枚举部分,控制传输部分
2、USBHostHUB_KM.C: USB主机应用例子,初始化和枚举USB端口连接的设备,支持一级外部HUB,可以操作USB键鼠和HUB,打印机,包含HID类命令处理
首先自己建立工程项目文件(过程参考我前面的评测帖子),编译烧录。嗯,一切正常。
先用一个无线鼠标的接收器测试,结果发现,评估板先上电后,结果如下图。
再把无线鼠标的接收器接入CH554评估板的USB母座,一切都正常,结果如下图。
在评估板上电状态下,把无线鼠标的接收器拔出来,会在调试串口输出“USB dev out”
但如果先把无线鼠标的接收器接入CH554评估板的USB母座。结果发现,评估板还没有上电时,D1电源指示灯就亮了。再评估板上电,结果串口没有任何输出。即使复位或重新上电串口都没有任何输出。
把无线鼠标的接收器拔出后,串口没有任何输出。但评估板复位或重新上电后,串口输出如下(与评估板不插无线鼠标的接收器上电一样)。
试着插入一个小容量USB盘测试,评估板上电后,把小容量USB盘接入CH554评估板的USB母座,识别正常。结果如下图。
换个USB键盘测试,评估板上电后,把USB键盘接入CH554评估板的USB母座,结果如下图。
换个USB游戏遥控器测试,评估板上电后,把USB游戏遥控器接入CH554评估板的USB母座,结果如下图。
分析串口打印出来的信息,最后在USBHOST.H中发现返回错误状态码:
- // 各子程序返回状态码
- #define ERR_SUCCESS 0x00 // 操作成功
- #define ERR_USB_CONNECT 0x15 /* 检测到USB设备连接事件,已经连接 */
- #define ERR_USB_DISCON 0x16 /* 检测到USB设备断开事件,已经断开 */
- #define ERR_USB_BUF_OVER 0x17 /* USB传输的数据有误或者数据太多缓冲区溢出 */
- #define ERR_USB_DISK_ERR 0x1F /* USB存储器操作失败,在初始化时可能是USB存储器不支持,在读写操作中可能是磁盘损坏或者已经断开 */
- #define ERR_USB_TRANSFER 0x20 /* NAK/STALL等更多错误码在0x20~0x2F */
- #define ERR_USB_UNSUPPORT 0xFB /*不支持的USB设备*/
- #define ERR_USB_UNKNOWN 0xFE /*设备操作出错*/
复制代码
其中
#define ERR_USB_BUF_OVER 0x17 /* USB传输的数据有误或者数据太多缓冲区溢出 */
#define ERR_USB_TRANSFER 0x20 /* NAK/STALL等更多错误码在0x20~0x2F */
可以得知评估板在获得设备描述,初始化设备的过程中出现了问题,调试串口输出信息给出错误标号17。通过跟踪调试串口输出信息(多次放置打印信息,确定错误位置),问题定位到CtrlGetDeviceDescr()函数,中下面这一句:
UsbDevEndp0Size = ( (PXUSB_DEV_DESCR)TxBuffer ) -> bMaxPacketSize0; // 端点0最大包长度,这是简化处理,正常应该先获取前8字节后立即更新UsbDevEndp0Size再继续
- /*******************************************************************************
- * Function Name : CtrlGetDeviceDescr
- * Description : 获取设备描述符,返回在TxBuffer中
- * Input : None
- * Output : None
- * Return : ERR_USB_BUF_OVER 描述符长度错误
- ERR_SUCCESS 成功
- 其他
- *******************************************************************************/
- UINT8 CtrlGetDeviceDescr( void )
- {
- UINT8 s;
- UINT8 len;
- UsbDevEndp0Size = DEFAULT_ENDP0_SIZE;
- CopySetupReqPkg( SetupGetDevDescr );
- s = HostCtrlTransfer( TxBuffer, (PUINT8)&len ); // 执行控制传输
- if ( s != ERR_SUCCESS )
- {
- return( s );
- }
-
- #if DE_PRINTF
- printf( "CtrlGetConfigDescr3\n" );
- #endif
-
-
- UsbDevEndp0Size = ( (PXUSB_DEV_DESCR)TxBuffer ) -> bMaxPacketSize0; // 端点0最大包长度,这是简化处理,正常应该先获取前8字节后立即更新UsbDevEndp0Size再继续
- if ( len < ( (PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL )
- {
- return( ERR_USB_BUF_OVER ); // 描述符长度错误
- }
- #if DE_PRINTF
- printf( "CtrlGetConfigDescr4\n" );
- #endif
-
-
- return( ERR_SUCCESS );
- }
复制代码
可以看出,沁恒的代码做了简化,不是按USB规范处理。所以有些没想到的情况下就出错了。
正确的应该是像上篇帖子提到的:注意(6)(7)(8)步骤,主机先通过地址0获取部分从设备的设备描述符,获取最大数据包长度 ,然后复位总线,通知从设备切换通讯地址,接下来使用新地址获取从设备的完整的设备描述符。
具体的代码请沁恒的技术支持帮忙改改吧。
此内容由EEWORLD论坛网友yang_alex原创,如需转载或用于商业用途需征得作者同意并注明出处
分析串口打印出来的信息,最后在USBHOST.H中发现返回错误状态码: