Merge pull request #140 from KMKfw/topic-keys19-round2

cKeys Prep: Round 2 - Cleanup SO MUCH STUFF
This commit is contained in:
Josh Klar 2019-07-26 11:25:40 -07:00 committed by GitHub
commit 0ed40d3cef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 584 additions and 749 deletions

View File

@ -50,20 +50,21 @@ dist-deploy: devdeps dist
@[[ -n "$${CIRCLE_TAG}" ]] && $(PIPENV) run s3cmd -c .s3cfg put -P dist/kmk-latest.zip s3://kmk-releases/$${CIRCLE_TAG}.zip >/dev/null || true @[[ -n "$${CIRCLE_TAG}" ]] && $(PIPENV) run s3cmd -c .s3cfg put -P dist/kmk-latest.zip s3://kmk-releases/$${CIRCLE_TAG}.zip >/dev/null || true
@[[ -n "$${CIRCLE_TAG}" ]] && $(PIPENV) run s3cmd -c .s3cfg put -P dist/kmk-latest.unoptimized.zip s3://kmk-releases/$${CIRCLE_TAG}.unoptimized.zip >/dev/null || true @[[ -n "$${CIRCLE_TAG}" ]] && $(PIPENV) run s3cmd -c .s3cfg put -P dist/kmk-latest.unoptimized.zip s3://kmk-releases/$${CIRCLE_TAG}.unoptimized.zip >/dev/null || true
dist/kmk-latest.zip: compile dist/kmk-latest.zip: compile boot.py
@echo "===> Building optimized ZIP" @echo "===> Building optimized ZIP"
@mkdir -p dist @mkdir -p dist
@cd $(MPY_TARGET_DIR) && zip -r ../dist/kmk-latest.zip kmk 2>&1 >/dev/null @cd $(MPY_TARGET_DIR) && zip -r ../dist/kmk-latest.zip kmk 2>&1 >/dev/null
@zip -r dist/kmk-latest.zip boot.py 2>&1 >/dev/null
dist/$(DIST_DESCRIBE).zip: dist/kmk-latest.zip dist/$(DIST_DESCRIBE).zip: dist/kmk-latest.zip
@echo "===> Aliasing optimized ZIP" @echo "===> Aliasing optimized ZIP"
@cp dist/kmk-latest.zip dist/kmk-$(DIST_DESCRIBE).zip @cp dist/kmk-latest.zip dist/kmk-$(DIST_DESCRIBE).zip
dist/kmk-latest.unoptimized.zip: $(PY_KMK_TREE) dist/kmk-latest.unoptimized.zip: $(PY_KMK_TREE) boot.py
@echo "===> Building unoptimized ZIP" @echo "===> Building unoptimized ZIP"
@mkdir -p dist @mkdir -p dist
@echo "KMK_RELEASE = '$(DIST_DESCRIBE)'" > kmk/release_info.py @echo "KMK_RELEASE = '$(DIST_DESCRIBE)'" > kmk/release_info.py
@zip -r dist/kmk-latest.unoptimized.zip kmk 2>&1 >/dev/null @zip -r dist/kmk-latest.unoptimized.zip kmk boot.py 2>&1 >/dev/null
@rm -rf kmk/release_info.py @rm -rf kmk/release_info.py
dist/$(DIST_DESCRIBE).unoptimized.zip: dist/kmk-latest.unoptimized.zip dist/$(DIST_DESCRIBE).unoptimized.zip: dist/kmk-latest.unoptimized.zip
@ -89,14 +90,13 @@ docker-base-deploy: docker-base
devdeps: .devdeps devdeps: .devdeps
lint: devdeps lint: devdeps
@$(PIPENV) run black --check
@$(PIPENV) run flake8 @$(PIPENV) run flake8
fix-formatting: devdeps fix-formatting: devdeps
@$(PIPENV) run black . @$(PIPENV) run black .
fix-isort: devdeps fix-isort: devdeps
@find kmk/ tests/ user_keymaps/ -name "*.py" | xargs $(PIPENV) run isort @find kmk/ user_keymaps/ -name "*.py" | xargs $(PIPENV) run isort
clean: clean:
@echo "===> Cleaning build artifacts" @echo "===> Cleaning build artifacts"

View File

@ -20,6 +20,7 @@ neovim = "*"
s3cmd = "*" s3cmd = "*"
black = "==19.3b0" black = "==19.3b0"
flake8-quotes = "*" flake8-quotes = "*"
flake8-black = "*"
[requires] [requires]
python_version = "3.7" python_version = "3.7"

9
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "019b67ce05e7e68766ba54ddbfd3e2faf5dd81c7ded79f80ff3ef85b0017c99d" "sha256": "e2a8058d3c40039167ababbfee7347b3b61cb679c65b7f98c2b56ba91fafa0dd"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -76,6 +76,13 @@
"index": "pypi", "index": "pypi",
"version": "==3.6.0" "version": "==3.6.0"
}, },
"flake8-black": {
"hashes": [
"sha256:6b5fe2a609fa750170da8d5b1ed7c11029bceaff025660be7f19307ec6fa0c35"
],
"index": "pypi",
"version": "==0.1.0"
},
"flake8-commas": { "flake8-commas": {
"hashes": [ "hashes": [
"sha256:d3005899466f51380387df7151fb59afec666a0f4f4a2c6a8995b975de0f44b7", "sha256:d3005899466f51380387df7151fb59afec666a0f4f4a2c6a8995b975de0f44b7",

View File

@ -86,7 +86,9 @@ Coming (hopefully) soon: Bluetooth support! Stay tuned.
extract the zip to the USB drive exposed by CircuitPython, typically labeled extract the zip to the USB drive exposed by CircuitPython, typically labeled
`CIRCUITPY`. Again, [we'll defer to Adafruit's `CIRCUITPY`. Again, [we'll defer to Adafruit's
documentation](https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries) documentation](https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries)
on adding libraries to a CircuitPython installation. on adding libraries to a CircuitPython installation. You should end up with a
folder called `kmk` and a file called `boot.py`, both living at the top of
this USB drive.
- Define your keyboard in a file called `main.py` on this `CIRCUITPY` drive and - Define your keyboard in a file called `main.py` on this `CIRCUITPY` drive and
get tinkering! Examples of both handwired and ProMicro-\>ItsyBitsy converted get tinkering! Examples of both handwired and ProMicro-\>ItsyBitsy converted

105
docs/config_and_keymap.md Normal file
View File

@ -0,0 +1,105 @@
# Configuring KMK
KMK is configured through a rather large plain-old-Python class called
`KMKKeyboard`. Subclasses of this configuration exist which pre-fill defaults
for various known keyboards (for example, many Keebio keyboards are supported
through our ItsyBitsy to ProMicro pinout adapter). This class is the main
interface between end users and the inner workings of KMK. Let's dive in!
- Edit or create a file called `main.py` on your `CIRCUITPY` drive. You can also
keep this file on your computer (perhaps under `user_keymaps` - please feel
free to submit a pull request with your layout definitions!) and copy it over
(either manually or, if you're adept with developer tooling and/or a command
line, [our
Makefile](https://github.com/KMKfw/kmk_firmware/blob/master/docs/flashing.md)).
It's definitely recommended to keep a backup of your configuration somewhere
that isn't the microcontroller itself - MCUs die, CircuitPython may run into
corruption bugs, or you might just have bad luck and delete the wrong file
some day.
- Import the `KMKKeyboard` object for your keyboard from `kmk.boards` (or, if
handwiring your keyboard, import `KMKKeyboard` from `kmk.kmk_keyboard`).
- Assign a `KMKKeyboard` instance to a variable (ex. `keyboard = KMKKeyboard()` - note
the parentheses)
- Make sure this `KMKKeyboard` instance is actually run at the end of the file with
a block such as the following:
```python
if __name__ == '__main__':
keyboard.go()
```
- Assign pins and your diode orientation (only necessary on handwire keyboards),
for example:
```python
import board
from kmk.matrix import DiodeOrientation
col_pins = (board.SCK, board.MOSI, board.MISO, board.RX, board.TX, board.D4)
row_pins = (board.D10, board.D11, board.D12, board.D13, board.D9, board.D6, board.D5, board.SCL)
rollover_cols_every_rows = 4
diode_orientation = DiodeOrientation.COLUMNS
```
The pins should be based on whatever CircuitPython calls pins on your particular
board. You can find these in the REPL on your CircuitPython device:
```python
import board
print(dir(board))
```
> Note: `rollover_cols_every_rows` is only supported with
> `DiodeOrientation.COLUMNS`, not `DiodeOrientation.ROWS`. It is used for boards
> such as the Planck Rev6 which reuse column pins to simulate a 4x12 matrix in
> the form of an 8x6 matrix
- Import the global list of key definitions with `from kmk.keys import KC`. You
can either print this out in the REPL as we did with `board` above, or simply
look at [our Key
documentation](https://github.com/KMKfw/kmk_firmware/blob/master/docs/keycodes.md).
We've tried to keep that listing reasonably up to date, but if it feels like
something is missing, you may need to read through `kmk/keys.py` (and then
open a ticket to tell us our docs are out of date, or open a PR and fix the
docs yourself!)
- Define a keymap, which is, in Python terms, a List of Lists of `Key` objects.
A very simple keymap, for a keyboard with just two physical keys on a single
layer, may look like this:
```python
keyboard.keymap = [[KC.A, KC.B]]
```
You can further define a bunch of other stuff:
- `debug_enabled` which will spew a ton of debugging information to the serial
console. This is very rarely needed, but can provide very valuable information
if you need to open an issue.
- `unicode_mode` from `kmk.consts.UnicodeMode`, which defines the default
operating system implementation to use for unicode sequences (see examples
below, or `unicode.md`. This can be changed after boot with a key (see
`keycodes.md`)
- `tap_time` which defines how long `KC.TT` and `KC.LT` will wait before
considering a key "held" (see `keycodes.md`)
- `leader_dictionary`, which defines leader sequences (see `leader.md`), defined
as tuples of keycode objects (or you can use
`kmk.keycodes.generate_leader_dictionary_seq` with a string)
We also support unicode sequences (emojis, emoticons, umlauted letters,
whatever) if your operating system and system setup do! See `unicode.md` for
details.
[Here's a giant example of all the
above](https://github.com/KMKfw/kmk_firmware/blob/master/user_keymaps/klardotsh/klarank_featherm4.py).
This is my personal 4x12 matrix layout running on a Planck Rev6 PCB, with a
Feather M4 Express wired up to the outer matrix pins (in somewhat of a "spider"
setup), utilizing most of the above features - it's one of the "kitchen sink
tester" definitions we use on the KMK Core team.

View File

@ -8,8 +8,11 @@ Linux).
Given `make` and `rsync` are available on your system (in `$PATH`), the Given `make` and `rsync` are available on your system (in `$PATH`), the
following will copy the `kmk` tree to your CircuitPython device, and will copy following will copy the `kmk` tree to your CircuitPython device, and will copy
the file defined as `USER_KEYMAP` as your `main.py`. If any of these files exist the file defined as `USER_KEYMAP` as your `main.py`. It will also copy our
on your CircuitPython device already, they will be overwritten without a prompt. `boot.py`, which allocates a larger stack size (simply - more of the device's
RAM will be available to KMK and your keyboard config) than CircuitPython's
default. If any of these files exist on your CircuitPython device already, they
will be overwritten without a prompt.
If you get permissions errors here, **don't run make as root or with sudo**. See If you get permissions errors here, **don't run make as root or with sudo**. See
`Troubleshooting` below. `Troubleshooting` below.

View File

@ -1,177 +0,0 @@
# Keymap
Keymaps in KMK are simple Python class objects with various attributes assigned
(some by default, however all are overridable).
The basics of what you'll need to get started are:
- Import the `KeyboardConfig` object for your keyboard from `kmk.boards` (or, if
handwiring your keyboard, import `KeyboardConfig` from the appropriate MCU for your
board from `kmk.mcus`. See `hardware.md` for the list of supported boards and
map this to the correct Python module under either of those paths.
- Add a file to `user_keymaps/your_username` called whatever you'd like
- Assign a `KeyboardConfig` instance to a variable (ex. `keyboard = KeyboardConfig()` - note
the parentheses)
- Make sure this `KeyboardConfig` instance is actually run at the end of the file with
a block such as the following:
```python
if __name__ == '__main__':
keyboard.go()
```
- Assign pins and your diode orientation (only necessary on handwire keyboards),
for example:
```python
col_pins = (P.SCK, P.MOSI, P.MISO, P.RX, P.TX, P.D4)
row_pins = (P.D10, P.D11, P.D12, P.D13, P.D9, P.D6, P.D5, P.SCL)
rollover_cols_every_rows = 4
diode_orientation = DiodeOrientation.COLUMNS
swap_indicies = {
(3, 3): (3, 9),
(3, 4): (3, 10),
(3, 5): (3, 11),
}
```
The pins should be based on whatever CircuitPython calls pins on your particular
board. You can find these in the REPL on your CircuitPython device:
```python
import board
print(dir(board))
```
> Note: `rollover_cols_every_rows` is only supported with
> `DiodeOrientation.COLUMNS`, not `DiodeOrientation.ROWS`. It is used for boards
> such as the Planck Rev6 which reuse column pins to simulate a 4x12 matrix in
> the form of an 8x6 matrix
> Note: `swap_indicies` is used to literally flip two keys' positions in the
> matrix. This is pretty rarely needed, but for example the Planck Rev6 in full
> 1u Grid mode swaps the bottom three right keys on each "half", thus the
> example above
You can further define a bunch of other stuff:
- `debug_enabled` which will spew a ton of debugging information to the serial
console. This is very rarely needed, but can provide very valuable information
if you need to open an issue.
- `unicode_mode` from `kmk.consts.UnicodeMode`, which defines the default
operating system implementation to use for unicode sequences (see examples
below, or `unicode.md`. This can be changed after boot with a key (see
`keycodes.md`)
- `tap_time` which defines how long `KC.TT` and `KC.LT` will wait before
considering a key "held" (see `keycodes.md`)
- `leader_dictionary`, which defines leader sequences (see `leader.md`), defined
as tuples of keycode objects (or you can use
`kmk.keycodes.generate_leader_dictionary_seq` with a string)
We also support unicode sequences (emojis, emoticons, umlauted letters,
whatever) if your operating system and system setup do! See `unicode.md` for
details.
Here's a giant example of all the above. This is my personal 4x12 matrix layout
running on a Planck Rev6 PCB, with a Feather M4 Express wired up to the outer
matrix pins (in somewhat of a "spider" setup), utilizing most of the above
features:
```python
from kmk.boards.klarank import KeyboardConfig
from kmk.consts import UnicodeMode
from kmk.keycodes import KC
from kmk.keycodes import generate_leader_dictionary_seq as glds
from kmk.macros.simple import send_string
from kmk.macros.unicode import compile_unicode_string_sequences as cuss
keyboard = KeyboardConfig()
keyboard.debug_enabled = True
keyboard.unicode_mode = UnicodeMode.LINUX
_______ = KC.TRNS
xxxxxxx = KC.NO
emoticons = cuss({
# Emojis
'BEER': r'🍺',
'BEER_TOAST': r'🍻',
'FACE_CUTE_SMILE': r'😊',
'FACE_HEART_EYES': r'😍',
'FACE_JOY': r'😂',
'FACE_SWEAT_SMILE': r'😅',
'FACE_THINKING': r'🤔',
'FIRE': r'🔥',
'FLAG_CA': r'🇨🇦',
'FLAG_US': r'🇺🇸',
'HAND_CLAP': r'👏',
'HAND_HORNS': r'🤘',
'HAND_OK': r'👌',
'HAND_THUMB_DOWN': r'👎',
'HAND_THUMB_UP': r'👍',
'HAND_WAVE': r'👋',
'HEART': r'❤️',
'MAPLE_LEAF': r'🍁',
'POOP': r'💩',
'TADA': r'🎉',
# Emoticons, but fancier
'ANGRY_TABLE_FLIP': r'(ノಠ痊ಠ)ノ彡┻━┻',
'CELEBRATORY_GLITTER': r'+。:.゚ヽ(´∀。)ノ゚.:。+゚゚+。:.゚ヽ(*´∀)ノ゚.:。+゚',
'SHRUGGIE': r'¯\_(ツ)_/¯',
'TABLE_FLIP': r'(╯°□°)╯︵ ┻━┻',
})
WPM = send_string("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bibendum arcu vitae elementum curabitur vitae nunc sed. Facilisis sed odio morbi quis.")
keyboard.leader_dictionary = {
glds('hello'): send_string('hello world from kmk macros'),
glds('wpm'): WPM,
glds('atf'): emoticons.ANGRY_TABLE_FLIP,
glds('tf'): emoticons.TABLE_FLIP,
glds('fca'): emoticons.FLAG_CA,
glds('fus'): emoticons.FLAG_US,
glds('cel'): emoticons.CELEBRATORY_GLITTER,
}
keyboard.keymap = [
[
[KC.GESC, KC.QUOT, KC.COMM, KC.DOT, KC.P, KC.Y, KC.F, KC.G, KC.C, KC.R, KC.L, KC.BSPC],
[KC.TAB, KC.A, KC.O, KC.E, KC.U, KC.I, KC.D, KC.H, KC.T, KC.N, KC.S, KC.ENT],
[KC.LGUI, KC.SCLN, KC.Q, KC.J, KC.K, KC.X, KC.B, KC.M, KC.W, KC.V, KC.Z, KC.LALT],
[KC.LCTL, KC.LEAD, KC.LSHIFT(KC.LGUI), KC.MO(2), KC.MO(3), KC.LSFT, KC.SPC, KC.MO(1), KC.LEFT, KC.DOWN, KC.UP, KC.RGHT],
],
[
[KC.GESC, xxxxxxx, xxxxxxx, KC.F10, KC.F11, KC.F12, xxxxxxx, KC.PSLS, KC.N7, KC.N8, KC.N9, KC.BSPC],
[KC.TAB, xxxxxxx, xxxxxxx, KC.F7, KC.F8, KC.F9, xxxxxxx, KC.PAST, KC.N4, KC.N5, KC.N6, _______],
[KC.LGUI, xxxxxxx, xxxxxxx, KC.F4, KC.F5, KC.F6, xxxxxxx, KC.PMNS, KC.N1, KC.N2, KC.N3, _______],
[KC.LCTL, xxxxxxx, _______, KC.F1, KC.F2, KC.F3, KC.SPC, _______, KC.N0, KC.DOT, xxxxxxx, KC.EQL],
],
[
[KC.GESC, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.BSLS, KC.LBRC, KC.RBRC, KC.DEL],
[KC.TAB, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.MINS],
[KC.LGUI, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.LBRC, xxxxxxx, xxxxxxx, KC.INS],
[KC.LCTL, xxxxxxx, _______, _______, xxxxxxx, _______, xxxxxxx, xxxxxxx, KC.HOME, KC.PGDN, KC.PGUP, KC.END],
],
[
[KC.GRV, KC.EXLM, KC.AT, KC.HASH, KC.DLR, KC.PERC, KC.CIRC, KC.AMPR, KC.ASTR, KC.LPRN, KC.RPRN, KC.SLSH],
[KC.TAB, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, KC.MINS],
[KC.LGUI, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx],
[KC.LCTL, xxxxxxx, xxxxxxx, xxxxxxx, _______, _______, xxxxxxx, xxxxxxx, KC.MUTE, KC.VOLD, KC.VOLU, xxxxxxx],
],
]
if __name__ == '__main__':
keyboard.go()
```

View File

@ -40,11 +40,11 @@ Here's an example of all this in action:
```python ```python
# user_keymaps/some_silly_example.py # user_keymaps/some_silly_example.py
from kmk.boards.klarank import KeyboardConfig from kmk.boards.klarank import KMKKeyboard
from kmk.keycodes import KC from kmk.keycodes import KC
from kmk.macros.simple import send_string from kmk.macros.simple import send_string
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
keyboard.tap_time = 750 keyboard.tap_time = 750

View File

@ -1,9 +1,10 @@
from kmk.consts import DiodeOrientation import board
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.matrix import DiodeOrientation
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.D9, P.D10, P.D11, P.D12, P.D13, P.SCL) col_pins = (board.D9, board.D10, board.D11, board.D12, board.D13, board.SCL)
row_pins = (P.A3, P.A4, P.A5, P.SCK, P.MOSI) row_pins = (board.A3, board.A4, board.A5, board.SCK, board.MOSI)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,13 +1,30 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (
row_pins = (P.TX, P.RX, P.SDA, P.SCL, P.D13, P.D12, P.D11, P.D10) board.A0,
board.A1,
board.A2,
board.A3,
board.A4,
board.A5,
board.SCK,
board.MOSI,
)
row_pins = (
board.TX,
board.RX,
board.SDA,
board.SCL,
board.D13,
board.D12,
board.D11,
board.D10,
)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.D9 rgb_pixel_pin = board.D9
rgb_num_pixels = 12 rgb_num_pixels = 12

View File

@ -1,11 +1,20 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.RX, P.D13, P.A0, P.D11, P.A4, P.A5, P.D10, P.D9, P.SCK) col_pins = (
board.RX,
board.D13,
board.A0,
board.D11,
board.A4,
board.A5,
board.D10,
board.D9,
board.SCK,
)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (board.A1, board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (P.A0, P.D11, P.D10, P.D9) row_pins = (board.A0, board.D11, board.D10, board.D9)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (P.D11, P.D10, P.D9, P.D7, P.D13) row_pins = (board.D11, board.D10, board.D9, board.D7, board.D13)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,17 +1,16 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P from kmk.matrix import intify_coordinate as ic
from kmk.util import intify_coordinate as ic
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
# Pin mappings for converter board found at hardware/README.md # Pin mappings for converter board found at hardware/README.md
# QMK: MATRIX_COL_PINS { F6, F7, B1, B3, B2, B6 } # QMK: MATRIX_COL_PINS { F6, F7, B1, B3, B2, B6 }
# QMK: MATRIX_ROW_PINS { D7, E6, B4, D2, D4 } # QMK: MATRIX_ROW_PINS { D7, E6, B4, D2, D4 }
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (P.D11, P.D10, P.D9, P.RX, P.D13) row_pins = (board.D11, board.D10, board.D9, board.RX, board.D13)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
split_flip = True split_flip = True

View File

@ -1,12 +1,28 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.SDA, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (
row_pins = (P.TX, P.A0, P.RX, P.A1, P.D11, P.D9, P.D12, P.D10) board.SDA,
board.A2,
board.A3,
board.A4,
board.A5,
board.SCK,
board.MOSI,
)
row_pins = (
board.TX,
board.A0,
board.RX,
board.A1,
board.D11,
board.D9,
board.D12,
board.D10,
)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.D13 rgb_pixel_pin = board.D13

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.A0) col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.A0)
row_pins = (P.D11, P.D10, P.D9, P.D7) row_pins = (board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (P.D13, P.D11, P.D10, P.D9) row_pins = (board.D13, board.D11, board.D10, board.D9)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
split_type = 'UART' split_type = 'UART'

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7) row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.RX, P.A1, P.A2, P.A3, P.A4, P.A5) col_pins = (board.RX, board.A1, board.A2, board.A3, board.A4, board.A5)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7) row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
split_type = 'UART' split_type = 'UART'

View File

@ -1,14 +1,22 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
# Will need additional work and testing # Will need additional work and testing
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI, P.D12) col_pins = (
row_pins = (P.A0, P.D13, P.D11, P.D10, P.D9, P.D7) board.A1,
board.A2,
board.A3,
board.A4,
board.A5,
board.SCK,
board.MOSI,
board.D12,
)
row_pins = (board.A0, board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (P.D11, P.D10, P.D9, P.RX, P.D13) row_pins = (board.D11, board.D10, board.D9, board.RX, board.D13)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,9 +1,29 @@
from kmk.consts import DiodeOrientation import board
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.matrix import DiodeOrientation
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (
row_pins = (P.TX, P.RX, P.SDA, P.SCL, P.D9, P.D10, P.D12, P.D11, P.D13) board.A0,
board.A1,
board.A2,
board.A3,
board.A4,
board.A5,
board.SCK,
board.MOSI,
)
row_pins = (
board.TX,
board.RX,
board.SDA,
board.SCL,
board.D9,
board.D10,
board.D12,
board.D11,
board.D13,
)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (board.A1, board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7) row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK) col_pins = (board.A0, board.A1, board.A2, board.A3, board.A4, board.A5, board.SCK)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7) row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.A5, P.A4, P.A3, P.A2, P.A1, P.A0) col_pins = (board.A5, board.A4, board.A3, board.A2, board.A1, board.A0)
row_pins = (P.D7, P.D9, P.D10, P.D11) row_pins = (board.D7, board.D9, board.D10, board.D11)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig from kmk.matrix import DiodeOrientation
from kmk.pins import Pin as P
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
col_pins = (P.MOSI, P.SCK, P.A5, P.A4, P.A3, P.A2) col_pins = (board.MOSI, board.SCK, board.A5, board.A4, board.A3, board.A2)
row_pins = (P.D11, P.D10, P.D9, P.D7) row_pins = (board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX rgb_pixel_pin = board.TX
uart_pin = board.SCL uart_pin = board.SCL

View File

@ -1,9 +1,10 @@
from kmk.consts import DiodeOrientation import board
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P
from kmk.util import intify_coordinate as ic
# Implements what used to be handled by KeyboardConfig.swap_indicies for this from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.matrix import DiodeOrientation
from kmk.matrix import intify_coordinate as ic
# Implements what used to be handled by KMKKeyboard.swap_indicies for this
# board, by flipping various row3 (bottom physical row) keys so their # board, by flipping various row3 (bottom physical row) keys so their
# coord_mapping matches what the user pressed (even if the wiring # coord_mapping matches what the user pressed (even if the wiring
# underneath is sending different coordinates) # underneath is sending different coordinates)
@ -17,11 +18,20 @@ def r3_swap(col):
return col return col
class KeyboardConfig(_KeyboardConfig): class KMKKeyboard(_KMKKeyboard):
# physical, visible cols (SCK, MO, MI, RX, TX, D4) # physical, visible cols (SCK, MO, MI, RX, TX, D4)
# physical, visible rows (10, 11, 12, 13) (9, 6, 5, SCL) # physical, visible rows (10, 11, 12, 13) (9, 6, 5, SCL)
col_pins = (P.SCK, P.MOSI, P.MISO, P.RX, P.TX, P.D4) col_pins = (board.SCK, board.MOSI, board.MISO, board.RX, board.TX, board.D4)
row_pins = (P.D10, P.D11, P.D12, P.D13, P.D9, P.D6, P.D5, P.SCL) row_pins = (
board.D10,
board.D11,
board.D12,
board.D13,
board.D9,
board.D6,
board.D5,
board.SCL,
)
rollover_cols_every_rows = 4 rollover_cols_every_rows = 4
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -3,50 +3,6 @@ try:
except Exception: except Exception:
KMK_RELEASE = 'copied-from-git' KMK_RELEASE = 'copied-from-git'
CIRCUITPYTHON = 'CircuitPython'
MICROPYTHON = 'MicroPython'
class HIDReportTypes:
KEYBOARD = 1
MOUSE = 2
CONSUMER = 3
SYSCONTROL = 4
class HIDUsage:
KEYBOARD = 0x06
MOUSE = 0x02
CONSUMER = 0x01
SYSCONTROL = 0x80
class HIDUsagePage:
CONSUMER = 0x0C
KEYBOARD = MOUSE = SYSCONTROL = 0x01
# Currently only used by the CircuitPython HIDHelper because CircuitPython
# actually enforces these limits with a ValueError. Unused on PyBoard because
# we can happily send full reports there and it magically works.
HID_REPORT_SIZES = {
HIDReportTypes.KEYBOARD: 8,
HIDReportTypes.MOUSE: 4,
HIDReportTypes.CONSUMER: 2,
HIDReportTypes.SYSCONTROL: 8, # TODO find the correct value for this
}
class DiodeOrientation:
'''
Orientation of diodes on handwired boards. You can think of:
COLUMNS = vertical
ROWS = horizontal
'''
COLUMNS = 0
ROWS = 1
class UnicodeMode: class UnicodeMode:
NOOP = 0 NOOP = 0

View File

@ -2,7 +2,13 @@ from kmk.consts import UnicodeMode
from kmk.handlers.stock import passthrough from kmk.handlers.stock import passthrough
from kmk.keys import KC, make_key from kmk.keys import KC, make_key
from kmk.types import AttrDict, KeySequenceMeta from kmk.types import AttrDict, KeySequenceMeta
from kmk.util import get_wide_ordinal
def get_wide_ordinal(char):
if len(char) != 2:
return ord(char)
return 0x10000 + (ord(char[0]) - 0xD800) * 0x400 + (ord(char[1]) - 0xDC00)
def sequence_press_handler(key, state, KC, *args, **kwargs): def sequence_press_handler(key, state, KC, *args, **kwargs):

View File

@ -1,5 +1,4 @@
from kmk.kmktime import sleep_ms from kmk.kmktime import sleep_ms
from kmk.util import reset_bootloader, reset_keyboard
def passthrough(key, state, *args, **kwargs): def passthrough(key, state, *args, **kwargs):
@ -29,11 +28,28 @@ def default_released(key, state, KC, coord_int=None, coord_raw=None):
def reset(*args, **kwargs): def reset(*args, **kwargs):
reset_keyboard() try:
import machine
machine.reset()
except ImportError:
import microcontroller
microcontroller.reset()
def bootloader(*args, **kwargs): def bootloader(*args, **kwargs):
reset_bootloader() try:
import machine
machine.bootloader()
except ImportError:
import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()
def debug_pressed(key, state, KC, *args, **kwargs): def debug_pressed(key, state, KC, *args, **kwargs):

View File

@ -1,8 +1,44 @@
from kmk.consts import HID_REPORT_SIZES, HIDReportTypes, HIDUsage, HIDUsagePage import usb_hid
from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey
class USB_HID: class HIDModes:
NOOP = 0 # currently unused; for testing?
USB = 1
BLE = 2 # currently unused; for bluetooth
ALL_MODES = (NOOP, USB, BLE)
class HIDReportTypes:
KEYBOARD = 1
MOUSE = 2
CONSUMER = 3
SYSCONTROL = 4
class HIDUsage:
KEYBOARD = 0x06
MOUSE = 0x02
CONSUMER = 0x01
SYSCONTROL = 0x80
class HIDUsagePage:
CONSUMER = 0x0C
KEYBOARD = MOUSE = SYSCONTROL = 0x01
HID_REPORT_SIZES = {
HIDReportTypes.KEYBOARD: 8,
HIDReportTypes.MOUSE: 4,
HIDReportTypes.CONSUMER: 2,
HIDReportTypes.SYSCONTROL: 8, # TODO find the correct value for this
}
class AbstractHID:
REPORT_BYTES = 8 REPORT_BYTES = 8
def __init__(self): def __init__(self):
@ -152,15 +188,7 @@ class USB_HID:
return self return self
try: class USBHID(AbstractHID):
import usb_hid
PLATFORM_CIRCUITPYTHON = True
except ImportError:
PLATFORM_CIRCUITPYTHON = False
else:
class CircuitPythonUSB_HID(USB_HID):
REPORT_BYTES = 9 REPORT_BYTES = 9
def post_init(self): def post_init(self):
@ -193,3 +221,10 @@ else:
return self.devices[reporting_device_const].send_report( return self.devices[reporting_device_const].send_report(
evt[1 : HID_REPORT_SIZES[reporting_device_const] + 1] evt[1 : HID_REPORT_SIZES[reporting_device_const] + 1]
) )
class BLEHID(AbstractHID):
def __init__(self, *args, **kwargs):
raise NotImplementedError(
'BLE HID is not supported by upstream CircuitPython yet'
)

View File

@ -1,8 +1,8 @@
from kmk.consts import LeaderMode from kmk.consts import LeaderMode
from kmk.keys import KC from kmk.keys import KC
from kmk.kmktime import ticks_ms from kmk.kmktime import ticks_ms
from kmk.matrix import intify_coordinate
from kmk.types import TapDanceKeyMeta from kmk.types import TapDanceKeyMeta
from kmk.util import intify_coordinate
class InternalState: class InternalState:

View File

@ -1,59 +1,22 @@
# Welcome to RAM and stack size hacks central, I'm your host, klardotsh! # There's a chance doing preload RAM hacks this late will cause recursion
# We really get stuck between a rock and a hard place on CircuitPython # errors, but we'll see. I'd rather do it here than require everyone copy-paste
# sometimes: our import structure is deeply nested enough that stuff # a line into their keymaps.
# breaks in some truly bizarre ways, including: import kmk.preload_imports # isort:skip # NOQA
# - explicit RuntimeError exceptions, complaining that our
# stack depth is too deep
#
# - silent hard locks of the device (basically unrecoverable without
# UF2 flash if done in main.py, fixable with a reboot if done
# in REPL)
#
# However, there's a hackaround that works for us! Because sys.modules
# caches everything it sees (and future imports will use that cached
# copy of the module), let's take this opportunity _way_ up the import
# chain to import _every single thing_ KMK eventually uses in a normal
# workflow, in order from fewest to least nested dependencies.
# First, system-provided deps import busio
import busio # isort:skip import gc
import collections # isort:skip
import gc # isort:skip
import supervisor # isort:skip
# Now "light" KMK stuff with few/no external deps
import kmk.consts # isort:skip
import kmk.kmktime # isort:skip
import kmk.types # isort:skip
import kmk.util # isort:skip
from kmk.consts import LeaderMode, UnicodeMode, KMK_RELEASE # isort:skip
from kmk.hid import USB_HID # isort:skip
from kmk.internal_state import InternalState # isort:skip
from kmk.keys import KC # isort:skip
from kmk.matrix import MatrixScanner # isort:skip
# Now handlers that will be used in keys later
import kmk.handlers.layers # isort:skip
import kmk.handlers.stock # isort:skip
# Now stuff that depends on the above (and so on)
import kmk.keys # isort:skip
import kmk.matrix # isort:skip
import kmk.hid # isort:skip
import kmk.internal_state # isort:skip
# GC runs automatically after CircuitPython imports.
# Thanks for sticking around. Now let's do real work, starting below
from kmk import led, rgb
from kmk.consts import KMK_RELEASE, LeaderMode, UnicodeMode
from kmk.hid import BLEHID, USBHID, AbstractHID, HIDModes
from kmk.internal_state import InternalState
from kmk.keys import KC
from kmk.kmktime import sleep_ms from kmk.kmktime import sleep_ms
from kmk.util import intify_coordinate as ic from kmk.matrix import MatrixScanner
from kmk import led, rgb # isort:skip from kmk.matrix import intify_coordinate as ic
class KeyboardConfig: class KMKKeyboard:
debug_enabled = False debug_enabled = False
keymap = None keymap = None
@ -71,8 +34,6 @@ class KeyboardConfig:
leader_dictionary = {} leader_dictionary = {}
leader_timeout = 1000 leader_timeout = 1000
hid_helper = USB_HID
# Split config # Split config
extra_data_pin = None extra_data_pin = None
split_offsets = () split_offsets = ()
@ -95,7 +56,7 @@ class KeyboardConfig:
def __repr__(self): def __repr__(self):
return ( return (
'KeyboardConfig(' 'KMKKeyboard('
'debug_enabled={} ' 'debug_enabled={} '
'keymap=truncated ' 'keymap=truncated '
'coord_mapping=truncated ' 'coord_mapping=truncated '
@ -229,11 +190,14 @@ class KeyboardConfig:
else: else:
return busio.UART(tx=pin, rx=None, timeout=timeout) return busio.UART(tx=pin, rx=None, timeout=timeout)
def go(self): def go(self, hid_type=HIDModes.USB):
assert self.keymap, 'must define a keymap with at least one row' assert self.keymap, 'must define a keymap with at least one row'
assert self.row_pins, 'no GPIO pins defined for matrix rows' assert self.row_pins, 'no GPIO pins defined for matrix rows'
assert self.col_pins, 'no GPIO pins defined for matrix columns' assert self.col_pins, 'no GPIO pins defined for matrix columns'
assert self.diode_orientation is not None, 'diode orientation must be defined' assert self.diode_orientation is not None, 'diode orientation must be defined'
assert (
hid_type in HIDModes.ALL_MODES
), 'hid_type must be a value from kmk.consts.HIDModes'
# Attempt to sanely guess a coord_mapping if one is not provided # Attempt to sanely guess a coord_mapping if one is not provided
@ -253,6 +217,13 @@ class KeyboardConfig:
self._state = InternalState(self) self._state = InternalState(self)
if hid_type == HIDModes.NOOP:
self.hid_helper = AbstractHID
elif hid_type == HIDModes.USB:
self.hid_helper = USBHID
elif hid_type == HIDModes.BLE:
self.hid_helper = BLEHID
self._hid_helper_inst = self.hid_helper() self._hid_helper_inst = self.hid_helper()
# Split keyboard Init # Split keyboard Init

View File

@ -1,7 +1,6 @@
import pulseio
import time import time
from math import e, exp, pi, sin from math import e, exp, pi, sin
import pulseio
from micropython import const from micropython import const
led_config = { led_config = {

View File

@ -1,6 +1,20 @@
import digitalio import digitalio
import gc
from kmk.consts import DiodeOrientation
def intify_coordinate(row, col):
return row << 8 | col
class DiodeOrientation:
'''
Orientation of diodes on handwired boards. You can think of:
COLUMNS = vertical
ROWS = horizontal
'''
COLUMNS = 0
ROWS = 1
class MatrixScanner: class MatrixScanner:
@ -11,28 +25,29 @@ class MatrixScanner:
diode_orientation=DiodeOrientation.COLUMNS, diode_orientation=DiodeOrientation.COLUMNS,
rollover_cols_every_rows=None, rollover_cols_every_rows=None,
): ):
self.len_cols = len(cols)
self.len_rows = len(rows)
# A pin cannot be both a row and column, detect this by combining the # A pin cannot be both a row and column, detect this by combining the
# two tuples into a set and validating that the length did not drop # two tuples into a set and validating that the length did not drop
# #
# repr() hackery is because CircuitPython Pin objects are not hashable # repr() hackery is because CircuitPython Pin objects are not hashable
unique_pins = {repr(c) for c in cols} | {repr(r) for r in rows} unique_pins = {repr(c) for c in cols} | {repr(r) for r in rows}
if len(unique_pins) != len(cols) + len(rows): assert (
raise ValueError('Cannot use a pin as both a column and row') len(unique_pins) == self.len_cols + self.len_rows
), 'Cannot use a pin as both a column and row'
self.cols = cols del unique_pins
self.rows = rows gc.collect()
self.len_cols = len(cols)
self.len_rows = len(rows)
self.diode_orientation = diode_orientation self.diode_orientation = diode_orientation
if self.diode_orientation == DiodeOrientation.COLUMNS: if self.diode_orientation == DiodeOrientation.COLUMNS:
self.outputs = self.cols self.outputs = [digitalio.DigitalInOut(x) for x in cols]
self.inputs = self.rows self.inputs = [digitalio.DigitalInOut(x) for x in rows]
self.translate_coords = True self.translate_coords = True
elif self.diode_orientation == DiodeOrientation.ROWS: elif self.diode_orientation == DiodeOrientation.ROWS:
self.outputs = self.rows self.outputs = [digitalio.DigitalInOut(x) for x in rows]
self.inputs = self.cols self.inputs = [digitalio.DigitalInOut(x) for x in cols]
self.translate_coords = False self.translate_coords = False
else: else:
raise ValueError( raise ValueError(
@ -64,7 +79,7 @@ class MatrixScanner:
any_changed = False any_changed = False
for oidx, opin in enumerate(self.outputs): for oidx, opin in enumerate(self.outputs):
opin.value(True) opin.value = True
for iidx, ipin in enumerate(self.inputs): for iidx, ipin in enumerate(self.inputs):
# cast to int to avoid # cast to int to avoid
@ -78,7 +93,7 @@ class MatrixScanner:
# I haven't dived too far into what causes this, but it's # I haven't dived too far into what causes this, but it's
# almost certainly because bool types in Python aren't just # almost certainly because bool types in Python aren't just
# aliases to int values, but are proper pseudo-types # aliases to int values, but are proper pseudo-types
new_val = int(ipin.value()) new_val = int(ipin.value)
old_val = self.state[ba_idx] old_val = self.state[ba_idx]
if old_val != new_val: if old_val != new_val:
@ -104,7 +119,7 @@ class MatrixScanner:
ba_idx += 1 ba_idx += 1
opin.value(False) opin.value = False
if any_changed: if any_changed:
break break

View File

View File

@ -1,6 +0,0 @@
from kmk.hid import CircuitPythonUSB_HID
from kmk.keyboard_config import KeyboardConfig as _KeyboardConfig
class KeyboardConfig(_KeyboardConfig):
hid_helper = CircuitPythonUSB_HID

View File

@ -1,99 +0,0 @@
from micropython import const
from kmk.consts import CIRCUITPYTHON, MICROPYTHON
PULL_UP = const(1)
PULL_DOWN = const(2)
try:
import board
import digitalio
PLATFORM = CIRCUITPYTHON
PIN_SOURCE = board
except ImportError:
import machine
PLATFORM = MICROPYTHON
PIN_SOURCE = machine.Pin.board
def get_pin(pin):
'''
Cross-platform method to find a pin by string.
The pin definitions are platform-dependent, but this provides
a way to say "I'm using pin D20" without rolling a D20 and
having to actually learn MicroPython/CircuitPython and the
differences in how they handle pinouts.
This also makes the keymap sanity checker actually work for
CircuitPython boards, since it's not possible in CPY to
define a module stub for `board` that uses Passthrough
natively (which is how the MicroPython stub worked originally)
'''
return getattr(PIN_SOURCE, pin)
class AbstractedDigitalPin:
def __init__(self, pin):
self.raw_pin = pin
if PLATFORM == CIRCUITPYTHON:
self.pin = digitalio.DigitalInOut(pin)
elif PLATFORM == MICROPYTHON:
self.pin = machine.Pin(pin)
else:
self.pin = pin
self.call_value = callable(self.pin.value)
def __repr__(self):
return 'AbstractedPin({})'.format(repr(self.raw_pin))
def switch_to_input(self, pull=None):
if PLATFORM == CIRCUITPYTHON:
if pull == PULL_UP:
return self.pin.switch_to_input(pull=digitalio.Pull.UP)
elif pull == PULL_DOWN:
return self.pin.switch_to_input(pull=digitalio.Pull.DOWN)
return self.pin.switch_to_input(pull=pull)
elif PLATFORM == MICROPYTHON:
if pull == PULL_UP:
return self.pin.init(machine.Pin.IN, machine.Pin.PULL_UP)
elif pull == PULL_DOWN:
return self.pin.init(machine.Pin.IN, machine.Pin.PULL_DOWN)
raise ValueError('only PULL_UP and PULL_DOWN supported on MicroPython')
raise NotImplementedError('switch_to_input not supported on platform')
def switch_to_output(self):
if PLATFORM == CIRCUITPYTHON:
return self.pin.switch_to_output()
elif PLATFORM == MICROPYTHON:
return self.pin.init(machine.Pin.OUT)
raise NotImplementedError('switch_to_output not supported on platform')
def value(self, value=None):
if value is None:
if self.call_value:
return self.pin.value()
return self.pin.value
if self.call_value:
return self.pin.value(value)
self.pin.value = value
return value
class PinLookup:
def __getattr__(self, attr):
return AbstractedDigitalPin(get_pin(attr))
Pin = PinLookup()

45
kmk/preload_imports.py Normal file
View File

@ -0,0 +1,45 @@
# Welcome to RAM and stack size hacks central, I'm your host, klardotsh!
# Our import structure is deeply nested enough that stuff
# breaks in some truly bizarre ways, including:
# - explicit RuntimeError exceptions, complaining that our
# stack depth is too deep
#
# - silent hard locks of the device (basically unrecoverable without
# UF2 flash if done in main.py, fixable with a reboot if done
# in REPL)
#
# However, there's a hackaround that works for us! Because sys.modules
# caches everything it sees (and future imports will use that cached
# copy of the module), let's take this opportunity _way_ up the import
# chain to import _every single thing_ KMK eventually uses in a normal
# workflow, in nesting order
#
# GC runs automatically after CircuitPython imports.
# First, system-provided deps
import busio
import collections
import gc
import supervisor
# Now "light" KMK stuff with few/no external deps
import kmk.consts # isort:skip
import kmk.kmktime # isort:skip
import kmk.types # isort:skip
from kmk.consts import LeaderMode, UnicodeMode, KMK_RELEASE # isort:skip
from kmk.hid import USBHID # isort:skip
from kmk.internal_state import InternalState # isort:skip
from kmk.keys import KC # isort:skip
from kmk.matrix import MatrixScanner # isort:skip
# Now handlers that will be used in keys later
import kmk.handlers.layers # isort:skip
import kmk.handlers.stock # isort:skip
# Now stuff that depends on the above (and so on)
import kmk.keys # isort:skip
import kmk.matrix # isort:skip
import kmk.hid # isort:skip
import kmk.internal_state # isort:skip

View File

@ -1,6 +1,5 @@
import time import time
from math import e, exp, pi, sin from math import e, exp, pi, sin
from micropython import const from micropython import const
rgb_config = { rgb_config = {

View File

@ -11,23 +11,6 @@ class AttrDict(dict):
return self[key] return self[key]
class Anything:
'''
A stub class which will repr as a provided name
'''
def __init__(self, name):
self.name = name
def __repr__(self):
return 'Anything<{}>'.format(self.name)
class Passthrough:
def __getattr__(self, attr):
return Anything(attr)
class LayerKeyMeta: class LayerKeyMeta:
def __init__(self, layer, kc=None): def __init__(self, layer, kc=None):
self.layer = layer self.layer = layer

View File

@ -1,46 +0,0 @@
def intify_coordinate(row, col):
return row << 8 | col
def get_wide_ordinal(char):
if len(char) != 2:
return ord(char)
return 0x10000 + (ord(char[0]) - 0xD800) * 0x400 + (ord(char[1]) - 0xDC00)
def flatten_dict(d):
items = {}
for k, v in d.items():
if isinstance(v, dict):
items.update(flatten_dict(v))
else:
items[k] = v
return items
def reset_keyboard():
try:
import machine
machine.reset()
except ImportError:
import microcontroller
microcontroller.reset()
def reset_bootloader():
try:
import machine
machine.bootloader()
except ImportError:
import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()

View File

@ -18,5 +18,6 @@ exclude = '''
| build | build
| docs | docs
| user_keymaps | user_keymaps
| mnt
)/ )/
''' '''

View File

@ -1,23 +1,55 @@
[flake8] [flake8]
exclude = .git,__pycache__,vendor,.venv,build exclude = .git,__pycache__,vendor,.venv,build,dist,.compiled,mnt
# match black expectations # match black expectations
max_line_length = 88 max_line_length = 88
# enforce single quotes # enforce single quotes
select = Q0
docstring-quotes = ''' docstring-quotes = '''
multiline-quotes = ''' multiline-quotes = '''
ignore = X100, E262 extend-ignore =
X100, E262,
# See https://github.com/PyCQA/pycodestyle/issues/373
E203,
# comply with black
# it will handle line lengths automatically
E501,
# it also controls trailing commas in general
C812, C813, C815,
per-file-ignores = per-file-ignores =
# Allow crazy line lengths, unused variables, and multiple spaces after commas in lists (for grid alignment) # Allow crazy line lengths, unused variables, and multiple spaces after commas in lists (for grid alignment)
user_keymaps/**/*.py: F401,E501,E241,E131 user_keymaps/**/*.py: F401,E501,E241,E131,BLK100
tests/test_data/keymaps/**/*.py: F401,E501 tests/test_data/keymaps/**/*.py: F401,E501
# Forgive me for my RAM hack sins # Forgive me for my RAM hack sins
kmk/keyboard_config.py: I001,I003,I004,F401 kmk/preload_imports.py: I001,I003,I004,F401
[isort] [isort]
known_third_party = analogio,bitbangio,bleio,board,busio,digitalio,framebuf,gamepad,gc,microcontroller,micropython,pulseio,pyb,pydux,uio,ubluepy,machine,pyb,uos known_standard_library =
analogio,
bitbangio,
bleio,
board,
busio,
digitalio,
framebuf,
gamepad,
gc,
machine,
microcontroller,
micropython,
neopixel,
pulseio,
pyb,
pyb,
pydux,
supervisor,
ubluepy,
uio,
uos,
usb_hid,
# black compat
multi_line_output=3 multi_line_output=3
include_trailing_comma=True include_trailing_comma=True
force_grid_wrap=0 force_grid_wrap=0

View File

@ -1,21 +0,0 @@
import machine
from kmk.consts import DiodeOrientation
from kmk.entrypoints.handwire.pyboard import main
from kmk.keycodes import KC
p = machine.Pin.board
cols = (p.X10, p.X10, p.X12)
rows = (p.X1, p.X2, p.X3)
diode_orientation = DiodeOrientation.COLUMNS
keymap = [
[
[KC.MO(1), KC.H, KC.RESET],
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[[KC.TRNS, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -1,21 +0,0 @@
import machine
from kmk.consts import DiodeOrientation
from kmk.entrypoints.handwire.pyboard import main
from kmk.keycodes import KC
p = machine.Pin.board
cols = (p.X10, p.X11, p.X12)
rows = (p.X1, p.X11, p.X3)
diode_orientation = DiodeOrientation.COLUMNS
keymap = [
[
[KC.MO(1), KC.H, KC.RESET],
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[[KC.TRNS, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -1,21 +0,0 @@
import machine
from kmk.consts import DiodeOrientation
from kmk.entrypoints.handwire.pyboard import main
from kmk.keycodes import KC
p = machine.Pin.board
cols = (p.X10, p.X11, p.X12)
rows = (p.X1, p.X2, p.X3)
diode_orientation = DiodeOrientation.COLUMNS
keymap = [
[
[KC.MO(1), KC.H, KC.RESET],
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[[KC.A, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -1,21 +0,0 @@
import machine
from kmk.consts import DiodeOrientation
from kmk.entrypoints.handwire.pyboard import main
from kmk.keycodes import KC
p = machine.Pin.board
cols = (p.X10, p.X11, p.X12)
rows = (p.X1, p.X2, p.X3)
diode_orientation = DiodeOrientation.COLUMNS
keymap = [
[
[KC.MO(1), KC.H, KC.RESET],
[KC.MO(2), KC.I, KC.ENTER],
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
],
[[KC.TRNS, KC.B, KC.C], [KC.NO, KC.D, KC.E], [KC.F, KC.G, KC.H]],
[[KC.X, KC.Y, KC.Z], [KC.TRNS, KC.N, KC.O], [KC.R, KC.P, KC.Q]],
]

View File

@ -1,7 +1,7 @@
from kmk.boards.converter.fourtypercentclub.luddite import KeyboardConfig from kmk.boards.converter.fourtypercentclub.luddite import KMKKeyboard
from kmk.keys import KC from kmk.keys import KC
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
_______ = KC.TRNS _______ = KC.TRNS
XXXXXXX = KC.NO XXXXXXX = KC.NO

View File

@ -1,7 +1,7 @@
from kmk.boards.converter.keebio.nyquist_r2 import KeyboardConfig from kmk.boards.converter.keebio.nyquist_r2 import KMKKeyboard
from kmk.keys import KC from kmk.keys import KC
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
_______ = KC.TRNS _______ = KC.TRNS
XXXXXXX = KC.NO XXXXXXX = KC.NO

View File

@ -1,12 +1,13 @@
from kmk.consts import DiodeOrientation, UnicodeMode import board
from kmk.handlers.sequences import (compile_unicode_string_sequences,
send_string) from kmk.consts import UnicodeMode
from kmk.handlers.sequences import compile_unicode_string_sequences, send_string
from kmk.keys import KC from kmk.keys import KC
from kmk.mcus.circuitpython_usbhid import KeyboardConfig from kmk.kmk_keyboard import KMKKeyboard
from kmk.pins import Pin as P from kmk.matrix import DiodeOrientation
from kmk.types import AttrDict from kmk.types import AttrDict
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
''' '''
Converter/handwire: Converter/handwire:
@ -30,8 +31,8 @@ PF5: A5
Mosfet on B5 to control backlight Mosfet on B5 to control backlight
''' '''
keyboard.col_pins = (P.A4, P.A2, P.A3, P.A1, P.A0, P.SDA) keyboard.col_pins = (board.A4, board.A2, board.A3, board.A1, board.A0, board.SDA)
keyboard.row_pins = (P.D2, P.TX, P.RX, P.MISO, P.MOSI) keyboard.row_pins = (board.D2, board.TX, board.RX, board.MISO, board.MOSI)
# Kyle is fucking stupid # Kyle is fucking stupid
keyboard.col_pins = tuple(reversed(keyboard.col_pins)) keyboard.col_pins = tuple(reversed(keyboard.col_pins))

View File

@ -1,15 +1,16 @@
from kmk.consts import DiodeOrientation, UnicodeMode import board
from kmk.handlers.sequences import (compile_unicode_string_sequences,
send_string) from kmk.consts import UnicodeMode
from kmk.handlers.sequences import compile_unicode_string_sequences, send_string
from kmk.keys import KC from kmk.keys import KC
from kmk.mcus.circuitpython_usbhid import KeyboardConfig from kmk.kmk_keyboard import KMKKeyboard
from kmk.pins import Pin as P from kmk.matrix import DiodeOrientation
from kmk.types import AttrDict from kmk.types import AttrDict
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
keyboard.col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI, P.MISO, P.RX, P.TX, P.D4) keyboard.col_pins = (board.A0, board.A1, board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI, board.MISO, board.RX, board.TX, board.D4)
keyboard.row_pins = (P.D10, P.D11, P.D12, P.D13) keyboard.row_pins = (board.D10, board.D11, board.D12, board.D13)
keyboard.diode_orientation = DiodeOrientation.COLUMNS keyboard.diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,9 +1,9 @@
from kmk.boards.converter.keebio.levinson_r2 import KeyboardConfig from kmk.boards.converter.keebio.levinson_r2 import KMKKeyboard
from kmk.consts import LeaderMode, UnicodeMode from kmk.consts import LeaderMode, UnicodeMode
from kmk.handlers.sequences import compile_unicode_string_sequences from kmk.handlers.sequences import compile_unicode_string_sequences
from kmk.keys import KC from kmk.keys import KC
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
# ------------------User level config variables --------------------------------------- # ------------------User level config variables ---------------------------------------
keyboard.leader_mode = LeaderMode.TIMEOUT keyboard.leader_mode = LeaderMode.TIMEOUT

View File

@ -1,7 +1,7 @@
from kmk.boards.converter.fourtypercentclub.luddite import KeyboardConfig from kmk.boards.converter.fourtypercentclub.luddite import KMKKeyboard
from kmk.keys import KC from kmk.keys import KC
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
# ---------------------------------- Config -------------------------------------------- # ---------------------------------- Config --------------------------------------------

View File

@ -1,7 +1,7 @@
from kmk.boards.converter.keebio.nyquist_r2 import KeyboardConfig from kmk.boards.converter.keebio.nyquist_r2 import KMKKeyboard
from kmk.keys import KC from kmk.keys import KC
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
# ------------------User level config variables --------------------------------------- # ------------------User level config variables ---------------------------------------
keyboard.tap_time = 150 keyboard.tap_time = 150

View File

@ -1,10 +1,10 @@
from kmk.boards.converter.keebio.iris_r2 import KeyboardConfig from kmk.boards.converter.keebio.iris_r2 import KMKKeyboard
from kmk.consts import LeaderMode, UnicodeMode from kmk.consts import LeaderMode, UnicodeMode
from kmk.handlers.sequences import compile_unicode_string_sequences as cuss from kmk.handlers.sequences import compile_unicode_string_sequences as cuss
from kmk.handlers.sequences import send_string from kmk.handlers.sequences import send_string
from kmk.keys import KC from kmk.keys import KC
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
keyboard.debug_enabled = False keyboard.debug_enabled = False
keyboard.unicode_mode = UnicodeMode.LINUX keyboard.unicode_mode = UnicodeMode.LINUX

View File

@ -1,10 +1,10 @@
from kmk.boards.klarank import KeyboardConfig from kmk.boards.klarank import KMKKeyboard
from kmk.consts import LeaderMode, UnicodeMode from kmk.consts import LeaderMode, UnicodeMode
from kmk.handlers.sequences import compile_unicode_string_sequences as cuss from kmk.handlers.sequences import compile_unicode_string_sequences as cuss
from kmk.handlers.sequences import send_string from kmk.handlers.sequences import send_string
from kmk.keys import KC, make_key from kmk.keys import KC, make_key
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
keyboard.debug_enabled = True keyboard.debug_enabled = True
keyboard.unicode_mode = UnicodeMode.LINUX keyboard.unicode_mode = UnicodeMode.LINUX

View File

@ -1,9 +1,9 @@
from kmk.boards.converter.keebio.levinson_r2 import KeyboardConfig from kmk.boards.converter.keebio.levinson_r2 import KMKKeyboard
from kmk.consts import LeaderMode, UnicodeMode from kmk.consts import LeaderMode, UnicodeMode
from kmk.handlers.sequences import compile_unicode_string_sequences from kmk.handlers.sequences import compile_unicode_string_sequences
from kmk.keys import KC from kmk.keys import KC
keyboard = KeyboardConfig() keyboard = KMKKeyboard()
# ------------------User level config variables --------------------------------------- # ------------------User level config variables ---------------------------------------
keyboard.leader_mode = LeaderMode.TIMEOUT keyboard.leader_mode = LeaderMode.TIMEOUT