T3.6 USB Host - Keyboard

Status
Not open for further replies.

mietek

New member
I am working on a project that uses the Teensy 3.6 USB host functionality, and I am trying to understand how the keyboard support is done in the USB host library. The way keycode translation is done in the library is rather puzzling to me.

1. Why does teensy3/keylayouts.h contain what seems to be the correct key codes from the HID usage tables — except bitwise or-ed with 0xF000?

2. The keycodes_ascii[] array looks like a mapping from ASCII character to HID key code combinations. Why is keycode translation done using the keycodes_ascii[] array? Is the USB keyboard sending ASCII characters and not HID key codes?

3. What is the purpose of the keycode_extras[] and keycode_numlock[] arrays? Why do they contain hardcoded values different to the key codes listed in teensy3/keylayouts.h?
 
Not sure if I can answer all of these.
1) teensy3/keylayouts.h - was in that format long before we started playing with the USB Host code, so made due with what was there. These tables are used, when the Teensy 3.x is configured to act like a keyboard.

2) It has been awhile, but the code converts the key information returned by the keyboard (boot device format) into Ascii characters to pass back to the user. It also tries to maintain some information about things like cap lock, num lock, ...

3) Extras, there are some things not coming through on the standard boot device and instead an extra HID device is created. So there is the extras... Numlock stuff has to do with what to return if the numberlock is on versus off. i.e. numbers versus PG up/down... type keys...

Again it has been awhile
 
Thanks for the reply, Kurt. I found one of the relevant commits. The comment says:

This delta, adds an extra keyboard object to handle those keys that are not part of the main keyboard class. In particular there are separate HID reports for some of the keys, such as Power keys, and multimedia keys.

These reports might be on separate Interface or in cases where the mouse and keyboard are on the same device, the extra reports may be on the Mouse Interface.

So far I have not tried to combine with Keyboard object as might require multiple inheritance which I would like to avoid.

Also I extended the special key mapping table to map several other keys like F1-12, Arrow, Home/end... To special values where the 0x80 bit is set. I used the same values as used for the Arduino Keyboard library. I did not use their defines as they used defines like KEY_F1, which already exists in core, but in core it is the scan code from the keyboard and not the end user value.

I do not understand the reasoning for using different key codes.

I cannot see in the code how the KeyboardController class manages to get reports from an extra HID. The KeyboardController::claim_collection() method looks possibly relevant, but it is not clear to me how it works, or how it fits into the grand scheme of things.

***

I did some testing using the Mouse.ino example.

1. An Apple USB Keyboard, model A1242, from 2008, is not recognised at all. Connecting the keyboard gives no messages.

2. An Apple USB Keyboard, model A1048, from 2005, does not seem to be supported. Connecting the keyboard only gives the following messages:
Code:
23:51:32.898 -> *** Device Hub1 5ac:1003 - connected ***
23:51:32.898 ->   manufacturer: Mitsumi Electric
23:51:32.898 ->   product: Hub in Apple Extended USB Keyboa

3. An Apple USB Keyboard, model M2452, from 1999, works — partially. The keys on the numpad do not work as expected. Connecting the keyboard and pressing some F-keys gives the following messages:
Code:
23:52:30.749 -> *** Device Hub1 5ac:1001 - connected ***
23:52:30.749 ->   manufacturer: Alps Electric
23:52:30.749 ->   product: Hub in Apple USB
23:52:30.932 -> *** Device KB1 5ac:202 - connected ***
23:52:30.932 ->   manufacturer: Alps Electric
23:52:30.932 ->   product: Apple USB Keyboard
23:52:52.242 -> key 'F1'  194 MOD: 0 OEM: 3A LEDS: 0
23:52:52.678 -> key 'F2'  195 MOD: 0 OEM: 3B LEDS: 0
23:52:53.003 -> key 'F3'  196 MOD: 0 OEM: 3C LEDS: 0
23:52:53.371 -> key 'F4'  197 MOD: 0 OEM: 3D LEDS: 0
23:52:54.050 -> key 'F5'  198 MOD: 0 OEM: 3E LEDS: 0

There is no message about an extra HID having been connected. Therefore, it seems to me that the F-key reports must come from the keyboard device, and not from some extra HID. What am I missing?

***

I am a bit concerned seeing comments such as // TODO: free resources, // TODO: queue events, perform callback from Task, or // WIP: special keys. Is this work still in progress? What work remains to be done?

Is there anything that prevents PR#18 from being merged?
 
As for PR#18 I have not looked at it... As this is Paul's library it is up to him if/when PR's are taken in.... I also have pending PR requests...

As for some of the TODO messages: some have been taken care of. Some are in place to remind mostly to double check. Example free resources. Hopefully all of the pieces are in place to release everything when for example the keyboard is unplugged. But it is always good to double check... Maybe some of the string buffers were not released or...

As for Queue events I don't remember... It probably had to do with some issue on some specific keyboard...

Special keys will probably always be a WIP, as many times each keyboard manufacturer who creates specialized keyboards like Microsoft, Logitech... Then provide PCs with special drivers which use specialized reports or device mechanisms to handle.

Yes some/all F keys are handled by the boot protocol... But the Main tables in the T3.x code base did not have them for setting a Teensy as a USB keyboard... The main keyboard code only works with boot protocol. I wanted the extra keys that were not part of those tables to get mapped, so I added the keycode_extras in order to get them...

Also the Keypad keys created their own codes which again were not part of main code base, and there needed to be some special handling depending on if the NUMLOCK state was set or not... So that was the keycode_numlock

Now as for the extra HID device not being created... That implies that device did not have an extra HID device created on it for some of the special keys like Multi-media keys (volume up, ... ) that have a standard defined for them.. That is we look for two special reports:
System control and comumer control... And only claim those two...

As for mydevice versus device... They are two different variables. One is used when the Keyboard object is in use as the top level USB object (Boot protocol stuff) and bad name mydevice is used when a HID claim is happens. (Again for User or System HID top usage). Should be renamed to something like hiddevice...

Note: Soon in a different PR, there will also be btdevice - for Bluetooth Hid device claim... This will be if you have a bluetooth dongle and have a bluetooth keyboard paired to it ...

As for which extra HID keys may be reported, look at the example mouse.ino and look at onHIDExtrasPress and it shows a list of most of the defined special keys...

And again there are still some other keys that on some of my keyboards did not respond here as again they have defined their own reports... to handle.
 
First part was to get the T3.6 host to Connect/Pair to the device: Bluetooth Specification 5: Vol 3, Part E
Currently the code is setup to always have to pair each time... This is the next thing I will change...

Once these were talking, then needed to start using the Logical Link Control and Adaptation Protocol (L2CAP), which is
Vol 3 Part A...

Then once these parts are talking, you then need to setup the HID stuff, which was different PDF file (HID_v1.1.1pdf)...

Again the code is currently pretty hard code in order of things, plus not handling errors and the like, but today I was able to start receiving key data and trackpad data

The debug data shows data going through four different pipes. The control pipe, two different Read pipes and a write pipe.
Some of the commands are sent to Control others to the write... Some things come in on the RX and others come in on the other RX (RX2)...

Once I add the code to handle both automatically connecting to previously paired device versus always having to pair and trimming down all of the debug output ... I need to start figuring out how to factor some of this code.

That is, the current code is setup with one device which is probably: Bluetooth Core - HID(using L2CAP)

But: I would also like for the Bluetooth code to also support joysticks like PS3 and PS4..

Maybe Serial replacements (might be nice to talk to smart phone)... Maybe Sound? ...

So should we aim toward a single Bluetooth object, which tries to combine everything into the one big object. Or should we do closer to the USB Host shield code, which has a Bluetooth base class and some subclasses (BTHID, PS3BT...)
or closer to our HID stuff, where we have a USBHidParser and then several classes derived from USBHIDInput....
So have a base Bluetooth object and then some bluetooth protocol objects?

Then talking about Bluetooth HID object. We have things like Mouse and Keyboard, and trackpad...
Should we have new objects like: BTKeyboardController so each program that wants keyboard data may have to handle both types of objects, or should the KeyboardController object should also be derived form some Bluetooth object, such that all of the data is funneled through the one object... , likewise for Mouse...
 
You might want to look at our USBHost_T36 code in the Bluetooth WIP branch: https://github.com/KurtE/USBHost_t36/tree/WIP2-Bluetooth
We have a PR to get it into mainline code...

Still lots to do, like being able to connect to multiple BT devices at the same time, but we do support some Mice, some keyboards, some Joysticks like (PS3, PS4, PS3 move)...

And yes we have the Keyboard, Mouse, Joystick code derived from a base class to add Bluetooth support.

Note: when I say it supports some mice... There are some Mice that appear to use the BLE extensions to Bluetooth and we so far we have not put in support for the BLE stuff...
 
Looks like @paul did a couple of commits for midi

So maybe if you do any midi stuff
 
You might want to look at our USBHost_T36 code in the Bluetooth WIP branch: https://github.com/KurtE/USBHost_t36/tree/WIP2-Bluetooth
We have a PR to get it into mainline code...

Still lots to do, like being able to connect to multiple BT devices at the same time, but we do support some Mice, some keyboards, some Joysticks like (PS3, PS4, PS3 move)...

And yes we have the Keyboard, Mouse, Joystick code derived from a base class to add Bluetooth support. visit the site

Note: when I say it supports some mice... There are some Mice that appear to use the BLE extensions to Bluetooth and we so far we have not put in support for the BLE stuff...

Maybe Serial replacements (might be nice to talk to smart phone)... Maybe Sound? ..
 
Status
Not open for further replies.
Back
Top