STM32 USB HID 解决USTS c0000004问题

文章讲述了在使用STM32模拟PS4手柄时遇到的USB-HID通信问题,包括stallpid错误和GET_REPORT请求缺失。作者通过调试代码和查阅文档找到了问题所在,并提供了添加GET_REPORT处理的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:使用STM32模拟PS4手柄

基于STM32USB-HID:

在custom-hid模式下根据下面这个Wiki进行配置
https://www.psdevwiki.com/ps4/DS4-USB#cite_ref-3
配置完成后可以作为自定义控制器使用,但是使用DS4Windows的时候有以下bug
DS4Windows界面
WARNING: Failed to read serial# from a gamepad (0x054C/0x05C4). Generating MAC address from a device path. From now on you should connect this gamepad always into the same USB port or BT pairing host to keep the same device path.


问题描述

提示:这里描述项目中遇到的问题:

首先查看DS4的日志:
DS4日志
看了挺多github上面的问题描述,不太符合我这边的问题,所以我感觉还是我这边代码没配好……
https://github.com/Ryochan7/DS4Windows/issues/2438

使用USB Hound工具抓包,于是出现了如题目所示的stall pid问题,c0000004
stall pid问题
经过各种试验调试,基本可以得出结论:上一句的输入不符合要求时,立即触发stall pid错误
因此这里是输出的字符 “Wireless Controller” 的发送出现了问题

找到哪里发送的这个字符
USBD_PRODUCT_STRING
查了以下GetString这个函数没有相关参数有问题(到这里我还是完全相信STM32给的库的)
找到哪里发送的:

/**
  * @brief  USBD_CUSTOM_HID_DataOut
  *         handle data OUT Stage
  * @param  pdev: device instance
  * @param  epnum: endpoint index
  * @retval status
  */
static uint8_t  USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev,
                                        uint8_t epnum)
{

  USBD_CUSTOM_HID_HandleTypeDef     *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;

  ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],
                                                            hhid->Report_buf[1]);

  USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
                         USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); //BUF_SIZE?

  return USBD_OK;
}

发现这个USBD_CUSTOMHID_OUTREPORT_BUF_SIZE好像是直接发送输出report的尺寸,原来是10
BUF_SIZE错误
然而我一般发送的数组尺寸是64的,直接在这里找到一个问题,修正为 64
重新发送一遍
问题1解决
问题1解决了,GET_DESCRIPTOR后面跟了正常的数据,可是还是不行,往下看:

到300多个cmd之后居然发送了一个GET REPORT
请求的数据是 a1 01 12 03 00 00 40 00
GET REPORT错误
好家伙,我在库里面根本没有发现跟这个函数,先查查资料
官方文档是这样写的:Get_Report请求
USBHID官方手册文档
自定义hid设备set_report设置和get_report获取报告描述符控制8字节数据
http://zhangzhian.blog.163.com/blog/static/23589602010426103338869/

根据手册和上面文档的一一对应,可以得到他需要的 Report ID是0x12
正好,PS4的Wiki上面有这段说明
Wiki说明

还是找了个好的PS4手柄读了一下数据
OK的GET REPORT
反馈的数据是:12 c0 45 12 f2 41 8c 08 25 00 23 64 e0 fa 43 98
得了,直接按照这个来发试试!

解决方案:

添加有关GET_REPORT的程序:

官方的库中有定义 CUSTOM_HID_REQ_GET_REPORT 这个变量,但是并没有写他应该返回什么
我们直接在 usbd_customhid.c 文件中
函数 static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,USBD_SetupReqTypedef *req)
加上

uint8_t id12[16] = {0x12,0xc0,0x45,0x12,
                      0xf2,0x41,0x8c,0x08,
                      0x25,0x00,0x23,0x64,
                      0xe0,0xfa,0x43,0x98};

case CUSTOM_HID_REQ_SET_REPORT 下面加上这段代码

        /* Get Report : a0    bmRequest Type
                        01    GET_REPORT
                        12    Report ID
                        03    Feature Report
                        0000  Interface
                        0040  Report Length(64)
        */
        // Report ID = 0x12: 12 c0 45 12 f2 41 8c 08 25 00 23 64 e0 fa 43 98
        case CUSTOM_HID_REQ_GET_REPORT:
          USBD_CtlSendData(pdev, id12, 16U);
          break;

这样就补充解决了GET_REPORT没有反馈的问题
不过这个只是一个补丁,如果他需要得到其他ID的REPORT,那也不知道给什么比较好……
修复问题后,STM32的模拟PS4手柄终于可以被识别到了!
成功

Bus Hound 6.00 capture on Windows Vista (x64). Complements of www.perisoft.net Device - Device ID (followed by the endpoint for USB devices) (38) USB Input Device (39) USB Input Device (40) HID-compliant vendor-defined device (41) HID-compliant vendor-defined device (42) HID-compliant mouse Length - Total transfer length Phase - Phase Type CTL USB control transfer IN Data in transfer OUT Data out transfer USTS USB status Data - Hex dump of the data transferred Descr - Description of the phase Cmd... - Position in the captured data Device Length Phase Data Description Cmd.Phase.Ofs(rep) ------ -------- ----- -------------------------------------------------- ---------------- ------------------ 38.1 USTS c0000011 xact error 41.1.0 39.2 USTS c0000011 xact error 42.1.0 38.0 CTL 80 06 00 01 00 00 12 00 GET DESCRIPTOR 43.1.0 38.0 18 IN 12 01 10 01 00 00 00 40 6d 20 01 09 01 00 01 02 .......@m ...... 43.2.0 03 01 .. 43.2.16 38.0 CTL 80 06 00 02 00 00 09 00 GET DESCRIPTOR 44.1.0 38.0 9 IN 09 02 29 00 01 01 00 80 32 ..).....2 44.2.0 38.0 CTL 80 06 00 02 00 00 29 00 GET DESCRIPTOR 45.1.0 38.0 41 IN 09 02 29 00 01 01 00 80 32 09 04 00 00 02 03 00 ..).....2....... 45.2.0 00 00 09 21 11 01 00 01 22 34 00 07 05 81 03 40 ...!...."4.....@ 45.2.16 38.0 CTL 00 09 01 00 00 00 00 00 SET CONFIG 46.1.0 38.0 CTL 21 0a 00 00 00 00 00 00 SET IDLE 47.1.0 38.0 USTS c0000004 stall pid 47.2.0 38.0 CTL 81 06 00 22 00 00 74 00 GET DESCRIPTOR 48.1.0 38.0 52 IN 06 aa ff 09 01 a1 01 85 1b 15 00 25 ff 75 08 95 ...........%.u.. 48.2.0 3f 09 02 81 02 09 03 91 02 c0 06 ab ff 09 01 a1 ?............... 48.2.16 39.0 CTL 80 06 00 01 00 00 12 00 GET DESCRIPTOR 49.1.0 39.0 18 IN 12 01 10 01 00 00 00 40 6d 20 01 09 01 00 01 02 .......@m ...... 49.2.0 03 01 .. 49.2.16 39.0 CTL 80 06 00 02 00 00 09 00 GET DESCRIPTOR 50.1.0 39.0 9 IN 09 02 22 00 01 01 00 80 32 ..".....2 50.2.0 39.0 CTL 80 06 00 02 00 00 22 00 GET DESCRIPTOR 51.1.0 39.0 34 IN 09 02 22 00 01 01 00 80 32 09 04 01 00 01 03 00 ..".....2....... 51.2.0 00 00 09 21 11 01 00 01 22 4a 00 07 05 82 03 40 ...!...."J.....@ 51.2.16 39.0 CTL 00 09 01 00 00 00 00 00 SET CONFIG 52.1.0 39.0 CTL 21 0a 00 00 01 00 00 00 SET IDLE 53.1.0 39.0 USTS c0000004 stall pid 53.2.0 39.0 CTL 81 06 00 22 01 00 8a 00 GET DESCRIPTOR 54.1.0 39.0 74 IN 05 01 09 02 a1 01 85 55 09 01 a1 00 05 09 19 01 .......U........ 54.2.0 29 03 15 00 25 01 95 03 75 01 81 02 95 01 75 05 )...%...u.....u. 54.2.16 这是设备掉线时抓取的报告,
最新发布
07-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值