CH32V103模拟HID复合设备

各位好


我在使用CH32V103开发一个HID设备


在只有Keyboard1和Keyboard2的情况下,识别和运行正常;

以上基础再增加一个Consumer1,Linux可以识别运行,Windows报错;

折腾了几天没有想明白问题在哪里,还请赐教


除了Descriptor相关的更新以外,主函数只有如下几处更新:

case USB_DESCR_TYP_REPORT:
switch( (pSetupReqPak->wIndex)&0xff )
case UIS_TOKEN_IN | 3:


#include "USB_HID_Lib.h"
#include "string.h"

#define DevEP0SIZE			0x08        // Max 8 bypes
#define USBD_VID			0xFFFF
#define USBD_PID_FS			0xFFFF
#define USB_CFG_DESCR_LEN	0x47
//uint16_t wTotalLength
//total length of the descriptor
//all related interface, endpoint, and vendor-specific descriptors
//USBCfgDescr			09
//KeyBoard1ItfDescr		09
//KeyBoard1INEndpDescr	07
//KeyBoard1OUTEndpDescr	07
//KeyBoard2ItfDescr		09
//KeyBoard2INEndpDescr	07
//KeyBoard2OUTEndpDescr	07
//Consumer1ItfDescr		09
//Consumer1INEndpDescr	07
//------------------------
//SubTotal				71 = 0x47

static const uint8_t Keyboard1RepDescr[] =
{
		0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
		0x09, 0x06,        // Usage (Keyboard)
		0xA1, 0x01,        // Collection (Application)
		0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
		0x19, 0xE0,        //   Usage Minimum (0xE0)
		0x29, 0xE7,        //   Usage Maximum (0xE7)
		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)
		0x95, 0x01,        //   Report Count (1)
		0x75, 0x08,        //   Report Size (8)
		0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x95, 0x06,        //   Report Count (6)
		0x75, 0x08,        //   Report Size (8)
		0x25, 0xFF,        //   Logical Maximum (-1)
		0x19, 0x00,        //   Usage Minimum (0x00)
		0x29, 0x65,        //   Usage Maximum (0x65)
		0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x25, 0x01,        //   Logical Maximum (1)
		0x95, 0x07,        //   Report Count (7)
		0x75, 0x01,        //   Report Size (1)
		0x05, 0x08,        //   Usage Page (LEDs)
		0x19, 0x01,        //   Usage Minimum (Num Lock)
		0x29, 0x07,        //   Usage Maximum (Shift)
		0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
		0x95, 0x01,        //   Report Count (1)
		0x75, 0x01,        //   Report Size (1)
		0x91, 0x03,        //   Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
		0xC0,              // End Collection
};

static const uint8_t Keyboard2RepDescr[] =
{
		0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
		0x09, 0x06,        // Usage (Keyboard)
		0xA1, 0x01,        // Collection (Application)
		0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
		0x19, 0xE0,        //   Usage Minimum (0xE0)
		0x29, 0xE7,        //   Usage Maximum (0xE7)
		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)
		0x95, 0x01,        //   Report Count (1)
		0x75, 0x08,        //   Report Size (8)
		0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x95, 0x06,        //   Report Count (6)
		0x75, 0x08,        //   Report Size (8)
		0x25, 0xFF,        //   Logical Maximum (-1)
		0x19, 0x00,        //   Usage Minimum (0x00)
		0x29, 0x65,        //   Usage Maximum (0x65)
		0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x25, 0x01,        //   Logical Maximum (1)
		0x95, 0x07,        //   Report Count (7)
		0x75, 0x01,        //   Report Size (1)
		0x05, 0x08,        //   Usage Page (LEDs)
		0x19, 0x01,        //   Usage Minimum (Num Lock)
		0x29, 0x07,        //   Usage Maximum (Shift)
		0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
		0x95, 0x01,        //   Report Count (1)
		0x75, 0x01,        //   Report Size (1)
		0x91, 0x03,        //   Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
		0xC0,              // End Collection
};

static const uint8_t Consumer1RepDescr[] =
{
		0x05, 0x0C,        // Usage Page (Consumer)
		0x09, 0x01,        // Usage (Consumer Control)
		0xA1, 0x01,        // Collection (Application)
		0x15, 0x00,        //   Logical Minimum (0)
		0x25, 0x01,        //   Logical Maximum (1)
		0x75, 0x01,        //   Report Size (1)
		0x95, 0x01,        //   Report Count (1)
		0x09, 0xCD,        //   Usage (Play/Pause)
		0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
		0x09, 0xB5,        //   Usage (Scan Next Track)
		0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
		0x09, 0xB6,        //   Usage (Scan Previous Track)
		0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
		0x09, 0xE2,        //   Usage (Mute)
		0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
		0x09, 0xE9,        //   Usage (Volume Increment)
		0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
		0x09, 0xEA,        //   Usage (Volume Decrement)
		0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
		0x09, 0xB3,        //   Usage (Fast Forward)
		0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x09, 0xB4,        //   Usage (Rewind)
		0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0xC0,              // End Collection
};

static const USB_DEV_DESCR USBDevDescr = {
        .bLength = 18,                  //length of this descr
        .bDescriptorType = 0x01,        //device descr
        .bcdUSB = 0x0200,               //USB 2.0
        .bDeviceClass = 0x00,           //custom protocol
        .bDeviceSubClass = 0x00,        //custom protocol
        .bDeviceProtocol = 0x00,        //custom protocol
        .bMaxPacketSize0 = DevEP0SIZE,  //8 bytes
        .idVendor = USBD_VID,           //custom vendor
        .idProduct = USBD_PID_FS,       //custom product
        .bcdDevice = 0x0100,            //version 1.0
        .iManufacturer = 0x01,          //MyManuInfo[]
        .iProduct = 0x02,               //MyProdInfo[]
        .iSerialNumber = 0x03,          //MyProdIDInfo[]
        .bNumConfigurations = 0x01      //with 1 config
};

static const USB_CFG_DESCR  USBCfgDescr = {
        .bLength = 0x09,                //length of this descr
        .bDescriptorType = 0x02,        //config descr
        .wTotalLength =
        		USB_CFG_DESCR_LEN,  	//total length
        .bNumInterfaces = 0x03,         //2 interface
        .bConfigurationValue = 0x01,	//use interface 1
        .iConfiguration = 0x00,         //no string
        .bmAttributes = 0xA0,           //attributes
        .MaxPower = 0xFA                //max currency 500ma, unit as 2 mA
        //Attributes
        //D0-D4 reserved as 0
        //D5    remote wake-up
        //D6    self-powered
        //D7    reserved as 1
        //B10100000 = 0x0A
};

static const USB_ITF_DESCR  KeyBoard1ItfDescr = {
        .bLength = 0x09,            //length
        .bDescriptorType = 0x04,    //interface descr
        .bInterfaceNumber = 0x00,   //number of interface, 0 based
        .bAlternateSetting = 0x00,  //alternative interface
        .bNumEndpoints = 0x01,      //endpoint used, 0 excluded
        .bInterfaceClass = 0x03,    //HID Class
        .bInterfaceSubClass = 0x01, //0=noBOOT 1=BOOT
        .bInterfaceProtocol = 0x01, //0=none 1=keyboard 2=mouse
        .iInterface = 0x00          //index of string
};

static const USB_ITF_DESCR  KeyBoard2ItfDescr = {
        .bLength = 0x09,            //length
        .bDescriptorType = 0x04,    //interface descr
        .bInterfaceNumber = 0x01,   //number of interface, 0 based
        .bAlternateSetting = 0x00,  //alternative interface
        .bNumEndpoints = 0x02,      //endpoint used, 0 excluded
        .bInterfaceClass = 0x03,    //HID Class
        .bInterfaceSubClass = 0x01, //0=noBOOT 1=BOOT
        .bInterfaceProtocol = 0x01, //0=none 1=keyboard 2=mouse
        .iInterface = 0x00          //index of string
};

static const USB_ITF_DESCR  Consumer1ItfDescr = {
        .bLength = 0x09,            //length
        .bDescriptorType = 0x04,    //interface descr
        .bInterfaceNumber = 0x02,   //number of interface, 0 based
        .bAlternateSetting = 0x00,  //alternative interface
        .bNumEndpoints = 0x03,      //endpoint used, 0 excluded
        .bInterfaceClass = 0x03,    //HID Class
        .bInterfaceSubClass = 0x01, //0=noBOOT 1=BOOT
        .bInterfaceProtocol = 0x01, //0=none 1=keyboard 2=mouse
        .iInterface = 0x00          //index of string
};

static const USB_HID_DESCR  KeyBoard1HIDDescr = {
        .bLength = 0x09,            //length
        .bDescriptorType = 0x21,    //HID type
        .bcdHID = 0x0111,           //HID version 1.11
        .bCountryCode = 0x00,       //country code
        .bNumDescriptors = 0x01,    //number of descr
        .bDescriptorTypeX = 0x22,   //type of descr
        .wDescriptorLengthH = 0x00,
		.wDescriptorLengthL =
				sizeof(Keyboard1RepDescr)&0xFF,
		//WCH custom?
};

static const USB_HID_DESCR  KeyBoard2HIDDescr = {
        .bLength = 0x09,            //length
        .bDescriptorType = 0x21,    //HID type
        .bcdHID = 0x0111,           //HID version 1.11
        .bCountryCode = 0x00,       //country code
        .bNumDescriptors = 0x01,    //number of descr
        .bDescriptorTypeX = 0x22,   //type of descr
        .wDescriptorLengthH = 0x00,
		.wDescriptorLengthL =
				sizeof(Keyboard2RepDescr)&0xFF,
		//WCH custom?
};

static const USB_HID_DESCR  Consumer1HIDDescr = {
        .bLength = 0x09,            //length
        .bDescriptorType = 0x21,    //HID type
        .bcdHID = 0x0111,           //HID version 1.11
        .bCountryCode = 0x00,       //country code
        .bNumDescriptors = 0x01,    //number of descr
        .bDescriptorTypeX = 0x22,   //type of descr
        .wDescriptorLengthH = 0x00,
		.wDescriptorLengthL =
				sizeof(Consumer1RepDescr)&0xFF,
		//WCH custom?
};

static const USB_ENDP_DESCR  KeyBoard1INEndpDescr = {
        .bLength = 0x07,            	//length
        .bDescriptorType = 0x05,    	//endpoint descriptor
        .bEndpointAddress = 0x81,   	//end point info
        .bmAttributes = 0x03,       	//attributes
        .wMaxPacketSize = DevEP0SIZE,	//8 bytes max package //UINT16
        .bInterval = 0x0A				//10ms interval
        //End point info
        //D0-D3 end point number
        //D4-D6 reserved as 0
        //D7    0(OUT) 1(IN)
        //B10000001 = 0x81
        //Attributes
        //D0-D1 transfer,   00-control 01-isochronous 10-bulk 11-interrupt
        //D2-D3 types,      00-none 01-asynchronous 10-adaptive 11-synchronous
        //D4-D5 usage,      00-data 01-feedback 10-explicit 11-reserved
        //D6-D7 reserved as 0
        //if D0-D1=01, D2-D7 reserved as 0
};

static const USB_ENDP_DESCR  KeyBoard2INEndpDescr = {
        .bLength = 0x07,            	//length
        .bDescriptorType = 0x05,    	//endpoint descriptor
        .bEndpointAddress = 0x82,   	//end point info
        .bmAttributes = 0x03,       	//attributes
        .wMaxPacketSize = DevEP0SIZE,	//8 bytes max package //UINT16
        .bInterval = 0x0A				//10ms interval
        //similar to in end point
};

static const USB_ENDP_DESCR  Consumer1INEndpDescr = {
        .bLength = 0x07,            	//length
        .bDescriptorType = 0x05,    	//endpoint descriptor
        .bEndpointAddress = 0x83,   	//end point info
        .bmAttributes = 0x03,       	//attributes
        .wMaxPacketSize = 0x011,		//8 bytes max package //UINT16
        .bInterval = 0x0A				//10ms interval
        //similar to in end point
};

static const USB_ENDP_DESCR  KeyBoard1OUTEndpDescr = {
        .bLength = 0x07,                //length
        .bDescriptorType = 0x05,        //endpoint descriptor
        .bEndpointAddress = 0x01,       //end point info
        .bmAttributes = 0x03,           //attributes
        .wMaxPacketSize = DevEP0SIZE,   //8 bytes max package //2 bytes
        .bInterval = 0x0A               //10ms interval
        //similar to in end point
};

static const USB_ENDP_DESCR  KeyBoard2OUTEndpDescr = {
        .bLength = 0x07,                //length
        .bDescriptorType = 0x05,        //endpoint descriptor
        .bEndpointAddress = 0x02,       //end point info
        .bmAttributes = 0x03,           //attributes
        .wMaxPacketSize = DevEP0SIZE,   //8 bytes max package //2 bytes
        .bInterval = 0x0A               //10ms interval
        //similar to in end point
};

typedef struct __PACKED {
    USB_CFG_DESCR   cfg_descr;
    USB_ITF_DESCR   keyboard1_itf_descr;
    USB_HID_DESCR   keyboard1_hid_descr;
    USB_ENDP_DESCR  keyboard1_inendp_descr;
    USB_ENDP_DESCR  keyboard1_outendp_descr;
    USB_ITF_DESCR   keyboard2_itf_descr;
    USB_HID_DESCR   keyboard2_hid_descr;
    USB_ENDP_DESCR  keyboard2_inendp_descr;
    USB_ENDP_DESCR  keyboard2_outendp_descr;
    USB_ITF_DESCR   Consumer1_itf_descr;
    USB_HID_DESCR   Consumer1_hid_descr;
    USB_ENDP_DESCR  Consumer1_inendp_descr;
} USB_CFG_DESCR_KEYBOARD;

static const USB_CFG_DESCR_KEYBOARD CfgDescr_keyboard = {
    .cfg_descr = USBCfgDescr,
    .keyboard1_itf_descr = KeyBoard1ItfDescr,
    .keyboard1_hid_descr = KeyBoard1HIDDescr,
    .keyboard1_inendp_descr = KeyBoard1INEndpDescr,
    .keyboard1_outendp_descr = KeyBoard1OUTEndpDescr,
    .keyboard2_itf_descr = KeyBoard2ItfDescr,
    .keyboard2_hid_descr = KeyBoard2HIDDescr,
    .keyboard2_inendp_descr = KeyBoard2INEndpDescr,
    .keyboard2_outendp_descr = KeyBoard2OUTEndpDescr,
	.Consumer1_itf_descr = Consumer1ItfDescr,
	.Consumer1_hid_descr = Consumer1HIDDescr,
	.Consumer1_inendp_descr = Consumer1INEndpDescr,
};

static const UINT8  MyLangDescr[] = {
        0x04,   //length
        0x03,   //string descr
        0x09,   //0409 en_US
        0x04
};

static const UINT8 MyManuInfo[] = {
        0x1A,   //length
        0x03,   //string descr
        0x5A, 0x00,
        0x65, 0x00,
        0x6C, 0x00,
        0x52, 0x00,
        0x61, 0x00,
        0x20, 0x00,
        0x44, 0x00,
        0x65, 0x00,
        0x73, 0x00,
        0x69, 0x00,
        0x67, 0x00,
        0x6E, 0x00
        /*ZelRa Design*/
};

static const UINT8 MyProdInfo[] = {
        0x20,   //length
        0x03,   //string descr
        0x5A, 0x00,
        0x65, 0x00,
        0x70, 0x00,
        0x68, 0x00,
        0x79, 0x00,
        0x72, 0x00,
        0x20, 0x00,
        0x56, 0x00,
        0x61, 0x00,
        0x6C, 0x00,
        0x6B, 0x00,
        0x79, 0x00,
        0x72, 0x00,
        0x69, 0x00,
        0x65, 0x00
        /*Zephyr Valkyrie*/
};

static const UINT8 MyProdIDInfo[] = {
        0x1C,   //length
        0x03,   //string descr
        0x52, 0x00,
        0x49, 0x00,
        0x53, 0x00,
        0x43, 0x00,
        0x2D, 0x00,
        0x56, 0x00,
        0x20, 0x00,
        0x49, 0x00,
        0x6E, 0x00,
        0x73, 0x00,
        0x69, 0x00,
        0x64, 0x00,
        0x65, 0x00
        /*RISC-V Inside*/
};

static UINT8   DevConfig;
static UINT8   SetupReqCode;
static UINT16  SetupReqLen;
static const UINT8 *pDescr;
static volatile UINT8   HIDInitFlag = 0;
static volatile UINT8   KeyBoard1HIDEndpBusy = 0;
static volatile UINT8	KeyBoard2HIDEndpBusy = 0;
static UINT8  KeyLedStatus = 0;

typedef struct
{
  UINT8 modifiers;
  UINT8 reserved;
  UINT8 keys[6];
} KeyReport;

typedef struct
{
	UINT8 key[1];
} ConReport;

KeyReport _keyReport1;
KeyReport _keyReport2;
ConReport _conReport1;

__attribute__ ((aligned(4))) UINT8 EP0_Databuf[8];		//ep0(8)
__attribute__ ((aligned(4))) UINT8 EP1_Databuf[8+8];	//ep1_out(8)+ep1_in(8)
__attribute__ ((aligned(4))) UINT8 EP2_Databuf[8+8];	//ep2_out(8)+ep2_out(8)
__attribute__ ((aligned(4))) UINT8 EP3_Databuf[8+8];	//ep3_out(1)+ep3_out(1)
//endpoint0 as system reserved
//endpoint1 as keyboard 1
//endpoint2 as keyboard 2
//endpoint3 as consumer 1

void USBHD_IRQHandler(void) __attribute__((interrupt()));

static void USBHD_ClockCmd(UINT32 RCC_USBCLKSource,FunctionalState NewState)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, NewState);
    EXTEN->EXTEN_CTR |= EXTEN_USBHD_IO_EN;
    RCC_USBCLKConfig(RCC_USBCLKSource);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHD,NewState);
    //USBclk=PLLclk/1.5=48Mhz
}

void USB_DevTransProcess( void )
{
    UINT8  len, chtype;
    UINT8  intflag, errflag = 0;
    intflag = R8_USB_INT_FG;
    if( intflag & RB_UIF_TRANSFER )
    {
        switch ( R8_USB_INT_ST & MASK_UIS_TOKEN)
        {
            case UIS_TOKEN_SETUP:
                R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
                len = R8_USB_RX_LEN;
                if ( len == sizeof( USB_SETUP_REQ ) )
                {
                    SetupReqLen = pSetupReqPak->wLength;
                    SetupReqCode = pSetupReqPak->bRequest;
                    chtype = pSetupReqPak->bRequestType;
                    len = 0;
                    errflag = 0;
                    if ( ( pSetupReqPak->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )
                    {
                        switch(SetupReqCode)
                        {
                            case HID_GET_REPORT:
                                len = 1;
                                pEP0_DataBuf[0] = 0xaa;
                                break;
                            case HID_SET_IDLE:
                                R8_UEP0_T_LEN = 0;
                                break;
                            case HID_SET_REPORT:
                                HIDInitFlag = 1;
                                break;
                            default:
                                errflag = 0xFF;
                        }
                    }
                    else
                    {
                        switch( SetupReqCode )
                        {
                            case USB_GET_DESCRIPTOR:
                            {
                                switch( ((pSetupReqPak->wValue)>>8) )
                                {
                                    case USB_DESCR_TYP_DEVICE:
                                        pDescr = (const UINT8*)&USBDevDescr;
                                        len = sizeof(USB_DEV_DESCR);
                                        break;
                                    case USB_DESCR_TYP_CONFIG:
                                    	pDescr = (const UINT8*)&CfgDescr_keyboard;
                                    	len = sizeof(USB_CFG_DESCR_KEYBOARD);
                                        break;
                                    case USB_DESCR_TYP_STRING:
                                        switch( (pSetupReqPak->wValue)&0xff )
                                        {
                                            case 0:
                                                pDescr = MyLangDescr;
                                                len = MyLangDescr[0];
                                                break;
                                            case 1:
                                                pDescr = MyManuInfo;
                                                len = MyManuInfo[0];
                                                break;
                                            case 2:
                                                pDescr = MyProdInfo;
                                                len = MyProdInfo[0];
                                                break;
                                            case 3:
                                                pDescr = MyProdIDInfo;
                                                len = MyProdIDInfo[0];
                                                break;
                                            default:
                                                errflag = 0xFF;
                                                break;
                                        }
                                        break;
                                        case USB_DESCR_TYP_REPORT:
                                        	if(((pSetupReqPak->wIndex)&0xff) == 0)
                                        	{
												pDescr = Keyboard1RepDescr;
												len = sizeof(Keyboard1RepDescr);
                                        	}
                                        	else if(((pSetupReqPak->wIndex)&0xff) == 1)
                                        	{
                                                pDescr = Keyboard1RepDescr;
                                                len = sizeof(Keyboard2RepDescr);
                                        	}
                                        	else if(((pSetupReqPak->wIndex)&0xff) == 2)
                                        	{
                                                pDescr = Keyboard1RepDescr;
                                                len = sizeof(Consumer1RepDescr);
                                                HIDInitFlag = 1;
                                        	}
                                        	else len = 0xff;
                                        break;
                                    default :
                                        errflag = 0xff;
                                        break;
                                }
                                if( SetupReqLen>len )   SetupReqLen = len;
                                len = (SetupReqLen >= DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;
                                memcpy( pEP0_DataBuf, pDescr, len );
                                pDescr += len;
                            }
                                break;
                            case USB_SET_ADDRESS:
                                SetupReqLen = (pSetupReqPak->wValue)&0xff;
                                break;
                            case USB_GET_CONFIGURATION:
                                pEP0_DataBuf[0] = DevConfig;
                                if ( SetupReqLen > 1 ) SetupReqLen = 1;
                                break;
                            case USB_SET_CONFIGURATION:
                                DevConfig = (pSetupReqPak->wValue)&0xff;
                                break;
                            case USB_CLEAR_FEATURE:
                                if ( ( pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )
                                {
                                    switch( (pSetupReqPak->wIndex)&0xff )
                                    {
                                    case 0x83:
                                        R8_UEP3_CTRL = (R8_UEP3_CTRL & ~( RB_UEP_T_TOG|MASK_UEP_T_RES )) | UEP_T_RES_NAK;
                                        break;
                                    case 0x03:
                                        R8_UEP3_CTRL = (R8_UEP3_CTRL & ~( RB_UEP_R_TOG|MASK_UEP_R_RES )) | UEP_R_RES_ACK;
                                        break;
                                    case 0x82:
                                        R8_UEP2_CTRL = (R8_UEP2_CTRL & ~( RB_UEP_T_TOG|MASK_UEP_T_RES )) | UEP_T_RES_NAK;
                                        break;
                                    case 0x02:
                                        R8_UEP2_CTRL = (R8_UEP2_CTRL & ~( RB_UEP_R_TOG|MASK_UEP_R_RES )) | UEP_R_RES_ACK;
                                        break;
                                    case 0x81:
                                        R8_UEP1_CTRL = (R8_UEP1_CTRL & ~( RB_UEP_T_TOG|MASK_UEP_T_RES )) | UEP_T_RES_NAK;
                                        break;
                                    case 0x01:
                                        R8_UEP1_CTRL = (R8_UEP1_CTRL & ~( RB_UEP_R_TOG|MASK_UEP_R_RES )) | UEP_R_RES_ACK;
                                        break;
                                    default:
                                        errflag = 0xFF;
                                        break;
                                    }
                                }
                                else    errflag = 0xFF;
                                break;
                            case USB_GET_INTERFACE:
                                pEP0_DataBuf[0] = 0x00;
                                if ( SetupReqLen > 1 ) SetupReqLen = 1;
                                break;
                            case USB_GET_STATUS:
                                pEP0_DataBuf[0] = 0x00;
                                pEP0_DataBuf[1] = 0x00;
                                if ( SetupReqLen > 2 ) SetupReqLen = 2;
                                break;
                            default:
                                errflag = 0xff;
                                break;
                        }
                    }
                }
                else    errflag = 0xff;

                if( errflag == 0xff)
                {
                    R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL;
                }
                else
                {
                    if( chtype & 0x80 )
                    {
                        len = (SetupReqLen>DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;
                        SetupReqLen -= len;
                    }
                    else  len = 0;
                    R8_UEP0_T_LEN = len;
                    R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;
                }
                break;
            case UIS_TOKEN_IN:
                switch ( R8_USB_INT_ST & ( MASK_UIS_TOKEN | MASK_UIS_ENDP ) )
                {
                    case UIS_TOKEN_IN:
                        switch( SetupReqCode )
                        {
                            case USB_GET_DESCRIPTOR:
                                    len = SetupReqLen >= DevEP0SIZE ? DevEP0SIZE : SetupReqLen;
                                    memcpy( pEP0_DataBuf, pDescr, len );
                                    SetupReqLen -= len;
                                    pDescr += len;
                                    R8_UEP0_T_LEN = len;
                                    R8_UEP0_CTRL ^= RB_UEP_T_TOG;
                                    break;
                            case USB_SET_ADDRESS:
                                    R8_USB_DEV_AD = (R8_USB_DEV_AD&RB_UDA_GP_BIT) | SetupReqLen;
                                    R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
                                    break;
                            default:
                                    R8_UEP0_T_LEN = 0;
                                    R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
                                    break;
                        }
                        break;
                    case UIS_TOKEN_IN | 1:
                        R8_UEP1_T_LEN = 0;
                        KeyBoard1HIDEndpBusy = 0;
                        R8_UEP1_CTRL ^=  RB_UEP_T_TOG;
                        R8_UEP1_CTRL = (R8_UEP1_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
                        break;
                    case UIS_TOKEN_IN | 2:
                        R8_UEP2_T_LEN = 0;
                        KeyBoard2HIDEndpBusy = 0;
                        R8_UEP2_CTRL ^=  RB_UEP_T_TOG;
                        R8_UEP2_CTRL = (R8_UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
                        break;
                    case UIS_TOKEN_IN | 3:
                        R8_UEP3_T_LEN = 0;
                        KeyBoard2HIDEndpBusy = 0;
                        R8_UEP3_CTRL ^=  RB_UEP_T_TOG;
                        R8_UEP3_CTRL = (R8_UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
                        break;
                }
                break;
            case UIS_TOKEN_OUT:
                switch ( R8_USB_INT_ST & ( MASK_UIS_TOKEN | MASK_UIS_ENDP ) )
                {
                    case UIS_TOKEN_OUT:
                        len = R8_USB_RX_LEN;
                    break;
                    case UIS_TOKEN_OUT | 1:
                        if ( R8_USB_INT_ST & RB_UIS_TOG_OK )
                        {
                            R8_UEP1_CTRL ^= RB_UEP_R_TOG;
                            len = R8_USB_RX_LEN;
                            DevEP1_OUT_Deal( len );
                        }
                        break;
                }
                break;
            case UIS_TOKEN_SOF:
                break;
            default :
                break;
        }
        R8_USB_INT_FG = RB_UIF_TRANSFER;
    }
    else if( intflag & RB_UIF_BUS_RST )
    {
        R8_USB_DEV_AD = 0;
        R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
        R8_UEP1_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
        R8_UEP2_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
        R8_USB_INT_FG |= RB_UIF_BUS_RST;
        HIDInitFlag = 0;
    }
    else if( intflag & RB_UIF_SUSPEND )
    {
        if ( R8_USB_MIS_ST & RB_UMS_SUSPEND ) {;}
        else{;}
        R8_USB_INT_FG = RB_UIF_SUSPEND;
        HIDInitFlag = 0;
    }
    else
    {
        R8_USB_INT_FG = intflag;
    }
}

static void KB1_Send(UINT8 *kb)
{
    if(HIDInitFlag == 0)
        return;
    while( KeyBoard1HIDEndpBusy )
    {;}
    KeyBoard1HIDEndpBusy = 1;
    memcpy(pEP1_IN_DataBuf, kb, 8);
    DevEP1_IN_Deal(8);
}

static void KB2_Send(UINT8 *kb)
{
    if(HIDInitFlag == 0)
        return;
    while( KeyBoard2HIDEndpBusy )
    {;}
    KeyBoard2HIDEndpBusy = 1;
    memcpy(pEP2_IN_DataBuf, kb, 8);
    DevEP2_IN_Deal(8);
}

void DevEP1_OUT_Deal( UINT8 l )
{
    KeyLedStatus = pEP1_OUT_DataBuf[0];
}

void USBHD_IRQHandler (void)
{
    USB_DevTransProcess();
}

void USB_HID_Init(void)
{
    pEP0_RAM_Addr = EP0_Databuf;
    pEP1_RAM_Addr = EP1_Databuf;
    pEP2_RAM_Addr = EP2_Databuf;
    USBHD_ClockCmd(RCC_USBCLKSource_PLLCLK_1Div5,ENABLE);
    USB_DeviceInit();
    NVIC_EnableIRQ(USBHD_IRQn);
}

bool KB_Read_num_lock(void)
{
    return KeyLedStatus & 0x01;
}

bool KB_Read_caps_lock(void)
{
    return KeyLedStatus & 0x02;
}

void Report1_Add(UINT8 value)
{
	int i;
	for (i=0;i<6;i++)
	{
		if (_keyReport1.keys[i]==0)
		{
			_keyReport1.keys[i]=value;
			break;
		};
	};
}

void Report1_Remove(UINT8 value)
{
	int j;
	for (j=0;j<6;j++)
	{
		if (_keyReport1.keys[j]==value)
		{
			_keyReport1.keys[j]=0;
			break;
		};
	};
}

void Report2_Add(UINT8 value)
{
	int i;
	for (i=0;i<6;i++)
	{
		if (_keyReport2.keys[i]==0)
		{
			_keyReport2.keys[i]=value;
			break;
		};
	};
}

void Report2_Remove(UINT8 value)
{
	int j;
	for (j=0;j<6;j++)
	{
		if (_keyReport2.keys[j]==value)
		{
			_keyReport2.keys[j]=0;
			break;
		};
	};
}

void Report1_Update(void)
{
	KB1_Send((UINT8 *)&_keyReport1);
}

void Report2_Update(void)
{
	KB2_Send((UINT8 *)&_keyReport2);
}


您好,windows报错是报什么错,可以用Bus Hound或USB分析仪抓一下设备连接主机时枚举过程数据看一下,可以看一下是在哪个步骤出了问题。后面问题可以通过邮箱(lzs@wch.cn)沟通。


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