本帖最后由 chenbingjy 于 2023-6-25 22:22 编辑
uint8_t g_usbDeviceDescriptor[USB_DEVICE_DESCRIPTOR_SIZE] =
{
/* bLength */
0x12,
/* bDescriptorType */
USBD_DESC_DEVICE,
/* bcdUSB */
0x00, 0x02,
/* bDeviceClass */
0x00,
/* bDeviceSubClass */
0x00,
/* bDeviceProtocol */
0x00,
/* bMaxPacketSize = 64 */
0x40,
/* idVendor = 314b*/
0x34, 0x12,
/* idProduct = 0107 */
0x21, 0x44,
/* bcdDevice = 2.00 */
0x00, 0x02,
/* Index of string descriptor describing manufacturer */
1,
/* Index of string descriptor describing product */
2,
/* Index of string descriptor describing the device serial number */
3,
/* bNumConfigurations */
USBD_CONFIGURATION_NUM,
};
uint8_t g_usbConfigDescriptor[USB_CONFIG_DESCRIPTOR_SIZE] =
{
0x09, /* bLength: Configuation Descriptor size */
0x02, //USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
sizeof(g_usbConfigDescriptor)&0xff, //JOYSTICK_SIZ_CONFIG_DESC,
/* wTotalLength: Bytes returned */
//0x00,
(sizeof(g_usbConfigDescriptor)>>8)&0xff,
0x01, /*bNumInterfaces: 1 interface*/
0x01, /*bConfigurationValue: Configuration value*/
0x00, /*iConfiguration: Index of string descriptor describing the configuration*/
0xC0, /*bmAttributes: self powered */
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
//ò????a?ó?ú?èê?·?
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /*bLength: Interface Descriptor size*/
0x04, //USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
0x00, /*bInterfaceNumber: Number of Interface*/
0x00, /*bAlternateSetting: Alternate setting*/
0x02, /*bNumEndpoints*/
0x03, /*bInterfaceClass: HID*/
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x01, /*bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
//ò????aHID?èê?·?
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
0x10, /*bcdHID: HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
0x22, /*bDescriptorType*/
//JOYSTICK_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
//0x00,
sizeof(g_hidMouseReportDescriptor)&0xff,
(sizeof(g_hidMouseReportDescriptor)>>8)&0xff,
//ò????aê?è???μ?1?èê?·?
/******************** Descriptor of Joystick Mouse endpoint ********************/
/* 27 */
0x07, /*bLength: Endpoint Descriptor size*/
0x05, //USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
0x81, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /*bmAttributes: Interrupt endpoint*/
0x0A, /*wMaxPacketSize: 10 Byte max */
0x00,
0x20, /*bInterval: Polling Interval (32 ms)*/
//ò????aê?3???μ?1?èê?·?
/* 34 */
0x07, /*bLength: Endpoint Descriptor size*/
0x05, //USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
0x01, /*bEndpointAddress: Endpoint Address (OUT)*/
0x03, /*bmAttributes: Interrupt endpoint*/
0x0A, /*wMaxPacketSize: 10 Byte max */
0x00,
0x20, /*bInterval: Polling Interval (32 ms)*/
};
uint8_t g_hidMouseReportDescriptor[121] =
{
/************************USB?ü?ì2?·?±¨???èê?·?**********************/
/*******************************************************************/
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
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)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
//3??bità′′?3éò?×??ú?£
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0xc0, // END_COLLECTION
/************************USBêó±ê2?·?±¨???èê?·?**********************/
/*******************************************************************/
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x02, // Report ID (2)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
void SendReport(void)
{
//需要返回的9字节报告的缓冲(一字节报告ID加键盘8字节报告)
//而鼠标报告只有4字节,加上一字节报告ID总共5字节,9字节够了。
uint8_t Buf[9]={0,0,0,0,0,0,0,0,0};
//由于需要返回多个按键,所以需要增加一个变量来保存当前的位置。
//由于报告ID占用第一字节,所以普通按键从第四字节开始存放。
//uint8_t i=3;
//我们用KEY1键来选择剩余的7个键是键盘功能还是鼠标功能。
//当KEY1按住时,剩余7个键为键盘功能,这7个键的功能跟键盘
//实例的一样。当KEY1松开时,剩余7个键为鼠标功能,功能分别为:
//KEY2:光标左移,KEY3:光标右移,KEY4:光标上移,KEY5:光标下移。
//KEY6:鼠标左键,KEY7:鼠标中键,KEY8:鼠标右键。
if(g_usbDev.devState != USBD_DEVICE_STATE_CONFIGURED)
{
return;
}
//根据不同的按键设置输入报告
if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_1)==0) //如果KEY1按住,则为键盘功能
{
if(s_statusEP)
{
Buf[0]=0x01; //第一字节为报告ID,键盘报告ID为1。
if(KeyPress & 0x01) //如果KEY2按住
{
Buf[3]=0x04; //KEY2为左Shift键。
}
if(KeyPress & 0x02) //如果KEY3按住
{
Buf[3]=0x05; //KEY2为左Shift键。
}
if(KeyPress & 0x04) //如果KEY4按住
{
Buf[3]=0x06; //KEY2为左Shift键。
}
if(KeyPress & 0x08) //如果KEY5按住
{
Buf[3]=0x07; //KEY2为左Shift键。
}
s_statusEP = 0;
USBD_TxData(USB_EP_1, Buf, sizeof(Buf));
memset(Buf,0,sizeof(Buf));
}
}
if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_0)==0) //如果KEY1按住,则为键盘功能 //KEY1松开,为鼠标功能
{
if(s_statusEP)
{
Buf[0]=0x02; //第一字节为报告ID,鼠标报告ID为2。
if(KeyDown & 1) //如果KEY2按下
{
Buf[2]=-10; //KEY2为鼠标左移,按一次移动10个单位。
}
if(KeyDown & 2) //如果KEY3按下
{
Buf[2]=10; //KEY3为鼠标右移,按一次移动10个单位。
}
if(KeyDown & 4) //如果KEY4按下
{
Buf[3]=-10; //KEY4为鼠标上移,按一次移动10个单位。
}
if(KeyDown & 8) //如果KEY5按下
{
Buf[3]=10; //KEY5为鼠标下移,按一次移动10个单位。
}
s_statusEP = 0;
USBD_TxData(USB_EP_1, Buf, 5);
memset(Buf,0,5);
}
}
//记得清除KeyUp和KeyDown
KeyUp=0;
KeyDown=0;
}
|