Refactor MatrixScanner to use enhanced Pins abstraction; add DEBUG_ENABLED to SAMD51 boards
This commit is contained in:
parent
70db4ae84d
commit
3b0cd6c421
@ -1,9 +0,0 @@
|
||||
from kmk.common.consts import DiodeOrientation
|
||||
|
||||
|
||||
class AbstractMatrixScanner():
|
||||
def __init__(self, cols, rows, active_layers, diode_orientation=DiodeOrientation.COLUMNS):
|
||||
raise NotImplementedError('Abstract implementation')
|
||||
|
||||
def scan_for_pressed(self):
|
||||
raise NotImplementedError('Abstract implementation')
|
@ -1,3 +1,7 @@
|
||||
CIRCUITPYTHON = 'CircuitPython'
|
||||
MICROPYTHON = 'MicroPython'
|
||||
|
||||
|
||||
class HIDReportTypes:
|
||||
KEYBOARD = 1
|
||||
MOUSE = 2
|
||||
|
@ -1,11 +1,10 @@
|
||||
import digitalio
|
||||
|
||||
from kmk.common.abstract.matrix_scanner import AbstractMatrixScanner
|
||||
from kmk.common.consts import DiodeOrientation
|
||||
from kmk.common.event_defs import matrix_changed
|
||||
|
||||
|
||||
class MatrixScanner(AbstractMatrixScanner):
|
||||
class MatrixScanner:
|
||||
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
|
||||
@ -15,8 +14,8 @@ class MatrixScanner(AbstractMatrixScanner):
|
||||
if len(unique_pins) != len(cols) + len(rows):
|
||||
raise ValueError('Cannot use a pin as both a column and row')
|
||||
|
||||
self.cols = [digitalio.DigitalInOut(pin) for pin in cols]
|
||||
self.rows = [digitalio.DigitalInOut(pin) for pin in rows]
|
||||
self.cols = cols
|
||||
self.rows = rows
|
||||
self.diode_orientation = diode_orientation
|
||||
self.last_pressed_len = 0
|
||||
|
||||
@ -41,15 +40,15 @@ class MatrixScanner(AbstractMatrixScanner):
|
||||
pressed = []
|
||||
|
||||
for oidx, opin in enumerate(self.outputs):
|
||||
opin.value = True
|
||||
opin.value(True)
|
||||
|
||||
for iidx, ipin in enumerate(self.inputs):
|
||||
if ipin.value:
|
||||
if ipin.value():
|
||||
pressed.append(
|
||||
(oidx, iidx) if self.diode_orientation == DiodeOrientation.ROWS else (iidx, oidx) # noqa
|
||||
)
|
||||
|
||||
opin.value = False
|
||||
opin.value(False)
|
||||
|
||||
if len(pressed) != self.last_pressed_len:
|
||||
self.last_pressed_len = len(pressed)
|
@ -1,18 +1,22 @@
|
||||
from micropython import const
|
||||
|
||||
from kmk.common.consts import CIRCUITPYTHON, MICROPYTHON
|
||||
|
||||
PULL_UP = const(1)
|
||||
PULL_DOWN = const(2)
|
||||
|
||||
|
||||
try:
|
||||
import board
|
||||
import digitalio
|
||||
|
||||
PLATFORM = 'CircuitPython'
|
||||
PLATFORM = CIRCUITPYTHON
|
||||
PIN_SOURCE = board
|
||||
except ImportError:
|
||||
import machine
|
||||
|
||||
PLATFORM = 'MicroPython'
|
||||
PLATFORM = MICROPYTHON
|
||||
PIN_SOURCE = machine.Pin.board
|
||||
except ImportError:
|
||||
from kmk.common.types import Passthrough
|
||||
|
||||
PLATFORM = 'Unit Testing'
|
||||
PIN_SOURCE = Passthrough()
|
||||
|
||||
|
||||
def get_pin(pin):
|
||||
@ -32,9 +36,64 @@ def get_pin(pin):
|
||||
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 get_pin(attr)
|
||||
return AbstractedDigitalPin(get_pin(attr))
|
||||
|
||||
|
||||
Pin = PinLookup()
|
||||
|
@ -1,14 +1,24 @@
|
||||
import sys
|
||||
from logging import WARNING
|
||||
|
||||
from kmk.circuitpython.hid import HIDHelper
|
||||
from kmk.circuitpython.matrix import MatrixScanner
|
||||
from kmk.common.consts import UnicodeModes
|
||||
from kmk.common.matrix import MatrixScanner
|
||||
from kmk.firmware import Firmware
|
||||
|
||||
|
||||
def main():
|
||||
from kmk_keyboard_user import cols, diode_orientation, keymap, rows
|
||||
import kmk_keyboard_user
|
||||
cols = getattr(kmk_keyboard_user, 'cols')
|
||||
diode_orientation = getattr(kmk_keyboard_user, 'diode_orientation')
|
||||
keymap = getattr(kmk_keyboard_user, 'keymap')
|
||||
rows = getattr(kmk_keyboard_user, 'rows')
|
||||
|
||||
DEBUG_ENABLE = getattr(kmk_keyboard_user, 'DEBUG_ENABLE', False)
|
||||
|
||||
if DEBUG_ENABLE:
|
||||
from logging import DEBUG as log_level
|
||||
else:
|
||||
from logging import ERROR as log_level
|
||||
|
||||
try:
|
||||
from kmk_keyboard_user import unicode_mode
|
||||
@ -22,7 +32,7 @@ def main():
|
||||
col_pins=cols,
|
||||
diode_orientation=diode_orientation,
|
||||
unicode_mode=unicode_mode,
|
||||
log_level=WARNING,
|
||||
log_level=log_level,
|
||||
matrix_scanner=MatrixScanner,
|
||||
hid=HIDHelper,
|
||||
)
|
||||
|
@ -1,14 +1,24 @@
|
||||
import sys
|
||||
from logging import WARNING
|
||||
|
||||
from kmk.circuitpython.hid import HIDHelper
|
||||
from kmk.circuitpython.matrix import MatrixScanner
|
||||
from kmk.common.consts import UnicodeModes
|
||||
from kmk.common.matrix import MatrixScanner
|
||||
from kmk.firmware import Firmware
|
||||
|
||||
|
||||
def main():
|
||||
from kmk_keyboard_user import cols, diode_orientation, keymap, rows
|
||||
import kmk_keyboard_user
|
||||
cols = getattr(kmk_keyboard_user, 'cols')
|
||||
diode_orientation = getattr(kmk_keyboard_user, 'diode_orientation')
|
||||
keymap = getattr(kmk_keyboard_user, 'keymap')
|
||||
rows = getattr(kmk_keyboard_user, 'rows')
|
||||
|
||||
DEBUG_ENABLE = getattr(kmk_keyboard_user, 'DEBUG_ENABLE', False)
|
||||
|
||||
if DEBUG_ENABLE:
|
||||
from logging import DEBUG as log_level
|
||||
else:
|
||||
from logging import ERROR as log_level
|
||||
|
||||
try:
|
||||
from kmk_keyboard_user import unicode_mode
|
||||
@ -22,7 +32,7 @@ def main():
|
||||
col_pins=cols,
|
||||
diode_orientation=diode_orientation,
|
||||
unicode_mode=unicode_mode,
|
||||
log_level=WARNING,
|
||||
log_level=log_level,
|
||||
matrix_scanner=MatrixScanner,
|
||||
hid=HIDHelper,
|
||||
)
|
||||
|
@ -2,8 +2,8 @@ import sys
|
||||
|
||||
import gc
|
||||
|
||||
from kmk.common.matrix import MatrixScanner
|
||||
from kmk.firmware import Firmware
|
||||
from kmk.micropython.matrix import MatrixScanner
|
||||
from kmk.micropython.pyb_hid import HIDHelper
|
||||
|
||||
|
||||
@ -17,9 +17,9 @@ def main():
|
||||
DEBUG_ENABLE = getattr(kmk_keyboard_user, 'DEBUG_ENABLE', False)
|
||||
|
||||
if DEBUG_ENABLE:
|
||||
from logging import DEBUG
|
||||
from logging import DEBUG as log_level
|
||||
else:
|
||||
from logging import ERROR as DEBUG
|
||||
from logging import ERROR as log_level
|
||||
|
||||
# This will run out of ram at this point unless you manually GC
|
||||
gc.collect()
|
||||
@ -31,7 +31,7 @@ def main():
|
||||
col_pins=cols,
|
||||
diode_orientation=diode_orientation,
|
||||
hid=HIDHelper,
|
||||
log_level=DEBUG,
|
||||
log_level=log_level,
|
||||
matrix_scanner=MatrixScanner,
|
||||
)
|
||||
# This will run out of ram at this point unless you manually GC
|
||||
|
@ -1,63 +0,0 @@
|
||||
import machine
|
||||
|
||||
from kmk.common.abstract.matrix_scanner import AbstractMatrixScanner
|
||||
from kmk.common.consts import DiodeOrientation
|
||||
from kmk.common.event_defs import matrix_changed
|
||||
|
||||
|
||||
class MatrixScanner(AbstractMatrixScanner):
|
||||
def __init__(self, cols, rows, active_layers, 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
|
||||
#
|
||||
# repr() hackery is because MicroPython Pin objects are not hashable.
|
||||
# Technically we support passing either a string (hashable) or the
|
||||
# Pin object directly here, so the hackaround is necessary.
|
||||
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 = [machine.Pin(pin) for pin in cols]
|
||||
self.rows = [machine.Pin(pin) for pin in rows]
|
||||
self.diode_orientation = diode_orientation
|
||||
self.active_layers = active_layers
|
||||
self.last_pressed_len = 0
|
||||
|
||||
if self.diode_orientation == DiodeOrientation.COLUMNS:
|
||||
self.outputs = self.cols
|
||||
self.inputs = self.rows
|
||||
elif self.diode_orientation == DiodeOrientation.ROWS:
|
||||
self.outputs = self.rows
|
||||
self.inputs = self.cols
|
||||
else:
|
||||
raise ValueError('Invalid DiodeOrientation: {}'.format(
|
||||
self.diode_orientation,
|
||||
))
|
||||
|
||||
for pin in self.outputs:
|
||||
pin.init(machine.Pin.OUT)
|
||||
pin.off()
|
||||
|
||||
for pin in self.inputs:
|
||||
pin.init(machine.Pin.IN, machine.Pin.PULL_DOWN)
|
||||
pin.off()
|
||||
|
||||
def scan_for_pressed(self):
|
||||
pressed = []
|
||||
|
||||
for oidx, opin in enumerate(self.outputs):
|
||||
opin.value(1)
|
||||
|
||||
for iidx, ipin in enumerate(self.inputs):
|
||||
if ipin.value():
|
||||
pressed.append(
|
||||
(oidx, iidx) if self.diode_orientation == DiodeOrientation.ROWS else (iidx, oidx) # noqa
|
||||
)
|
||||
|
||||
opin.value(0)
|
||||
|
||||
if len(pressed) != self.last_pressed_len:
|
||||
self.last_pressed_len = len(pressed)
|
||||
return matrix_changed(pressed)
|
||||
|
||||
return None # The default, but for explicitness
|
@ -5,9 +5,16 @@ class Anything:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
return 'Anything<{}>'.format(self.name)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return None
|
||||
|
||||
|
||||
class Passthrough:
|
||||
def __getattr__(self, attr):
|
||||
@ -16,3 +23,9 @@ class Passthrough:
|
||||
|
||||
class Pin:
|
||||
board = Passthrough()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.board
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return getattr(self.board, attr)
|
||||
|
@ -7,6 +7,8 @@ from kmk.common.types import AttrDict
|
||||
from kmk.entrypoints.handwire.itsybitsy_m4_express import main
|
||||
from kmk.firmware import Firmware
|
||||
|
||||
DEBUG_ENABLE = True
|
||||
|
||||
cols = (P.A4, P.A5, P.D7)
|
||||
rows = (P.D12, P.D11, P.D10)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user