STM32 USB HID 解决USTS c0000004问题

项目场景:使用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手柄终于可以被识别到了!
成功

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值