convert matrix report from row/col byte array to linear key_number.
This commit is contained in:
		@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user