Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questions & comments about the spec #2

Open
algernon opened this issue Jul 7, 2017 · 6 comments
Open

Questions & comments about the spec #2

algernon opened this issue Jul 7, 2017 · 6 comments

Comments

@algernon
Copy link

algernon commented Jul 7, 2017

Hi!

I've read through the spec fully, finally, and have a few observations about it, and a question or two. I'll start with the questions, those are easier.

Questions

Layers

Are there any plans to have a layer switching command? Where the host can tell the keyboard to turn various layers on? (Or ask it for the active layers)

This would be incredibly useful, because the host-side daemon could monitor the active application, and tell the keyboard to switch layers depending on which window is in focus.

If I could make a suggestion, I'd propose something like this:

0x?? <layer> <layer...>

+> <active layer list>
-> <out-of-bounds layer indexes>

We'd have a layer-on and a layer-off command, to make things easier. It would return the list of active layers in both cases. To get the list of active layers without changing anything, a command without payload could be sent (and both the layer-on and layer-off commands would give the same response in this case).

LEDs

It would be great if it would be possible to control the LEDs from the host. The problem here is that there are many ways keyboards can use LEDs: status LEDs, single-color backlight, RGB backlight strip, per-key RGB LEDs, and so on. So to keep things simple, I'd think that a command to set the "LED mode" would be the best. The keyboard can decide what those modes can do.

Though, if the host could have more control over the LEDs, that would be grand. But I'm not sure how to approach that yet.

Observations

There are a few commands in the spec which I think are... problematic to implement properly, and where a different solution may be better.

0x12 keyboard layout

I'm not sure I follow what this is supposed to do... to allow displaying the active layout? But then, what about keys that do not have an USB code? Like layer switching keys, macros, and so on?

0x13 button layout & 0x14 keycap shapes

This is something that I believe would be better implemented outside of the keyboard. For one, this information would be a big static blob for most keyboards, that would just take up space, and would be the same for all builds. Instead, we could have a hardware database shipped with the daemon, and that could look up the same info based on device IDs and such.

To give an example, the Keyboardio Model 01 has custom sculpted keycaps, all 64 keys are different. If I understand the intent of this command, it would allow the host to draw a keyboard, with proper keycap sizes and such. This would work for keyboards that use standard keycaps, but would utterfly fail for those that use custom ones. Or if they have a non-standard physical layout.

I'd just push this task onto the host, and a hardware database instead. Takes less space in the firmware, and allows much more flexibility, and a more precise description.

@haata
Copy link
Member

haata commented Jul 8, 2017

Layers

Absolutely, I want a way to control layers. Functions I want available (atm):

  • Activate layer (KLL has shift, lock and latch for a layer, layers are merged in realtime for kiiibohd, so these are quite useful)
    • Shift state must be cached by the firmware, so it can respond to unshift
  • Check active layer(s)
    • Perhaps have different commands for top layer and all layers
  • Status of layer (shift, lock, latch)

How about something like this initially?

Layer Control.
8-bit layer Id, KLL supports 16-bit layer indexing and more, but in practice they aren't used, so we can just reserve another Id for 16-bit layers. For keyboards that support 16-bit Ids, 8-bit commands still work, they just won't address as high.

0x?? <action> [<layer>] [<action> [<layer>]...]

actions: 8bit
0x0: status: Status of specified layer
0x1: status all: Status of all layers
0x2: shift: Shift layer (and cache, simulates holding a key down)
0x3: unshift: Unshift layer (unsets cached shift)
0x4: lock: Lock specified layer
0x5: unlock: Unlock specified layer
0x6: latch: Latch specified layer
0x7: unlatch: Unlatch specified layer
0x8: reset layer: Reset layer state
0x9: reset all layers: Reset all layers

layer: 8bit

status: 8bit
0x0: Layer off
0x1: Layer shift
0x2: Layer lock
0x4: Layer latch

error status: 8 bit
0x0: Generic error
0x1: Invalid layer index
0x2: Unsupported action

+> <layer> <status> [<layer> <status>...]
-> <layer> <status> <error status> [<layer> <status> <error status>...]

Layer Id Width

0x??

+> Number of bytes in highest layer Id
->

LEDs

Yeah, LEDs get complicated. KLL supports a wide number of addressing schemes as well as multiple channel widths on the same keyboard (say a few single color leds and RGB for different pixels).
Let me think about this a bit (I need to put something together with LEDs by the end of the month, so it won't be too long, haha).
The easiest way to support all the different methods would probably be to add a variety of commands for each of the addressing schemes and then each keyboard can just support the ones it wants to and it's up to the HID-IO daemon (or some sort of control script) to make it work.

0x12 keyboard layout

Basically, this is intended to auto populate an onscreen keyboard, including all the keys that are programmed.
Keys that are not USB would be given an internal reference code which, can either be a database lookup based on which keyboard it is, or queried from the keyboard (if the keyboard supports this).

0x13 button layout & 0x14 keycap shapes

Yeah, I don't expect most keyboard to implement these Ids. As I mentioned earlier, KLL defines the physical position and rotation of each key and LED. There are a few reasons for this:

  • Simulating x,y grids when doing LED animations
  • Handling custom keyboards without having to query a database that may not be up to date
  • A bit further down the road, but being able to determine spacial events, as in "these two keys were pressed at the same time, but are right next to each other".

Perhaps in addition to this, we can have, as you suggested, a hardware database and then just have a giant list to add keyboards (and revisions) to? This is much easier to implement in the short term.
How about...

Device Id

0x??

group id: 16bit
Company/Group/Project Id
e.g. Input Club, keyboard.io, QMK, etc.

device id: 16bit
Specific Device Id (per group id has it's own range)
e.g. K-Type, Model 01, etc.

customization id: 16bit
Reserved Id for special editions of modifications
Can be issued to people outside of the group if approved.
0x0000 to 0x1000 is reserved for group
e.g. Prototype run 1, Infinity Ergodox no LCD, etc.

+> <group id> <device id> <customization id>

This would be different from USB VID:PID

@algernon
Copy link
Author

algernon commented Jul 9, 2017

Layer control

What should happen if a keyboard implements only a part of the layer stuff? Like, if it does not support Latch? (for example, Kaleidoscope implements it in a plugin, and as such, it is completely optional; QMK allows to turn it off too, though it has it enabled by default)

Perhaps the firmware could respond with a NACK, indicating it does not support that action? And then the host-side can do something with that information.

As for layer width: 8 bits should be enough, indeed, but the layer id width command sounds good for future proofing!

LEDs

Yeah, different commands for the different addressing modes sound reasonable. I'd still suggest a "LED mode" command too - selecting from a pre-defined set of effects is an addressing mode too, if you squint a little. ;)

Device Id

👍

@eltang
Copy link

eltang commented Jul 14, 2017

Relying on the host set layers and LEDs on a keyboard directly has always seemed really cumbersome to me. That forces you to have host-side code which has to be on every computer you want to use the keyboard with. Why not have the host share data with the keyboard such as the current application, and let the keyboard do whatever it wants?

@haata
Copy link
Member

haata commented Jul 14, 2017

@eltang Yeah, for KLL I'm definitely going to have that as an option :D

@algernon
Copy link
Author

Why not have the host share data with the keyboard such as the current application, and let the keyboard do whatever it wants?

Space reasons. The atmega32u4 boards I work with, code that does stuff based on the application is often too much to fit into the available space, even if a lot of things are moved to EEPROM, space can easily be an issue. (On both my ErgoDox EZ, and on the Keyboardio Model01, my own keymap is near the limits.)

Having an id that sends the application from the host side would be awesome, for boards that have the resources to implement that. For others, the layer switching ids require significantly less space.

For hid-io to work, one will have to have a host-side application anyway, so I do not see much harm making that application smarter, instead of pushing everything onto the keyboard. Mind you, I share the sentiment of not wanting too much logic on the host-side... if we could push everything onto the keyboard, that would rock, but there are limited resources on the keyboard.

@RotsiserMho
Copy link

Where can one find the spec?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants