各位好
我在使用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); }
热门产品 :
CH634: 4端口USB3.0 HUB控制器芯片