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

Feature: Add physical layout support #2283

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

petejohanson
Copy link
Contributor

This feature enhancement adds support for "physical layouts" that describe a given keyboard layout. Example uses cases for multiple physical layouts include:

  • Devices with removable columns, e.g. Corne V2,
  • Devices that can be built with multiple configurations, e.g. a 60% PCB that supports both ISO and ANSI, or a Planck-like with multiple bottom rows.

To make avoid code duplication, under the hood we are still using a "synthetic physical layout" when none are explicitly specified, using the chosen matrix transform and kscan nodes to set up a single physical layout that is then used.

A Physical Layout includes:

  • The list of keys' physical attributes, including width, height, x, y, r, rx, and ry values.
  • The matrix transform to use when the layout is active.
  • The kscan device to use with this layout (this allows for freeing up kscan hardware (e.g. extra column pins) not eased for every layout for other purposes.

Selecting a physical layout will do the necessary setup for the layout's kscan instance, and when processing kscan events, use the associated matrix transform to map that kscan event to a key position.

The code here also has some tweaks to calculate the ZMK_KEYMAP_LEN, aka the maximum key position index, based on the longest transform available from all the physical layouts defined, which we will use down the road in the ZMK Studio work to ensure we have enough pre-allocated locations for keymaps the user sets up after picking a layout.

Not yet implemented, to come as follow up work:

  • Selection of physical layout being propagated to split peripherals.
  • Runtime selected layout persistence to settings subsystem.

@petejohanson petejohanson added enhancement New feature or request keymaps PRs and issues related to keymaps core Core functionality/behavior of ZMK studio ZMK Studio (runtime keymaps) labels Apr 25, 2024
@petejohanson petejohanson self-assigned this Apr 25, 2024
@petejohanson petejohanson requested a review from a team as a code owner April 25, 2024 06:42
app/src/matrix_transform.c Outdated Show resolved Hide resolved
app/src/matrix_transform.c Outdated Show resolved Hide resolved
app/src/physical_layouts.c Outdated Show resolved Hide resolved
@petejohanson petejohanson force-pushed the core/physical-layout-refactor branch 5 times, most recently from e6fb8c2 to 60e5c30 Compare May 1, 2024 21:09
@petejohanson
Copy link
Contributor Author

Ok, I've pushed some minor cleanups and fixes, as well as an implementation of this for ZMK Uno to show how this works. Tested working for the ZMK Uno split as well.

@petejohanson petejohanson force-pushed the core/physical-layout-refactor branch from 60e5c30 to e05784f Compare May 2, 2024 06:22
@caksoylar
Copy link
Contributor

In case anyone wants to test the physical layout, here is a helper script to convert from QMK-style info.json files or ortho-like specs to a devicetree snippet for keys property, based on https://github.com/caksoylar/keymap-drawer: https://gist.github.com/caksoylar/1f6809446ab2415d4116882ed1c60db2#file-physical_layout_to_dt-py

❯ python physical_layout_to_dt.py -k corne_rotated -l LAYOUT_split_3x5_3

keys  //                     w   h    x    y     rot   rx   ry
    = <&key_physical_attrs 100 100    0   37       0    0    0>
    , <&key_physical_attrs 100 100  100   12       0    0    0>
    , <&key_physical_attrs 100 100  200    0       0    0    0>
    , <&key_physical_attrs 100 100  300   12       0    0    0>
    , <&key_physical_attrs 100 100  400   25       0    0    0>
    , <&key_physical_attrs 100 100  800   25       0    0    0>
    , <&key_physical_attrs 100 100  900   12       0    0    0>
    , <&key_physical_attrs 100 100 1000    0       0    0    0>
    , <&key_physical_attrs 100 100 1100   12       0    0    0>
    , <&key_physical_attrs 100 100 1200   37       0    0    0>
    , <&key_physical_attrs 100 100    0  137       0    0    0>
    , <&key_physical_attrs 100 100  100  112       0    0    0>
    , <&key_physical_attrs 100 100  200  100       0    0    0>
    , <&key_physical_attrs 100 100  300  112       0    0    0>
    , <&key_physical_attrs 100 100  400  125       0    0    0>
    , <&key_physical_attrs 100 100  800  125       0    0    0>
    , <&key_physical_attrs 100 100  900  112       0    0    0>
    , <&key_physical_attrs 100 100 1000  100       0    0    0>
    , <&key_physical_attrs 100 100 1100  112       0    0    0>
    , <&key_physical_attrs 100 100 1200  137       0    0    0>
    , <&key_physical_attrs 100 100    0  237       0    0    0>
    , <&key_physical_attrs 100 100  100  212       0    0    0>
    , <&key_physical_attrs 100 100  200  200       0    0    0>
    , <&key_physical_attrs 100 100  300  212       0    0    0>
    , <&key_physical_attrs 100 100  400  225       0    0    0>
    , <&key_physical_attrs 100 100  800  225       0    0    0>
    , <&key_physical_attrs 100 100  900  212       0    0    0>
    , <&key_physical_attrs 100 100 1000  200       0    0    0>
    , <&key_physical_attrs 100 100 1100  212       0    0    0>
    , <&key_physical_attrs 100 100 1200  237       0    0    0>
    , <&key_physical_attrs 100 100  250  315       0    0    0>
    , <&key_physical_attrs 100 100  360  330    1500  409  380>
    , <&key_physical_attrs 100 150  476  325    3000  527  400>
    , <&key_physical_attrs 100 150  723  325 (-3000)  773  400>
    , <&key_physical_attrs 100 100  840  330 (-1500)  890  380>
    , <&key_physical_attrs 100 100  950  315       0    0    0>
    ;

@petejohanson petejohanson force-pushed the core/physical-layout-refactor branch from e05784f to f218060 Compare May 30, 2024 19:14
@petejohanson petejohanson force-pushed the core/physical-layout-refactor branch from f218060 to 03dbb65 Compare May 31, 2024 05:33
@petejohanson petejohanson force-pushed the core/physical-layout-refactor branch 10 times, most recently from 2eda9f8 to 0045d63 Compare June 13, 2024 22:13
* Add bindings to allow creating multiple physical layouts that specify
  their key's physical attributes, and the matching matrix transform
  and dependant kscan to use.
* Synthesize a basic physical layout if none specified, for backwards
  compatibility.
* Update matrix transform API to explicitly pass in the selected transform
  to the API instead of using a fixed chosen transform.
* Move kscan subscription and handling into the physical layout code, so
  that selecting a different physical layout at runtime can also use the
  correct kscan instance.
* Add `physical_layouts.dtsi` file to include so you can use the
  pre-configured `&key_physical_attrs` for adding you layout keys.
* Update our GPIO kscan drivers to more completely support PM device,
  by doing proper hardare init/deinit in the PM action hook.
* Add physical layout definitions for uno and split uno shields.
@petejohanson petejohanson force-pushed the core/physical-layout-refactor branch from 0045d63 to 22d540a Compare June 13, 2024 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Core functionality/behavior of ZMK enhancement New feature or request keymaps PRs and issues related to keymaps studio ZMK Studio (runtime keymaps)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants