diff options
author | Maxim Devaev <[email protected]> | 2023-08-25 12:35:28 +0300 |
---|---|---|
committer | Maxim Devaev <[email protected]> | 2023-08-25 12:35:28 +0300 |
commit | 21eddbde1c11961d7fb958422d6dd72b94c33375 (patch) | |
tree | 2a869d17932914a4481e6356dc78ab8690cd872c /kvmd/plugins/hid/_mcu/__init__.py | |
parent | 82ca2b1caed602030d2d849a9e61748ea7249ac9 (diff) |
pico hid bridge mode
Diffstat (limited to 'kvmd/plugins/hid/_mcu/__init__.py')
-rw-r--r-- | kvmd/plugins/hid/_mcu/__init__.py | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/kvmd/plugins/hid/_mcu/__init__.py b/kvmd/plugins/hid/_mcu/__init__.py index 6001b6de..f475a880 100644 --- a/kvmd/plugins/hid/_mcu/__init__.py +++ b/kvmd/plugins/hid/_mcu/__init__.py @@ -71,6 +71,10 @@ from .proto import check_response # ===== +class _SelfResetError(Exception): + pass + + class _RequestError(Exception): def __init__(self, msg: str) -> None: super().__init__(msg) @@ -302,18 +306,18 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many- time.sleep(1) def __hid_loop(self) -> None: + reset = True while not self.__stop_event.is_set(): try: - if not self.__hid_loop_wait_device(): + if not self.__hid_loop_wait_device(reset): continue + reset = True with self.__phy.connected() as conn: while not (self.__stop_event.is_set() and self.__events_queue.qsize() == 0): if self.__reset_required_event.is_set(): - try: - self.__set_state_busy(True) - self.__gpio.reset() - finally: - self.__reset_required_event.clear() + self.__set_state_busy(True) + self.__reset_required_event.clear() + break # Проваливаемся и резетим в __hid_loop_wait_device() try: event = self.__events_queue.get(timeout=0.1) except queue.Empty: @@ -323,17 +327,21 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many- self.__set_state_busy(True) if not self.__process_request(conn, event.make_request()): self.clear_events() + except _SelfResetError: + time.sleep(1) # Pico перезагружается сам вскоре после ответа + reset = False except Exception: self.clear_events() get_logger(0).exception("Unexpected error in the HID loop") time.sleep(1) - def __hid_loop_wait_device(self) -> bool: + def __hid_loop_wait_device(self, reset: bool) -> bool: logger = get_logger(0) - logger.info("Initial HID reset and wait for %s ...", self.__phy) - self.__gpio.reset() - # На самом деле SPI и Serial-девайсы не пропадают, просто резет и ожидание - # логичнее всего делать именно здесь. Ну и на будущее, да + if reset: + logger.info("Initial HID reset and wait for %s ...", self.__phy) + self.__gpio.reset() + # На самом деле SPI и Serial-девайсы не пропадают, + # а вот USB CDC (Pico HID Bridge) вполне себе пропадает for _ in range(10): if self.__phy.has_device(): logger.info("Physical HID interface found: %s", self.__phy) @@ -342,6 +350,7 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many- break time.sleep(1) logger.error("Missing physical HID interface: %s", self.__phy) + self.__set_state_online(False) return False def __process_request(self, conn: BasePhyConnection, request: bytes) -> bool: # pylint: disable=too-many-branches @@ -427,6 +436,5 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many- self.__state_flags.update(online=1, busy=reset_required, status=status) if reset_required: if self.__reset_self: - time.sleep(1) # Pico перезагружается сам вскоре после ответа - else: - self.__reset_required_event.set() + raise _SelfResetError() + self.__reset_required_event.set() |