I need to write 2HIds in one composite device in STM32 microcontrollers.One for pointer mouse operation and other one for keypad operation.So i wish to know is it possible to do so?If yes will I need to write 2 separate report descriptors.I am using 2 interfaces and 2 ENDPOINTS (enp1 and enp2). Please help...
Two HID "device" on single USB device
There are two ways, a) Multi-TLCs (Top-Level Collections) on single HID b) HID + HID interfaces on composite device
a) is easier than b), when you have base code of both.
In Multi-TLCs method, the major modification is applied just to the report descriptor.
a-1) Report descriptor When you start with keyboard example, - Insert "REPORT ID (1)" before the keyboard report descriptor - Append "REPORT ID (2)" after the keyboard report descriptor - Append mouse report descriptor, as is
Report descriptor - REPORT ID (1) 0x85, 0x01 - - full-contents of keyboard report descriptor - REPORT ID (2) 0x85, 0x02 - - full-contents of mouse report descriptor
Of course, the size of report descriptor increases by the appendage. Tune the constant (#define) of the report descriptor size, referred at HID interface, and Get_Descriptor( HID_REPORT ) process.
a-2) Report ID As the one-byte report ID is attached before each input/output report,
- wMaxPacketSize field of the interrupt IN/OUT endpoint descriptors should be tuned to fit to this report size. Usually, "standard" keyboard puts 8 bytes input report (1 modifier, 1 constant, 6 key index array), at least 9 bytes (+1 byte report ID) is required.
/******************** Descriptor of Joystick Mouse endpoint ********************/ /* 27 */ 0x07, /*bLength: Endpoint Descriptor size*/ USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/ 0x81, /*bEndpointAddress: Endpoint Address (IN)*/ 0x03, /*bmAttributes: Interrupt endpoint*/ 0x04, /*wMaxPacketSize: 4 Byte max */ // <------ 9 bytes 0x00, 0x20, /*bInterval: Polling Interval (32 ms)*/ // <---- 1ms is better
The interrupt IN endpoint is shared by keyboard and mouse. The keyboard code puts an input report with one-byte report ID (1). - 1 (report ID), keyboard input report follows.
The mouse code puts an input report with one-byte report ID (2). - 2 (report ID), mouse input report follows.
That's all
Tsuneo
Hi Tsuneo ,
Your idea of Multi-TLCs seems good but actually I already proceeded with 2 HID composite device and now I am stuck in need for multiple Report descriptors.So I will switch to Multi-TLC
I have small doubts in the descriptors:
1. In Multi-TLCs as Rport-ID comes to picture Modifier-type ( INPUT(DATA,VARIABLE,ABSOLUTE) ) so do i need to change INPUT (0x81)
2. Mine is a custom Keypad with 30 buttons but still i will be sending 9 bytes ???
3. My mouse sends 4 bytes from ENDP1 so as ReportID comes to picture will this increment to 5 bytes ???
4. My keypad is custom one so i am using both ENDP1 and ENDP2 in my HID for keypad. So my interface will be 1 and endpoints 2 . Am I correct ???
Regards, Dhanush
"2. Mine is a custom Keypad with 30 buttons but still i will be sending 9 bytes ???"
The total number of keys on the keyboard doesn't matter. The standard 8-byte message have 6 bytes to report which buttons are concurrently pressed.
> 1. In Multi-TLCs as Rport-ID comes to picture Modifier-type ( INPUT(DATA,VARIABLE,ABSOLUTE) ) so do i need to change INPUT (0x81)
Report ID is applied when the report descriptor defines two or more Input (or Output or Feature) reports, to identify each report. Report ID doesn't have any other side effect. You may bind keyboard and mouse report descriptors without any change.
> 2. Mine is a custom Keypad with 30 buttons but still i will be sending 9 bytes ???
As Per said, yes.
> 3. My mouse sends 4 bytes from ENDP1 so as ReportID comes to picture will this increment to 5 bytes ???
One-byte of Report ID (2) preceeds your original mouse input report, to distiguish it from the keyboard input report (report ID 1).
> 4. My keypad is custom one so i am using both ENDP1 and ENDP2 in my HID for keypad. So my interface will be 1 and endpoints 2 . Am I correct ???
HID device should have single interrupt IN endpoint. If your "custom" keyboard would really need two IN EPs, you may append another keyboard report descriptor (TLC) for the second keyboard, and assign report ID 3 to it.
But I believe, even for "custom" keyboard, two keyboards aren't required. For example of full-keybaord, all keytops of alphabet, tenkeys, function keys are supported by single TLC.
Anyway, tell the details of your customization.
I tried doing as you said , I wrote report id (1) , then copied Mouse HID and Report id(2) ,then copied keyboard HID and changed descriptor size accordingly . Thats it . However this time my PC is not detecting the new HID, It shows an exclamation mark along side and noew i am stuck .Is there anything else to do . Can you once again explain in detail how to sending both mouse and keyboard data through the same interface and same endpoint . Because I didnt understand the idea.How OS understands that which is report id and which is data.
The actual mouse data sends 4 bytes ,So now iam sending 5 bytes i.e reportid + 4byte mouse data It seems that I am doing something wrong somewhere.. ;)
Dhanush
Can you also explain me how to proceed with 2HID report descriptor composite device ??
> Can you also explain me how to proceed with 2HID report descriptor composite device ??
The implementation of composite device heavily depends on the USB stack on which you are working. Not just the descriptors, you have to modify - Get_Descriptor( HID_Report ) process - Enabling additional EP(s) etc.
Which one are you playing? - Keil RL-USB - ST's STSW-STM32046 - STM32_USB-Host-Device_Lib_V2.1.0 - ST's STSW-STM32121 - STM32_USB-FS-Device_Lib_V4.0.0 etc.
I am using STM32F103R8 and making it work as keypad-controller *** pointing device.
It was working for both individually however together they always fail.
> I am using STM32F103R8
And what is the USB library?