- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] Configuration descriptor
- */
- const uint8_t g_hidMouseConfigDescriptor[HID_MOUSE_CONFIG_DESCRIPTOR_SIZE] =
- {
- /** bLength */
- 0x09,
- /** bDescriptorType */
- USB_DESC_CONFIGURATION,
- /** wTotalLength */
- HID_MOUSE_CONFIG_DESCRIPTOR_SIZE & 0XFF, HID_MOUSE_CONFIG_DESCRIPTOR_SIZE >> 8,
-
- /** bNumInterfaces */
- 0X01,
- /** bConfigurationValue */
- 0X01,
- /** iConfiguration */
- 0X00,
- /** bmAttributes */
- 0XE0,
- /** MaxPower */
- 0X32,
- /** bLength */
- 0X09,
- /** bDescriptorType */
- USB_DESC_INTERFACE,
- /** bInterfaceNumber */
- 0X00,
- /** bAlternateSetting */
- 0X00,
- /** bNumEndpoints */
- 0X02,
- /** bInterfaceClass */
- 0X03,
- /** bInterfaceSubClass */
- 0X00,
- /** nInterfaceProtocol */
- 0X00,
- /** iInterface */
- 0X00,
- /** bLength */
- 0X09,
- /** bDescriptorType = HID */
- 0x21,
- /** bcdHID */
- 0X00, 0X01,
- /** bCountryCode */
- 0X00,
- /** bNumDescriptors */
- 0X01,
- /** bDescriptorType */
- 0X22,
- /** wItemLength */
- HID_MOUSE_REPORT_DESCRIPTOR_SIZE & 0XFF, HID_MOUSE_REPORT_DESCRIPTOR_SIZE >> 8,
- //IN endpoint
- /** bLength */
- 0X07,
- /** bDescriptorType */
- USB_DESC_ENDPOINT,
- /** bEndpointAddress */
- 0X81,
- /** bmAttributes */
- 0X03,
- /** wMaxPacketSize */
- 0X40, 0X00,
- /** bInterval */
- 0X10,
-
- //OUT endpoint
- /** bLength */
- 0X07,
- /** bDescriptorType */
- USB_DESC_ENDPOINT,
- /** bEndpointAddress */
- 0X01,
- /** bmAttributes */
- 0X03,
- /** wMaxPacketSize */
- 0X40, 0X00,
- /** bInterval */
- 0X10
- };
然后就是手柄的报告描述符
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] HID report descriptor
- */
- const uint8_t g_hidMouseReportDescriptor[HID_MOUSE_REPORT_DESCRIPTOR_SIZE] =
- {
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x05, // USAGE (Game Pad)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x09, 0x01, // USAGE (Pointer)
- 0xa1, 0x00, // COLLECTION (Physical)
- 0x09, 0x30, // USAGE (X)
- 0x09, 0x31, // USAGE (Y)
- 0x09, 0x33, // USAGE (RX)
- 0x09, 0x34, // USAGE (RY)
- 0x15, 0x81, // LOGICAL_MINIMUM (-127)
- 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x04, // REPORT_COUNT (4)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0xc0, // END_COLLECTION
-
- 0x09, 0x36, // USAGE (Silder)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
-
- 0x09, 0x39, // USAGE (Hat switch)
- 0x15, 0x01, // LOGICAL_MINIMUM (1)
- 0x25, 0x08, // LOGICAL_MAXIMUM (8)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x81, 0x42, // INPUT (Data,Var,Abs,Null)
-
- 0x05, 0x09, // USAGE_PAGE (Button)
- 0x19, 0x01, // USAGE_MINIMUM (Button 1)
- 0x29, 0x10, // USAGE_MAXIMUM (Button 16)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x10, // REPORT_COUNT (16)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
-
- 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined Page 1)
- 0x09, 0x01, // USAGE (Vendor Usage 1)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x04, // REPORT_COUNT (4)
- 0x91, 0x02, // OUTPUT (Data,Var,Abs)
-
- 0xc0 // END_COLLECTION
- };
下面是USB端点的初始化,这个初始化是在USB复位中处理的
- void HidMouse_Reset(void)
- {
- uint8_t i;
- s_usbConfigStatus = 0; //usb not config,disable send data
-
- USBD_SetBufferTable(USB_BUFFER_TABLE_ADDR);
- //endpoint 0 init
- USBD_ResetEPKind(USBD_EP_0);
-
- USBD_SetEPType(USBD_EP_0, USBD_EP_TYPE_CONTROL);
- USBD_SetEPTxStatus(USBD_EP_0, USBD_EP_STATUS_STALL);
- USBD_SetEPTxAddr(USBD_EP_0, USB_EP0_TX_ADDR);
-
- USBD_SetEPRxStatus(USBD_EP_0, USBD_EP_STATUS_VALID);
- USBD_SetEPRxAddr(USBD_EP_0, USB_EP0_RX_ADDR);
- USBD_SetEPRxCnt(USBD_EP_0, USB_EP_PACKET_SIZE);
- //endpoint 1 init
- USBD_SetEPType(USBD_EP_1, USBD_EP_TYPE_INTERRUPT);
- USBD_SetEPTxAddr(USBD_EP_1, USB_EP1_TX_ADDR);
- USBD_SetEPTxCnt(USBD_EP_1, 0x8);
-
- USBD_SetEPRxAddr(USBD_EP_1, USB_EP1_RX_ADDR);
- USBD_SetEPRxCnt(USBD_EP_1, 0x4);
- USBD_SetEPRxTxStatus(USBD_EP_1, USBD_EP_STATUS_NAK, USBD_EP_STATUS_VALID);
-
- //endpoint addr
- for(i = 0; i < USB_EP_NUM; i++)
- {
- USBD_SetEpAddr((USBD_EP_T)i, i);
- }
-
- USBD_SetDeviceAddr(0);
- USBD_Enable();
- }
USB的输出端点处理
- void HidMouse_EPHandler(uint8_t ep, uint8_t dir)
- {
- if(dir == 0) //out endpoint
- {
- switch(ep)
- {
- case USBD_EP_0:
- break;
- case USBD_EP_1:
- USBD_ReadDataFromEP(USBD_EP_1,s_usb_recv_buff,4);
- USBD_SetEPRxStatus(USBD_EP_1, USBD_EP_STATUS_VALID); //recv data valid
- //recv data process
- if(s_usb_recv_buff[0]&0x01)
- {
- GPIO_ResetBits(GPIOE,GPIO_PIN_5);
- }else
- {
- GPIO_SetBits(GPIOE,GPIO_PIN_5);
- }
-
- if(s_usb_recv_buff[1]&0x01)
- {
- GPIO_ResetBits(GPIOE,GPIO_PIN_6);
- }else
- {
- GPIO_SetBits(GPIOE,GPIO_PIN_6);
- }
-
- break;
- case USBD_EP_2:
- break;
- case USBD_EP_3:
- break;
- case USBD_EP_4:
- break;
- case USBD_EP_5:
- break;
- case USBD_EP_6:
- break;
- case USBD_EP_7:
- break;
- }
- }else
- {
- //in endpoint
- switch(ep)
- {
- case USBD_EP_0:
- break;
- case USBD_EP_1:
- s_statusEP = 1; //endpoint1 can send data
- break;
- case USBD_EP_2:
- break;
- case USBD_EP_3:
- break;
- case USBD_EP_4:
- break;
- case USBD_EP_5:
- break;
- case USBD_EP_6:
- break;
- case USBD_EP_7:
- break;
- }
- }
- }
USB的输入报告处理
- void HidMouse_Write(uint8_t key)
- {
- static int8_t x = 0;
- static int8_t y = 0;
- uint8_t buffer[8] = {0, 0, 0, 0};
-
- switch (key)
- {
- case HID_MOUSE_KEY_LEFT:
- x -= 10;
- buffer[5] = 3;
- buffer[6] = 0x01;
- break;
-
- case HID_MOUSE_KEY_RIGHT:
- x += 10;
- buffer[5] = 7;
- buffer[6] = 0x02;
- break;
-
- case HID_MOUSE_KEY_UP:
- y -= 10;
- break;
-
- case HID_MOUSE_KEY_DOWN:
- y += 10;
- break;
-
- default:
- return;
- }
- buffer[0] = x;
- buffer[1] = y;
- s_statusEP = 0; //send over flag
-
- USBD_WriteDataToEP(USBD_EP_1, buffer, sizeof(buffer)); //write data to buffer
- USBD_SetEPTxStatus(USBD_EP_1, USBD_EP_STATUS_VALID); //send data valid
- }
主要修改以上内容,中间经过多次调试,最终成功枚举到USB手柄设备,并且输入输出数据正常。
下面是识别的USB手柄。用了 板上的2个按键模拟数据。
下面输出数据,调试可以看到接收数据。
在调试的过程中也发现了一些问题。
首先USB那个1.5k电阻上拉是跳线帽控制的,这个很不方便,每次还要手动拔插一下。
再就是用户手册文档USB那块发现一些明显错误,明显是从其他那抄来的,都不检查一下。开始看得奇奇怪怪的。
程序下面: