使用CH374模拟一个鼠标/键盘 EP2收不到数据

这是可以用的配置描述符及报告描述符 这个是鼠标键盘 复合的设备:

//配置描述符    如果有配置描述符长度改变,记得修改第2,3字节!!!!                                          

const   uint8_t MyCfgDescr[9 + 9 + 9 + 7 + 7] = { 0x09, 0x02, 0x29, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32,  /* 配置描述符 */

                                             0x09, 0x04, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x00,  /* 接口描述符 */

                                             0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, 0x75, 0x00,  /* HID描述符  */

                                             0x07, 0x05, 0x82, 0x03, 0x10, 0x00, 0x04,              /* 输入端点描述符 使用ep2的in端点,因为ep1的in端点大小只有8字节 */

                                             0x07, 0x05, 0x01, 0x03, 0x10, 0x00, 0x04};             /* 输出端点描述符 使用ep1的out端点*/

//键盘报告描述符    如果报告描述符长度改变,记得修改HID描述符里的下级描述符长度字段!!!!

uint8_t ReportDescr[] =    {

    0x05, 0x01,

    0x09, 0x06,

    0xa1, 0x01,

    0x85, 0x01,

    0x05, 0x07,

    0x19, 0xe0,

    0x29, 0xe7,

    0x15, 0x00,

    0x25, 0x01,

    0x95, 0x08,

    0x75, 0x01,

    0x81, 0x02,

    0x95, 0x01,

    0x75, 0x08,

    0x81, 0x03,

    0x95, 0x06,

    0x75, 0x08,

    0x15, 0x00,

    0x25, 0xff,

    0x05, 0x07,

    0x19, 0x00,

    0x29, 0x65,

    0x81, 0x00,


    0x25, 0x01, //定义一个5位的数组,用于存储5个LED的状态。

    0x95, 0x05,

    0x75, 0x01,


    0x05, 0x08,//使用LED页面。


    0x19, 0x01,//LED的代码范围是0x01到0x05。

    0x29, 0x05,


    0x91, 0x02,//这个数组是输出报告的一部分


    0x95, 0x01,//定义一个3位的常量,用于填充输出报告的剩余部分。

    0x75, 0x03,


    0x91, 0x03,

   

    0xc0,


    0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)

    0x09, 0x02,        // Usage (Mouse)

    0xA1, 0x01,        // Collection (Application)

    0x85, 0x02,        //   Report ID (66)

    0x09, 0x01,        //   Usage (Pointer)

    0xA1, 0x00,        //   Collection (Physical)


    0x05, 0x09,        //     Usage Page (Button)

    0x19, 0x01,        //     Usage Minimum (0x01)

    0x29, 0x08,        //     Usage Maximum (0x08)

    0x15, 0x00,        //     Logical Minimum (0)

    0x25, 0x01,        //     Logical Maximum (1)

    0x95, 0x08,        //     Report Count (8)

    0x75, 0x01,        //     Report Size (1)

    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)


    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)

    0x16, 0x01, 0x80,  //     Logical Minimum (-32767)

    0x26, 0xFF, 0x7F,  //     Logical Maximum (32767)

    0x09, 0x30,        //     Usage (X)

    0x09, 0x31,        //     Usage (Y)

    0x09, 0x38,        //     Usage (Wheel)

    0x75, 0x10,        //     Report Size (16)

    0x95, 0x03,        //     Report Count (3)

    0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)

    0xC0,              //   End Collection

    0xC0,              // End Collection

};


然后这个是自己改的 只用端点二的单个鼠标设备的描述符 然后问题就是改成这个之后 端点二就收不到数据了

// 鼠标配置描述符        如果有配置描述符长度改变,记得修改第2,3字节!!!!  

const   uint8_t MyCfgDescr[9 + 9 + 9 + 7] = { 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32,  /* 配置描述符 */

                                             0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x02, 0x00,  /* 接口描述符 */

                                             0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, 0x32, 0x00,  /* HID描述符  */

                                             0x07, 0x05, 0x82, 0x03, 0x10, 0x00, 0x04};             /* 输入端点描述符 */

//鼠标报告描述符    如果报告描述符长度改变,记得修改HID描述符里的下级描述符长度字段!!!!

uint8_t ReportDescr[] =    {                

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)

0x09, 0x02,        // Usage (Mouse)

0xA1, 0x01,        // Collection (Application)

#if 1

0x85, 0x02,        //   Report ID (66)

#endif

0x09, 0x01,        //   Usage (Pointer)

0xA1, 0x00,        //   Collection (Physical)

0x05, 0x09,        //     Usage Page (Button)

0x19, 0x01,        //     Usage Minimum (0x01)

0x29, 0x08,        //     Usage Maximum (0x08)

0x15, 0x00,        //     Logical Minimum (0)

0x25, 0x01,        //     Logical Maximum (1)

0x95, 0x08,        //     Report Count (8)

0x75, 0x01,        //     Report Size (1)

0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)

0x16, 0x01, 0x80,  //     Logical Minimum (-32767)

0x26, 0xFF, 0x7F,  //     Logical Maximum (32767)

0x09, 0x30,        //     Usage (X)

0x09, 0x31,        //     Usage (Y)

0x09, 0x38,        //     Usage (Wheel)

0x75, 0x10,        //     Report Size (16)

0x95, 0x03,        //     Report Count (3)

0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)

0xC0,              //   End Collection

0xC0,              // End Collection

};


然后这个是处理函数

void usb_device_task(void*parm)

{

    uint8_t i;

    uint8_t int_status, usb_status, usb_len;

    static  uint8_t SetupReq, SetupLen, device_addr;

    static  uint8_t*    pDescr;

    bool ep2_in_intr_flag = false;


    while(1)

    {

        if(ch374_query_interrupt()){


            int_status = ch374_read_byte(REG_INTER_FLAG); // 获取中断状态

            usb_status = ch374_read_byte( REG_USB_STATUS );

            usb_len = ch374_read_byte( REG_USB_LENGTH );


            // printf("\n");


            if ( int_status & BIT_IF_BUS_RESET ) {  // USB总线复位

                printf("usb bus reset\n");

                ch374_write_byte( REG_USB_ADDR, 0x00 );  // 清USB设备地址

                ch374_write_byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );

                ch374_write_byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );

                ch374_write_byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );

                ch374_write_byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_BUS_RESET );  // 清中断标志

            }else if ( int_status & BIT_IF_TRANSFER ) {  // USB传输完成

                printf("usb translate complete\n");

                usb_status = ch374_read_byte( REG_USB_STATUS );

                switch( usb_status & BIT_STAT_PID_ENDP ) {  // USB设备中断状态

                    case USB_INT_EP2_OUT: {  // 批量端点下传成功

                        // printf("bulk ep download ok \n");

                        uint8_t buf[64];

                        if ( usb_status & BIT_STAT_TOG_MATCH ) {  // 仅同步包

                            usb_len = ch374_read_byte( REG_USB_LENGTH );

                            ch374_read_bytes( RAM_ENDP2_RECV, buf, usb_len);

                            for ( i = 0; i < usb_len; i ++ ){

                                buf[i] ^= 0xFF;  // 数据取反由计算机验证

                            }

                            ch374_write_bytes( RAM_ENDP2_TRAN, buf, usb_len);  // 演示回传

                            ch374_write_byte( REG_USB_LENGTH, usb_len );

                            ch374_write_byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( ch374_read_byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );

                        }

                        break;

                    }


                    case USB_INT_EP2_IN: {  // 批量端点上传成功,未处理

                        ch374_write_byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( ch374_read_byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG );

                        printf("interrupt ep up ok\n");

                        ep2_in_intr_flag = true;

                        break;

                    }

                    case USB_INT_EP1_IN: {  // 中断端点上传成功,未处理

                        // printf("interrupt ep up ok\n");

                        ch374_write_byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( ch374_read_byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG );

                        break;

                    }

                    case USB_INT_EP0_SETUP: {  // 控制传输

                        USB_SETUP_REQ   SetupReqBuf;

                        usb_len = ch374_read_byte( REG_USB_LENGTH );

                        // printf("control translate usb_len = %d\n", usb_len);

                        int i;

                       

                        if ( usb_len == sizeof( USB_SETUP_REQ ) ) {

                            ch374_read_bytes( RAM_ENDP0_RECV, (uint8_t *)&SetupReqBuf, usb_len);

                            for(i = 0;i < usb_len;i++){

                                printf("0x%02x ", *((uint8_t *)&SetupReqBuf + i));

                            }

                            printf("\n");


                            SetupLen = SetupReqBuf.wLengthL;

                            if ( SetupReqBuf.wLengthH || SetupLen > 0x7F ) {

                                SetupLen = 0x7F;  // 限制总长度

                            }

                            usb_len = 0; // 默认为成功并且上传0长度

                            if ( ( SetupReqBuf.bType & DEF_USB_REQ_TYPE ) != DEF_USB_REQ_STAND ) {  /* 只支持标准请求 */

                                usb_len = 0xFF;  // 操作失败

                            }

                            else {  // 标准请求

                                printf("standard request:");

                                SetupReq = SetupReqBuf.bReq;  // 请求码

                                switch( SetupReq ) {

                                    case DEF_USB_GET_DESCR:

                                        switch( SetupReqBuf.wValueH ) {

                                            case 1:

                                                printf("get device desc\n");

                                                pDescr = (uint8_t *)( &MyDevDescr[0] );

                                                usb_len = sizeof( MyDevDescr );

                                                break;

                                            case 2:

                                                printf("get config desc\n");

                                                pDescr = (uint8_t *)( &MyCfgDescr[0] );

                                                usb_len = sizeof( MyCfgDescr );

                                                break;

                                            case 3:

                                                switch( SetupReqBuf.wValueL ) {

                                                    printf("get string desc, value = %d\n",SetupReqBuf.wValueL);

                                                    case 1:

                                                        pDescr = (uint8_t *)( &MyManuInfo[0] );

                                                        usb_len = sizeof( MyManuInfo );

                                                        break;

                                                    case 2:

                                                        pDescr = (uint8_t *)( &MyProdInfo[0] );

                                                        usb_len = sizeof( MyProdInfo );

                                                        break;

                                                    case 0:

                                                        pDescr = (uint8_t *)( &MyLangDescr[0] );

                                                        usb_len = sizeof( MyLangDescr );

                                                        break;

                                                    default:

                                                        usb_len = 0xFF;  // 操作失败

                                                        break;

                                                }

                                                break;

                                            case USB_REPORT_DESCR_TYPE:

                                                printf("get report desc\n");

                                                pDescr = (uint8_t *)( &ReportDescr[0] );

                                                usb_len = sizeof( ReportDescr );

                                                is_fake_km_ready = true;

                                                xTaskCreate(mouse_task,"test_task",4096,NULL,12,NULL);

                                                break;

                                            default:

                                                printf("get desc: defautl\n");

                                                usb_len = 0xFF;  // 操作失败

                                                break;

                                        }

                                        if ( SetupLen > usb_len ) SetupLen = usb_len;  // 限制总长度

                                        usb_len = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen;  // 本次传输长度

                                        ch374_write_bytes(RAM_ENDP0_TRAN,pDescr,usb_len);  /* 加载上传数据 */

                                        SetupLen -= usb_len;

                                        pDescr += usb_len;

                                        break;

                                    case DEF_USB_SET_ADDRESS:

                                        printf("set addr\n");

                                        device_addr = SetupReqBuf.wValueL;  // 暂存USB设备地址

                                        break;

                                    case DEF_USB_GET_CONFIG:

                                        printf("get config\n");

                                        ch374_write_byte(RAM_ENDP0_TRAN,UsbConfig);

                                        if ( SetupLen >= 1 ) usb_len = 1;

                                        break;

                                    case DEF_USB_SET_CONFIG:

                                        printf("set config\n");

                                        UsbConfig = SetupReqBuf.wValueL;

                                        break;

                                    case DEF_USB_CLR_FEATURE:

                                        printf("clear feature\n");

                                        if ( ( SetupReqBuf.bType & 0x1F ) == 0x02 ) {  // 不是端点不支持

                                            switch( SetupReqBuf.wIndexL ) {

                                                case 0x82:

                                                    ch374_write_byte(REG_USB_ENDP2,M_SET_EP2_TRAN_NAK(ch374_read_byte(REG_USB_ENDP2)));

                                                    break;

                                                case 0x02:

                                                    ch374_write_byte(REG_USB_ENDP2,M_SET_EP2_RECV_ACK(ch374_read_byte(REG_USB_ENDP2)));

                                                    break;

                                                case 0x81:

                                                    ch374_write_byte(REG_USB_ENDP1,M_SET_EP1_TRAN_NAK(ch374_read_byte(REG_USB_ENDP1)));

                                                    break;

                                                case 0x01:

                                                    ch374_write_byte(REG_USB_ENDP1,M_SET_EP1_RECV_ACK(ch374_read_byte(REG_USB_ENDP1)));

                                                    break;

                                                default:

                                                    usb_len = 0xFF;  // 操作失败

                                                    break;

                                            }

                                        }

                                        else usb_len = 0xFF;  // 操作失败

                                        break;

                                    case DEF_USB_GET_INTERF:

                                        printf("get interf\n");

                                        ch374_write_byte(RAM_ENDP0_TRAN,0);

                                        if ( SetupLen >= 1 ) usb_len = 1;

                                        break;

                                    case DEF_USB_GET_STATUS:

                                        printf("get status\n");

                                        ch374_write_byte(RAM_ENDP0_TRAN,0);

                                        ch374_write_byte(RAM_ENDP0_TRAN+1,0);

                                        if ( SetupLen >= 2 ) usb_len = 2;

                                        else usb_len = SetupLen;

                                        break;

                                    default:

                                        printf("default!!!\n");

                                        usb_len = 0xFF;  // 操作失败

                                        break;

                                }

                            }

                        }

                        else {

                            usb_len = 0xFF;  // 操作失败

                        }

                        if ( usb_len == 0xFF ) {  // 操作失败

                            ch374_write_byte( REG_USB_ENDP0, M_SET_EP0_RECV_STA( M_SET_EP0_TRAN_STA( 0 ) ) );  // STALL

                        }

                        else if ( usb_len <= RAM_ENDP0_SIZE ) {  // 上传数据

                            ch374_write_byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( ch374_read_byte( REG_USB_ENDP0 ) ), usb_len ) | BIT_EP0_TRAN_TOG );  // DATA1

                        }

                        else {  // 下传数据或其它

                            ch374_write_byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( M_SET_EP0_RECV_ACK( ch374_read_byte( REG_USB_ENDP0 ) ) ) | BIT_EP0_RECV_TOG );  // DATA1

                        }

                        break;

                    }


                    case USB_INT_EP0_IN: {

                        printf("USB_INT_EP0_IN\n");

                        //uint8_t len;

                        switch( SetupReq ) {

                            case DEF_USB_GET_DESCR:

                                usb_len = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen;  // 本次传输长度

                                ch374_write_bytes(RAM_ENDP0_TRAN,pDescr,usb_len);  /* 加载上传数据 */

                                SetupLen -= usb_len;

                                pDescr += usb_len;

                                ch374_write_byte(REG_USB_ENDP0,M_SET_EP0_TRAN_ACK(ch374_read_byte(REG_USB_ENDP0),usb_len)^BIT_EP0_TRAN_TOG);

                                break;

                            case DEF_USB_SET_ADDRESS:

                                ch374_write_byte(REG_USB_ADDR,device_addr);

                            default:

                                ch374_write_byte(REG_USB_ENDP0,M_SET_EP0_TRAN_NAK(0));  // 结束

                                break;

                        }

                        break;

                    }


                    case USB_INT_EP0_OUT: {

                        printf("USB_INT_EP0_OUT\n");

                        switch( SetupReq ) {

        //                  case download:

        //                      get_data;

        //                      break;

                            case DEF_USB_GET_DESCR:

                            default:

                                ch374_write_byte(REG_USB_ENDP0,M_SET_EP0_TRAN_NAK(0));  // 结束

                                break;

                        }

                        break;

                    }


                    // case


                    default:

                        printf("CAPS  default\n");

                    break;

                }


                ch374_write_byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER );  // 清中断标志

                if(ep2_in_intr_flag == true) {

                    ep2_in_intr_flag = false;

                    xEventGroupSetBits(Event_Handle, EP2_IN_EVENT);

                }

            }else if ( int_status & BIT_IF_USB_SUSPEND ) {  // USB总线挂起

                printf("usb bus suspend\n");

                ch374_write_byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_USB_SUSPEND );  // 清中断标志

                ch374_write_byte( REG_SYS_CTRL, ch374_read_byte( REG_SYS_CTRL ) | BIT_CTRL_OSCIL_OFF );  // 时钟振荡器停止振荡,进入睡眠状态

            }else if ( int_status & BIT_IF_WAKE_UP ) {  // 芯片唤醒完成

                printf("wake up\n");

                ch374_write_byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_WAKE_UP );  // 清中断标志

            }else {  // 意外的中断,不可能发生的情况,除了硬件损坏

                printf("hardware error\n");

                ch374_write_byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG );  // 清中断标志

            }

        }

        //vTaskDelay(20 / portTICK_PERIOD_MS);  //关闭了watch dog

    }

       

    vTaskDelete(NULL);

}




已解决了


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