- __ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
- {
-
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x04, // USAGE (Joystick)
- 0xa1, 0x01, // COLLECTION (Application)
- 0xa1, 0x02, // COLLECTION (Logical)
- 0x09, 0x30, // USAGE (X)
- 0x09, 0x31, // USAGE (Y)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
- 0x35, 0x00, // PHYSICAL_MINIMUM (0)
- 0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x02, // REPORT_COUNT (2)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x05, 0x09, // USAGE_PAGE (Button)
- 0x19, 0x01, // USAGE_MINIMUM (Button 1)
- 0x29, 0x08, // USAGE_MAXIMUM (Button 8)
- 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)
- 0xc0, // END_COLLECTION
- 0xc0 // END_COLLECTION
-
- };
- /* USER CODE BEGIN PRIVATE_VARIABLES */
- __ALIGN_BEGIN static uint8_t Mouse_ReportDesc_FS[USBD_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
- {
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x02, // USAGE (Mouse)
- 0xa1, 0x01, // COLLECTION (Application)
- 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
- };
- __ALIGN_BEGIN static uint8_t KEY_ReportDesc_FS[USBD_KEY_REPORT_DESC_SIZE] __ALIGN_END =
- {
- /* USER CODE BEGIN 0 */
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x06, // USAGE (Keyboard)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)
- 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
- 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x08, // REPORT_COUNT (8)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x81, 0x03, // INPUT (Cnst,Var,Abs)
- 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)
- 0x91, 0x03, // OUTPUT (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)
- 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
- 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
- 0x81, 0x00, // INPUT (Data,Ary,Abs)
- /* USER CODE END 0 */
- 0xC0 /* END_COLLECTION */
- };
- typedef struct _USBD_CUSTOM_HID_Itf
- {
- uint8_t *jReport;
- uint8_t *mReport;
- uint8_t *kReport;
- int8_t (* Init)(void);
- int8_t (* DeInit)(void);
- int8_t (* OutEvent)(uint8_t event_idx, uint8_t state);
- } USBD_CUSTOM_HID_ItfTypeDef;
- USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops_FS =
- {
- CUSTOM_HID_ReportDesc_FS,
- Mouse_ReportDesc_FS,
- KEY_ReportDesc_FS,
- CUSTOM_HID_Init_FS,
- CUSTOM_HID_DeInit_FS,
- CUSTOM_HID_OutEvent_FS
- };
- __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
- {
- 0x09, /* bLength: Configuration Descriptor size */
- USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
- USB_CUSTOM_HID_CONFIG_DESC_SIZ,
- /* wTotalLength: Bytes returned */
- 0x00,
- 0x03, /*bNumInterfaces: 1 interface*/
- 0x01, /*bConfigurationValue: Configuration value*/
- 0x00, /*iConfiguration: Index of string descriptor describing the configuration*/
- 0x80, /*bmAttributes: bus powered */
- 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
- //----------- Descriptor of Joystick interface ---------------------//
- /* 09 */
- 0x09, /*bLength: Interface Descriptor size*/
- USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
- 0x00, /*bInterfaceNumber: Number of Interface*/
- 0x00, /*bAlternateSetting: Alternate setting*/
- 0x01, /*bNumEndpoints*/
- 0x03, /*bInterfaceClass: CUSTOM_HID*/
- 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
- 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
- 0, /*iInterface: Index of string descriptor*/
- //-----------HID Descriptor of Joystick ---------------------//
- /* 18 */
- 0x09, /*bLength: CUSTOM_HID Descriptor size*/
- CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
- 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
- 0x01,
- 0x00, /*bCountryCode: Hardware target country*/
- 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
- 0x22, /*bDescriptorType*/
- USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
- 0x00,
- //----------- Descriptor of Joystick endpoints ---------------------//
- /* 27 */
- 0x07, /*bLength: Endpoint Descriptor size*/
- USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
- CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
- 0x03, /*bmAttributes: Interrupt endpoint*/
- CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */
- 0x00,
- CUSTOM_HID_FS_BINTERVAL, /*bInterval: Polling Interval */
- /* 34 */
- //----------- Descriptor of Mouse interface ---------------------//
- 0x09, /*bLength: Interface Descriptor size*/
- USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
- 0x01, /*bInterfaceNumber: Number of Interface*/
- 0x00, /*bAlternateSetting: Alternate setting*/
- 0x01, /*bNumEndpoints*/
- 0x03, /*bInterfaceClass: CUSTOM_HID*/
- 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
- 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
- 0, /*iInterface: Index of string descriptor*/
- //----------- Descriptor of Mouse CUSTOM_HID ---------------------//
- /* 43 */
- 0x09, /*bLength: CUSTOM_HID Descriptor size*/
- CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
- 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
- 0x01,
- 0x00, /*bCountryCode: Hardware target country*/
- 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
- 0x22, /*bDescriptorType*/
- USBD_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
- 0x00,
- //----------- Descriptor of Mouse endpoints ---------------------//
- /* 52 */
- 0x07, /*bLength: Endpoint Descriptor size*/
- USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
- MOUSE_HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
- 0x03, /*bmAttributes: Interrupt endpoint*/
- MOUSE_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */
- 0x00,
- CUSTOM_HID_FS_BINTERVAL, /*bInterval: Polling Interval */
- /* 59 */
- //----------- Descriptor of KeyBoard interface ---------------------//
- 0x09, /*bLength: Interface Descriptor size*/
- USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
- 0x02, /*bInterfaceNumber: Number of Interface*/
- 0x00, /*bAlternateSetting: Alternate setting*/
- 0x01, /*bNumEndpoints*/
- 0x03, /*bInterfaceClass: CUSTOM_HID*/
- 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
- 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
- 0, /*iInterface: Index of string descriptor*/
- //----------- Descriptor of KeyBoard CUSTOM_HID ---------------------//
- /* 68 */
- 0x09, /*bLength: CUSTOM_HID Descriptor size*/
- CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
- 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
- 0x01,
- 0x00, /*bCountryCode: Hardware target country*/
- 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
- 0x22, /*bDescriptorType*/
- USBD_KEY_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
- 0x00,
- //----------- Descriptor of KeyBoard endpoints ---------------------//
- /* 77 */
- 0x07, /*bLength: Endpoint Descriptor size*/
- USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
- KEY_HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
- 0x03, /*bmAttributes: Interrupt endpoint*/
- KEY_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */
- 0x00,
- CUSTOM_HID_FS_BINTERVAL, /*bInterval: Polling Interval */
- /* 84 */
- };
- #define USBD_MAX_NUM_INTERFACES 3
- static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
- USBD_SetupReqTypedef *req)
- {
- USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
- uint16_t len = 0U;
- uint8_t *pbuf = NULL;
- uint16_t status_info = 0U;
- uint8_t ret = USBD_OK;
- switch (req->bmRequest & USB_REQ_TYPE_MASK)
- {
- case USB_REQ_TYPE_STANDARD:
- switch (req->bRequest)
- {
- case USB_REQ_GET_DESCRIPTOR:
- if (req->wValue >> 8 == CUSTOM_HID_REPORT_DESC)
- {
- if (req->wIndex == 0)
- {
- len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength);
- pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->jReport;
- }else if (req->wIndex == 1){//mouse
- len = MIN(USBD_MOUSE_REPORT_DESC_SIZE, req->wLength);
- pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->mReport;
-
- }else if (req->wIndex == 2){//
- len = MIN(USBD_KEY_REPORT_DESC_SIZE, req->wLength);
- pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->kReport;
- }
- }
- else
- {
- if (req->wValue >> 8 == CUSTOM_HID_DESCRIPTOR_TYPE)
- {
- pbuf = USBD_CUSTOM_HID_Desc;
- len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength);
- }
- }
- USBD_CtlSendData(pdev, pbuf, len);
- break;
- }
- return ret;
- }
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x40);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x80);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CUSTOM_HID_EPIN_ADDR , PCD_SNG_BUF, 0xC0);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CUSTOM_HID_EPOUT_ADDR , PCD_SNG_BUF, 0x100);
-
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , MOUSE_HID_EPIN_ADDR , PCD_SNG_BUF, 0x140);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , KEY_HID_EPIN_ADDR , PCD_SNG_BUF, 0x180);
- static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev,uint8_t cfgidx)
- {
- uint8_t ret = 0U;
- USBD_CUSTOM_HID_HandleTypeDef *hhid;
- /* Open EP IN */
- USBD_LL_OpenEP(pdev, CUSTOM_HID_EPIN_ADDR, USBD_EP_TYPE_INTR,CUSTOM_HID_EPIN_SIZE);
- pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 1U;
- /* Open EP OUT */
- USBD_LL_OpenEP(pdev, CUSTOM_HID_EPOUT_ADDR, USBD_EP_TYPE_INTR,CUSTOM_HID_EPOUT_SIZE);
- pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 1U;
- /* Open MOUSE EP IN */
- USBD_LL_OpenEP(pdev, MOUSE_HID_EPIN_ADDR, USBD_EP_TYPE_INTR,MOUSE_HID_EPIN_SIZE);
- pdev->ep_in[MOUSE_HID_EPIN_ADDR & 0xFU].is_used = 1U;
- /* Open KEY EP IN */
- USBD_LL_OpenEP(pdev, KEY_HID_EPIN_ADDR, USBD_EP_TYPE_INTR,KEY_HID_EPIN_SIZE);
- pdev->ep_in[KEY_HID_EPIN_ADDR & 0xFU].is_used = 1U;
- pdev->pClassData = USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef));
- if (pdev->pClassData == NULL)
- {
- ret = 1U;
- }
- else
- {
- hhid = (USBD_CUSTOM_HID_HandleTypeDef *) pdev->pClassData;
- hhid->state = CUSTOM_HID_IDLE;
- ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init();
- /* Prepare Out endpoint to receive 1st packet */
- USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
- USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
- }
- return ret;
- }
- static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev,
- uint8_t cfgidx)
- {
- /* Close CUSTOM_HID EP IN */
- USBD_LL_CloseEP(pdev, CUSTOM_HID_EPIN_ADDR);
- pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 0U;
- /* Close CUSTOM_HID EP OUT */
- USBD_LL_CloseEP(pdev, CUSTOM_HID_EPOUT_ADDR);
- pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 0U;
- /* Close MOUSE_HID EP IN */
- USBD_LL_CloseEP(pdev, MOUSE_HID_EPIN_ADDR);
- pdev->ep_in[MOUSE_HID_EPIN_ADDR & 0xFU].is_used = 0U;
-
- /* Close JOYSTICK_HID EP IN */
- USBD_LL_CloseEP(pdev, KEY_HID_EPIN_ADDR);
- pdev->ep_in[KEY_HID_EPIN_ADDR & 0xFU].is_used = 0U;
- /* FRee allocated memory */
- if (pdev->pClassData != NULL)
- {
- ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->DeInit();
- USBD_free(pdev->pClassData);
- pdev->pClassData = NULL;
- }
- return USBD_OK;
- }
至此,插上USB已经可以枚举成三个组合的HID了。但是也仅仅是万丈高楼平地起,只是打了了基础,只是配置好了usb,仅仅是实现了usb功能,我们的应用功能还需要安排上。
- MultiTimer timer1;
- MultiTimer timer2;
- MultiTimer timer3;
- void SystemClock_Config(void);
- typedef enum
- {
- DEVICE_JOYSTICK=0,
- DEVICE_MOUSE,
- DEVICE_KEYBOARD
- }DEVICE_TypeDef;
- DEVICE_TypeDef myHid=DEVICE_JOYSTICK;
- void RportTimer1Callback(MultiTimer* timer, void *userData)
- {
- if(myHid==DEVICE_JOYSTICK)
- {
- Joystick_Handle();
- }else if(myHid==DEVICE_MOUSE){
- Mouse_Handle();
- }else if(myHid==DEVICE_KEYBOARD){
- Key_Board_Handle();
- }
- MultiTimerStart(timer, 10, RportTimer1Callback, userData);
- }
- void WS2812BTimer2Callback(MultiTimer* timer, void *userData)
- {
- if(myHid==DEVICE_JOYSTICK)
- {
- WS_WriteAll_RGB(0xFF,0x00,0x00);
- }else if(myHid==DEVICE_MOUSE){
- WS_WriteAll_RGB(0x00,0xFF,0x00);
- }else if(myHid==DEVICE_KEYBOARD){
- WS_WriteAll_RGB(0x00,0x00,0xFF);
- }
- MultiTimerStart(timer, 100, WS2812BTimer2Callback, userData);
- }
- void DeviceSwitchTimer3Callback(MultiTimer* timer, void *userData)
- {
- static u16 swtick=0;
- if((UPKEY)==0)
- {
- if(swtick++>300)
- {
- swtick=0;
- if(++myHid>DEVICE_KEYBOARD)
- {
- myHid=DEVICE_JOYSTICK;
- }
- }
- }else{
- swtick=0;
- }
- MultiTimerStart(timer, 10, DeviceSwitchTimer3Callback, userData);
- }
- int main(void)
- {
- HAL_Init();
- SystemClock_Config();
- MultiTimerInstall(PlatformTicksGetFunc);
- MX_GPIO_Init();
- MX_DMA_Init();
- MX_ADC1_Init();
- MX_USB_DEVICE_Init();
- MX_USART1_UART_Init();
- MX_TIM3_Init();
- Gp_ADC_Start_DMA();
- MultiTimerStart(&timer1, 5, RportTimer1Callback, NULL);
- MultiTimerStart(&timer2, 10, WS2812BTimer2Callback, NULL);
- MultiTimerStart(&timer3, 10, DeviceSwitchTimer3Callback, NULL);
- while (1)
- {
- MultiTimerYield();
- }
- }
下载验证我们把固件程序下载进去,摇动摇杆,按住SW2大于4s,可依次切换成鼠标模式成摇杆、鼠标、键盘模式,2812显示对应的红绿蓝色。在不同设备模式下摇动摇杆或轻触按键可以测试不同设备下的不同功能,而由于我们硬件条件有限,所以使用了分时复用,而如果您是自己设计了其他硬件,完全可以在我们的基础上修改,加加加,实现自己客制化的功能,毕竟现在网上有很多客制化键盘鼠标摇杆方案。具体的实现现象可以观看我们的视频;
视频教程