Basic uart split support. Still need docs and testing

This commit is contained in:
Kyle Brown 2018-10-19 02:22:22 -07:00
parent d60cdc6f7f
commit 49da93e436
3 changed files with 158 additions and 25 deletions

View File

@ -35,6 +35,9 @@ import kmk.internal_state # isort:skip
# Thanks for sticking around. Now let's do real work, starting below # Thanks for sticking around. Now let's do real work, starting below
import gc import gc
import supervisor
import board
import busio
from kmk.consts import LeaderMode, UnicodeModes from kmk.consts import LeaderMode, UnicodeModes
from kmk.hid import USB_HID from kmk.hid import USB_HID
@ -59,6 +62,10 @@ class Firmware:
hid_helper = USB_HID hid_helper = USB_HID
split_type = None
split_offsets = ()
split_master_left = True
def __init__(self): def __init__(self):
self._state = InternalState(self) self._state = InternalState(self)
@ -75,6 +82,54 @@ class Firmware:
self._state.force_keycode_up(key) self._state.force_keycode_up(key)
self._send_hid() self._send_hid()
def _handle_update(self, update):
if self.split_type is not None and not self.split_master_left:
update[1] += self.split_offsets[update[1]]
if update is not None:
self._state.matrix_changed(
update[0],
update[1],
update[2],
)
if self._state.hid_pending:
self._send_hid()
for key in self._state.pending_keys:
self._send_key(key)
self._state.pending_key_handled()
if self._state.macro_pending:
for key in self._state.macro_pending(self):
self._send_key(key)
self._state.resolve_macro()
if self.debug_enabled:
print('New State: {}'.format(self._state._to_dict()))
def _send_to_master(self, update):
if self.split_type == "UART":
if self.uart is None:
self.uart = busio.UART(board.TX, board.RX, timeout=0)
# Update column with offset
if self.split_master_left:
update[1] += self.split_offsets[update[1]]
self.uart.write(update)
def _receive_from_slave(self):
if self.split_type == "UART":
if self.uart is None:
self.uart = busio.UART(board.TX, board.RX, timeout=0)
update = self.uart.read()
return update
return None
def go(self): def go(self):
assert self.keymap, 'must define a keymap with at least one row' assert self.keymap, 'must define a keymap with at least one row'
assert self.row_pins, 'no GPIO pins defined for matrix rows' assert self.row_pins, 'no GPIO pins defined for matrix rows'
@ -95,30 +150,18 @@ class Firmware:
print("Firin' lazers. Keyboard is booted.") print("Firin' lazers. Keyboard is booted.")
while True: while True:
update = self.matrix.scan_for_changes() if self.split_type is not None:
if update is not None: update = self._receive_from_slave()
self._state.matrix_changed( if update is not None:
update[0], self._handle_update(update)
update[1],
update[2],
)
if self._state.hid_pending: for update in self.matrix.scan_for_changes():
self._send_hid() # Abstract this later. Bluetooth will fail here
if supervisor.runtime.serial_connected:
self._handle_update(update)
if self.debug_enabled: else:
print('New State: {}'.format(self._state._to_dict())) # This keyboard is a slave, and needs to send data to master
self._send_to_master(update)
self._state.process_timeouts()
for key in self._state.pending_keys:
self._send_key(key)
self._state.pending_key_handled()
if self._state.macro_pending:
for key in self._state.macro_pending(self):
self._send_key(key)
self._state.resolve_macro()
gc.collect() gc.collect()

View File

@ -16,9 +16,9 @@ keyboard.diode_orientation = DiodeOrientation.COLUMNS
# ------------------User level config variables --------------------------------------- # ------------------User level config variables ---------------------------------------
keyboard.unicode_mode = UnicodeModes.LINUX keyboard.unicode_mode = UnicodeModes.LINUX
keyboard.tap_time = 900 keyboard.tap_time = 350
keyboard.leader_timeout = 2000 keyboard.leader_timeout = 2000
keyboard.debug_enabled = True keyboard.debug_enabled = False
emoticons = compile_unicode_string_sequences({ emoticons = compile_unicode_string_sequences({
# Emoticons, but fancier # Emoticons, but fancier

View File

@ -0,0 +1,90 @@
from kmk.consts import DiodeOrientation, UnicodeModes
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
from kmk.mcus.circuitpython_samd51 import Firmware
from kmk.pins import Pin as P
from kmk.types import AttrDict
keyboard = Firmware()
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.diode_orientation = DiodeOrientation.COLUMNS
# ------------------User level config variables ---------------------------------------
keyboard.unicode_mode = UnicodeModes.LINUX
keyboard.tap_time = 900
keyboard.leader_timeout = 2000
keyboard.debug_enabled = True
emoticons = compile_unicode_string_sequences({
# Emoticons, but fancier
'ANGRY_TABLE_FLIP': r'(ノಠ痊ಠ)ノ彡┻━┻',
'CHEER': r'+。:.゚ヽ(´∀。)ノ゚.:。+゚゚+。:.゚ヽ(*´∀)ノ゚.:。+゚',
'TABLE_FLIP': r'(╯°□°)╯︵ ┻━┻',
'WAT': r'⊙.☉',
'FF': r'凸(゚Д゚#)',
'F': r'( ̄^ ̄)凸',
'MEH': r'╮( ̄_ ̄)╭',
'YAY': r'o(^▽^)o',
})
# ---------------------- Leader Key Macros --------------------------------------------
keyboard.leader_dictionary = {
glds('flip'): emoticons.ANGRY_TABLE_FLIP,
glds('cheer'): emoticons.CHEER,
glds('wat'): emoticons.WAT,
glds('ff'): emoticons.FF,
glds('f'): emoticons.F,
glds('meh'): emoticons.MEH,
glds('yay'): emoticons.YAY,
}
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.")
# ---------------------- Keymap ---------------------------------------------------------
keyboard.keymap = [
[
# Default
[KC.GESC, KC.QUOTE, KC.COMMA, KC.DOT, KC.P, KC.Y, KC.F, KC.G, KC.C, KC.R, KC.L, KC.BKSP],
[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.LSFT, KC.SCLN, KC.Q, KC.J, KC.K, KC.X, KC.B, KC.M, KC.W, KC.V, KC.Z, KC.SLSH],
[KC.LCTRL, KC.LGUI, KC.LALT, KC.LEAD, KC.MO(2), KC.LT(3, KC.SPC), KC.LT(3, KC.SPC), KC.MO(4), KC.LEFT, KC.DOWN, KC.UP, KC.RIGHT],
],
[
# Gaming
[KC.TAB, KC.QUOT, KC.COMM, KC.DOT, KC.P, KC.Y, KC.F, KC.G, KC.C, KC.R, KC.L, KC.BKSP],
[KC.ESC, KC.A, KC.O, KC.E, KC.U, KC.I, KC.D, KC.H, KC.T, KC.N, KC.S, KC.ENT],
[KC.LSFT, KC.SCLN, KC.Q, KC.J, KC.K, KC.X, KC.B, KC.M, KC.W, KC.V, KC.Z, KC.SLSH],
[KC.LCTRL, KC.LGUI, KC.LALT, KC.F1, KC.F2, KC.SPC, KC.SPC, KC.MO(4), KC.LEFT, KC.DOWN, KC.UP, KC.RIGHT],
],
[
# Raise1
[KC.TILD, KC.EXLM, KC.AT, KC.HASH, KC.DLR, KC.PERC, KC.CIRC, KC.AMPR, KC.ASTR, KC.LPRN, KC.RPRN, KC.DEL],
[KC.TRNS, KC.NO, KC.NO, KC.NO, KC.NO, KC.NO, KC.NO, KC.NO, KC.NO, KC.LBRC, KC.RBRC, KC.BSLS],
[KC.TRNS, KC.NO, KC.NO, KC.NO, KC.NO, KC.NO, KC.NO, KC.NO, KC.INS, KC.PGDN, KC.PGUP, KC.MINS],
[KC.RESET, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.NO, KC.NO, KC.EQL, KC.HOME, KC.VOLD, KC.VOLU, KC.END],
],
[
# Raise2
[KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.N7, KC.N8, KC.N9, KC.BKSP],
[KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.N4, KC.N5, KC.N6, KC.NO],
[KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.N1, KC.N2, KC.N3, KC.NO],
[KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.N0, KC.N0, KC.PDOT, KC.ENT],
],
[
# Raise3
[WPM, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.F10, KC.F11, KC.F12, KC.LSHIFT(KC.INS)],
[KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.F7, KC.F8, KC.F9, KC.NO],
[KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.F4, KC.F5, KC.F6, KC.NO],
[KC.DF(0), KC.DF(1), KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.TRNS, KC.F1, KC.F2, KC.F3, KC.NO],
],
]
if __name__ == '__main__':
keyboard.go()