USB Host Mouse Driver

Status
Not open for further replies.
USBHS_USBCMD &= ~ ( USBHS_USBCMD_ASE); did it :) VGA OK now, Keyboard still works. Some very minor glitches.
 
@Paul and others - Do you want all USB Host stuff mentioned (At least summarized here) or should each area be split into other threads... Like Keyboard support?

Yesterday started playing with some keyboard stuff. As there were issues about being able to turn on LEDS on the keyboard. I have a version now that has this at least working in the test app (you can go to debug terminal and enter a key 0-9 and it will use that to turn on the different LEDS...

Today I updated the convert_to_unicode function to notice that the CTRL modifier was on and modify the return value by & 0x1f.

For this conversation, I am mainly talking about US keyboard, which would apply to most and for others probably even more things to handle...

Currently I know the handling of the keyboard is pretty limited.... More or less handles very generic keys. And for example does not handle keys like: Enter, Esc, let alone function keys... There is also simple issues like some keys map wrong as their OEM key is at least 0x40 and the code is setup to use the 0x40 bit as SHIFT key...

So wondering how we think some of this should work?

Currently a-z 0-9 / , [( like keys also with shift appear to work.
Shift(2)/Right Shift(20) Ctr(1)l/ALT(4)/Right Alt(40), Windows(8), Right Windows(80) - Modifiers come out in the Mods field - Our conversion is not checking/handling ALT key or Windows Key

Tab, Enter, Esc, BS - These have Ansi conversions we are not handling... (return 0 in conversion) Would like to add. Question is where? Should they be added to the keycodes_ascii table in core3? Or should we build special exception table that if not found in the first table check for them?

Keys that are modal, that effect translations like: Shift lock(0x39) and NumLock(0x53) - These translate to 0...
But should we instead, detect these, and have our keyboard code, keep a toggle state for these and set the LEDS.... Then if for example our Shift lock key is on it should effect the translations and likewise for NUMPAD (more later)

Arrow keys/Function keys/Home/End... - How should we translate? Should these call the users keypress function? Or should we have different function for these? Or should set high byte to something?

Keypad keys: Again should detect if numlock is on and translate to the numbers and if off to the arrows...

Beyond what I wish to do: should we handle: ALT+<1><3><4> to give us å Again don't which tables would control this... My PC keyboard is set to US english...

Probably more...

Question is Should we do some more of the obvious basics? Tab/Enter... Probably shift states, and keypad?
 
Update: Did some of the above.

I have processing of Caps lock/Num Lock/Scroll Lock, that toggle internal variables. I have Query and set functions as well. These also update the LEDS on the Keyboard.

I have the CAPS lock key state being processed. It XOR's the value of the SHIFT for the key, which appears to be working.

Mentioned in previous post CTRL key takes the value and ands by 0x1f

I added translations for ENTER key, TAB key, ESC key - Not sure best value for Enter - currently returning \n... Could be \r or ...

I have some Number keypad support. That is if numlock is on it will return the number values plus the /*+-. values

If numlock is not on, it has translations to convert the CODE to equivalent codes and then continues with translation lookup code.

The lookup code also now bails if the original code passed in has the SHIFT bit set... As these won't map properly.

So far it is at least working on simple DELL keyboard.

I updated my WIP branch if anyone wishes to take a look: https://github.com/KurtE/USBHost_t36/tree/HID-Device-API-Additions
 
Did a slight update to the above and converted the internal variables for LEDS into union/struct with LEDS as bits in the correct order.

Changed the setLEDS to just be LEDS and have it update the objects value as well as the LEDS. So can set all with one call.
Code also defers updates if in middle of New data call. Updated test app (MOUSE) to print out Leds state.

Pushed up changes.

Paul - Created Pull request for all my current stuff - let me know if want this all split up...
 
On Keyboard stuff, wondering if we should maybe model some of this similar to Visual studio in that you have three possible callbacks:

Keydown: All keys - Not sure if we should do some mapping, or simply have: <raw key> <mods>, maybe LED state or they call query if needed. This gets called for all keyboard down events

Keypress: This gets called only for those characters that we translate to Ascii... So not for keys like F1-F12, Home, End, ...

KeyUp: All keys - again gets called for all keys.

I also noticed that in visual studio, the functions are called with Key data and they have a large enum for all keys, so one can do something like:
if (key == Keys::F1) ...
 
@Paul, I am currently checking out a Keyboard that does not work. It is a DELL keyboard that came with one of my earlier PCs. What is interesting is that this keyboard has a built in USB hub. The idea was you could plug your mouse into it... I see Amazon sells keyboards with USB hubs still, so don't know yet if this is unique to this keyboard.

When I plug this keyboard in, the complete buffer passed to claim drivers is:
======== Claim Drivers: 09 04 00 00 01 09 00 00 02 07 05 81 03 01 00 18

The HUB code claims the whole device.
Code:
USB Host Testing
sizeof Device = 40
sizeof Pipe = 96
sizeof Transfer = 64
power up USBHS PHY

ISR: 4004
 Port Change
port change: 10001803
    connect

ISR: 1004088
 Timer0
  begin reset

ISR: 408C
 Port Change
port change: 10001805
  port enabled

ISR: 1004088
 Timer0
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
new_Control_Transfer

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF5420    token=80000200
  Followup 1FFF5360    token=100
  Followup 1FFF53A0    token=8000
enumeration:
new_Control_Transfer
  Followup 1FFF53E0    token=80280
  Followup 1FFF5420    token=80008180

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF53E0    token=80000200
  Followup 1FFF5420    token=8100
enumeration:
new_Control_Transfer
  Followup 1FFF5360    token=80280
  Followup 1FFF3580    token=80120180
  Followup 1FFF53A0    token=80008080

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF5360    token=80000200
  Followup 1FFF3580    token=100
  Followup 1FFF53A0    token=8000
enumeration:
new_Control_Transfer
  Followup 1FFF53E0    token=80280
  Followup 1FFF5420    token=80FC0180
  Followup 1FFF5360    token=80008080

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF53E0    token=80000200
  Followup 1FFF5420    token=F80100
  Followup 1FFF5360    token=8000
enumeration:
new_Control_Transfer
  Followup 1FFF3580    token=80280
  Followup 1FFF53A0    token=80FC0180
  Followup 1FFF53E0    token=80008080

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF3580    token=80000200
  Followup 1FFF53A0    token=80F20100
  Followup 1FFF53E0    token=8000
enumeration:
Manufacturer string: 0A 03 44 00 65 00 6C 00 6C 00 
new_Control_Transfer
  Followup 1FFF5420    token=80280
  Followup 1FFF5360    token=80FC0180
  Followup 1FFF3580    token=80008080

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF5420    token=80000200
  Followup 1FFF5360    token=80D00100
  Followup 1FFF3580    token=8000
enumeration:
Product string: 2C 03 44 00 65 00 6C 00 6C 00 20 00 55 00 53 00 42 00 20 00 4B 00 65 00 79 00 62 00 6F 00 61 00 72 00 64 00 20 00 48 00 75 00 62 00 
new_Control_Transfer
  Followup 1FFF53A0    token=80280
  Followup 1FFF53E0    token=80090180
  Followup 1FFF5420    token=80008080

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF53A0    token=80000200
  Followup 1FFF53E0    token=80000100
  Followup 1FFF5420    token=8000
enumeration:
Config data length = 25
new_Control_Transfer
  Followup 1FFF5360    token=80280
  Followup 1FFF3580    token=80190180
  Followup 1FFF53A0    token=80008080

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF5360    token=80000200
  Followup 1FFF3580    token=80000100
  Followup 1FFF53A0    token=8000
enumeration:
bNumInterfaces = 1
bConfigurationValue = 1
new_Control_Transfer
  Followup 1FFF53E0    token=80280
  Followup 1FFF5360    token=80008180

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF53E0    token=80000200
  Followup 1FFF5360    token=8100
enumeration:

======== Claim Drivers: 09 04 00 00 01 09 00 00 02 07 05 81 03 01 00 18 
USBHub memory usage = 928
USBHub claim_device this=1FFF36C0
  polling interval = 24
7
5
81
1
bDeviceClass = 9
bDeviceSubClass = 0
bDeviceProtocol = 0
new_Control_Transfer
===== Driver claimed whole device1FFF36C0
  Followup 1FFF3580    token=80280
  Followup 1FFF5420    token=80100180
  Followup 1FFF53A0    token=80008080

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF3580    token=80000200
  Followup 1FFF5420    token=80070100
  Followup 1FFF53A0    token=8000
USBHub control callback
09 29 03 0D 00 16 64 02 FF 00 00 00 00 00 00 00 
Hub ports = 3
new_Control_Transfer
new_Control_Transfer
  Followup 1FFF53E0    token=80280
  Followup 1FFF3580    token=80008180
  Followup 1FFF5420    token=80280
  Followup 1FFF3540    token=80008180

ISR: 4E081
 USB Async
Async Followup
  Followup 1FFF53E0    token=80000200
  Followup 1FFF3580    token=8100
USBHub control callback
new_Control_Transfer
  Followup 1FFF5420    token=80000200
  Followup 1FFF3540    token=8100
USBHub control callback
power turned on to all ports
device addr = 1
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 3
, at offset = 0, shift= 0
add_qh_to_periodic_schedule: 1FFF3460
  interval = 16
  offset =   0
    old slot 0: (empty)
  add to slot 0
    new slot 0: 1FFF3460
    old slot 16: (empty)
  add to slot 16
    new slot 16: 1FFF3460
Periodic Schedule:
 0: 1FFF3460
 1: (empty)
 2: (empty)
 3: (empty)
 4: (empty)
 5: (empty)
 6: (empty)
 7: (empty)
 8: (empty)
 9: (empty)
10: (empty)
11: (empty)
12: (empty)
13: (empty)
14: (empty)
15: (empty)
16: 1FFF3460
17: (empty)
18: (empty)
19: (empty)
20: (empty)
21: (empty)
22: (empty)
23: (empty)
24: (empty)
25: (empty)
26: (empty)
27: (empty)
28: (empty)
29: (empty)
30: (empty)
31: (empty)
pipe cap1 = F0010101
new_Data_Transfer
  Followup 1FFF5360    token=80000200
  Followup 1FFF53A0    token=8100
USBHub control callback

ISR: 4C081
 USB Async
Async Followup
It does not see that is also a keyboard. Note: If I plug a mouse one of the USB ports on the keyboard, the mouse works...

Some information from Linux board about this device.
Code:
kurt@kurt-UP-CHT01:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 0424:2530 Standard Microsystems Corp.
Bus 001 Device 004: ID 0bda:8178 Realtek Semiconductor Corp. RTL8192CU 802.11n WLAN Adapter
Bus 001 Device 003: ID 0424:4603 Standard Microsystems Corp.
Bus 001 Device 007: ID 413c:2006 Dell Computer Corp.
Bus 001 Device 006: ID 413c:1004 Dell Computer Corp.
Bus 001 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
kurt@kurt-UP-CHT01:~$ dmesg | tail -40
...
[  138.247918] usb 1-3: new full-speed USB device number 6 using xhci_hcd
[  138.376659] usb 1-3: New USB device found, idVendor=413c, idProduct=1004
[  138.376670] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  138.376677] usb 1-3: Product: Dell USB Keyboard Hub
[  138.376683] usb 1-3: Manufacturer: Dell
[  138.377033] usb 1-3: ep 0x81 - rounding interval to 128 microframes, ep desc says 192 mic                                       roframes
[  138.378697] hub 1-3:1.0: USB hub found
[  138.378816] hub 1-3:1.0: 3 ports detected
[  138.647953] usb 1-3.1: new low-speed USB device number 7 using xhci_hcd
[  138.741740] usb 1-3.1: New USB device found, idVendor=413c, idProduct=2006
[  138.741749] usb 1-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  138.741754] usb 1-3.1: Product: Dell USB Keyboard Hub
[  138.741758] usb 1-3.1: Manufacturer: Dell
[  138.742042] usb 1-3.1: ep 0x81 - rounding interval to 64 microframes, ep desc says 80 mic                                       roframes
[  138.742056] usb 1-3.1: ep 0x82 - rounding interval to 1024 microframes, ep desc says 2040                                        microframes
[  138.783979] usbcore: registered new interface driver usbhid
[  138.783986] usbhid: USB HID core driver
[  138.791371] input: Dell Dell USB Keyboard Hub as /devices/pci0000:00/0000:00:14.0/usb1/1-                                       3/1-3.1/1-3.1:1.0/0003:413C:2006.0001/input/input4
[  138.844965] hid-generic 0003:413C:2006.0001: input,hidraw0: USB HID v1.10 Keyboard [Dell                                        Dell USB Keyboard Hub] on usb-0000:00:14.0-3.1/input0
[  138.846643] input: Dell Dell USB Keyboard Hub as /devices/pci0000:00/0000:00:14.0/usb1/1-                                       3/1-3.1/1-3.1:1.1/0003:413C:2006.0002/input/input5
[  138.900249] hid-generic 0003:413C:2006.0002: input,hidraw1: USB HID v1.10 Device [Dell De                                       ll USB Keyboard Hub] on usb-0000:00:14.0-3.1/input1
kurt@kurt-UP-CHT01:~$
 
Dell seems to have a USB problem... :) Dunno what they do... The USB HUB in my DELL Display is bitchy, too. It takes it ages (>800ms..900ms) to tell the computer there is Teensy connected
 
Hi Kurt; I took your LED Code and merged it to my USB- Fork.
It works great, thank you very much !
But now, I have some work to do.. I have to update much more - there are many changes to USB.wow..
This will take some fiddling and deep thinking.. :) oh man..
 
You are welcome.

As for the Dell and USB hubs.

I am still fiddling around with the Dell keyboard and the HUB code. It is like it know that it has 3 ports, it powers them up, but the port associated with the keyboard does not send a change message saying it is there... Or maybe it tries to send, but before the pipe is created...

Not sure if way to force it to enum or the like... Looking at USB doc, but still mostly Greek to me :D

Also not sure if it matters, but the Port power up messages coming back are in the order: 1, 3, 2. And it creates the pipe when #3 is reported.
 
Also not sure if it matters, but the Port power up messages coming back are in the order: 1, 3, 2. And it creates the pipe when #3 is reported.

Paul - I think this function in HUB is incorrect:
Code:
static uint32_t lowestbit(uint32_t bitmask)
{
	return 31 - __builtin_clz(bitmask);
}
As it is counting leading zeros... I did a quick and dirty test program:
Code:
void setup() {
  while (!Serial) ;
  Serial.begin(115200);
}

void loop() {
  Serial.printf("using clz: %d\n", 31 - __builtin_clz(6));
  Serial.printf("using ctz: %d\n", __builtin_ctz(6));
  delay(5000);
}
Output:
Code:
using clz: 2
using ctz: 1
Will modify - probably long shot to fix the Dell keyboard, but...

Update: Changed function, and order now correct sill does not startup Keyboard...
Wonder the Hub descriptor is marked as a compound device. Not sure what that means in messages.

Descriptor: 09 29 03 0D 00 16 64 02 FF 00 00 00 00 00 00 00

Also in code you mention about handle removeable... Byte=2, so PORT 1 is marked...

Should mention difference in HUB descriptor versus simple HUB I have sitting here:
Code:
09 29 04 E9 00 32 64 00 FF 00 00 00 00 00 00 00 
  Port:0 Mesg: 290006A0
Hub ports = 4
new_Control_Transfer
 
Last edited:
I'm going to manually merge the new keyboard stuff for 1.40. Will look at the clz issue too. Have a family event this afternoon, so planning to do this late tonight or Sunday morning. Hopefully 1.40-beta3 by the end of Sunday.

Planning to save the id numbers & strings for 1.41.
 
attention , there is no single instruction* "CTZ" on Cortex M4 - it might be not as fast as you think.

* i've never seen this...
 
Not sure about either, I had to look up what the __builtin_clz - Found several hits on web like:
https://www.go4expert.com/articles/builtin-gcc-functions-builtinclz-t29238/

I was simply noticing the order of the messages (1 3 2) did not feel correct with the pending messages, so looked at code and saw things like:
Code:
	if (send_pending_poweron) {
		send_poweron(lowestbit(send_pending_poweron));

It worked with changing to ctz... But as you said may not be the fastest way...

Another option would be to change these masks to reverse the bits?
Code:
void USBHub::send_poweron(uint32_t port)
{
	if (port == 0 || port > numports) return;
	if (can_send_control_now()) {
		mk_setup(setup, 0x23, 3, 8, port, 0);
		queue_Control_Transfer(device, &setup, NULL, this);
		send_pending_poweron &= ~(1 << (MAXPORTS - port));
	} else {
		send_pending_poweron |= (1 << (MAXPORTS - port));
	}
}
Would need to figure out the offset from the Ctz value returned...
 
Last edited:
Just did a quick check. The compiler is using 2 single cycle instructions for __builtin_ctz.

Code:
     61c:       fa91 f1a1       rbit    r1, r1
     620:       fab1 f181       clz     r1, r1

Twice the time as clz, but still plenty fast enough!
 
Just did a quick check. The compiler is using 2 single cycle instructions for __builtin_ctz.

Code:
     61c:       fa91 f1a1       rbit    r1, r1
     620:       fab1 f181       clz     r1, r1

Twice the time as clz, but still plenty fast enough!

Especially since you then don't have to do the subtract the results from 31 ;)
 
I just did a little testing. Indeed, the function isn't quite doing what its name suggests. It's returning the lowest bit index, zero based. If no bits are set, it's returning 0xFFFFFFFFF.

However, the control transfer functions are setting the bits in the corresponding way. When port 1 later needs service, bit 0x02 is set. They're also considering any value greater than 7 to mean nothing needs to be done, so 0xFFFFFFFFF is handled correctly. This is confusing. At the very least it probably deserves a comment in the code. Perhaps it should be changed to something more straightforward and easier to understand, but for now I believe the final result is correct for up to 7 port hubs, so I'm going to leave this as-is for now.

Here's a quick test program to check the math:

Code:
void setup() {
  while (!Serial);
  uint8_t mask;
  for (uint32_t i=1; i <= 7; i++) {
    Serial.print(i);
    Serial.print(" -> ");
    uint8_t bitmask = (1 << i);
    Serial.print(bitmask, HEX);
    Serial.print(" -> ");
    uint32_t n = 31 - __builtin_clz((uint32_t)bitmask);
    Serial.println(n);
  }
  Serial.print("mask=0 -> ");
  uint32_t n = 31 - __builtin_clz((uint32_t)0);
  Serial.println(n);
}

void loop() {
}

Here's what it prints.

Code:
1 -> 2 -> 1
2 -> 4 -> 2
3 -> 8 -> 3
4 -> 10 -> 4
5 -> 20 -> 5
6 -> 40 -> 6
7 -> 80 -> 7
mask=0 -> 4294967295
 
Paul, the problem I was running into, which may not be a major problem is the code.
Code:
	  case 0x00080323: // power turned on
		if (port == numports && changepipe == NULL) {
			println("power turned on to all ports");
			println("device addr = ", device->address);
			changepipe = new_Pipe(device, 3, endpoint, 1, 1, interval);
			println("pipe cap1 = ", changepipe->qh.capabilities[0], HEX);
			changepipe->callback_function = callback;
			queue_Data_Transfer(changepipe, &changebits, 1, this);
			// See if this device is in the removable list? 
			for (uint32_t i=1; i <= numports; i++) {
				if (hub_desc[7] & (1 << i)) {
					println("Device Removable: ", i);
					send_enable(i);
				}
			}
		}
So in my case I have 3 ports, so we call: send_enable(1), send_enable(2), send_enable(3).
The 1 case sends out the packet, the 2 and 3 case are the deferred.
So with poweron code we have:
send_pending_poweron |= (1 << port);

So after this loop: send_pending_poweron = (1<<2) | 1 << 3) so 0xc .

From my earlier test program (modified for right values)
Code:
  Serial.printf("using clz: %d\n", 31 - __builtin_clz(0xc));
  Serial.printf("using ctz: %d\n", __builtin_ctz(0xc));
Code:
using clz: 3
using ctz: 2
Again maybe not an issue, it is simply the saved commands will be processed in the reverse port order.
Which in the case above the next code:
Code:
	  case 0x00080323: // power turned on
		if (port == numports && changepipe == NULL) {
			println("power turned on to all ports");
			println("device addr = ", device->address);
			changepipe = new_Pipe(device, 3, endpoint, 1, 1, interval);
Is not correct as we have not yet turned on #2...
 
I've merged the new keyboard code and some of the device status stuff.

I'll do more later, but for now I really need to get 1.40-beta3 up for testing. Especially for Linux, I want to get some feedback on how it's working for non-Ubuntu distros.

Please keep your branch alive on github. I'm going to bring in the device status stuff to the HID parser next. On the strings, I was originally planning something quite different, so need to look at that much more closely. Sadly, the improvements and bug fixes in Teensy Loader took several days longer than I had wanted. :(
 
Understood, glad you were able to get as much in as you did.

As for strings stuff, I was also not sure the best way to do this. You already have code that reads in the strings as part of the initial parse/claim, but did not have anywhere to store the data.
On many systems, I would be tempted to allocate a string and hold it, but I know that many do not like dynamic allocations. Also could allocate space in the device for it, but question is do we use up this memory for something like this, that many apps may not care about and those who do may only want it for a display at some initial time... So went with the call like I added. But as you noticed this is sort of a pain as you have to wait for the USB message to come back.
 
Notes: continue from Beta 3 thread...

Keyboards handle mutlimedia keys and the like:

As for multiple inheritance, I usually try to avoid it like the plague. Usually this ends up needing things like Dynamic casting and all of the run time support.

As for Keyboard. I keep wondering if it should be converted over to using the HID code like the mouse was... As for the media keys, it will be interesting to see how they are implemented. Do they generate events for the Keyboard object or are they another Interface? Obviously not something for this release. Maybe not for awhile as I can imagine this may be lower priority than getting some support in for other USB devices like FTDI. But I may take a quick look out of curiosity.

Took a quick look at a couple of keyboards on Linux at the HID stuff. Example more simple Dell keyboard:

Has two different interfaces:
Code:
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i0 | grep -v : | xxd -r -p | hidrd-convert -o spec
Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Keyboard),                   ; Keyboard (06h, application collection)
Collection (Application),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (KB Leftcontrol), ; Keyboard left control (E0h, dynamic value)
    Usage Maximum (KB Right GUI),   ; Keyboard right GUI (E7h, dynamic value)
    Logical Minimum (0),
    Logical Maximum (1),
    Report Count (8),
    Report Size (1),
    Input (Variable),
    Report Count (8),
    Report Size (1),
    Input (Constant),
    Usage Page (LED),               ; LEDs (08h)
    Usage Minimum (01h),
    Usage Maximum (03h),
    Report Count (3),
    Report Size (1),
    Output (Variable),
    Report Count (1),
    Report Size (5),
    Output (Constant),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (None),           ; No event (00h, selector)
    Usage Maximum (FFh),
    Logical Minimum (0),
    Logical Maximum (255),
    Report Count (6),
    Report Size (8),
    Input,
End Collection
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i1 | grep -v : | xxd -r -p | hidrd-convert -o spec                    Usage Page (Desktop),                   ; Generic desktop controls (01h)
Usage (Sys Control),                    ; System control (80h, application collection)
Collection (Application),
    Report ID (1),
    Usage Page (Desktop),               ; Generic desktop controls (01h)
    Usage Minimum (Sys Power Down),     ; System power down (81h, one-shot control)
    Usage Maximum (Sys Menu Exit),      ; System menu exit (88h, one-shot control)
    Logical Minimum (0),
    Logical Maximum (1),
    Report Count (8),
    Report Size (1),
    Input (Variable),
End Collection,
Usage Page (Consumer),                  ; Consumer (0Ch)
Usage (Consumer Control),               ; Consumer control (01h, application collection)
Collection (Application),
    Report ID (2),
    Logical Minimum (0),
    Logical Maximum (1),
    Usage (AL Consumer Control Config), ; AL consumer control configuration (0183h, selector                   )
    Usage (Play Pause),                 ; Play/pause (CDh, one-shot control)
    Usage (Stop),                       ; Stop (B7h, one-shot control)
    Usage (Volume Inc),                 ; Volume increment (E9h, re-trigger control)
    Usage (Volume Dec),                 ; Volume decrement (EAh, re-trigger control)
    Usage (Mute),                       ; Mute (E2h, on/off control)
    Usage (Scan Previous Track),        ; Scan previous track (B6h, one-shot control)
    Usage (Scan Next Track),            ; Scan next track (B5h, one-shot control)
    Usage (AL Email Reader),            ; AL email reader (018Ah, selector)
    Usage (AL Calculator),              ; AL calculator (0192h, selector)
    Usage (AL Local Machine Brwsr),     ; AL local machine browser (0194h, selector)
    Usage (AC Search),                  ; AC search (0221h, selector)
    Usage (AC Home),                    ; AC home (0223h, selector)
    Usage (AC Back),                    ; AC back (0224h, selector)
    Usage (AC Forward),                 ; AC forward (0225h, selector)
    Usage (AC Stop),                    ; AC stop (0226h, selector)
    Usage (AC Refresh),                 ; AC refresh (0227h, selector)
    Usage (AC Bookmarks),               ; AC bookmarks (022Ah, selector)
    Report Count (18),
    Report Size (1),
    Input (Variable),
    Report Count (1),
    Report Size (6),
    Input (Constant),
End Collection,
Usage Page (Button),                    ; Button (09h)
Usage (01h),
Collection (Application),
    Report ID (3),
    Logical Minimum (0),
    Logical Maximum (1),
    Usage (2Ch),
    Usage (18h),
    Usage (20h),
    Usage (1Fh),
    Usage (1Ch),
    Usage (3Dh),
    Usage (41h),
    Usage (42h),
    Usage (43h),
    Usage (46h),
    Report Count (10),
    Report Size (1),
    Input (Variable),
    Report Count (1),
    Report Size (6),
    Input (Constant),
End Collection
kurt@kurt-UP-CHT01:~$
Second one looks maybe another interface to handle special keys...

Looking at Logitech wireless combo:
Code:
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i0 | grep -v : | xxd -r -p | hidrd-convert -o spec
Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Keyboard),                   ; Keyboard (06h, application collection)
Collection (Application),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (KB Leftcontrol), ; Keyboard left control (E0h, dynamic value)
    Usage Maximum (KB Right GUI),   ; Keyboard right GUI (E7h, dynamic value)
    Logical Minimum (0),
    Logical Maximum (1),
    Report Size (1),
    Report Count (8),
    Input (Variable),
    Input (Constant, Variable),
    Report Count (5),
    Usage Page (LED),               ; LEDs (08h)
    Usage Minimum (01h),
    Usage Maximum (05h),
    Output (Variable),
    Report Count (1),
    Report Size (3),
    Output (Constant),
    Report Count (6),
    Report Size (8),
    Logical Minimum (0),
    Logical Maximum (164),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (None),           ; No event (00h, selector)
    Usage Maximum (KB ExSel),       ; Keyboard ExSel (A4h, selector)
    Input,
End Collection
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i1 | grep -v : | xxd -r -p | hidrd-convert -o spec
Usage Page (Desktop),                   ; Generic desktop controls (01h)
Usage (Mouse),                          ; Mouse (02h, application collection)
Collection (Application),
    Report ID (2),
    Usage (Pointer),                    ; Pointer (01h, physical collection)
    Collection (Physical),
        Usage Page (Button),            ; Button (09h)
        Usage Minimum (01h),
        Usage Maximum (08h),
        Logical Minimum (0),
        Logical Maximum (1),
        Report Count (8),
        Report Size (1),
        Input (Variable),
        Usage Page (Desktop),           ; Generic desktop controls (01h)
        Logical Minimum (-2047),
        Logical Maximum (2047),
        Report Size (12),
        Report Count (2),
        Usage (X),                      ; X (30h, dynamic value)
        Usage (Y),                      ; Y (31h, dynamic value)
        Input (Variable, Relative),
        Logical Minimum (-127),
        Logical Maximum (127),
        Report Size (8),
        Report Count (1),
        Usage (Wheel),                  ; Wheel (38h, dynamic value)
        Input (Variable, Relative),
        Usage Page (Consumer),          ; Consumer (0Ch)
        Usage (AC Pan),                 ; AC pan (0238h, linear control)
        Report Count (1),
        Input (Variable, Relative),
    End Collection,
End Collection,
Usage Page (Consumer),                  ; Consumer (0Ch)
Usage (Consumer Control),               ; Consumer control (01h, application collection)
Collection (Application),
    Report ID (3),
    Report Size (16),
    Report Count (2),
    Logical Minimum (1),
    Logical Maximum (652),
    Usage Minimum (Consumer Control),   ; Consumer control (01h, application collection)
    Usage Maximum (AC Send),            ; AC send (028Ch, selector)
    Input (No Preferred, Null State),
End Collection,
Usage Page (Desktop),                   ; Generic desktop controls (01h)
Usage (Sys Control),                    ; System control (80h, application collection)
Collection (Application),
    Report ID (4),
    Report Size (2),
    Report Count (1),
    Logical Minimum (1),
    Logical Maximum (3),
    Usage (Sys Sleep),                  ; System sleep (82h, one-shot control)
    Usage (Sys Power Down),             ; System power down (81h, one-shot control)
    Usage (Sys Wake Up),                ; System wake up (83h, one-shot control)
    Input (No Preferred, Null State),
    Report Size (6),
    Input (Constant, Variable),
End Collection,
Usage Page (FF00h),                     ; FF00h, vendor-defined
Usage (01h),
Collection (Application),
    Report ID (16),
    Report Size (8),
    Report Count (6),
    Logical Minimum (0),
    Logical Maximum (255),
    Usage (01h),
    Input,
    Usage (01h),
    Output,
End Collection,
Usage Page (FF00h),                     ; FF00h, vendor-defined
Usage (02h),
Collection (Application),
    Report ID (17),
    Report Size (8),
    Report Count (19),
    Logical Minimum (0),
    Logical Maximum (255),
    Usage (02h),
    Input,
    Usage (02h),
    Output,
End Collection
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i2 | grep -v : | xxd -r -p | hidrd-convert -o spec
No matching HID interfaces
kurt@kurt-UP-CHT01:~$
It does not appear to have special interface for other keys... Probably different report...

Looking at Microsoft Wireless:
Code:
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i0 | grep -v : | xxd -r -p | hidrd-convert -o spec
Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Keyboard),                   ; Keyboard (06h, application collection)
Collection (Application),
    Usage Page (LED),               ; LEDs (08h)
    Usage Minimum (01h),
    Usage Maximum (03h),
    Logical Minimum (0),
    Logical Maximum (1),
    Report Size (1),
    Report Count (3),
    Output (Variable),
    Report Count (5),
    Output (Constant),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (KB Leftcontrol), ; Keyboard left control (E0h, dynamic value)
    Usage Maximum (KB Right GUI),   ; Keyboard right GUI (E7h, dynamic value)
    Report Count (8),
    Input (Variable),
    Report Size (8),
    Report Count (1),
    Input (Constant),
    Usage Minimum (None),           ; No event (00h, selector)
    Usage Maximum (KB LANG2),       ; Keyboard LANG2 (91h, selector)
    Logical Maximum (255),
    Report Count (6),
    Input,
End Collection
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i1 | grep -v : | xxd -r -p | hidrd-convert -o spec
Usage Page (Desktop),                           ; Generic desktop controls (01h)
Usage (Mouse),                                  ; Mouse (02h, application collection)
Collection (Application),
    Usage Page (Desktop),                       ; Generic desktop controls (01h)
    Usage (Mouse),                              ; Mouse (02h, application collection)
    Collection (Logical),
        Report ID (26),
        Usage (Pointer),                        ; Pointer (01h, physical collection)
        Collection (Physical),
            Usage Page (Button),                ; Button (09h)
            Usage Minimum (01h),
            Usage Maximum (05h),
            Report Count (5),
            Report Size (1),
            Logical Minimum (0),
            Logical Maximum (1),
            Input (Variable),
            Report Size (3),
            Report Count (1),
            Input (Constant),
            Usage Page (Desktop),               ; Generic desktop controls (01h)
            Usage (X),                          ; X (30h, dynamic value)
            Usage (Y),                          ; Y (31h, dynamic value)
            Report Count (2),
            Report Size (16),
            Logical Minimum (-32767),
            Logical Maximum (32767),
            Input (Variable, Relative),
            Collection (Logical),
                Report ID (18),
                Usage (Resolution Multiplier),  ; Resolution multiplier (48h, dynamic value)
                Report Count (1),
                Report Size (2),
                Logical Minimum (0),
                Logical Maximum (1),
                Physical Minimum (1),
                Physical Maximum (12),
                Feature (Variable),
                Report ID (26),
                Usage (Wheel),                  ; Wheel (38h, dynamic value)
                Physical Minimum (0),
                Physical Maximum (0),
                Report Count (1),
                Report Size (16),
                Logical Minimum (-32767),
                Logical Maximum (32767),
                Input (Variable, Relative),
            End Collection,
            Collection (Logical),
                Report ID (18),
                Usage (Resolution Multiplier),  ; Resolution multiplier (48h, dynamic value)
                Report Size (2),
                Logical Minimum (0),
                Logical Maximum (1),
                Physical Minimum (1),
                Physical Maximum (12),
                Feature (Variable),
                Physical Minimum (0),
                Physical Maximum (0),
                Report Size (4),
                Feature (Constant),
                Report ID (26),
                Usage Page (Consumer),          ; Consumer (0Ch)
                Report Count (1),
                Report Size (16),
                Logical Minimum (-32767),
                Logical Maximum (32767),
                Usage (AC Pan),                 ; AC pan (0238h, linear control)
                Input (Variable, Relative),
            End Collection,
        End Collection,
    End Collection,
End Collection,
Usage Page (Consumer),                          ; Consumer (0Ch)
Usage (Consumer Control),                       ; Consumer control (01h, application collection)
Collection (Application),
    Usage Page (Desktop),                       ; Generic desktop controls (01h)
    Usage (Mouse),                              ; Mouse (02h, application collection)
    Collection (Logical),
        Report ID (31),
        Usage Page (Consumer),                  ; Consumer (0Ch)
        Usage (AC Pan),                         ; AC pan (0238h, linear control)
        Report Count (1),
        Report Size (16),
        Logical Minimum (-32767),
        Logical Maximum (32767),
        Input (Variable, Relative),
        Report ID (23),
        Usage Page (FF00h),                     ; FF00h, vendor-defined
        Usage (FF06h),
        Usage (FF0Fh),
        Logical Minimum (0),
        Logical Maximum (1),
        Physical Minimum (1),
        Physical Maximum (12),
        Report Count (2),
        Report Size (2),
        Feature (Variable),
        Usage (FF04h),
        Physical Minimum (0),
        Physical Maximum (0),
        Report Count (1),
        Report Size (1),
        Feature (Variable),
        Report Size (3),
        Feature (Constant),
    End Collection,
End Collection
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i2 | grep -v : | xxd -r -p | hidrd-convert -o spec
Usage Page (Consumer),      ; Consumer (0Ch)
Usage (Consumer Control),   ; Consumer control (01h, application collection)
Collection (Application),
    Report ID (32),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Logical Minimum (0),
    Logical Maximum (255),
    Report Size (8),
    Report Count (18),
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (33),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Logical Minimum (0),
    Logical Maximum (1),
    Report Size (1),
    Report Count (16),
    Usage Minimum (FA10h),
    Usage Maximum (FA1Fh),
    Input (Variable),
    Report ID (40),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Report Size (1),
    Report Count (24),
    Usage Minimum (FA10h),
    Usage Maximum (FA1Fh),
    Feature (Variable),
    Report ID (34),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Logical Minimum (0),
    Logical Maximum (255),
    Report Size (8),
    Report Count (26),
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (35),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (162),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (163),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (36),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Report Count (31),
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (37),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (164),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Report Count (31),
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (165),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (38),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FA0Ah),
    Feature (Variable),
    Report ID (39),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FA0Ah),
    Input (Variable),
End Collection,
Usage Page (Consumer),      ; Consumer (0Ch)
Usage (Consumer Control),   ; Consumer control (01h, application collection)
Collection (Application),
    Report ID (7),
    Usage Page (Consumer),  ; Consumer (0Ch)
    Usage Minimum (00h),
    Usage Maximum (03FFh),
    Report Count (1),
    Report Size (16),
    Logical Minimum (0),
    Logical Maximum (1023),
    Input,
    Usage Page (Keyboard),  ; Keyboard/keypad (07h)
    Usage Minimum (None),   ; No event (00h, selector)
    Usage Maximum (FFh),
    Report Size (8),
    Logical Maximum (255),
    Input,
    Input (Constant),
    Usage Page (FF00h),     ; FF00h, vendor-defined
    Usage (FE03h),
    Usage (FE04h),
    Report Size (1),
    Report Count (2),
    Logical Maximum (1),
    Input (Variable),
    Usage (FF05h),
    Report Count (1),
    Report Size (5),
    Logical Maximum (31),
    Input (Variable),
    Report Size (1),
    Input (Constant),
    Usage Minimum (FD01h),
    Usage Maximum (FDFFh),
    Logical Minimum (1),
    Logical Maximum (255),
    Report Size (8),
    Input,
    Usage (FF02h),
    Logical Maximum (255),
    Logical Minimum (0),
    Input (Variable),
End Collection,
Usage Page (Desktop),       ; Generic desktop controls (01h)
Usage (Sys Control),        ; System control (80h, application collection)
Collection (Application),
    Report ID (3),
    Usage Minimum (00h),
    Usage Maximum (FFh),
    Logical Minimum (0),
    Logical Maximum (255),
    Input,
End Collection
kurt@kurt-UP-CHT01:~$
This has third report, maybe for these keys, but looks different than other... Wondering if there is any standard here or why you often have to install another driver on Windows
to handle some of these different keyboards?
 
Status
Not open for further replies.
Back
Top