CH552 USB HID官方例子CompatibilityHID修改为gamepad后无法发送数据
/*设备描述符*/
UINT8C DevDesc[18] = {0x12,0x01,0x10,0x01,0x00,0x00,0x00,THIS_ENDP0_SIZE,
                      0x31,0x51,0x07,0x20,0x00,0x00,0x00,0x00,
                      0x00,0x01
                     };
UINT8C CfgDesc[41] =
{
    0x09,0x02,0x29,0x00,0x01,0x01,0x04,0xA0,0x23,               //配置描述符
    0x09,0x04,0x00,0x00,0x02,0x03,0x00,0x00,0x05,               //接口描述符
    0x09,0x21,0x00,0x01,0x00,0x01,0x22,0x22,0x00,               //HID类描述符
    0x07,0x05,0x82,0x03,ENDP2_IN_SIZE,0x00,0x01,              //端点描述符
    0x07,0x05,0x02,0x03,ENDP2_OUT_SIZE,0x00,0x01,              //端点描述符  
};
/*字符串描述符 略*/ 

/*HID类报表描述符*/
UINT8C HIDRepDesc[ ] =
{
    0x06, 0x00,0xff,
    0x09, 0x01,
    0xa1, 0x01,                                                   //集合开始
    0x09, 0x02,                                                   //Usage Page  用法
    0x15, 0x00,                                                   //Logical  Minimun
    0x26, 0x00,0xff,                                              //Logical  Maximun
    0x75, 0x08,                                                   //Report Size
    0x95, THIS_ENDP0_SIZE,                                        //Report Counet
    0x81, 0x06,                                                   //Input
    0x09, 0x02,                                                   //Usage Page  用法
    0x15, 0x00,                                                   //Logical  Minimun
    0x26, 0x00,0xff,                                              //Logical  Maximun
    0x75, 0x08,                                                   //Report Size
    0x95, THIS_ENDP0_SIZE,                                        //Report Counet
    0x91, 0x06,                                                   //Output
    0xC0
};

// 建议gamepad
UINT8C HIDRepDesc2[] = {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    // ReportID - 8 bits
    0x85, 0x01,                    //     REPORT_ID (1)
    // X & Y - 2x8 = 16 bits
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
    0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    // Buttons - 8 bits
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x08,                    //     USAGE_MAXIMUM (Button 8)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x01,                    //     REPORT_COUNT (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //     END_COLLECTION
    0xc0                           // END_COLLECTION
};

void Enp2BlukIn( )
{
    memcpy( Ep2Buffer+MAX_PACKET_SIZE_2, UserEp2Buf, USE_EP2_BUF_LEN);        //加载上传数据
    if( Ready )
    {

        UEP2_T_LEN = THIS_ENDP0_SIZE;                                              //上传最大包长度
        UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK;                  //有数据时上传数据并应答ACK
        Endp2Busy = 1;                                                          
    }
}

main()
{
    UINT8 i, ch;
    CfgFsys(); // CH559时钟选择配置
    mDelaymS(5); // 修改主频等待内部晶振稳定,必加
    mInitSTDIO(); // 串口0初始化
    Port1Cfg(1, 6);

    for (i = 0; i < ENDP2_IN_SIZE; i++) // 准备演示数据
    {
        UserEp2Buf[i] = i;
    }

    USBDeviceInit(); // USB设备模式初始化
    EA = 1; // 允许单片机中断
    UEP1_T_LEN = 0; // 预使用发送长度一定要清空
    UEP2_T_LEN = 0; // 预使用发送长度一定要清空
    Ready = 0;
    ch = 0;
    LED_PIN = 0;

    while (1) {
        if (Ready && (Ep2InKey == 0)) {
            while (Endp2Busy) { }

            UserEp2Buf[0] = 1;
            ++ch;

            UserEp2Buf[1] = ch;
            UserEp2Buf[2] = ch;
            UserEp2Buf[3] = ch;
            UserEp2Buf[4] = ch;

            Enp2IntIn();
        }

        LED_PIN = !Ep2InKey;

        mDelaymS(100); // 模拟单片机做其它事
    }
}

请教各位大佬,上面代码中HIDRepDesc是官网默认带的,可以发送数据,并通过HidRawDataWatcher看到发送了什么数据;

改为HIDRepDesc2,这个我自定义的gamepad后,Enp2BlukIn发送的数据HidRawDataWatcher就看不到了。


好像只要指定了report id就无法发送数据了,我在main中已经指定了UserEp2Buf的第一个字节是1了。


您好,

先大致看上去,配置描述符下的HID描述符中,wDescriptorLength段用于描述HID报告长度,这两个字节没有修改成修改后的描述符长度。

改HID报告,应当修改上述位置的报告长度,还应该修改中断服务函数处理中获取报告描述符请求的返回数组,有时还要注意端点包长是否也要对应修改,端点包长还可能和缓冲区定义有关。

与其相关的几个点都可以全局搜索下看看。


@TECH29

多谢回复。描述符长度已经修改了,我贴的代码没改。

经过调查发现是HIDRepDesc中的所有的report的数据大小未和端点buffer的尺寸一致所致。


只有登录才能回复,可以选择微信账号登录