Merge pull request #138 from KMKfw/topic-prep-for-ckeys2019

Prep for ckeys2019: Round One
This commit is contained in:
Josh Klar 2019-07-24 21:57:32 -07:00 committed by GitHub
commit 8100b91dbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 541 additions and 355 deletions

View File

@ -1,26 +1,24 @@
---
version: 2 version: 2
jobs: jobs:
test: build:
docker: docker:
- image: 'kmkfw/base' - image: 'kmkfw/base'
environment: environment:
KMK_TEST: 1 KMK_TEST: 1
PIPENV_VENV_IN_PROJECT: 1
steps: steps:
- checkout - checkout
- restore_cache:
keys:
- v2-kmk-venv-{{ checksum "Pipfile.lock" }}
- run: make test - run: make test
- run: make dist
- run: make dist-deploy
workflows: workflows:
version: 2 version: 2
build-deploy: build-deploy:
jobs: jobs:
- test: - build:
filters: filters:
branches: branches:
only: /.*/ only: /.*/

6
.gitignore vendored
View File

@ -102,6 +102,7 @@ venv.bak/
# mypy # mypy
.mypy_cache/ .mypy_cache/
.compiled/
.ampy .ampy
.submodules .submodules
@ -119,3 +120,8 @@ venv.bak/
# Mountpoints # Mountpoints
mnt/ mnt/
mnt2/ mnt2/
# build artifacts
kmk/release_info.py
kmk/release_info.mpy
*.mpy

81
.s3cfg Normal file
View File

@ -0,0 +1,81 @@
[default]
access_key =
access_token =
add_encoding_exts =
add_headers =
bucket_location = US
ca_certs_file =
cache_file =
check_ssl_certificate = True
check_ssl_hostname = True
cloudfront_host = cloudfront.amazonaws.com
content_disposition =
content_type =
default_mime_type = binary/octet-stream
delay_updates = False
delete_after = False
delete_after_fetch = False
delete_removed = False
dry_run = False
enable_multipart = True
encoding = UTF-8
encrypt = False
expiry_date =
expiry_days =
expiry_prefix =
follow_symlinks = False
force = False
get_continue = False
gpg_command = /usr/bin/gpg
gpg_decrypt = %(gpg_command)s -d --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s
gpg_encrypt = %(gpg_command)s -c --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s
gpg_passphrase =
guess_mime_type = True
host_base = sfo2.digitaloceanspaces.com
host_bucket = %(bucket)s.sfo2.digitaloceanspaces.com
human_readable_sizes = False
invalidate_default_index_on_cf = False
invalidate_default_index_root_on_cf = True
invalidate_on_cf = False
kms_key =
limit = -1
limitrate = 0
list_md5 = False
log_target_prefix =
long_listing = False
max_delete = -1
mime_type =
multipart_chunk_size_mb = 15
multipart_max_chunks = 10000
preserve_attrs = True
progress_meter = True
proxy_host =
proxy_port = 0
put_continue = False
recursive = False
recv_chunk = 65536
reduced_redundancy = False
requester_pays = False
restore_days = 1
restore_priority = Standard
secret_key =
send_chunk = 65536
server_side_encryption = False
signature_v2 = False
signurl_use_https = False
simpledb_host = sdb.amazonaws.com
skip_existing = False
socket_timeout = 300
stats = False
stop_on_error = False
storage_class =
throttle_max = 100
upload_id =
urlencoding_mode = normal
use_http_expect = False
use_https = True
use_mime_magic = True
verbosity = WARNING
website_endpoint = http://%(bucket)s.s3-website-%(location)s.amazonaws.com/
website_error =
website_index = index.html

20
Dockerfile Normal file
View File

@ -0,0 +1,20 @@
FROM python:3.7-alpine
RUN mkdir -p /app
WORKDIR /app
RUN apk update && apk add alpine-sdk coreutils curl gettext git git-lfs openssh rsync wget zip
RUN pip install pipenv
### Get a local copy of CircuitPython and its dependencies
# Our absolute baseline is 4.0.0, which (as of writing) shares MPY compat
# with all future versions. Our baseline will need to update as MPY compat
# changes
RUN git clone --branch 4.0.0 --depth 1 https://github.com/adafruit/CircuitPython /opt/circuitpython
RUN git -C /opt/circuitpython submodule update --init
### Build the MPY compiler
RUN make -C /opt/circuitpython/mpy-cross
ENV PATH=/opt/circuitpython/mpy-cross:${PATH}

View File

@ -1,21 +0,0 @@
# vim: ft=dockerfile
# Not using python:3.7 here because team-gcc-arm-embedded/ppa does not support
# Ubuntu Cosmic or Debian Stretch, and Alpine, bizarrely, does not seem to
# package GCC cross compilers
FROM ubuntu:bionic
# Set up PPAs we'll need for Python and for GCC ARM
RUN apt-get update && apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa
RUN add-apt-repository ppa:team-gcc-arm-embedded/ppa
# Install Python
RUN apt-get update && apt-get install -y python3.7 python3.7-dev build-essential pkg-config libffi-dev curl
RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7
# Downgrade pip to work around https://github.com/pypa/pipenv/issues/2924
RUN python3.7 -m pip install pip==18.0
RUN python3.7 -m pip install pipenv==2018.7.1
# Install KMK CI and/or build-time dependencies
RUN apt-get install -y gcc-arm-embedded gettext ssh wget unzip rsync git locales libusb-dev

View File

@ -6,20 +6,73 @@
.DEFAULT: all .DEFAULT: all
DIST_DESCRIBE_CMD = git describe --always --abbrev=0 --dirty --broken
DOCKER_BASE_TAG ?= latest DOCKER_BASE_TAG ?= latest
DOCKER_TAG ?= latest DOCKER_TAG ?= latest
AMPY_PORT ?= /dev/ttyUSB0 AMPY_PORT ?= /dev/ttyUSB0
AMPY_BAUD ?= 115200 AMPY_BAUD ?= 115200
AMPY_DELAY ?= 1.5 AMPY_DELAY ?= 1.5
ARDUINO ?= /usr/share/arduino PIPENV ?= $(shell which pipenv 2>/dev/null)
PIPENV ?= $(shell which pipenv)
MPY_CROSS ?= $(shell which mpy-cross 2>/dev/null)
MPY_FLAGS ?= '-O2'
MPY_SOURCES = 'kmk/'
MPY_TARGET_DIR ?= .compiled
PY_KMK_TREE = $(shell find $(MPY_SOURCES) -name "*.py")
DIST_DESCRIBE = $(shell $(DIST_DESCRIBE_CMD))
all: copy-kmk copy-bootpy copy-keymap all: copy-kmk copy-bootpy copy-keymap
.docker_base: Dockerfile_base compile: $(MPY_TARGET_DIR)/.mpy.compiled
$(MPY_TARGET_DIR)/.mpy.compiled: $(PY_KMK_TREE)
ifeq ($(MPY_CROSS),)
@echo "===> Could not find mpy-cross in PATH, exiting"
@false
endif
@echo "===> Compiling all py files to mpy with flags $(MPY_FLAGS)"
@mkdir -p $(MPY_TARGET_DIR)
@echo "KMK_RELEASE = '$(DIST_DESCRIBE)'" > $(MPY_SOURCES)/release_info.py
@find $(MPY_SOURCES) -name "*.py" -exec sh -c 'mkdir -p $(MPY_TARGET_DIR)/$$(dirname {}) && mpy-cross $(MPY_FLAGS) {} -o $(MPY_TARGET_DIR)/$$(dirname {})/$$(basename -s .py {}).mpy' \;
@rm -rf $(MPY_SOURCES)/release_info.py
@touch $(MPY_TARGET_DIR)/.mpy.compiled
dist: dist/kmk-latest.zip dist/kmk-latest.unoptimized.zip dist/$(DIST_DESCRIBE).zip dist/$(DIST_DESCRIBE).unoptimized.zip
dist-deploy: devdeps dist
@echo "===> Uploading artifacts to https://cdn.kmkfw.io/"
@$(PIPENV) run s3cmd -c .s3cfg put -P dist/kmk-$(DIST_DESCRIBE).zip dist/kmk-$(DIST_DESCRIBE).unoptimized.zip s3://kmk-releases/ >/dev/null
@[[ "$${CIRCLE_BRANCH}" == "master" ]] && echo "====> Uploading artifacts as 'latest' to https://cdn.kmkfw.io/" || true
@[[ "$${CIRCLE_BRANCH}" == "master" ]] && $(PIPENV) run s3cmd -c .s3cfg put -P dist/kmk-latest.zip dist/kmk-latest.unoptimized.zip s3://kmk-releases/ >/dev/null || true
@[[ -n "$${CIRCLE_TAG}" ]] && echo "====> Uploading artifacts as '$${CIRCLE_TAG}' to https://cdn.kmkfw.io/" || 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
dist/kmk-latest.zip: compile
@echo "===> Building optimized ZIP"
@mkdir -p dist
@cd $(MPY_TARGET_DIR) && zip -r ../dist/kmk-latest.zip kmk 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)
@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
@rm -rf kmk/release_info.py
dist/$(DIST_DESCRIBE).unoptimized.zip: dist/kmk-latest.unoptimized.zip
@echo "===> Aliasing unoptimized ZIP"
@cp dist/kmk-latest.unoptimized.zip dist/kmk-$(DIST_DESCRIBE).unoptimized.zip
.docker_base: Dockerfile
@echo "===> Building Docker base image kmkfw/base:${DOCKER_BASE_TAG}" @echo "===> Building Docker base image kmkfw/base:${DOCKER_BASE_TAG}"
@docker build -f Dockerfile_base -t kmkfw/base:${DOCKER_BASE_TAG} . @docker build -t kmkfw/base:${DOCKER_BASE_TAG} .
@touch .docker_base @touch .docker_base
docker-base: .docker_base docker-base: .docker_base
@ -30,7 +83,7 @@ docker-base-deploy: docker-base
.devdeps: Pipfile.lock .devdeps: Pipfile.lock
@echo "===> Installing dependencies with pipenv" @echo "===> Installing dependencies with pipenv"
@$(PIPENV) install --dev --ignore-pipfile @$(PIPENV) sync --dev
@touch .devdeps @touch .devdeps
devdeps: .devdeps devdeps: .devdeps
@ -41,14 +94,14 @@ lint: devdeps
fix-isort: devdeps fix-isort: devdeps
@find kmk/ tests/ user_keymaps/ -name "*.py" | xargs $(PIPENV) run isort @find kmk/ tests/ user_keymaps/ -name "*.py" | xargs $(PIPENV) run isort
clean: clean-build-log clean:
@echo "===> Cleaning build artifacts" @echo "===> Cleaning build artifacts"
@rm -rf .devdeps build @rm -rf .devdeps build dist $(MPY_TARGET_DIR)
clean-build-log:
@echo "===> Clearing previous .build.log"
@rm -rf .build.log
# This is mostly a leftover from the days we vendored stuff from
# micropython-lib via submodules. Leaving this here mostly in case someone goes
# exploring through the history of KMK's repo and manages to screw up their
# repo state (those were glitchy times...)
powerwash: clean powerwash: clean
@echo "===> Removing vendor/ to force a re-pull" @echo "===> Removing vendor/ to force a re-pull"
@rm -rf vendor @rm -rf vendor

15
Pipfile
View File

@ -4,19 +4,20 @@ verify_ssl = true
name = "pypi" name = "pypi"
[packages] [packages]
pydux = "*"
[dev-packages] [dev-packages]
adafruit-ampy = "*"
"flake8" = "*" "flake8" = "*"
"flake8-comprehensions" = "*"
ipython = "*"
ipdb = "*"
"flake8-commas" = "*" "flake8-commas" = "*"
isort = "*" "flake8-comprehensions" = "*"
"flake8-isort" = "*" "flake8-isort" = "*"
neovim = "*"
"flake8-per-file-ignores" = "*" "flake8-per-file-ignores" = "*"
"python-magic" = "*"
adafruit-ampy = "*"
ipdb = "*"
ipython = "*"
isort = "*"
neovim = "*"
s3cmd = "*"
[requires] [requires]
python_version = "3.7" python_version = "3.7"

214
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "96625b372d35c7f5ed0fd3289ba61afd0bcc034ddad31feb958a107e2751fb0a" "sha256": "8f51706fcfb278497a6d3083109744210150dc3c644ead11eda3e3cd806e2e14"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -15,23 +15,15 @@
} }
] ]
}, },
"default": { "default": {},
"pydux": {
"hashes": [
"sha256:5cb9217be9d8c7ff79b028f6f02597bbb055b107ce8eecbe5f631f3fc76d793f",
"sha256:bed123b5255d566f792b9ceebad87e3f9c1d2d85abed4b9a9475ffc831035879"
],
"index": "pypi",
"version": "==0.2.2"
}
},
"develop": { "develop": {
"adafruit-ampy": { "adafruit-ampy": {
"hashes": [ "hashes": [
"sha256:1055827874010f48c7dbd3cde4b1d7c6f6732661fad193b188a398e88961fc62" "sha256:46cbb1ebb585c2c01b9d34625dbef618df95c4256a1fc6ac13cb13bbd4a8b6c0",
"sha256:cd8d6b831a1c76d712e30e224e3945428f77bb0c6cccbf06239b31aaf4d4e5b7"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.0.5" "version": "==1.0.7"
}, },
"backcall": { "backcall": {
"hashes": [ "hashes": [
@ -42,25 +34,25 @@
}, },
"click": { "click": {
"hashes": [ "hashes": [
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d", "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
"sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b" "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
], ],
"version": "==6.7" "version": "==7.0"
}, },
"decorator": { "decorator": {
"hashes": [ "hashes": [
"sha256:2c51dff8ef3c447388fe5e4453d24a2bf128d3a4c32af3fabef1f01c6851ab82", "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de",
"sha256:c39efa13fbdeb4506c476c9b3babf6a718da943dab7811c206005a4a956c080c" "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6"
], ],
"version": "==4.3.0" "version": "==4.4.0"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0", "sha256:6a35f5b8761f45c5513e3405f110a86bea57982c3b75b766ce7b65217abe1670",
"sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37" "sha256:c01f8a3963b3571a8e6bd7a4063359aff90749e160778e03817cd9b71c9e07d2"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.5.0" "version": "==3.6.0"
}, },
"flake8-commas": { "flake8-commas": {
"hashes": [ "hashes": [
@ -72,27 +64,27 @@
}, },
"flake8-comprehensions": { "flake8-comprehensions": {
"hashes": [ "hashes": [
"sha256:b83891fec0e680b07aa1fd92e53eb6993be29a0f3673a09badbe8da307c445e0", "sha256:35f826956e87f230415cde9c3b8b454e785736cf5ff0be551c441b41b937f699",
"sha256:e4ccf1627f75f192eb7fde640f5edb81c98d04b1390df9d4145ffd7710bb1ef2" "sha256:f0b61d983d608790abf3664830d68efd3412265c2d10f6a4ba1a353274dbeb64"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.4.1" "version": "==2.1.0"
}, },
"flake8-isort": { "flake8-isort": {
"hashes": [ "hashes": [
"sha256:298d7904ac3a46274edf4ce66fd7e272c2a60c34c3cc999dea000608d64e5e6e", "sha256:1e67b6b90a9b980ac3ff73782087752d406ce0a729ed928b92797f9fa188917e",
"sha256:5992850626ce96547b1f1c7e8a7f0ef49ab2be44eca2177934566437b636fa3c" "sha256:81a8495eefed3f2f63f26cd2d766c7b1191e923a15b9106e6233724056572c68"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.5" "version": "==2.7.0"
}, },
"flake8-per-file-ignores": { "flake8-per-file-ignores": {
"hashes": [ "hashes": [
"sha256:3c4b1d770fa509aaad997ca147bd3533b730c3f6c48290b69a4265072c465522", "sha256:2ee2b61e23cc84e7e76b8f7b2ffc135ec0c3331cba776bb5c03ab5d562b0f40c",
"sha256:4ee4f24cbea5e18e1fefdfccb043e819caf483d16d08e39cb6df5d18b0407275" "sha256:aeac75cc29425b3b4b73eaa92941939dbe16b83f689381ebaef1471982fdcb47"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.6" "version": "==0.8.1"
}, },
"greenlet": { "greenlet": {
"hashes": [ "hashes": [
@ -120,18 +112,18 @@
}, },
"ipdb": { "ipdb": {
"hashes": [ "hashes": [
"sha256:7081c65ed7bfe7737f83fa4213ca8afd9617b42ff6b3f1daf9a3419839a2a00a" "sha256:dce2112557edfe759742ca2d0fee35c59c97b0cc7a05398b791079d78f1519ce"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.11" "version": "==0.12"
}, },
"ipython": { "ipython": {
"hashes": [ "hashes": [
"sha256:007dcd929c14631f83daff35df0147ea51d1af420da303fd078343878bd5fb62", "sha256:11067ab11d98b1e6c7f0993506f7a5f8a91af420f7e82be6575fcb7a6ca372a0",
"sha256:b0f2ef9eada4a68ef63ee10b6dde4f35c840035c50fd24265f8052c98947d5a4" "sha256:60bc55c2c1d287161191cc2469e73c116d9b634cff25fe214a43cba7cec94c79"
], ],
"index": "pypi", "index": "pypi",
"version": "==6.5.0" "version": "==7.6.1"
}, },
"ipython-genutils": { "ipython-genutils": {
"hashes": [ "hashes": [
@ -142,19 +134,18 @@
}, },
"isort": { "isort": {
"hashes": [ "hashes": [
"sha256:1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af", "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
"sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8", "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"
"sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.3.4" "version": "==4.3.21"
}, },
"jedi": { "jedi": {
"hashes": [ "hashes": [
"sha256:b409ed0f6913a701ed474a614a3bb46e6953639033e31f769ca7581da5bd1ec1", "sha256:53c850f1a7d3cfcd306cc513e2450a54bdf5cacd7604b74e42dd1f0758eaaf36",
"sha256:c254b135fb39ad76e78d4d8f92765ebc9bf92cbc76f49e97ade1d5f5121e1f6f" "sha256:e07457174ef7cb2342ff94fa56484fe41cec7ef69b0059f01d3f812379cb6f7c"
], ],
"version": "==0.12.1" "version": "==0.14.1"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
@ -165,37 +156,39 @@
}, },
"msgpack": { "msgpack": {
"hashes": [ "hashes": [
"sha256:0b3b1773d2693c70598585a34ca2715873ba899565f0a7c9a1545baef7e7fbdc", "sha256:26cb40116111c232bc235ce131cc3b4e76549088cb154e66a2eb8ff6fcc907ec",
"sha256:0bae5d1538c5c6a75642f75a1781f3ac2275d744a92af1a453c150da3446138b", "sha256:300fd3f2c664a3bf473d6a952f843b4a71454f4c592ed7e74a36b205c1782d28",
"sha256:0ee8c8c85aa651be3aa0cd005b5931769eaa658c948ce79428766f1bd46ae2c3", "sha256:3129c355342853007de4a2a86e75eab966119733eb15748819b6554363d4e85c",
"sha256:1369f9edba9500c7a6489b70fdfac773e925342f4531f1e3d4c20ac3173b1ae0", "sha256:31f6d645ee5a97d59d3263fab9e6be76f69fa131cddc0d94091a3c8aca30d67a",
"sha256:22d9c929d1d539f37da3d1b0e16270fa9d46107beab8c0d4d2bddffffe895cee", "sha256:3ce7ef7ee2546c3903ca8c934d09250531b80c6127e6478781ae31ed835aac4c",
"sha256:2ff43e3247a1e11d544017bb26f580a68306cec7a6257d8818893c1fda665f42", "sha256:4008c72f5ef2b7936447dcb83db41d97e9791c83221be13d5e19db0796df1972",
"sha256:31a98047355d34d047fcdb55b09cb19f633cf214c705a765bd745456c142130c", "sha256:62bd8e43d204580308d477a157b78d3fee2fb4c15d32578108dc5d89866036c8",
"sha256:8767eb0032732c3a0da92cbec5ac186ef89a3258c6edca09161472ca0206c45f", "sha256:70cebfe08fb32f83051971264466eadf183101e335d8107b80002e632f425511",
"sha256:8acc8910218555044e23826980b950e96685dc48124a290c86f6f41a296ea172", "sha256:72cb7cf85e9df5251abd7b61a1af1fb77add15f40fa7328e924a9c0b6bc7a533",
"sha256:ab189a6365be1860a5ecf8159c248f12d33f79ea799ae9695fa6a29896dcf1d4", "sha256:7c55649965c35eb32c499d17dadfb8f53358b961582846e1bc06f66b9bccc556",
"sha256:cfd6535feb0f1cf1c7cdb25773e965cc9f92928244a8c3ef6f8f8a8e1f7ae5c4", "sha256:86b963a5de11336ec26bc4f839327673c9796b398b9f1fe6bb6150c2a5d00f0f",
"sha256:e274cd4480d8c76ec467a85a9c6635bbf2258f0649040560382ab58cabb44bcf", "sha256:8c73c9bcdfb526247c5e4f4f6cf581b9bb86b388df82cfcaffde0a6e7bf3b43a",
"sha256:f86642d60dca13e93260187d56c2bef2487aa4d574a669e8ceefcf9f4c26fd00", "sha256:8e68c76c6aff4849089962d25346d6784d38e02baa23ffa513cf46be72e3a540",
"sha256:f8a57cbda46a94ed0db55b73e6ab0c15e78b4ede8690fa491a0e55128d552bb0", "sha256:97ac6b867a8f63debc64f44efdc695109d541ecc361ee2dce2c8884ab37360a1",
"sha256:fcea97a352416afcbccd7af9625159d80704a25c519c251c734527329bb20d0e" "sha256:9d4f546af72aa001241d74a79caec278bcc007b4bcde4099994732e98012c858",
"sha256:a28e69fe5468c9f5251c7e4e7232286d71b7dfadc74f312006ebe984433e9746",
"sha256:fd509d4aa95404ce8d86b4e32ce66d5d706fd6646c205e1c2a715d87078683a2"
], ],
"version": "==0.5.6" "version": "==0.6.1"
}, },
"neovim": { "neovim": {
"hashes": [ "hashes": [
"sha256:6ce58a742e0427491c0e1c8108556ee72ba33844209bd9e226b8da9538299276" "sha256:a6a0e7a5b4433bf4e6ddcbc5c5ff44170be7d84259d002b8e8d8fb4ee78af60f"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.2.6" "version": "==0.3.1"
}, },
"parso": { "parso": {
"hashes": [ "hashes": [
"sha256:35704a43a3c113cce4de228ddb39aab374b8004f4f2407d070b6a2ca784ce8a2", "sha256:63854233e1fadb5da97f2744b6b24346d2750b85965e7e399bec1620232797dc",
"sha256:895c63e93b94ac1e1690f5fdd40b65f07c8171e3e53cbd7793b5b96c0e0a7f24" "sha256:666b0ee4a7a1220f65d367617f2cd3ffddff3e205f3f16a0284df30e774c2a9c"
], ],
"version": "==0.3.1" "version": "==0.5.1"
}, },
"pathmatch": { "pathmatch": {
"hashes": [ "hashes": [
@ -205,26 +198,26 @@
}, },
"pexpect": { "pexpect": {
"hashes": [ "hashes": [
"sha256:2a8e88259839571d1251d278476f3eec5db26deb73a70be5ed5dc5435e418aba", "sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1",
"sha256:3fbd41d4caf27fa4a377bfd16fef87271099463e6fa73e92a52f92dfee5d425b" "sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb"
], ],
"markers": "sys_platform != 'win32'", "markers": "sys_platform != 'win32'",
"version": "==4.6.0" "version": "==4.7.0"
}, },
"pickleshare": { "pickleshare": {
"hashes": [ "hashes": [
"sha256:84a9257227dfdd6fe1b4be1319096c20eb85ff1e82c7932f36efccfe1b09737b", "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca",
"sha256:c9a2541f25aeabc070f12f452e1f2a8eae2abd51e1cd19e8430402bdf4c1d8b5" "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"
], ],
"version": "==0.7.4" "version": "==0.7.5"
}, },
"prompt-toolkit": { "prompt-toolkit": {
"hashes": [ "hashes": [
"sha256:1df952620eccb399c53ebb359cc7d9a8d3a9538cb34c5a1344bdbeb29fbcc381", "sha256:11adf3389a996a6d45cc277580d0d53e8a5afd281d0c9ec71b28e6f121463780",
"sha256:3f473ae040ddaa52b52f97f6b4a493cfa9f5920c255a12dc56a7d34397a398a4", "sha256:2519ad1d8038fd5fc8e770362237ad0364d16a7650fb5724af6997ed5515e3c1",
"sha256:858588f1983ca497f1cf4ffde01d978a3ea02b01c8a26a8bbc5cd2e66d816917" "sha256:977c6583ae813a37dc1c2e1b715892461fcbdaa57f6fc62f33a528c4886c8f55"
], ],
"version": "==1.0.15" "version": "==2.0.9"
}, },
"ptyprocess": { "ptyprocess": {
"hashes": [ "hashes": [
@ -235,24 +228,30 @@
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766", "sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
"sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9" "sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
], ],
"version": "==2.3.1" "version": "==2.4.0"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
"sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f", "sha256:9a7662ec724d0120012f6e29d6248ae3727d821bba522a0e6b356eff19126a49",
"sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805" "sha256:f661252913bc1dbe7fcfcbf0af0db3f42ab65aabd1a6ca68fe5d466bace94dae"
], ],
"version": "==1.6.0" "version": "==2.0.0"
}, },
"pygments": { "pygments": {
"hashes": [ "hashes": [
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d", "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc" "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
], ],
"version": "==2.2.0" "version": "==2.4.2"
},
"pynvim": {
"hashes": [
"sha256:cf6490c4e586c9da01a32f3e0ae21c61342d7ea171e06025bda210bdc95cbe05"
],
"version": "==0.3.2"
}, },
"pyserial": { "pyserial": {
"hashes": [ "hashes": [
@ -261,32 +260,49 @@
], ],
"version": "==3.4" "version": "==3.4"
}, },
"python-dateutil": {
"hashes": [
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
],
"version": "==2.8.0"
},
"python-dotenv": { "python-dotenv": {
"hashes": [ "hashes": [
"sha256:122290a38ece9fe4f162dc7c95cae3357b983505830a154d3c98ef7f6c6cea77", "sha256:debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093",
"sha256:4a205787bc829233de2a823aa328e44fd9996fedb954989a21f1fc67c13d7a77" "sha256:f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544"
], ],
"version": "==0.9.1" "version": "==0.10.3"
}, },
"simplegeneric": { "python-magic": {
"hashes": [ "hashes": [
"sha256:dc972e06094b9af5b855b3df4a646395e43d1c9d0d39ed345b7393560d0b9173" "sha256:f2674dcfad52ae6c49d4803fa027809540b130db1dec928cfbb9240316831375",
"sha256:f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5"
], ],
"version": "==0.8.1" "index": "pypi",
"version": "==0.4.15"
},
"s3cmd": {
"hashes": [
"sha256:231fe00daedb13095ce38ccf264bbe81d133f6e82f1484ef2f5efdc3f21b9ee8",
"sha256:6d7a3a49a12048a6c8e5fbb5ef42a83101e2fc69f16013d292b7f37ecfc574a0"
],
"index": "pypi",
"version": "==2.0.2"
}, },
"six": { "six": {
"hashes": [ "hashes": [
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
], ],
"version": "==1.11.0" "version": "==1.12.0"
}, },
"testfixtures": { "testfixtures": {
"hashes": [ "hashes": [
"sha256:334497d26344e8c0c5d01b4d785a1c83464573151e6a5f7ab250eb7981d452ec", "sha256:665a298976c8d77f311b65c46f16b7cda7229a47dff5ad7c822e5b3371a439e2",
"sha256:53c06c1feb0bf378d63c54d1d96858978422d5a34793b39f0dcb0e44f8ec26f4" "sha256:9d230c5c80746f9f86a16a1f751a5cf5d8e317d4cc48243a19fb180d22303bce"
], ],
"version": "==6.3.0" "version": "==6.10.0"
}, },
"traitlets": { "traitlets": {
"hashes": [ "hashes": [
@ -297,11 +313,11 @@
}, },
"typing": { "typing": {
"hashes": [ "hashes": [
"sha256:4027c5f6127a6267a435201981ba156de91ad0d1d98e9ddc2aa173453453492d", "sha256:38566c558a0a94d6531012c8e917b1b8518a41e418f7f15f00e129cc80162ad3",
"sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4", "sha256:53765ec4f83a2b720214727e319607879fec4acde22c4fbb54fa2604e79e44ce",
"sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a" "sha256:84698954b4e6719e912ef9a42a2431407fe3755590831699debda6fba92aac55"
], ],
"version": "==3.6.6" "version": "==3.7.4"
}, },
"wcwidth": { "wcwidth": {
"hashes": [ "hashes": [

201
README.md
View File

@ -1,99 +1,136 @@
# KMK: Python-based keyboard firmware for humans (and ARM microcontrollers) # KMK: Clackety Keyboards Powered by Python
[![CircleCI](https://circleci.com/gh/KMKfw/kmk_firmware/tree/master.svg?style=svg)](https://circleci.com/gh/KMKfw/kmk_firmware/tree/master)[![CLA assistant](https://cla-assistant.io/readme/badge/KMKfw/kmk_firmware)](https://cla-assistant.io/KMKfw/kmk_firmware) KMK is a feature-rich and beginner-friendly firmware for computer keyboards
written and configured in
[CircuitPython](https://github.com/adafruit/circuitpython). **KMK is currently
in public beta, however should handle almost all workflows without major
issues**.
#### [Join our Matrix community for chat and support!](https://matrix.to/#/+kmk:kmkfw.io) You can always find the latest releases on our CDN, in [compiled and
optimized](https://cdn.kmkfw.io/kmk-latest.zip) and [raw, hackable text
file](https://cdn.kmkfw.io/kmk-latest.unoptimized.zip) forms. These follow the
`master` branch here on GitHub.
[Or, head directly to the #support channel](https://matrix.to/#/#support:kmkfw.io) > If you need support with KMK or just want to say hi, find us in
> [#general:kmkfw.io on Matrix](https://matrix.to/#/#general:kmkfw.io). Other
> channels exist in [the same community](https://matrix.to/#/+kmk:kmkfw.io).
> These channels are bridged to Discord [here](https://discordapp.com/widget?id=493256121075761173&theme=dark)
> for convenience.
>
> If you ask for help on chat or open a bug report, if possible please give us
> your commit SHA, found by running `from kmk.consts import KMK_RELEASE;
> print(KMK_RELEASE)` in the REPL on your controller.
If you can't or won't use the Matrix infrastructure, a (possibly fragile) bridge ## Features
to Discord exists
[here](https://discordapp.com/widget?id=493256121075761173&theme=dark).
<hr/> - Fully configured through a single, easy to understand Python file that lives
on a "flash-drive"-esque space on your microcontroller - edit on the go
without DFU or other devtooling available!
- Single-piece or [two-piece split
keyboards](https://github.com/KMKfw/kmk_firmware/blob/master/docs/split_keyboards.md)
are supported
- [Chainable
keys](https://github.com/KMKfw/kmk_firmware/blob/master/docs/keys.md) such as
`KC.LWIN(KC.L)` to lock the screen on a Windows PC
- [Built-in unicode macros, including
emojis](https://github.com/KMKfw/kmk_firmware/blob/master/docs/sequences.md)
- [Multiple vim-inspired leader key
modes](https://github.com/KMKfw/kmk_firmware/blob/master/docs/leader.md)
- [RGB underglow](https://github.com/KMKfw/kmk_firmware/blob/master/docs/rgb.md)
and [LED
backlights](https://github.com/KMKfw/kmk_firmware/blob/master/docs/led.md)
- One key can turn into many more based on [how many times you tap
it](https://github.com/KMKfw/kmk_firmware/blob/master/docs/tapdance.md)
KMK is a firmware for (usually mechanical) keyboards, running on Coming (hopefully) soon: Bluetooth support! Stay tuned.
[CircuitPython](https://github.com/adafruit/circuitpython). It aims to provide a
means to write complex keyboard configurations quickly, without having to learn
much "real" programming, while preserving at least some of the hackability and
DIY spirit of CircuitPython. Learn more about the rationale of KMK in `Why KMK?`
below.
This project is currently written and maintained by: ## Getting Started
- [Josh Klar (@klardotsh)](https://github.com/klardotsh) - Start by grabbing a supported microcontroller. Broadly speaking, KMK supports
any device CircuitPython does, but KMK requires a decent bit of RAM, and in
general requires a working USB HID stack, which leads us to recommend the
following controllers:
* [Adafruit ItsyBitsy M4 Express](https://www.adafruit.com/product/3800)\*
* [Adafruit Feather M4 Express](https://www.adafruit.com/product/3857)
* [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
* [MakerDiary nRF52840 MDK](https://store.makerdiary.com/collections/frontpage/products/nrf52840-mdk-iot-development-kit)
* [SparkFun Pro nRF52840 Mini](https://www.sparkfun.com/products/15025)
> \* The ItsyBitsy M4 Express is the only controller we currently support in
> non-handwired configurations, using our [ItsyBitsy to Pro Micro converter
> PCB](https://github.com/KMKfw/kmk_firmware/tree/master/hardware) designed by
> @siddacious and @kdb424. It is our most-recommended MCU until [the ItsyBitsy is
> updated with an nRF52840
> chip](https://blog.adafruit.com/2019/01/26/comingsoon-itsybitsy-nrf52480-runs-circuitpython-adafruit-circuitpython-adafruit-circuitpython/)
> Some other controllers, such as the [Feather M0 Express](https://www.adafruit.com/product/3403),
> are usable in reduced functionality modes and may require custom hackery.
> For example, @kdb424 uses a ItsyBitsy M0 Express as a barebones matrix scanner
> in a split keyboard configuration
> [here](https://github.com/KMKfw/kmk_firmware/commit/1f84079dc8aadeb9627c4762d9f9fb855292c4a2).
> Use such controllers at your own risk.
- Ensure CircuitPython 4.0.0 or newer is installed on your controller. We
recommend the latest stable version from
[circuitpython.org](https://circuitpython.org/downloads). Flashing
instructions vary by device: all Adafruit boards can be flashed [using their
instructions](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython),
other boards generally have their instructions [in the CircuitPython
repository](https://github.com/adafruit/circuitpython) under the
`ports/atmel-samd/boards/<your board here>` and `ports/nrf/boards/<your board
here>` directories. If all else fails, consult your device's official
documentation.
- [Download the latest KMK release](https://cdn.kmkfw.io/kmk-latest.zip) and
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.
- Define your keyboard in a file called `main.py` on this `CIRCUITPY` drive and
get tinkering! Examples of both handwired and ProMicro-\>ItsyBitsy converted
boards exist under the `user_keymaps/` tree, and feel free to submit a pull
request of your own definitions! At this point, you'll want to look through
`docs/` in the source tree to explore the functionality at your disposal.
> Linux, BSD, and MacOS users can also make use of the `Makefile` provided in
> this source tree to flash KMK and a keymap using `rsync`. This is advanced
> functionality outside the scope of this README, but it's documented in the
> `docs/` tree.
## The KMK Team
KMK is primarily written and maintained by @klardotsh and @kdb424, but
contributions are welcome from all, whether it's in the form of code,
documentation, hardware designs, feature ideas, or anything else that comes to
mind. KMK's contributors and other helpers are listed alphabetically by username
below (we'll try to keep this up to date!):
- [Dan Halbert (@dhalbert)](https://github.com/dhalbert)
- [Elvis Pfützenreuter (@elvis-epx)](https://github.com/elvis-epx)
- [Kyle Brown (@kdb424)](https://github.com/kdb424) - [Kyle Brown (@kdb424)](https://github.com/kdb424)
- [Josh Klar (@klardotsh)](https://github.com/klardotsh)
With community help from: - [Limor Fried (@ladyada)](https://github.com/ladyada)
- [Ryan Karpinski (@rk463345)](https://github.com/rk463345)
- [@siddacious](https://github.com/siddacious) - [@siddacious](https://github.com/siddacious)
- [Scott Shawcroft (@tannewt)](https://github.com/tannewt) - [Scott Shawcroft (@tannewt)](https://github.com/tannewt)
> Scott is the lead developer of the CircuitPython project itself at Adafruit. > While Adafruit employees and affiliates are included in the above list and
> KMK, however, is not officially sponsored by Adafruit, and is an independent > their help has been crucial to KMK's success, KMK is not an official Adafruit
> project. > project, and the Core team is not compensated by Adafruit for its development.
Lastly, we'd like to make a couple of shoutouts to people not directly
affiliated with the project in any way, but who have helped or inspired us along
the way:
- [Jack Humbert (@jackhumbert)](https://jackhumbert.com/), for writing QMK.
Without QMK, I'd have never been exposed to the wonderful world of
programmable keyboards. He's also just an awesometastic human in general, if
you ever catch him on Discord/Reddit/etc. Jack also makes fantastic hardware -
check out [his store](https://olkb.com)!
- [Dan Halbert (@dhalbert)](https://danhalbert.org/), for his amazing and
unjudgemental support of two random dudes on Github asking all sorts of
bizzare (okay... and occasionally dumb) questions on the MicroPython and
CircuitPython Github projects and the Adafruit Discord. Dan, without your help
and pointers (even when those pointers are "Remember you're working with a
microcontroller with a few MHz of processing speed and a few KB of RAM"), this
project would have never gotten off the ground. Thank you, and an extended
thanks to Adafruit.
## Why KMK?
A question we get from time to time is, "why bother with KMK when QMK already
exists?", so here's a short bulleted list of our thoughts on the matter (in no
particular order):
- Python is awesome
- Python is super easy to write
- KMK cut all the "tech debt" of supporting AVR controllers, and frankly even
most ARM controllers with under 256KB of flash. This let us make some very
user-friendly (in our biased opinions) design decisions that should make it
simple for users to create even fairly complex keyboards - want a key on your
board that sends a shruggie (`¯\_(ツ)_/¯`)? No problem - it's supported out of
the box. Want a single key that can act as all 26 alphabet characters
depending on the number of times it's tapped? You're insane, but our simple
Tap Dance implementation has you covered (without a single line of matrix
mangling or timer madness)
- KMK supports a few small features QMK doesn't - most are probably not
deal-closers, but they exist no less..
- KMK plans to support some fairly powerful hardware that would enable things
like connecting halves (or thirds, or whatever) of a split keyboard to each
other via Bluetooth. This stuff is still in very early R&D.
## So how do I use it?
Since KMK is still in beta currently. Flashing KMK to a
board is still a process that requires a few lines of shell scripting. Check out
`docs/flashing.md` for instructions/details, though note that for now, the
instructions mostly assume Unix (Linux/MacOS/BSD) usage. You may want to check
out the Windows Subsystem for Linux if you're on Windows.
## License, Copyright, and Legal ## License, Copyright, and Legal
Most files in this project are licensed All software in this repository is licensed under the [GNU Public License,
[GPLv3](https://tldrlegal.com/license/gnu-general-public-license-v3-(gpl-3)) - verison 3](https://tldrlegal.com/license/gnu-general-public-license-v3-(gpl-3)).
see `LICENSE.md` at the top of this source tree for exceptions and the full All documentation and hardware designs are licensed under the [Creative Commons
license text. Attribution-ShareAlike 4.0](https://creativecommons.org/licenses/by-sa/4.0/)
license. Contributions to this repository must use these licenses unless
otherwise agreed to by the Core team.
When contributing for the first time, you'll need to sign a Contributor When you open your first pull request, you'll be asked to sign a Contributor
Licensing Agreement which is based on the Free Software Foundation's CLA. The Licensing Agreement which is based on the Free Software Foundation's CLA. The
CLA is basically a two-way promise that this code is and remains yours, but will CLA is basically a two-way promise that your code is and remains yours, but will
be distributed as part of a larger GPLv3 project. If you'd like to get it out of be distributed as part of a larger GPL project. This CLA can be read and/or
the way early, you can find said CLA [here]( signed [here](https://cla-assistant.io/kmkfw/kmk_firmware).
https://cla-assistant.io/kmkfw/kmk_firmware). If you forget, the bots will
remind you when you open the pull request, no worries!

View File

@ -1,45 +1,35 @@
# Flashing Instructions # Flashing Instructions
KMK sits on top of an existing CircuitPython install, flash that for your board In general, we recommend using the instructions in `README.md`, however, mostly
as appropriate (see [Adafruit's as a development artifact, another method of flashing KMK exists (tested and
documentation](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython), supported only on Linux, though it should also work on MacOS, the BSDs, and
though it doesn't cover all CircuitPython boards - you may need to glance around other Unix-likes. It may also work on Cygwin and the Windows Subsystem for
the CircuitPython source or ask on Discord). We primarily target CircuitPython Linux).
4.0-alpha1 to 4.0-alpha2. You'll only need
to flash CircuitPython once (unless we update our baseline supported version).
After CircuitPython has been flashed, a `CIRCUITPY` drive should show up on your Given `make` and `rsync` are available on your system (in `$PATH`), the
computer most likely. If not, check out the troubleshooting section below. 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.
# Windows If you get permissions errors here, **don't run make as root or with sudo**. See
Currently, we do not have an official "flasher" for windows. You can manually install it fairly easily and we recommend `Troubleshooting` below.
checking out the support page to join the community if you have any questions. An actual tool is in development.
Alternatively, you can flash from any linux like tool set (Cygwin, WSL, ect) using the Linux guide below.
# Mac
Until an interactive installer is created, please follow the linux instructions replacing /mnt with /Volumes
# Linux
While in the directory for kmk, simply run this, changing the mount point and keymap name to whatever is appropriate.
```sh ```sh
make MOUNTPOINT=/mnt/CIRCUITPY USER_KEYMAP=user_keymaps/nameofyourkeymap.py make MOUNTPOINT=/media/CIRCUITPY USER_KEYMAP=user_keymaps/nameofyourkeymap.py
``` ```
# Troubleshooting # Troubleshooting
## Windows
Please check out our support page to get in contact with us and the community and we can gladly help you out.
## Mac
Please check out our support page to get in contact with us and the community and we can gladly help you out.
## Linux/BSD ## Linux/BSD
Check to see if your drive may have mounted elsewhere with a gui tool. Most will give you the directory in the GUI.
If it's not mounted, you can read up on how to mount a drive manually [here](https://wiki.archlinux.org/index.php/File_systems#Mount_a_file_system)
It would look something like this Check to see if your drive may have mounted elsewhere with a GUI tool or other
automounter. Most of these tools will mount your device under `/media`, probably
as `/media/CIRCUITPY`. If it's not mounted, you can read up on how to mount a
drive manually
[here](https://wiki.archlinux.org/index.php/File_systems#Mount_a_file_system).
`sudo mount -o uid=1000,gid=1000 /dev/sdf1 ~/mnt` For example,
If you still are having issues, check out our support page to see where you can come say hi and the community will gladly help you out. `sudo mount -o uid=$(id -u),gid=$(id -g) /dev/disk/by-label/CIRCUITPY ~/mnt`
If you're still having issues, check out our support page to see where you can
come say hi and the community will gladly help you out.

View File

@ -5,17 +5,17 @@ Keymaps in KMK are simple Python class objects with various attributes assigned
The basics of what you'll need to get started are: The basics of what you'll need to get started are:
- Import the `Firmware` object for your keyboard from `kmk.boards` (or, if - Import the `KeyboardConfig` object for your keyboard from `kmk.boards` (or, if
handwiring your keyboard, import `Firmware` from the appropriate MCU for your 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 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. 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 - Add a file to `user_keymaps/your_username` called whatever you'd like
- Assign a `Firmware` instance to a variable (ex. `keyboard = Firmware()` - note - Assign a `KeyboardConfig` instance to a variable (ex. `keyboard = KeyboardConfig()` - note
the parentheses) the parentheses)
- Make sure this `Firmware` instance is actually run at the end of the file with - Make sure this `KeyboardConfig` instance is actually run at the end of the file with
a block such as the following: a block such as the following:
```python ```python
@ -85,14 +85,14 @@ matrix pins (in somewhat of a "spider" setup), utilizing most of the above
features: features:
```python ```python
from kmk.boards.klarank import Firmware from kmk.boards.klarank import KeyboardConfig
from kmk.consts import UnicodeMode from kmk.consts import UnicodeMode
from kmk.keycodes import KC from kmk.keycodes import KC
from kmk.keycodes import generate_leader_dictionary_seq as glds from kmk.keycodes import generate_leader_dictionary_seq as glds
from kmk.macros.simple import send_string from kmk.macros.simple import send_string
from kmk.macros.unicode import compile_unicode_string_sequences as cuss from kmk.macros.unicode import compile_unicode_string_sequences as cuss
keyboard = Firmware() keyboard = KeyboardConfig()
keyboard.debug_enabled = True keyboard.debug_enabled = True
keyboard.unicode_mode = UnicodeMode.LINUX keyboard.unicode_mode = UnicodeMode.LINUX

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 Firmware from kmk.boards.klarank import KeyboardConfig
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 = Firmware() keyboard = KeyboardConfig()
keyboard.tap_time = 750 keyboard.tap_time = 750

View File

@ -1,9 +1,9 @@
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.D9, P.D10, P.D11, P.D12, P.D13, P.SCL) 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) row_pins = (P.A3, P.A4, P.A5, P.SCK, P.MOSI)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) 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) row_pins = (P.TX, P.RX, P.SDA, P.SCL, P.D13, P.D12, P.D11, P.D10)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

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

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) 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) row_pins = (P.A0, P.D11, P.D10, P.D9)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) 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) row_pins = (P.D11, P.D10, P.D9, P.D7, P.D13)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,12 +1,12 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
from kmk.util import intify_coordinate as ic from kmk.util import intify_coordinate as ic
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
# 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 }

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.SDA, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) 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) row_pins = (P.TX, P.A0, P.RX, P.A1, P.D11, P.D9, P.D12, P.D10)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.A0) col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.A0)
row_pins = (P.D11, P.D10, P.D9, P.D7) row_pins = (P.D11, P.D10, P.D9, P.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI)
row_pins = (P.D13, P.D11, P.D10, P.D9) row_pins = (P.D13, P.D11, P.D10, P.D9)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) 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) row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.RX, P.A1, P.A2, P.A3, P.A4, P.A5) 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) row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
# 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 = (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) row_pins = (P.A0, P.D13, P.D11, P.D10, P.D9, P.D7)

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) 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) row_pins = (P.D11, P.D10, P.D9, P.RX, P.D13)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

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

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK, P.MOSI) 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) row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A0, P.A1, P.A2, P.A3, P.A4, P.A5, P.SCK) 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) row_pins = (P.D13, P.D11, P.D10, P.D9, P.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.A5, P.A4, P.A3, P.A2, P.A1, P.A0) col_pins = (P.A5, P.A4, P.A3, P.A2, P.A1, P.A0)
row_pins = (P.D7, P.D9, P.D10, P.D11) row_pins = (P.D7, P.D9, P.D10, P.D11)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,11 +1,11 @@
import board import board
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
col_pins = (P.MOSI, P.SCK, P.A5, P.A4, P.A3, P.A2) col_pins = (P.MOSI, P.SCK, P.A5, P.A4, P.A3, P.A2)
row_pins = (P.D11, P.D10, P.D9, P.D7) row_pins = (P.D11, P.D10, P.D9, P.D7)
diode_orientation = DiodeOrientation.COLUMNS diode_orientation = DiodeOrientation.COLUMNS

View File

@ -1,9 +1,9 @@
from kmk.consts import DiodeOrientation from kmk.consts import DiodeOrientation
from kmk.mcus.circuitpython_samd51 import Firmware as _Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig as _KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
from kmk.util import intify_coordinate as ic from kmk.util import intify_coordinate as ic
# Implements what used to be handled by Firmware.swap_indicies for this # Implements what used to be handled by KeyboardConfig.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)
@ -24,7 +24,7 @@ def r3_swap(col):
return col return col
class Firmware(_Firmware): class KeyboardConfig(_KeyboardConfig):
# 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 = (P.SCK, P.MOSI, P.MISO, P.RX, P.TX, P.D4)

View File

@ -1,3 +1,8 @@
try:
from kmk.release_info import KMK_RELEASE
except Exception:
KMK_RELEASE = 'copied-from-git'
CIRCUITPYTHON = 'CircuitPython' CIRCUITPYTHON = 'CircuitPython'
MICROPYTHON = 'MicroPython' MICROPYTHON = 'MicroPython'

View File

@ -101,10 +101,8 @@ def tt_pressed(key, state, *args, **kwargs):
def tt_released(key, state, *args, **kwargs): def tt_released(key, state, *args, **kwargs):
if ( tap_timed_out = ticks_diff(ticks_ms(), state.start_time['tt']) >= state.config.tap_time
state.start_time['tt'] is None or if state.start_time['tt'] is None or tap_timed_out:
ticks_diff(ticks_ms(), state.start_time['tt']) >= state.config.tap_time
):
# On first press, works like MO. On second press, does nothing unless let up within # On first press, works like MO. On second press, does nothing unless let up within
# time window, then acts like TG. # time window, then acts like TG.
state.start_time['tt'] = None state.start_time['tt'] = None

View File

@ -183,10 +183,7 @@ else:
self.devices[HIDReportTypes.MOUSE] = device self.devices[HIDReportTypes.MOUSE] = device
continue continue
if ( if up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL:
up == HIDUsagePage.SYSCONTROL and
us == HIDUsage.SYSCONTROL
):
self.devices[HIDReportTypes.SYSCONTROL] = device self.devices[HIDReportTypes.SYSCONTROL] = device
continue continue

View File

@ -200,10 +200,10 @@ class InternalState:
if changed_key not in self.tap_side_effects: if changed_key not in self.tap_side_effects:
self.tap_side_effects[changed_key] = None self.tap_side_effects[changed_key] = None
else: else:
if ( has_side_effects = self.tap_side_effects[changed_key] is not None
self.tap_side_effects[changed_key] is not None or hit_max_defined_taps = self.tap_dance_counts[changed_key] == len(changed_key.codes)
self.tap_dance_counts[changed_key] == len(changed_key.codes)
): if has_side_effects or hit_max_defined_taps:
self._end_tap_dance(changed_key) self._end_tap_dance(changed_key)
return self return self

View File

@ -27,7 +27,7 @@ import kmk.kmktime # isort:skip
import kmk.types # isort:skip import kmk.types # isort:skip
import kmk.util # isort:skip import kmk.util # isort:skip
from kmk.consts import LeaderMode, UnicodeMode # isort:skip from kmk.consts import LeaderMode, UnicodeMode, KMK_RELEASE # isort:skip
from kmk.hid import USB_HID # isort:skip from kmk.hid import USB_HID # isort:skip
from kmk.internal_state import InternalState # isort:skip from kmk.internal_state import InternalState # isort:skip
from kmk.keys import KC # isort:skip from kmk.keys import KC # isort:skip
@ -53,7 +53,7 @@ from kmk.util import intify_coordinate as ic
from kmk import led, rgb # isort:skip from kmk import led, rgb # isort:skip
class Firmware: class KeyboardConfig:
debug_enabled = False debug_enabled = False
keymap = None keymap = None
@ -95,7 +95,7 @@ class Firmware:
def __repr__(self): def __repr__(self):
return ( return (
'Firmware(' 'KeyboardConfig('
'debug_enabled={} ' 'debug_enabled={} '
'keymap=truncated ' 'keymap=truncated '
'coord_mapping=truncated ' 'coord_mapping=truncated '
@ -152,7 +152,7 @@ class Firmware:
if self.debug_enabled: if self.debug_enabled:
if init: if init:
print('KMKInit()') print('KMKInit(release={})'.format(KMK_RELEASE))
print(self) print(self)
print(self._state) print(self._state)

View File

@ -110,8 +110,11 @@ class led:
def effect_breathing(self): def effect_breathing(self):
# http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/ # http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
# https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806 # https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806
self.brightness = int((exp(sin((self.pos / 255.0) * pi)) - self.breathe_center / e) * sined = sin((self.pos / 255.0) * pi)
(self.brightness_limit / (e - 1 / e))) multip_1 = exp(sined) - self.breathe_center / e
multip_2 = self.brightness_limit / (e - 1 / e)
self.brightness = int(multip_1 * multip_2)
self.pos = (self.pos + self.animation_speed) % 256 self.pos = (self.pos + self.animation_speed) % 256
self.set_brightness(self.brightness) self.set_brightness(self.brightness)

View File

@ -1,6 +0,0 @@
from kmk.firmware import Firmware as _Firmware
from kmk.hid import CircuitPythonUSB_HID
class Firmware(_Firmware):
hid_helper = CircuitPythonUSB_HID

View File

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

View File

@ -424,8 +424,11 @@ class RGB:
def effect_breathing(self): def effect_breathing(self):
# http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/ # http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
# https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806 # https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806
self.val = int((exp(sin((self.pos / 255.0) * pi)) - self.breathe_center / e) * sined = sin((self.pos / 255.0) * pi)
(self.val_limit / (e - 1 / e))) multip_1 = exp(sined) - self.breathe_center / e
multip_2 = self.val_limit / (e - 1 / e)
self.val = int(multip_1 * multip_2)
self.pos = (self.pos + self.animation_speed) % 256 self.pos = (self.pos + self.animation_speed) % 256
self.set_hsv_fill(self.hue, self.sat, self.val) self.set_hsv_fill(self.hue, self.sat, self.val)

View File

@ -1 +0,0 @@
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", GROUP="uucp", MODE="0660"

View File

@ -7,7 +7,7 @@ per-file-ignores =
user_keymaps/**/*.py: F401,E501,E241,E131 user_keymaps/**/*.py: F401,E501,E241,E131
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/firmware.py: I001,I003,I004,F401 kmk/keyboard_config.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_third_party = analogio,bitbangio,bleio,board,busio,digitalio,framebuf,gamepad,gc,microcontroller,micropython,pulseio,pyb,pydux,uio,ubluepy,machine,pyb,uos

View File

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

View File

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

View File

@ -2,11 +2,11 @@ from kmk.consts import DiodeOrientation, UnicodeMode
from kmk.handlers.sequences import (compile_unicode_string_sequences, from kmk.handlers.sequences import (compile_unicode_string_sequences,
send_string) send_string)
from kmk.keys import KC from kmk.keys import KC
from kmk.mcus.circuitpython_samd51 import Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
from kmk.types import AttrDict from kmk.types import AttrDict
keyboard = Firmware() keyboard = KeyboardConfig()
''' '''
Converter/handwire: Converter/handwire:

View File

@ -2,11 +2,11 @@ from kmk.consts import DiodeOrientation, UnicodeMode
from kmk.handlers.sequences import (compile_unicode_string_sequences, from kmk.handlers.sequences import (compile_unicode_string_sequences,
send_string) send_string)
from kmk.keys import KC from kmk.keys import KC
from kmk.mcus.circuitpython_samd51 import Firmware from kmk.mcus.circuitpython_usbhid import KeyboardConfig
from kmk.pins import Pin as P from kmk.pins import Pin as P
from kmk.types import AttrDict from kmk.types import AttrDict
keyboard = Firmware() keyboard = KeyboardConfig()
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 = (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.row_pins = (P.D10, P.D11, P.D12, P.D13)

View File

@ -1,9 +1,9 @@
from kmk.boards.converter.keebio.levinson_r2 import Firmware from kmk.boards.converter.keebio.levinson_r2 import KeyboardConfig
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 = Firmware() keyboard = KeyboardConfig()
# ------------------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 Firmware from kmk.boards.converter.fourtypercentclub.luddite import KeyboardConfig
from kmk.keys import KC from kmk.keys import KC
keyboard = Firmware() keyboard = KeyboardConfig()
# ---------------------------------- Config -------------------------------------------- # ---------------------------------- Config --------------------------------------------

View File

@ -1,7 +1,7 @@
from kmk.boards.converter.keebio.nyquist_r2 import Firmware from kmk.boards.converter.keebio.nyquist_r2 import KeyboardConfig
from kmk.keys import KC from kmk.keys import KC
keyboard = Firmware() keyboard = KeyboardConfig()
# ------------------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 Firmware from kmk.boards.converter.keebio.iris_r2 import KeyboardConfig
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 = Firmware() keyboard = KeyboardConfig()
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 Firmware from kmk.boards.klarank import KeyboardConfig
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 = Firmware() keyboard = KeyboardConfig()
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 Firmware from kmk.boards.converter.keebio.levinson_r2 import KeyboardConfig
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 = Firmware() keyboard = KeyboardConfig()
# ------------------User level config variables --------------------------------------- # ------------------User level config variables ---------------------------------------
keyboard.leader_mode = LeaderMode.TIMEOUT keyboard.leader_mode = LeaderMode.TIMEOUT