diff --git a/Makefile b/Makefile index fb9f393..c114676 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,10 @@ freeze-nrf-vendor-deps \ lint +NRF_DFU_PORT ?= /dev/ttyUSB0 +NRF_DFU_BAUD ?= 115200 +NRF_DFU_DELAY ?= 1.5 + devdeps: Pipfile.lock @pipenv install --dev --ignore-pipfile @@ -39,15 +43,15 @@ circuitpy-freeze-kmk-nrf: freeze-nrf-vendor-deps @rm -rf vendor/circuitpython/ports/nrf/kmk* @cp -av kmk vendor/circuitpython/ports/nrf/freeze/ -circuitpy-flash-nrf: circuitpy-freeze-kmk-nrf +circuitpy-flash-nrf: @echo "===> Building and flashing CircuitPython with KMK and your keymap" - @make -C vendor/circuitpython/ports/nrf BOARD=feather_nrf52832 SERIAL=/dev/ttyUSB0 SD=s132 FROZEN_MPY_DIR=freeze clean dfu-gen dfu-flash + @make -C vendor/circuitpython/ports/nrf BOARD=feather_nrf52832 SERIAL=${NRF_DFU_PORT} SD=s132 FROZEN_MPY_DIR=freeze clean dfu-gen dfu-flash circuitpy-flash-nrf-entrypoint: @echo "===> Flashing entrypoint if it doesn't already exist" @sleep 2 - @-timeout -k 5s 10s pipenv run ampy rm main.py 2>/dev/null - @-timeout -k 5s 10s pipenv run ampy put entrypoints/feather_nrf52832.py main.py + @-timeout -k 5s 10s pipenv run ampy -p ${NRF_DFU_PORT} -d ${NRF_DFU_DELAY} -b ${NRF_DFU_BAUD} rm main.py 2>/dev/null + @-timeout -k 5s 10s pipenv run ampy -p ${NRF_DFU_PORT} -d ${NRF_DFU_DELAY} -b ${NRF_DFU_BAUD} put entrypoints/feather_nrf52832.py main.py @echo "===> Flashed keyboard successfully!" build-feather-test: lint devdeps circuitpy-deps circuitpy-freeze-kmk-nrf @@ -77,5 +81,5 @@ burn-it-all-with-fire: lint devdeps @$(MAKE) circuitpy-flash-nrf @echo "===> Wiping keyboard config" @sleep 2 - @-pipenv run ampy rm main.py 2>/dev/null + @-timeout -k 5s 10s pipenv run ampy -p ${NRF_DFU_PORT} -d ${NRF_DFU_DELAY} -b ${NRF_DFU_BAUD} rm main.py 2>/dev/null @echo "===> Wiped! Probably safe to flash keyboard, try Python serial REPL to verify?" diff --git a/boards/klardotsh/twotwo_matrix_feather.py b/boards/klardotsh/twotwo_matrix_feather.py index e8b23eb..84c9cb8 100644 --- a/boards/klardotsh/twotwo_matrix_feather.py +++ b/boards/klardotsh/twotwo_matrix_feather.py @@ -1,23 +1,25 @@ import board -from kmk.circuitpython.matrix import MatrixScanner from kmk.common.consts import DiodeOrientation -from kmk.common.keymap import Keymap +from kmk.firmware import Firmware def main(): cols = (board.A4, board.A5) rows = (board.D27, board.A6) - matrix = MatrixScanner( - cols=cols, rows=rows, - diode_orientation=DiodeOrientation.COLUMNS, - ) + diode_orientation = DiodeOrientation.COLUMNS - keymap = Keymap([ + keymap = [ ['A', 'B'], ['C', 'D'], - ]) + ] - while True: - keymap.parse(matrix.raw_scan()) + firmware = Firmware( + keymap=keymap, + row_pins=rows, + col_pins=cols, + diode_orientation=diode_orientation, + ) + + firmware.go() diff --git a/entrypoints/feather_nrf52832.py b/entrypoints/feather_nrf52832.py index 1f52211..c07d83c 100644 --- a/entrypoints/feather_nrf52832.py +++ b/entrypoints/feather_nrf52832.py @@ -1,5 +1,4 @@ from kmk_keyboard_user import main - if __name__ == '__main__': main() diff --git a/kmk/circuitpython/matrix.py b/kmk/circuitpython/matrix.py index 5203cc2..666a2ca 100644 --- a/kmk/circuitpython/matrix.py +++ b/kmk/circuitpython/matrix.py @@ -1,9 +1,10 @@ import digitalio +from kmk.common.abstract.matrix_scanner import AbstractMatrixScanner from kmk.common.consts import DiodeOrientation -class MatrixScanner: +class MatrixScanner(AbstractMatrixScanner): def __init__(self, cols, rows, diode_orientation=DiodeOrientation.COLUMNS): # 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 @@ -35,20 +36,7 @@ class MatrixScanner: pin.switch_to_input(pull=digitalio.Pull.DOWN) def _normalize_matrix(self, matrix): - ''' - We always want to internally look at a keyboard as a list of rows, - where a "row" is a list of keycodes (columns). - - This will convert DiodeOrientation.COLUMNS matrix scans into a - ROWS scan, so we never have to think about these things again. - ''' - if self.diode_orientation == DiodeOrientation.ROWS: - return matrix - - return [ - [col[col_entry] for col in matrix] - for col_entry in range(max(len(col) for col in matrix)) - ] + return super()._normalize_matrix(matrix) def raw_scan(self): matrix = [] diff --git a/kmk/circuitpython/util.py b/kmk/circuitpython/util.py index 01d63d5..0b822b1 100644 --- a/kmk/circuitpython/util.py +++ b/kmk/circuitpython/util.py @@ -1,7 +1,8 @@ +import sys +import time + import board import digitalio -import time -import sys def feather_signal_error_with_led_flash(rate=0.5): diff --git a/kmk/common/abstract/__init__.py b/kmk/common/abstract/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kmk/common/abstract/matrix_scanner.py b/kmk/common/abstract/matrix_scanner.py new file mode 100644 index 0000000..4ef71dc --- /dev/null +++ b/kmk/common/abstract/matrix_scanner.py @@ -0,0 +1,25 @@ +from kmk.common.consts import DiodeOrientation + + +class AbstractMatrixScanner(): + def __init__(self, cols, rows, diode_orientation=DiodeOrientation.COLUMNS): + raise NotImplementedError('Abstract implementation') + + def _normalize_matrix(self, matrix): + ''' + We always want to internally look at a keyboard as a list of rows, + where a "row" is a list of keycodes (columns). + + This will convert DiodeOrientation.COLUMNS matrix scans into a + ROWS scan, so we never have to think about these things again. + ''' + if self.diode_orientation == DiodeOrientation.ROWS: + return matrix + + return [ + [col[col_entry] for col in matrix] + for col_entry in range(max(len(col) for col in matrix)) + ] + + def raw_scan(self): + raise NotImplementedError('Abstract implementation') diff --git a/kmk/common/keymap.py b/kmk/common/keymap.py index cdcfc9c..815c082 100644 --- a/kmk/common/keymap.py +++ b/kmk/common/keymap.py @@ -10,9 +10,9 @@ class Keymap: for ridx, row in enumerate(matrix): for cidx, col in enumerate(row): if col != self.state[ridx][cidx]: - print('{}: {}'.format( + yield '{}: {}'.format( 'KEYDOWN' if col else 'KEYUP', self.map[ridx][cidx], - )) + ) self.state = matrix diff --git a/kmk/firmware.py b/kmk/firmware.py new file mode 100644 index 0000000..7e5fa22 --- /dev/null +++ b/kmk/firmware.py @@ -0,0 +1,18 @@ +from kmk.common.keymap import Keymap + +try: + from kmk.circuitpython.matrix import MatrixScanner +except ImportError: + from kmk.micropython.matrix import MatrixScanner + + +class Firmware: + def __init__(self, keymap, row_pins, col_pins, diode_orientation): + self.raw_keymap = keymap + self.keymap = Keymap(keymap) + self.matrix = MatrixScanner(col_pins, row_pins, diode_orientation) + + def go(self): + while True: + for event in self.keymap.parse(self.matrix.raw_scan()): + print(event)