cancel
Showing results for 
Search instead for 
Did you mean: 

Combined HID Descriptor Mouse and Keyboard doesn't work

duesentrieb
Associate II

Hello everyone,

I'm currently trying to emulate both a keyboard and the mouse as hid-devices using stm32 and the descriptor that contains two collections.

The descriptor:

 

 

// Keyboard
0x05, 0x01,                   
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
// Mouse
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

 

 

 Using only the keyboard or mouse-part of the descriptor, everything works. But if the descriptor is applied as above, neither the mouse or the keyboard emulation are working. I'm using the custom hid class generated by STM32CubeIDE. When debugging the USBD_CUSTOM_HID_SendReport function, pdev->dev_state equals USBD_STATE_CONFIGURED if only keyboard or mouse descriptor applied, or USBD_STATE_SUSPENDED if the combined one from above is applied. Also, the operating system (Windows 11) accepts and configures the devices properly, no issues with the descriptor reported. Maybe someone experienced the same issue and can help me out?

 

Best regards

1 ACCEPTED SOLUTION

Accepted Solutions

Issue fixed by setting the HID_EPIN_SIZE in the file usbd_hid.c correctly.

View solution in original post

3 REPLIES 3
Pavel A.
Evangelist III

 the operating system (Windows 11) accepts and configures the devices properly, no issues with the descriptor reported. 

So the problem is not in the descriptor, it is in other area of the firmware (likely in the code).

 

 

Ok, so I switched back to the example HID-device from STM32CubeIDE, but the mouse still doesn't work.

The codebase itself is rather small, the main function (using the mouse, doesn't work):

 

 

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USB_DEVICE_Init();
  struct keyboard_report_t
  {
  	uint8_t report_id;
  	uint8_t modifier;
  	uint8_t reserved;
  	uint8_t keycode[6];
  };
  struct mouse_report_t
  {
  	uint8_t report_id;
  	uint8_t buttons;
  	int8_t x;
  	int8_t y;
  };
  struct keyboard_report_t keyboard;
  struct mouse_report_t mouse;
  while (1)
  {
	  mouse.report_id = 0x02;
	  mouse.buttons = 0b00000000;
	  mouse.x = -10;
	  mouse.y = 10;
	  size_t res = USBD_HID_SendReport(&hUsbDeviceFS,&mouse,sizeof(mouse));
	  HAL_Delay(50);

	    // transmit part start (logs via uart console)
		uint8_t message[35] = {'\0'};
		switch(res){
			case USBD_STATE_DEFAULT:
				  sprintf(message, "USBD_STATE_DEFAULT\r\n");
				  break;
			case USBD_STATE_ADDRESSED:
				sprintf(message, "USBD_STATE_ADDRESSED\r\n");
				break;
			case USBD_STATE_CONFIGURED:
				sprintf(message, "USBD_STATE_CONFIGURED\r\n");
				break;
			case USBD_STATE_SUSPENDED:
				sprintf(message, "USBD_STATE_SUSPENDED\r\n");
				break;
			default:
				sprintf(message, "Nothing found: %d\r\n", res);
		}

	    HAL_UART_Transmit(&huart1, message, sizeof(message), 100);
	    // transmit part end
  }
}

  

 

 

And simulating a keyboard (works):

 

 

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USB_DEVICE_Init();
  struct keyboard_report_t
  {
  	uint8_t report_id;
  	uint8_t modifier;
  	uint8_t reserved;
  	uint8_t keycode[6];
  };
  struct mouse_report_t
  {
  	uint8_t report_id;
  	uint8_t buttons;
  	int8_t x;
  	int8_t y;
  };
  struct keyboard_report_t keyboard;
  struct mouse_report_t mouse;
  while (1)
  {
	  keyboard.report_id = 0x01;
	  keyboard.modifier = 0x00;
	  keyboard.reserved = 0x00;
	  keyboard.keycode[0] = 0x05;
	  keyboard.keycode[1] = 0x00;
	  keyboard.keycode[2] = 0x00;
	  keyboard.keycode[3] = 0x00;
	  keyboard.keycode[4] = 0x00;
	  keyboard.keycode[5] = 0x00;
	  size_t res = USBD_HID_SendReport(&hUsbDeviceFS,&keyboard,sizeof(keyboard));
	  HAL_Delay(50);
	    // transmit part start
		uint8_t message[35] = {'\0'};
		#define USBD_STATE_DEFAULT                              0x01U
		#define USBD_STATE_ADDRESSED                            0x02U
		#define USBD_STATE_CONFIGURED                           0x03U
		#define USBD_STATE_SUSPENDED                            0x04U
		switch(res){
			case USBD_STATE_DEFAULT:
				  sprintf(message, "USBD_STATE_DEFAULT\r\n");
				  break;
			case USBD_STATE_ADDRESSED:
				sprintf(message, "USBD_STATE_ADDRESSED\r\n");
				break;
			case USBD_STATE_CONFIGURED:
				sprintf(message, "USBD_STATE_CONFIGURED\r\n");
				break;
			case USBD_STATE_SUSPENDED:
				sprintf(message, "USBD_STATE_SUSPENDED\r\n");
				break;
			default:
				sprintf(message, "Nothing found: %d\r\n", res);
		}
	    HAL_UART_Transmit(&huart1, message, sizeof(message), 100);
	    // transmit part end
	    keyboard.keycode[0] = 0x00;
	    res = USBD_HID_SendReport(&hUsbDeviceFS,&keyboard,sizeof(keyboard));
	    HAL_Delay(50);
  }
}

 

 

The descriptor including and its length are written into usbd_custom_hid.c. Rest of the code is the generated one from STM32CubeIDE. When using the mouse-code from above, no interaction:

duesentrieb_0-1717706204400.png

- Descriptor with both keyboard ANDmouse: only keyboard example works

- Descriptor with mouse OR keyboard: the specified device works

I've also attached the project's code as a 7z-file.

Screenshot 2024-06-06 232416.png

Screenshot 2024-06-06 232631.png

  

Issue fixed by setting the HID_EPIN_SIZE in the file usbd_hid.c correctly.