From e7d306cf300b3ad2a3c1b148e9da64a368ed6ae8 Mon Sep 17 00:00:00 2001 From: tonasz <27835465+Tonasz@users.noreply.github.com> Date: Sun, 20 Feb 2022 20:55:22 +0100 Subject: [PATCH] Add Kyria board configuration and examples --- boards/kyria/README.md | 53 ++++++++++++++++++ boards/kyria/kyria_v1_kb2040.py | 34 +++++++++++ boards/kyria/kyria_v1_rp2040.py | 34 +++++++++++ boards/kyria/main.py | 99 +++++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 boards/kyria/README.md create mode 100644 boards/kyria/kyria_v1_kb2040.py create mode 100644 boards/kyria/kyria_v1_rp2040.py create mode 100644 boards/kyria/main.py diff --git a/boards/kyria/README.md b/boards/kyria/README.md new file mode 100644 index 0000000..2e05e46 --- /dev/null +++ b/boards/kyria/README.md @@ -0,0 +1,53 @@ +# Kyria Keyboard + +A split keyboard with a 3x6 columnar stagger and 7 thumb keys. One button on each side is usually replaced by an +encoder. + +Official retailer of Kyria PCB: [splitkb.com](https://splitkb.com/collections/keyboard-kits/products/kyria-pcb-kit). PCB +was designed with QMK in mind and KMK implementation is not officially supported by PCB designer and seller. + +Keyboard works with controllers having Pro Micro layout. Existing configurations: + +| PCB version | Board | Config file | +|:-----------:|----------------------------------------------------------------------|---------------------------| +| 1.* | [Sparkfun Pro Micro RP2040](https://www.sparkfun.com/products/18288) | kyria_v1_rp2040 | +| 1.* | [Adafruit KB2040](https://www.adafruit.com/product/5302) | kyria_v1_kb2040 | +| 2.* | [Sparkfun Pro Micro RP2040](https://www.sparkfun.com/products/18288) | _waiting for pinout docs_ | +| 2.* | [Adafruit KB2040](https://www.adafruit.com/product/5302) | _waiting for pinout docs_ | + +## Compatibility issues + +- **TRRS connection** - KMK has no protocol for one-pin communication between two splits. So, if you are using TRRS wire + connection, only right side send matrix events to the left side. No issue when using BLE. +- **Right side encoder** - right encoder currently doesn't send updates to left half and can even freeze right half +- **OLED screens** - OLED screens are not required, but often element of Kyria keyboards. KMK have no official OLED + implementation, but as it's based on Circuit Python, adding one is very simple and there are many examples, also on + KMK forks + +## `main.py` example config + +Current layout is based on default [QMK Kyria layout](https://config.qmk.fm/#/splitkb/kyria/rev1/LAYOUT) + +It has the following modules/extensions enabled: + +- [Split](https://github.com/KMKfw/kmk_firmware/tree/master/docs/split_keyboards.md) Connects halves using a wire +- [Layers](https://github.com/KMKfw/kmk_firmware/tree/master/docs/layers.md) Do you need more keys than switches? Use + layers. +- [ModTap](https://github.com/KMKfw/kmk_firmware/blob/master/docs/modtap.md) Enable press/hold double binding of keys +- [MediaKeys](https://github.com/KMKfw/kmk_firmware/blob/master/docs/media_keys.md) Common media controls + +Also uncomment right section to enable samples of following: + +- [RGB](https://github.com/KMKfw/kmk_firmware/tree/master/docs/rgb.md) Turn on the backlight (**requires neopixel.py + library to work**) +- [Encoder](https://github.com/KMKfw/kmk_firmware/blob/master/docs/encoder.md) Make the knobs do something + +## More steps required during install + +In order to mitigate lack of one-wire protocol, KMK use its UART implementation but with special low-level PIO +subprogram available only on RP2040. It allows using other pins for UART than on-board RX and TX. + +Because of the above, besides of normal installation steps, you have to also: + +- install Circuit Python in 7.2+ version +- add `adafruit_pioasm.mpy` library to lib or root folder of a board diff --git a/boards/kyria/kyria_v1_kb2040.py b/boards/kyria/kyria_v1_kb2040.py new file mode 100644 index 0000000..27006d6 --- /dev/null +++ b/boards/kyria/kyria_v1_kb2040.py @@ -0,0 +1,34 @@ +import board + +from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard +from kmk.matrix import DiodeOrientation +from kmk.matrix import intify_coordinate as ic + + +class KMKKeyboard(_KMKKeyboard): + col_pins = ( + board.A3, + board.A2, + board.A1, + board.A0, + board.SCK, + board.MISO, + board.MOSI, + board.D10, + ) + row_pins = (board.D8, board.D7, board.D6, board.D4) + diode_orientation = DiodeOrientation.COL2ROW + data_pin = board.D1 + rgb_pixel_pin = board.D0 + encoder_pin_0 = board.D9 + encoder_pin_1 = board.D5 + + coord_mapping = [] + coord_mapping.extend(ic(0, x, 8) for x in range(6)) + coord_mapping.extend(ic(4, x, 8) for x in range(5, -1, -1)) + coord_mapping.extend(ic(1, x, 8) for x in range(6)) + coord_mapping.extend(ic(5, x, 8) for x in range(5, -1, -1)) + coord_mapping.extend(ic(2, x, 8) for x in range(8)) + coord_mapping.extend(ic(6, x, 8) for x in range(7, -1, -1)) + coord_mapping.extend(ic(3, x, 8) for x in range(3, 8)) + coord_mapping.extend(ic(7, x, 8) for x in range(7, 2, -1)) diff --git a/boards/kyria/kyria_v1_rp2040.py b/boards/kyria/kyria_v1_rp2040.py new file mode 100644 index 0000000..73d141d --- /dev/null +++ b/boards/kyria/kyria_v1_rp2040.py @@ -0,0 +1,34 @@ +import board + +from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard +from kmk.matrix import DiodeOrientation +from kmk.matrix import intify_coordinate as ic + + +class KMKKeyboard(_KMKKeyboard): + col_pins = ( + board.D29, + board.D28, + board.D27, + board.D26, + board.D22, + board.D20, + board.D23, + board.D21, + ) + row_pins = (board.D8, board.D7, board.D6, board.D4) + diode_orientation = DiodeOrientation.COL2ROW + data_pin = board.RX + rgb_pixel_pin = board.D0 + encoder_pin_0 = board.D9 + encoder_pin_1 = board.D5 + + coord_mapping = [] + coord_mapping.extend(ic(0, x, 8) for x in range(6)) + coord_mapping.extend(ic(4, x, 8) for x in range(5, -1, -1)) + coord_mapping.extend(ic(1, x, 8) for x in range(6)) + coord_mapping.extend(ic(5, x, 8) for x in range(5, -1, -1)) + coord_mapping.extend(ic(2, x, 8) for x in range(8)) + coord_mapping.extend(ic(6, x, 8) for x in range(7, -1, -1)) + coord_mapping.extend(ic(3, x, 8) for x in range(3, 8)) + coord_mapping.extend(ic(7, x, 8) for x in range(7, 2, -1)) diff --git a/boards/kyria/main.py b/boards/kyria/main.py new file mode 100644 index 0000000..f022e1a --- /dev/null +++ b/boards/kyria/main.py @@ -0,0 +1,99 @@ +from kyria_v1_rp2040 import KMKKeyboard + +from kmk.extensions.media_keys import MediaKeys +from kmk.extensions.rgb import RGB, AnimationModes +from kmk.keys import KC +from kmk.modules.encoder import EncoderHandler +from kmk.modules.layers import Layers +from kmk.modules.modtap import ModTap +from kmk.modules.split import Split, SplitType + +keyboard = KMKKeyboard() +keyboard.debug_enabled = True + +keyboard.modules.append(Layers()) +keyboard.modules.append(ModTap()) +keyboard.extensions.append(MediaKeys()) + +# Using drive names (KYRIAL, KYRIAR) to recognize sides; use split_side arg if you're not doing it +split = Split(split_type=SplitType.UART, use_pio=True) +keyboard.modules.append(split) + +# Uncomment below if you're using encoder +encoder_handler = EncoderHandler() +encoder_handler.pins = ((keyboard.encoder_pin_0, keyboard.encoder_pin_1, None, False),) + +# Uncomment below if you're having RGB +rgb_ext = RGB( + pixel_pin=keyboard.rgb_pixel_pin, + num_pixels=10, + animation_mode=AnimationModes.BREATHING_RAINBOW, +) +keyboard.extensions.append(rgb_ext) + +# Edit your layout below +# Currently, that's a default QMK Kyria Layout - https://config.qmk.fm/#/splitkb/kyria/rev1/LAYOUT +ESC_LCTL = KC.MT(KC.ESC, KC.LCTL) +QUOTE_RCTL = KC.MT(KC.QUOTE, KC.RCTL) +ENT_LALT = KC.MT(KC.ENT, KC.LALT) +MINUS_RCTL = KC.MT(KC.MINUS, KC.RCTL) +keyboard.keymap = [ + [ + KC.TAB, KC.Q, KC.W, KC.E, KC.R, KC.T, KC.Y, KC.U, KC.I, KC.O, KC.P, KC.BSPC, + ESC_LCTL, KC.A, KC.S, KC.D, KC.F, KC.G, KC.H, KC.J, KC.K, KC.L, KC.SCLN, QUOTE_RCTL, + KC.LSFT, KC.Z, KC.X, KC.C, KC.V, KC.B, KC.LBRC, KC.CAPS, KC.MO(5), KC.RBRC, KC.N, KC.M, KC.COMM, KC.DOT, KC.SLSH, KC.RSFT, + KC.MO(6), KC.LGUI, ENT_LALT, KC.SPC, KC.MO(3), KC.MO(4), KC.SPC, KC.RALT, KC.RGUI, KC.APP, + ], + [ + KC.TAB, KC.QUOT, KC.COMM, KC.DOT, KC.P, KC.Y, KC.F, KC.G, KC.C, KC.R, KC.L, KC.BSPC, + ESC_LCTL, KC.A, KC.O, KC.E, KC.U, KC.I, KC.D, KC.H, KC.T, KC.N, KC.S, MINUS_RCTL, + KC.LSFT, KC.SCLN, KC.Q, KC.J, KC.K, KC.X, KC.LBRC, KC.CAPS, KC.MO(5), KC.RBRC, KC.B, KC.M, KC.W, KC.V, KC.Z, KC.RSFT, + KC.MO(6), KC.LGUI, ENT_LALT, KC.SPC, KC.MO(3), KC.MO(4), KC.SPC, KC.RALT, KC.RGUI, KC.APP, + ], + [ + KC.TAB, KC.Q, KC.W, KC.F, KC.P, KC.B, KC.J, KC.L, KC.U, KC.Y, KC.SCLN, KC.BSPC, + ESC_LCTL, KC.A, KC.R, KC.S, KC.T, KC.G, KC.M, KC.N, KC.E, KC.I, KC.O, QUOTE_RCTL, + KC.LSFT, KC.Z, KC.X, KC.C, KC.D, KC.V, KC.LBRC, KC.CAPS, KC.MO(5), KC.RBRC, KC.K, KC.H, KC.COMM, KC.DOT, KC.SLSH, KC.RSFT, + KC.MO(6), KC.LGUI, ENT_LALT, KC.SPC, KC.MO(3), KC.MO(4), KC.SPC, KC.RALT, KC.RGUI, KC.APP, + ], + [ + KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.PGUP, KC.HOME, KC.UP, KC.END, KC.VOLU, KC.DEL, + KC.TRNS, KC.LGUI, KC.LALT, KC.LCTL, KC.LSFT, KC.TRNS, KC.PGDN, KC.LEFT, KC.DOWN, KC.RGHT, KC.VOLD, KC.INS, + KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.SLCK, KC.TRNS, KC.TRNS, KC.PAUS, KC.MPRV, KC.MPLY, KC.MNXT, KC.MUTE, KC.PSCR, + KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, + ], + [ + KC.GRV, KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.N6, KC.N7, KC.N8, KC.N9, KC.N0, KC.EQL, + KC.TILD, KC.EXLM, KC.AT, KC.HASH, KC.DLR, KC.PERC, KC.CIRC, KC.AMPR, KC.ASTR, KC.LPRN, KC.RPRN, KC.PLUS, + KC.PIPE, KC.BSLS, KC.COLN, KC.SCLN, KC.MINS, KC.LBRC, KC.LCBR, KC.TRNS, KC.TRNS, KC.RCBR, KC.RBRC, KC.UNDS, KC.COMM, KC.DOT, KC.SLSH, KC.QUES, + KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, + ], + [ + KC.TRNS, KC.F9, KC.F10, KC.F11, KC.F12, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, + KC.TRNS, KC.F5, KC.F6, KC.F7, KC.F8, KC.TRNS, KC.TRNS, KC.RSFT, KC.RCTL, KC.LALT, KC.RGUI, KC.TRNS, + KC.TRNS, KC.F1, KC.F2, KC.F3, KC.F4, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, + KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, + ], + [ + KC.TRNS, KC.TRNS, KC.TRNS, KC.DF(0), KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, + KC.TRNS, KC.TRNS, KC.TRNS, KC.DF(1), KC.TRNS, KC.TRNS, KC.RGB_TOG, KC.RGB_SAI, KC.RGB_HUI, KC.RGB_VAI, KC.RGB_M_P, KC.TRNS, + KC.TRNS, KC.TRNS, KC.TRNS, KC.DF(2), KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.RGB_SAD, KC.RGB_HUD, KC.RGB_VAD, KC.RGB_M_P, KC.TRNS, + KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, + ], +] + +# Uncomment below if using an encoder +# Edit your encoder layout below +encoder_handler.map = ( + ((KC.VOLD, KC.VOLU),), + ((KC.VOLD, KC.VOLU),), + ((KC.VOLD, KC.VOLU),), + ((KC.MPRV, KC.MNXT),), + ((KC.MPRV, KC.MNXT),), + ((KC.MPRV, KC.MNXT),), + ((KC.MPRV, KC.MNXT),), +) +keyboard.modules.append(encoder_handler) + +if __name__ == '__main__': + keyboard.go()