【STM32】USB HID Keyboard + Mouse

前言

本篇要接續上一篇【STM32】USB HID Mouse,把HID descripotr改為keyboard + mouse



1. HID Descriptor

這裡的都是從HID Descriptor Tool的keybrd.hid 加上 mouse.hid,因為是兩個裝置所以有2個endpoint

descriptor要分別加上REPORT_ID (1)和REPORT_ID (2)

usbd_hid.c

修改HID_MOUSE_ReportDesc[]


0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
0x09, 0x06,                    // USAGE (Keyboard)
0xa1, 0x01,                    // COLLECTION (Application)
0x85, 0x01,                    //   REPORT_ID (1)
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, 0x65,                    //   LOGICAL_MAXIMUM (101)
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)
0xc0,                           // END_COLLECTION

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)
0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
0x75, 0x08,                    //     REPORT_SIZE (8)
0x95, 0x02,                    //     REPORT_COUNT (2)
0x81, 0x06,                    //     INPUT (Data,Var,Rel)
0xc0,                          //   END_COLLECTION
0xc0                           // END_COLLECTION

usbd_hid.h

HID_MOUSE_REPORT_DESC_SIZE 長度修改為117 bytes


#define HID_MOUSE_REPORT_DESC_SIZE    117U

usbd_hid.c

修改HID_MOUSE_ReportDesc[],最後再加一個endpoint descriptor

byte 27~34是本來存在的,wMaxPacketSize的HID_EPIN_SIZE看是要改成10,或者直接寫上10

byte 34~41再加上另一個endpoint


  /******************** Descriptor of Mouse endpoint ********************/
  /* 27 */
  0x07,          /*bLength: Endpoint Descriptor size*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/

  HID_EPIN_ADDR,     /*bEndpointAddress: Endpoint Address (IN)*/
  0x03,          /*bmAttributes: Interrupt endpoint*/
  10,//HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
  0x00,
  HID_FS_BINTERVAL,          /*bInterval: Polling Interval */
  /* 34 */
  /******************** Descriptor of second endpoint ********************/
  0x07,         /*bLength: Endpoint Descriptor size*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
  0x01,			/*bEndpointAddress: Endpoint Address (OUT)*/
  0x03,         /*bmAttributes: Interrupt endpoint*/
  1,//HID_EPIN_SIZE,
  0x00,
  HID_FS_BINTERVAL,          /*bInterval: Polling Interval */
  /* 41 */
};

usbd_hid.h

USB_HID_CONFIG_DESC_SIZ長度改為41


#define USB_HID_CONFIG_DESC_SIZ       41U


main.c

應用程式在按下User button(PA0)時輸入'a',依次遞增,並且按下滑鼠右鍵

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usbd_hid.h"
/* USER CODE END Includes */

while (1)
{
   /* USER CODE BEGIN 3 */
  extern USBD_HandleTypeDef hUsbDeviceFS;
  static uint8_t key = 0x04;//'a'
  uint8_t KeyBoard[9] = {1,0,0,key,0,0,0,0,0};
  int8_t Mouse[4] = {2,0,0,0};

  if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 1)
  {
	  KeyBoard[3] = key++;
	  USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard,sizeof(KeyBoard));
	  HAL_Delay(15);

	  KeyBoard[3] = 0;
	  USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard,sizeof(KeyBoard));
	  HAL_Delay(15);

	  // Mouse-Right key
	  Mouse[1] = 0x02;
	  USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&Mouse, 4);
	  HAL_Delay(15);

	  Mouse[1] = 0x00;
	  USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&Mouse, 4);
	  HAL_Delay(300);
  }
}