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