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.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"
@mkdir -p dist
@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
@echo "===> Aliasing optimized 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"
@mkdir -p dist
@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
dist/$(DIST_DESCRIBE).unoptimized.zip: dist/kmk-latest.unoptimized.zip
@ -89,14 +90,13 @@ docker-base-deploy: docker-base
devdeps: .devdeps
lint: devdeps
@$(PIPENV) run black --check
@$(PIPENV) run flake8
fix-formatting: devdeps
@$(PIPENV) run black .
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:
@echo "===> Cleaning build artifacts"

View File

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

9
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "019b67ce05e7e68766ba54ddbfd3e2faf5dd81c7ded79f80ff3ef85b0017c99d"
"sha256": "e2a8058d3c40039167ababbfee7347b3b61cb679c65b7f98c2b56ba91fafa0dd"
},
"pipfile-spec": 6,
"requires": {
@ -76,6 +76,13 @@
"index": "pypi",
"version": "==3.6.0"
},
"flake8-black": {
"hashes": [
"sha256:6b5fe2a609fa750170da8d5b1ed7c11029bceaff025660be7f19307ec6fa0c35"
],
"index": "pypi",
"version": "==0.1.0"
},
"flake8-commas": {
"hashes": [
"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
`CIRCUITPY`. Again, [we'll defer to Adafruit's
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
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
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
on your CircuitPython device already, they will be overwritten without a prompt.
the file defined as `USER_KEYMAP` as your `main.py`. It will also copy our
`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
`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
# 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.macros.simple import send_string
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
keyboard.tap_time = 750

View File

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

View File

@ -1,13 +1,30 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.TX, P.RX, P.SDA, P.SCL, P.D13, P.D12, P.D11, P.D10)
class KMKKeyboard(_KMKKeyboard):
col_pins = (
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
rgb_pixel_pin = board.D9
rgb_num_pixels = 12

View File

@ -1,11 +1,20 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.RX, P.D13, P.A0, P.D11, P.A4, P.A5, P.D10, P.D9, P.SCK)
class KMKKeyboard(_KMKKeyboard):
col_pins = (
board.RX,
board.D13,
board.A0,
board.D11,
board.A4,
board.A5,
board.D10,
board.D9,
board.SCK,
)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.A0, P.D11, P.D10, P.D9)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A1, board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (board.A0, board.D11, board.D10, board.D9)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.D11, P.D10, P.D9, P.D7, P.D13)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (board.D11, board.D10, board.D9, board.D7, board.D13)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

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

View File

@ -1,12 +1,28 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.SDA, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.TX, P.A0, P.RX, P.A1, P.D11, P.D9, P.D12, P.D10)
class KMKKeyboard(_KMKKeyboard):
col_pins = (
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
rgb_pixel_pin = board.D13

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.A0)
row_pins = (P.D11, P.D10, P.D9, P.D7)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.A0)
row_pins = (board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.D13, P.D11, P.D10, P.D9)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (board.D13, board.D11, board.D10, board.D9)
diode_orientation = DiodeOrientation.COLUMNS
split_type = 'UART'

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.RX, P.A1, P.A2, P.A3, P.A4, P.A5)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.RX, board.A1, board.A2, board.A3, board.A4, board.A5)
row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS
split_type = 'UART'

View File

@ -1,14 +1,22 @@
import board
from kmk.consts import DiodeOrientation
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):
# Will need additional work and testing
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI, P.D12)
row_pins = (P.A0, P.D13, P.D11, P.D10, P.D9, P.D7)
col_pins = (
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
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.D11, P.D10, P.D9, P.RX, P.D13)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (board.D11, board.D10, board.D9, board.RX, board.D13)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

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

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A1, board.A2, board.A3, board.A4, board.A5, board.SCK, board.MOSI)
row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK)
row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A0, board.A1, board.A2, board.A3, board.A4, board.A5, board.SCK)
row_pins = (board.D13, board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.A5, P.A4, P.A3, P.A2, P.A1, P.A0)
row_pins = (P.D7, P.D9, P.D10, P.D11)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.A5, board.A4, board.A3, board.A2, board.A1, board.A0)
row_pins = (board.D7, board.D9, board.D10, board.D11)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,13 +1,12 @@
import board
from kmk.consts import DiodeOrientation
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):
col_pins = (P.MOSI, P.SCK, P.A5, P.A4, P.A3, P.A2)
row_pins = (P.D11, P.D10, P.D9, P.D7)
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.MOSI, board.SCK, board.A5, board.A4, board.A3, board.A2)
row_pins = (board.D11, board.D10, board.D9, board.D7)
diode_orientation = DiodeOrientation.COLUMNS
rgb_pixel_pin = board.TX
uart_pin = board.SCL

View File

@ -1,9 +1,10 @@
from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P
from kmk.util import intify_coordinate as ic
import board
# 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
# coord_mapping matches what the user pressed (even if the wiring
# underneath is sending different coordinates)
@ -17,11 +18,20 @@ def r3_swap(col):
return col
class KeyboardConfig(_KeyboardConfig):
class KMKKeyboard(_KMKKeyboard):
# physical, visible cols (SCK, MO, MI, RX, TX, D4)
# 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)
row_pins = (P.D10, P.D11, P.D12, P.D13, P.D9, P.D6, P.D5, P.SCL)
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

View File

@ -3,50 +3,6 @@ try:
except Exception:
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:
NOOP = 0

View File

@ -2,7 +2,13 @@ from kmk.consts import UnicodeMode
from kmk.handlers.stock import passthrough
from kmk.keys import KC, make_key
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):

View File

@ -1,5 +1,4 @@
from kmk.kmktime import sleep_ms
from kmk.util import reset_bootloader, reset_keyboard
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):
reset_keyboard()
try:
import machine
machine.reset()
except ImportError:
import microcontroller
microcontroller.reset()
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):

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
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
def __init__(self):
@ -152,44 +188,43 @@ class USB_HID:
return self
try:
import usb_hid
class USBHID(AbstractHID):
REPORT_BYTES = 9
PLATFORM_CIRCUITPYTHON = True
except ImportError:
PLATFORM_CIRCUITPYTHON = False
else:
def post_init(self):
self.devices = {}
class CircuitPythonUSB_HID(USB_HID):
REPORT_BYTES = 9
for device in usb_hid.devices:
us = device.usage
up = device.usage_page
def post_init(self):
self.devices = {}
if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER:
self.devices[HIDReportTypes.CONSUMER] = device
continue
for device in usb_hid.devices:
us = device.usage
up = device.usage_page
if up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD:
self.devices[HIDReportTypes.KEYBOARD] = device
continue
if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER:
self.devices[HIDReportTypes.CONSUMER] = device
continue
if up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE:
self.devices[HIDReportTypes.MOUSE] = device
continue
if up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD:
self.devices[HIDReportTypes.KEYBOARD] = device
continue
if up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL:
self.devices[HIDReportTypes.SYSCONTROL] = device
continue
if up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE:
self.devices[HIDReportTypes.MOUSE] = device
continue
def hid_send(self, evt):
# int, can be looked up in HIDReportTypes
reporting_device_const = self.report_device[0]
if up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL:
self.devices[HIDReportTypes.SYSCONTROL] = device
continue
return self.devices[reporting_device_const].send_report(
evt[1 : HID_REPORT_SIZES[reporting_device_const] + 1]
)
def hid_send(self, evt):
# int, can be looked up in HIDReportTypes
reporting_device_const = self.report_device[0]
return self.devices[reporting_device_const].send_report(
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.keys import KC
from kmk.kmktime import ticks_ms
from kmk.matrix import intify_coordinate
from kmk.types import TapDanceKeyMeta
from kmk.util import intify_coordinate
class InternalState:

View File

@ -1,59 +1,22 @@
# Welcome to RAM and stack size hacks central, I'm your host, klardotsh!
# We really get stuck between a rock and a hard place on CircuitPython
# sometimes: 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 order from fewest to least nested dependencies.
# There's a chance doing preload RAM hacks this late will cause recursion
# errors, but we'll see. I'd rather do it here than require everyone copy-paste
# a line into their keymaps.
import kmk.preload_imports # isort:skip # NOQA
# First, system-provided deps
import busio # isort:skip
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
import busio
import gc
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.util import intify_coordinate as ic
from kmk import led, rgb # isort:skip
from kmk.matrix import MatrixScanner
from kmk.matrix import intify_coordinate as ic
class KeyboardConfig:
class KMKKeyboard:
debug_enabled = False
keymap = None
@ -71,8 +34,6 @@ class KeyboardConfig:
leader_dictionary = {}
leader_timeout = 1000
hid_helper = USB_HID
# Split config
extra_data_pin = None
split_offsets = ()
@ -95,7 +56,7 @@ class KeyboardConfig:
def __repr__(self):
return (
'KeyboardConfig('
'KMKKeyboard('
'debug_enabled={} '
'keymap=truncated '
'coord_mapping=truncated '
@ -229,11 +190,14 @@ class KeyboardConfig:
else:
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.row_pins, 'no GPIO pins defined for matrix rows'
assert self.col_pins, 'no GPIO pins defined for matrix columns'
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
@ -253,6 +217,13 @@ class KeyboardConfig:
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()
# Split keyboard Init

View File

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

View File

@ -1,6 +1,20 @@
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:
@ -11,28 +25,29 @@ class MatrixScanner:
diode_orientation=DiodeOrientation.COLUMNS,
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
# two tuples into a set and validating that the length did not drop
#
# repr() hackery is because CircuitPython Pin objects are not hashable
unique_pins = {repr(c) for c in cols} | {repr(r) for r in rows}
if len(unique_pins) != len(cols) + len(rows):
raise ValueError('Cannot use a pin as both a column and row')
self.cols = cols
self.rows = rows
self.len_cols = len(cols)
self.len_rows = len(rows)
assert (
len(unique_pins) == self.len_cols + self.len_rows
), 'Cannot use a pin as both a column and row'
del unique_pins
gc.collect()
self.diode_orientation = diode_orientation
if self.diode_orientation == DiodeOrientation.COLUMNS:
self.outputs = self.cols
self.inputs = self.rows
self.outputs = [digitalio.DigitalInOut(x) for x in cols]
self.inputs = [digitalio.DigitalInOut(x) for x in rows]
self.translate_coords = True
elif self.diode_orientation == DiodeOrientation.ROWS:
self.outputs = self.rows
self.inputs = self.cols
self.outputs = [digitalio.DigitalInOut(x) for x in rows]
self.inputs = [digitalio.DigitalInOut(x) for x in cols]
self.translate_coords = False
else:
raise ValueError(
@ -64,7 +79,7 @@ class MatrixScanner:
any_changed = False
for oidx, opin in enumerate(self.outputs):
opin.value(True)
opin.value = True
for iidx, ipin in enumerate(self.inputs):
# cast to int to avoid
@ -78,7 +93,7 @@ class MatrixScanner:
# I haven't dived too far into what causes this, but it's
# almost certainly because bool types in Python aren't just
# 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]
if old_val != new_val:
@ -104,7 +119,7 @@ class MatrixScanner:
ba_idx += 1
opin.value(False)
opin.value = False
if any_changed:
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
from math import e, exp, pi, sin
from micropython import const
rgb_config = {

View File

@ -11,23 +11,6 @@ class AttrDict(dict):
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:
def __init__(self, layer, kc=None):
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
| docs
| user_keymaps
| mnt
)/
'''

View File

@ -1,23 +1,55 @@
[flake8]
exclude = .git,__pycache__,vendor,.venv,build
exclude = .git,__pycache__,vendor,.venv,build,dist,.compiled,mnt
# match black expectations
max_line_length = 88
# enforce single quotes
select = Q0
docstring-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 =
# 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
# Forgive me for my RAM hack sins
kmk/keyboard_config.py: I001,I003,I004,F401
kmk/preload_imports.py: I001,I003,I004,F401
[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
include_trailing_comma=True
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
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
_______ = KC.TRNS
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
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
_______ = KC.TRNS
XXXXXXX = KC.NO

View File

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

View File

@ -1,15 +1,16 @@
from kmk.consts import DiodeOrientation, UnicodeMode
from kmk.handlers.sequences import (compile_unicode_string_sequences,
send_string)
import board
from kmk.consts import UnicodeMode
from kmk.handlers.sequences import compile_unicode_string_sequences, send_string
from kmk.keys import KC
from kmk.mcus.circuitpython_usbhid import KeyboardConfig
from kmk.pins import Pin as P
from kmk.kmk_keyboard import KMKKeyboard
from kmk.matrix import DiodeOrientation
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.row_pins = (P.D10, P.D11, P.D12, P.D13)
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 = (board.D10, board.D11, board.D12, board.D13)
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.handlers.sequences import compile_unicode_string_sequences
from kmk.keys import KC
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
# ------------------User level config variables ---------------------------------------
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
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
# ---------------------------------- 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
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
# ------------------User level config variables ---------------------------------------
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.handlers.sequences import compile_unicode_string_sequences as cuss
from kmk.handlers.sequences import send_string
from kmk.keys import KC
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
keyboard.debug_enabled = False
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.handlers.sequences import compile_unicode_string_sequences as cuss
from kmk.handlers.sequences import send_string
from kmk.keys import KC, make_key
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
keyboard.debug_enabled = True
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.handlers.sequences import compile_unicode_string_sequences
from kmk.keys import KC
keyboard = KeyboardConfig()
keyboard = KMKKeyboard()
# ------------------User level config variables ---------------------------------------
keyboard.leader_mode = LeaderMode.TIMEOUT