From 936ff7024db31e4e39baeea299ba7a850f0c91a1 Mon Sep 17 00:00:00 2001 From: "regicidal.plutophage" <36969337+regicidalplutophage@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:54:36 +0300 Subject: [PATCH 1/4] Update devcontainer.json --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8975c70a1..1dbb24f74 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,7 @@ { "name": "Python 3", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye", + "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bookworm", "features": { "ghcr.io/devcontainers/features/python:1": {} }, From 8e8dccf3a72c1c44d3db17ed1227b1580fbb20a2 Mon Sep 17 00:00:00 2001 From: "regicidal.plutophage" <36969337+regicidalplutophage@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:33:08 +0000 Subject: [PATCH 2/4] hid watchdog --- kmk/hid.py | 119 ++++++++++++++++++++++++-------------------- kmk/kmk_keyboard.py | 23 +++++++++ 2 files changed, 87 insertions(+), 55 deletions(-) diff --git a/kmk/hid.py b/kmk/hid.py index 7d65409a2..cbd36c7f4 100644 --- a/kmk/hid.py +++ b/kmk/hid.py @@ -5,6 +5,8 @@ from storage import getmount from kmk.keys import ConsumerKey, KeyboardKey, ModifierKey, MouseKey + +# from kmk.scheduler import create_task from kmk.utils import Debug, clamp try: @@ -55,13 +57,47 @@ class HIDUsagePage: class AbstractHID: - REPORT_BYTES = 8 + report_bytes_default = 8 + REPORT_BYTES = report_bytes_default + hid_devices = {} def __init__(self, **kwargs): + self._nkro = False + self._mouse = True + self._pan = False + self.make_device_list() + + self._cc_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.CONSUMER] + 1) + self._cc_report[0] = HIDReportTypes.CONSUMER + self._cc_pending = False + + self.test_nkro() + self.test_mouse() + + def make_device_list(self): + self.devices = {} + + for device in self.hid_devices: + if not hasattr(device, 'send_report'): + continue + us = device.usage + up = device.usage_page + + if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER: + self.devices[HIDReportTypes.CONSUMER] = device + elif up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD: + self.devices[HIDReportTypes.KEYBOARD] = device + elif up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE: + self.devices[HIDReportTypes.MOUSE] = device + elif up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL: + self.devices[HIDReportTypes.SYSCONTROL] = device + + def test_nkro(self): + if self._nkro: + return self._evt = bytearray(self.REPORT_BYTES) self._evt[0] = HIDReportTypes.KEYBOARD - self._nkro = False # bodgy NKRO autodetect try: @@ -87,9 +123,9 @@ def __init__(self, **kwargs): self.report_mods = memoryview(self._evt)[1:2] self.report_non_mods = memoryview(self._evt)[3:] - self._cc_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.CONSUMER] + 1) - self._cc_report[0] = HIDReportTypes.CONSUMER - self._cc_pending = False + def test_mouse(self): + if not self._mouse or self._pan: + return self._pd_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.MOUSE] + 1) self._pd_report[0] = HIDReportTypes.MOUSE @@ -103,12 +139,17 @@ def __init__(self, **kwargs): except ValueError: self._pd_report = bytearray(6) self._pd_report[0] = HIDReportTypes.MOUSE + self._pan = True if debug.enabled: debug('use pan') except KeyError: + self._mouse = False if debug.enabled: debug('mouse disabled') + def watchdog(self): + return + def __repr__(self): return f'{self.__class__.__name__}(REPORT_BYTES={self.REPORT_BYTES})' @@ -254,27 +295,22 @@ def has_key(self, key): class USBHID(AbstractHID): - REPORT_BYTES = 9 + report_bytes_default = 9 + REPORT_BYTES = report_bytes_default def __init__(self, **kwargs): - - self.devices = {} - - for device in usb_hid.devices: - us = device.usage - up = device.usage_page - - if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER: - self.devices[HIDReportTypes.CONSUMER] = device - elif up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD: - self.devices[HIDReportTypes.KEYBOARD] = device - elif up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE: - self.devices[HIDReportTypes.MOUSE] = device - elif up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL: - self.devices[HIDReportTypes.SYSCONTROL] = device - + self.hid = usb_hid + self.hid_devices = self.hid.devices + self.usb_status = None super().__init__(**kwargs) + def watchdog(self): + if self.usb_status != supervisor.runtime.usb_connected: + self.usb_status = supervisor.runtime.usb_connected + self.make_device_list() + self.test_nkro() + self.test_mouse() + def hid_send(self, evt): if not supervisor.runtime.usb_connected: return @@ -291,11 +327,12 @@ class BLEHID(AbstractHID): MAX_CONNECTIONS = const(2) def __init__(self, ble_name=str(getmount('/').label), **kwargs): - + self.ble_status = None self.ble_name = ble_name self.ble = BLERadio() self.ble.name = self.ble_name self.hid = HIDService() + self.hid_devices = self.hid.devices self.hid.protocol_mode = 0 # Boot protocol super().__init__(**kwargs) @@ -307,38 +344,10 @@ def __init__(self, ble_name=str(getmount('/').label), **kwargs): if not self.ble.connected or not self.hid.devices: self.start_advertising() - @property - def devices(self): - '''Search through the provided list of devices to find the ones with the - send_report attribute.''' - if not self.ble.connected: - return {} - - result = {} - - for device in self.hid.devices: - if not hasattr(device, 'send_report'): - continue - us = device.usage - up = device.usage_page - - if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER: - result[HIDReportTypes.CONSUMER] = device - continue - - if up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD: - result[HIDReportTypes.KEYBOARD] = device - continue - - if up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE: - result[HIDReportTypes.MOUSE] = device - continue - - if up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL: - result[HIDReportTypes.SYSCONTROL] = device - continue - - return result + def watchdog(self): + if self.ble_status != self.ble.connected: + self.ble_status = self.ble.connected + self.make_device_list() def hid_send(self, evt): if not self.ble.connected: diff --git a/kmk/kmk_keyboard.py b/kmk/kmk_keyboard.py index 96d69059f..91c241021 100644 --- a/kmk/kmk_keyboard.py +++ b/kmk/kmk_keyboard.py @@ -34,6 +34,20 @@ class Sandbox: class KMKKeyboard: + def __init__( + self, + keymap=[], + coord_mapping=None, + matrix=None, + modules=[], + extensions=[], + ): + self.keymap = keymap + self.coord_mapping = coord_mapping + self.matrix = matrix + self.modules = modules + self.extensions = extensions + ##### # User-configurable keymap = [] @@ -185,6 +199,14 @@ def _process_resume_buffer(self): self._resume_buffer_x = buffer + @property + def debug_enabled(self) -> bool: + return debug.enabled + + @debug_enabled.setter + def debug_enabled(self, enabled: bool): + debug.enabled = enabled + def pre_process_key( self, key: Key, @@ -286,6 +308,7 @@ def _init_hid(self) -> None: else: self._hid_helper = AbstractHID self._hid_helper = self._hid_helper(**self._go_args) + self._watchdog = create_task(self._hid_helper.watchdog, period_ms=200) self._hid_send_enabled = True if debug.enabled: From eaa0c031ef4e0d24fd0bdee77553e4268c54f0fc Mon Sep 17 00:00:00 2001 From: "regicidal.plutophage" <36969337+regicidalplutophage@users.noreply.github.com> Date: Wed, 18 Dec 2024 17:11:20 +0000 Subject: [PATCH 3/4] add start_watchdog() method --- kmk/hid.py | 18 ++++++++++++++---- kmk/kmk_keyboard.py | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/kmk/hid.py b/kmk/hid.py index cbd36c7f4..ae2c6fccb 100644 --- a/kmk/hid.py +++ b/kmk/hid.py @@ -5,6 +5,7 @@ from storage import getmount from kmk.keys import ConsumerKey, KeyboardKey, ModifierKey, MouseKey +from kmk.scheduler import create_task # from kmk.scheduler import create_task from kmk.utils import Debug, clamp @@ -65,7 +66,7 @@ def __init__(self, **kwargs): self._nkro = False self._mouse = True self._pan = False - self.make_device_list() + self.find_devices() self._cc_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.CONSUMER] + 1) self._cc_report[0] = HIDReportTypes.CONSUMER @@ -74,7 +75,7 @@ def __init__(self, **kwargs): self.test_nkro() self.test_mouse() - def make_device_list(self): + def find_devices(self): self.devices = {} for device in self.hid_devices: @@ -150,6 +151,9 @@ def test_mouse(self): def watchdog(self): return + def start_watchdog(self): + return + def __repr__(self): return f'{self.__class__.__name__}(REPORT_BYTES={self.REPORT_BYTES})' @@ -307,10 +311,13 @@ def __init__(self, **kwargs): def watchdog(self): if self.usb_status != supervisor.runtime.usb_connected: self.usb_status = supervisor.runtime.usb_connected - self.make_device_list() + self.find_devices() self.test_nkro() self.test_mouse() + def start_watchdog(self, period_ms=200): + return create_task(self.watchdog, period_ms=period_ms) + def hid_send(self, evt): if not supervisor.runtime.usb_connected: return @@ -347,7 +354,10 @@ def __init__(self, ble_name=str(getmount('/').label), **kwargs): def watchdog(self): if self.ble_status != self.ble.connected: self.ble_status = self.ble.connected - self.make_device_list() + self.find_devices() + + def start_watchdog(self, period_ms=200): + return create_task(self.watchdog, period_ms=period_ms) def hid_send(self, evt): if not self.ble.connected: diff --git a/kmk/kmk_keyboard.py b/kmk/kmk_keyboard.py index 91c241021..f76529dd5 100644 --- a/kmk/kmk_keyboard.py +++ b/kmk/kmk_keyboard.py @@ -308,7 +308,7 @@ def _init_hid(self) -> None: else: self._hid_helper = AbstractHID self._hid_helper = self._hid_helper(**self._go_args) - self._watchdog = create_task(self._hid_helper.watchdog, period_ms=200) + self._hid_helper.start_watchdog() self._hid_send_enabled = True if debug.enabled: From fa5b323a6180b629cd2b846a365e0559827d17ba Mon Sep 17 00:00:00 2001 From: "regicidal.plutophage" <36969337+regicidalplutophage@users.noreply.github.com> Date: Wed, 18 Dec 2024 17:21:35 +0000 Subject: [PATCH 4/4] make watchdog self-contained --- kmk/hid.py | 2 ++ kmk/kmk_keyboard.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kmk/hid.py b/kmk/hid.py index ae2c6fccb..a7570e42f 100644 --- a/kmk/hid.py +++ b/kmk/hid.py @@ -75,6 +75,8 @@ def __init__(self, **kwargs): self.test_nkro() self.test_mouse() + self.start_watchdog() + def find_devices(self): self.devices = {} diff --git a/kmk/kmk_keyboard.py b/kmk/kmk_keyboard.py index f76529dd5..2817ffc28 100644 --- a/kmk/kmk_keyboard.py +++ b/kmk/kmk_keyboard.py @@ -308,7 +308,6 @@ def _init_hid(self) -> None: else: self._hid_helper = AbstractHID self._hid_helper = self._hid_helper(**self._go_args) - self._hid_helper.start_watchdog() self._hid_send_enabled = True if debug.enabled: