convert matrix report from row/col byte array to linear key_number.
This commit is contained in:
parent
7519a97eaa
commit
da3e87ee2d
@ -112,19 +112,15 @@ class KMKKeyboard:
|
||||
|
||||
def _handle_matrix_report(self, update=None):
|
||||
if update is not None:
|
||||
self._on_matrix_changed(update[0], update[1], update[2])
|
||||
self._on_matrix_changed(update)
|
||||
self.state_changed = True
|
||||
|
||||
def _find_key_in_map(self, int_coord, row, col):
|
||||
def _find_key_in_map(self, int_coord):
|
||||
try:
|
||||
idx = self.coord_mapping.index(int_coord)
|
||||
except ValueError:
|
||||
if self.debug_enabled:
|
||||
print(
|
||||
'CoordMappingNotFound(ic={}, row={}, col={})'.format(
|
||||
int_coord, row, col
|
||||
)
|
||||
)
|
||||
print('CoordMappingNotFound(ic={})'.format(int_coord))
|
||||
|
||||
return None
|
||||
|
||||
@ -144,22 +140,25 @@ class KMKKeyboard:
|
||||
|
||||
return layer_key
|
||||
|
||||
def _on_matrix_changed(self, row, col, is_pressed):
|
||||
def _on_matrix_changed(self, kevent):
|
||||
int_coord = kevent.key_number
|
||||
is_pressed = kevent.pressed
|
||||
if self.debug_enabled:
|
||||
print('MatrixChange(col={} row={} pressed={})'.format(col, row, is_pressed))
|
||||
|
||||
int_coord = intify_coordinate(row, col)
|
||||
print('MatrixChange(ic={} pressed={})'.format(int_coord, is_pressed))
|
||||
|
||||
if not is_pressed:
|
||||
self.current_key = self._coordkeys_pressed[int_coord]
|
||||
try:
|
||||
self.current_key = self._coordkeys_pressed[int_coord]
|
||||
except KeyError:
|
||||
print(f'KeyNotPressed(ic={int_coord})')
|
||||
if self.debug_enabled:
|
||||
print('PressedKeyResolution(key={})'.format(self.current_key))
|
||||
|
||||
if self.current_key is None:
|
||||
self.current_key = self._find_key_in_map(int_coord, row, col)
|
||||
self.current_key = self._find_key_in_map(int_coord)
|
||||
|
||||
if self.current_key is None:
|
||||
print('MatrixUndefinedCoordinate(col={} row={})'.format(col, row))
|
||||
print('MatrixUndefinedCoordinate(ic={})'.format(int_coord))
|
||||
return self
|
||||
|
||||
for module in self.modules:
|
||||
@ -179,15 +178,15 @@ class KMKKeyboard:
|
||||
del self._coordkeys_pressed[int_coord]
|
||||
|
||||
if self.current_key:
|
||||
self.process_key(self.current_key, is_pressed, int_coord, (row, col))
|
||||
self.process_key(self.current_key, is_pressed, int_coord)
|
||||
|
||||
return self
|
||||
|
||||
def process_key(self, key, is_pressed, coord_int=None, coord_raw=None):
|
||||
def process_key(self, key, is_pressed, coord_int=None):
|
||||
if is_pressed:
|
||||
key.on_press(self, coord_int, coord_raw)
|
||||
key.on_press(self, coord_int)
|
||||
else:
|
||||
key.on_release(self, coord_int, coord_raw)
|
||||
key.on_release(self, coord_int)
|
||||
|
||||
return self
|
||||
|
||||
@ -274,7 +273,9 @@ class KMKKeyboard:
|
||||
|
||||
for ridx in range(rows_to_calc):
|
||||
for cidx in range(cols_to_calc):
|
||||
self.coord_mapping.append(intify_coordinate(ridx, cidx))
|
||||
self.coord_mapping.append(
|
||||
intify_coordinate(ridx, cidx, cols_to_calc)
|
||||
)
|
||||
|
||||
def _init_hid(self):
|
||||
if self.hid_type == HIDModes.NOOP:
|
||||
@ -400,6 +401,7 @@ class KMKKeyboard:
|
||||
self._init_sanity_check()
|
||||
self._init_coord_mapping()
|
||||
self._init_hid()
|
||||
self._init_matrix()
|
||||
|
||||
for module in self.modules:
|
||||
try:
|
||||
@ -415,8 +417,6 @@ class KMKKeyboard:
|
||||
if self.debug_enabled:
|
||||
print('Failed to load extension', err, ext)
|
||||
|
||||
self._init_matrix()
|
||||
|
||||
self._print_debug_cycle(init=True)
|
||||
|
||||
def _main_loop(self):
|
||||
@ -432,17 +432,11 @@ class KMKKeyboard:
|
||||
self.after_matrix_scan()
|
||||
|
||||
if self.secondary_matrix_update:
|
||||
# bytearray constructor here to produce a copy
|
||||
# otherwise things get strange when self.secondary_matrix_update
|
||||
# gets modified.
|
||||
self.matrix_update_queue.append(bytearray(self.secondary_matrix_update))
|
||||
self.matrix_update_queue.append(self.secondary_matrix_update)
|
||||
self.secondary_matrix_update = None
|
||||
|
||||
if self.matrix_update:
|
||||
# bytearray constructor here to produce a copy
|
||||
# otherwise things get strange when self.matrix_update
|
||||
# gets modified.
|
||||
self.matrix_update_queue.append(bytearray(self.matrix_update))
|
||||
self.matrix_update_queue.append(self.matrix_update)
|
||||
self.matrix_update = None
|
||||
|
||||
# only handle one key per cycle.
|
||||
|
@ -1,8 +1,8 @@
|
||||
import digitalio
|
||||
|
||||
|
||||
def intify_coordinate(row, col):
|
||||
return row << 8 | col
|
||||
def intify_coordinate(row, col, len_cols):
|
||||
return len_cols * row + col
|
||||
|
||||
|
||||
class DiodeOrientation:
|
||||
@ -20,6 +20,12 @@ class DiodeOrientation:
|
||||
ROW2COL = ROWS
|
||||
|
||||
|
||||
class KeyEvent:
|
||||
def __init__(self, key_number, pressed):
|
||||
self.key_number = key_number
|
||||
self.pressed = pressed
|
||||
|
||||
|
||||
class MatrixScanner:
|
||||
def __init__(
|
||||
self,
|
||||
@ -27,9 +33,11 @@ class MatrixScanner:
|
||||
rows,
|
||||
diode_orientation=DiodeOrientation.COLUMNS,
|
||||
rollover_cols_every_rows=None,
|
||||
offset=0,
|
||||
):
|
||||
self.len_cols = len(cols)
|
||||
self.len_rows = len(rows)
|
||||
self.offset = offset
|
||||
|
||||
# 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
|
||||
@ -92,7 +100,6 @@ class MatrixScanner:
|
||||
|
||||
self.len_state_arrays = self.len_cols * self.len_rows
|
||||
self.state = bytearray(self.len_state_arrays)
|
||||
self.report = bytearray(3)
|
||||
|
||||
def scan_for_changes(self):
|
||||
'''
|
||||
@ -131,13 +138,13 @@ class MatrixScanner:
|
||||
iidx // self.rollover_cols_every_rows
|
||||
)
|
||||
|
||||
self.report[0] = new_iidx
|
||||
self.report[1] = new_oidx
|
||||
row = new_iidx
|
||||
col = new_oidx
|
||||
else:
|
||||
self.report[0] = oidx
|
||||
self.report[1] = iidx
|
||||
row = oidx
|
||||
col = iidx
|
||||
|
||||
self.report[2] = new_val
|
||||
pressed = new_val
|
||||
self.state[ba_idx] = new_val
|
||||
|
||||
any_changed = True
|
||||
@ -150,4 +157,5 @@ class MatrixScanner:
|
||||
break
|
||||
|
||||
if any_changed:
|
||||
return self.report
|
||||
key_number = self.len_cols * row + col + self.offset
|
||||
return KeyEvent(key_number, pressed)
|
||||
|
@ -6,7 +6,7 @@ from supervisor import runtime, ticks_ms
|
||||
from storage import getmount
|
||||
|
||||
from kmk.kmktime import check_deadline
|
||||
from kmk.matrix import intify_coordinate
|
||||
from kmk.matrix import KeyEvent, intify_coordinate
|
||||
from kmk.modules import Module
|
||||
|
||||
|
||||
@ -119,7 +119,8 @@ class Split(Module):
|
||||
if self.split_flip and self.split_side == SplitSide.RIGHT:
|
||||
keyboard.col_pins = list(reversed(keyboard.col_pins))
|
||||
|
||||
self.split_offset = len(keyboard.col_pins)
|
||||
if self.split_offset is None:
|
||||
self.split_offset = len(keyboard.col_pins) * len(keyboard.row_pins)
|
||||
|
||||
if self.split_type == SplitType.UART and self.data_pin is not None:
|
||||
if self._is_target or not self.uart_flip:
|
||||
@ -141,12 +142,20 @@ class Split(Module):
|
||||
if not keyboard.coord_mapping:
|
||||
keyboard.coord_mapping = []
|
||||
|
||||
rows_to_calc = len(keyboard.row_pins) * 2
|
||||
cols_to_calc = len(keyboard.col_pins) * 2
|
||||
rows_to_calc = len(keyboard.row_pins)
|
||||
cols_to_calc = len(keyboard.col_pins)
|
||||
|
||||
for ridx in range(rows_to_calc):
|
||||
for cidx in range(cols_to_calc):
|
||||
keyboard.coord_mapping.append(intify_coordinate(ridx, cidx))
|
||||
keyboard.coord_mapping.append(
|
||||
intify_coordinate(ridx, cidx, cols_to_calc)
|
||||
)
|
||||
for cidx in range(cols_to_calc):
|
||||
keyboard.coord_mapping.append(
|
||||
intify_coordinate(rows_to_calc + ridx, cidx, cols_to_calc)
|
||||
)
|
||||
if self.split_side == SplitSide.RIGHT:
|
||||
keyboard.matrix.offset = self.split_offset
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
if self.split_type == SplitType.BLE:
|
||||
@ -269,12 +278,20 @@ class Split(Module):
|
||||
'''Resets the rescan timer'''
|
||||
self._ble_last_scan = ticks_ms()
|
||||
|
||||
def _serialize_update(self, update):
|
||||
buffer = bytearray(2)
|
||||
buffer[0] = update.key_number
|
||||
buffer[1] = update.pressed
|
||||
return buffer
|
||||
|
||||
def _deserialize_update(self, update):
|
||||
kevent = KeyEvent(key_number=update[0], pressed=update[1])
|
||||
return kevent
|
||||
|
||||
def _send_ble(self, update):
|
||||
if self._uart:
|
||||
try:
|
||||
if not self._is_target:
|
||||
update[1] += self.split_offset
|
||||
self._uart.write(update)
|
||||
self._uart.write(self._serialize_update(update))
|
||||
except OSError:
|
||||
try:
|
||||
self._uart.disconnect()
|
||||
@ -289,11 +306,11 @@ class Split(Module):
|
||||
|
||||
def _receive_ble(self, keyboard):
|
||||
if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
|
||||
while self._uart.in_waiting >= 3:
|
||||
self._uart_buffer.append(self._uart.read(3))
|
||||
while self._uart.in_waiting >= 2:
|
||||
update = self._deserialize_update(self._uart.read(2))
|
||||
self._uart_buffer.append(update)
|
||||
if self._uart_buffer:
|
||||
keyboard.secondary_matrix_update = bytearray(self._uart_buffer.pop(0))
|
||||
return
|
||||
keyboard.secondary_matrix_update = self._uart_buffer.pop(0)
|
||||
|
||||
def _checksum(self, update):
|
||||
checksum = bytes([sum(update) & 0xFF])
|
||||
@ -303,12 +320,8 @@ class Split(Module):
|
||||
def _send_uart(self, update):
|
||||
# Change offsets depending on where the data is going to match the correct
|
||||
# matrix location of the receiever
|
||||
|
||||
if self.split_side == SplitSide.RIGHT:
|
||||
# if we're on the right, we by definition are sending to the left, so we need to offset.
|
||||
update[1] += self.split_offset
|
||||
|
||||
if self._uart is not None:
|
||||
update = self._serialize_update(update)
|
||||
self._uart.write(self.uart_header)
|
||||
self._uart.write(update)
|
||||
self._uart.write(self._checksum(update))
|
||||
@ -321,16 +334,13 @@ class Split(Module):
|
||||
|
||||
microcontroller.reset()
|
||||
|
||||
while self._uart.in_waiting >= 5:
|
||||
while self._uart.in_waiting >= 4:
|
||||
# Check the header
|
||||
if self._uart.read(1) == self.uart_header:
|
||||
update = self._uart.read(3)
|
||||
update = self._uart.read(2)
|
||||
|
||||
# check the checksum
|
||||
if self._checksum(update) == self._uart.read(1):
|
||||
self._uart_buffer.append(update)
|
||||
|
||||
self._uart_buffer.append(self._deserialize_update(update))
|
||||
if self._uart_buffer:
|
||||
keyboard.secondary_matrix_update = bytearray(self._uart_buffer.pop(0))
|
||||
|
||||
return
|
||||
keyboard.secondary_matrix_update = self._uart_buffer.pop(0)
|
||||
|
@ -51,7 +51,7 @@ class TapDance(Module):
|
||||
keyboard.hid_pending = True
|
||||
keyboard._send_hid()
|
||||
keyboard.set_timeout(
|
||||
False, lambda: keyboard.process_key(key, is_pressed, None, None)
|
||||
False, lambda: keyboard.process_key(key, is_pressed)
|
||||
)
|
||||
return None
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user