mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-13 01:30:31 +08:00
pico hid bridge mode
This commit is contained in:
parent
82ca2b1cae
commit
21eddbde1c
@ -10,6 +10,7 @@ target_sources(${target_name} PRIVATE
|
|||||||
ph_ps2.c
|
ph_ps2.c
|
||||||
ph_cmds.c
|
ph_cmds.c
|
||||||
ph_com.c
|
ph_com.c
|
||||||
|
ph_com_bridge.c
|
||||||
ph_com_spi.c
|
ph_com_spi.c
|
||||||
ph_com_uart.c
|
ph_com_uart.c
|
||||||
ph_debug.c
|
ph_debug.c
|
||||||
|
|||||||
@ -114,8 +114,8 @@ int main(void) {
|
|||||||
//ph_debug_act_init();
|
//ph_debug_act_init();
|
||||||
//ph_debug_uart_init();
|
//ph_debug_uart_init();
|
||||||
ph_outputs_init();
|
ph_outputs_init();
|
||||||
ph_usb_init();
|
|
||||||
ph_ps2_init();
|
ph_ps2_init();
|
||||||
|
ph_usb_init(); // Тут может быть инициализация USB-CDC для бриджа
|
||||||
ph_com_init(_data_handler, _timeout_handler);
|
ph_com_init(_data_handler, _timeout_handler);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|||||||
@ -26,6 +26,8 @@
|
|||||||
#include "hardware/gpio.h"
|
#include "hardware/gpio.h"
|
||||||
|
|
||||||
#include "ph_types.h"
|
#include "ph_types.h"
|
||||||
|
#include "ph_outputs.h"
|
||||||
|
#include "ph_com_bridge.h"
|
||||||
#include "ph_com_spi.h"
|
#include "ph_com_spi.h"
|
||||||
#include "ph_com_uart.h"
|
#include "ph_com_uart.h"
|
||||||
|
|
||||||
@ -36,32 +38,30 @@
|
|||||||
static bool _use_spi = true;
|
static bool _use_spi = true;
|
||||||
|
|
||||||
|
|
||||||
|
#define _COM(x_func, ...) { \
|
||||||
|
if (ph_g_is_bridge) { \
|
||||||
|
ph_com_bridge_##x_func(__VA_ARGS__); \
|
||||||
|
} else if (_use_spi) { \
|
||||||
|
ph_com_spi_##x_func(__VA_ARGS__); \
|
||||||
|
} else { \
|
||||||
|
ph_com_uart_##x_func(__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ph_com_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)) {
|
void ph_com_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)) {
|
||||||
gpio_init(_USE_SPI_PIN);
|
gpio_init(_USE_SPI_PIN);
|
||||||
gpio_set_dir(_USE_SPI_PIN, GPIO_IN);
|
gpio_set_dir(_USE_SPI_PIN, GPIO_IN);
|
||||||
gpio_pull_up(_USE_SPI_PIN);
|
gpio_pull_up(_USE_SPI_PIN);
|
||||||
sleep_ms(10); // Нужен небольшой слип для активации pull-up
|
sleep_ms(10); // Нужен небольшой слип для активации pull-up
|
||||||
_use_spi = gpio_get(_USE_SPI_PIN);
|
_use_spi = gpio_get(_USE_SPI_PIN);
|
||||||
|
_COM(init, data_cb, timeout_cb);
|
||||||
if (_use_spi) {
|
|
||||||
ph_com_spi_init(data_cb, timeout_cb);
|
|
||||||
} else {
|
|
||||||
ph_com_uart_init(data_cb, timeout_cb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ph_com_task(void) {
|
void ph_com_task(void) {
|
||||||
if (_use_spi) {
|
_COM(task);
|
||||||
ph_com_spi_task();
|
|
||||||
} else {
|
|
||||||
ph_com_uart_task();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ph_com_write(const u8 *data) {
|
void ph_com_write(const u8 *data) {
|
||||||
if (_use_spi) {
|
_COM(write, data);
|
||||||
ph_com_spi_write(data);
|
|
||||||
} else {
|
|
||||||
ph_com_uart_write(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
84
hid/pico/src/ph_com_bridge.c
Normal file
84
hid/pico/src/ph_com_bridge.c
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
# #
|
||||||
|
# KVMD - The main PiKVM daemon. #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2018-2023 Maxim Devaev <mdevaev@gmail.com> #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
|
# #
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ph_com_bridge.h"
|
||||||
|
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#include "ph_types.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define _TIMEOUT_US 100000
|
||||||
|
|
||||||
|
|
||||||
|
static u8 _buf[8] = {0};
|
||||||
|
static u8 _index = 0;
|
||||||
|
static u64 _last_ts = 0;
|
||||||
|
|
||||||
|
static void (*_data_cb)(const u8 *) = NULL;
|
||||||
|
static void (*_timeout_cb)(void) = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
void ph_com_bridge_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)) {
|
||||||
|
_data_cb = data_cb;
|
||||||
|
_timeout_cb = timeout_cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ph_com_bridge_task(void) {
|
||||||
|
if (!tud_cdc_connected()) {
|
||||||
|
tud_cdc_write_clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tud_cdc_available() > 0) {
|
||||||
|
const s32 ch = tud_cdc_read_char();
|
||||||
|
if (ch < 0) {
|
||||||
|
goto no_data;
|
||||||
|
}
|
||||||
|
_buf[_index] = (u8)ch;
|
||||||
|
if (_index == 7) {
|
||||||
|
_data_cb(_buf);
|
||||||
|
_index = 0;
|
||||||
|
} else {
|
||||||
|
_last_ts = time_us_64();
|
||||||
|
++_index;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
no_data:
|
||||||
|
if (_index > 0) {
|
||||||
|
if (_last_ts + _TIMEOUT_US < time_us_64()) {
|
||||||
|
_timeout_cb();
|
||||||
|
_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ph_com_bridge_write(const u8 *data) {
|
||||||
|
if (tud_cdc_connected()) {
|
||||||
|
tud_cdc_write(data, 8);
|
||||||
|
tud_cdc_write_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
30
hid/pico/src/ph_com_bridge.h
Normal file
30
hid/pico/src/ph_com_bridge.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
# #
|
||||||
|
# KVMD - The main PiKVM daemon. #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2018-2023 Maxim Devaev <mdevaev@gmail.com> #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
|
# #
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ph_types.h"
|
||||||
|
|
||||||
|
|
||||||
|
void ph_com_bridge_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void));
|
||||||
|
void ph_com_bridge_task(void);
|
||||||
|
void ph_com_bridge_write(const u8 *data);
|
||||||
@ -35,6 +35,8 @@
|
|||||||
#define _PS2_SET_KBD_PIN 3
|
#define _PS2_SET_KBD_PIN 3
|
||||||
#define _PS2_SET_MOUSE_PIN 4
|
#define _PS2_SET_MOUSE_PIN 4
|
||||||
|
|
||||||
|
#define _BRIDGE_MODE_PIN 5
|
||||||
|
|
||||||
#define _USB_DISABLED_PIN 6
|
#define _USB_DISABLED_PIN 6
|
||||||
#define _USB_ENABLE_W98_PIN 7
|
#define _USB_ENABLE_W98_PIN 7
|
||||||
#define _USB_SET_MOUSE_REL_PIN 8
|
#define _USB_SET_MOUSE_REL_PIN 8
|
||||||
@ -43,6 +45,7 @@
|
|||||||
|
|
||||||
u8 ph_g_outputs_active = 0;
|
u8 ph_g_outputs_active = 0;
|
||||||
u8 ph_g_outputs_avail = 0;
|
u8 ph_g_outputs_avail = 0;
|
||||||
|
bool ph_g_is_bridge = false;
|
||||||
|
|
||||||
|
|
||||||
static int _read_outputs(void);
|
static int _read_outputs(void);
|
||||||
@ -54,6 +57,8 @@ void ph_outputs_init(void) {
|
|||||||
INIT_SWITCH(_PS2_SET_KBD_PIN);
|
INIT_SWITCH(_PS2_SET_KBD_PIN);
|
||||||
INIT_SWITCH(_PS2_SET_MOUSE_PIN);
|
INIT_SWITCH(_PS2_SET_MOUSE_PIN);
|
||||||
|
|
||||||
|
INIT_SWITCH(_BRIDGE_MODE_PIN);
|
||||||
|
|
||||||
INIT_SWITCH(_USB_DISABLED_PIN);
|
INIT_SWITCH(_USB_DISABLED_PIN);
|
||||||
INIT_SWITCH(_USB_ENABLE_W98_PIN);
|
INIT_SWITCH(_USB_ENABLE_W98_PIN);
|
||||||
INIT_SWITCH(_USB_SET_MOUSE_REL_PIN);
|
INIT_SWITCH(_USB_SET_MOUSE_REL_PIN);
|
||||||
@ -65,7 +70,9 @@ void ph_outputs_init(void) {
|
|||||||
const bool o_ps2_kbd = !gpio_get(_PS2_SET_KBD_PIN);
|
const bool o_ps2_kbd = !gpio_get(_PS2_SET_KBD_PIN);
|
||||||
const bool o_ps2_mouse = !gpio_get(_PS2_SET_MOUSE_PIN);
|
const bool o_ps2_mouse = !gpio_get(_PS2_SET_MOUSE_PIN);
|
||||||
|
|
||||||
const bool o_usb_disabled = !gpio_get(_USB_DISABLED_PIN);
|
ph_g_is_bridge = !gpio_get(_BRIDGE_MODE_PIN);
|
||||||
|
|
||||||
|
const bool o_usb_disabled = (ph_g_is_bridge || !gpio_get(_USB_DISABLED_PIN));
|
||||||
const bool o_usb_enabled_w98 = !gpio_get(_USB_ENABLE_W98_PIN);
|
const bool o_usb_enabled_w98 = !gpio_get(_USB_ENABLE_W98_PIN);
|
||||||
const bool o_usb_mouse_rel = !gpio_get(_USB_SET_MOUSE_REL_PIN);
|
const bool o_usb_mouse_rel = !gpio_get(_USB_SET_MOUSE_REL_PIN);
|
||||||
const bool o_usb_mouse_w98 = !gpio_get(_USB_SET_MOUSE_W98_PIN);
|
const bool o_usb_mouse_w98 = !gpio_get(_USB_SET_MOUSE_W98_PIN);
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#define PH_O_IS_MOUSE_PS2 PH_O_MOUSE(PS2)
|
#define PH_O_IS_MOUSE_PS2 PH_O_MOUSE(PS2)
|
||||||
|
|
||||||
|
|
||||||
|
extern bool ph_g_is_bridge;
|
||||||
extern u8 ph_g_outputs_active;
|
extern u8 ph_g_outputs_active;
|
||||||
extern u8 ph_g_outputs_avail;
|
extern u8 ph_g_outputs_avail;
|
||||||
|
|
||||||
|
|||||||
@ -62,13 +62,13 @@ static void _mouse_rel_send_report(s8 x, s8 y, s8 h, s8 v);
|
|||||||
|
|
||||||
|
|
||||||
void ph_usb_init(void) {
|
void ph_usb_init(void) {
|
||||||
if (PH_O_IS_KBD_USB || PH_O_IS_MOUSE_USB) {
|
if (ph_g_is_bridge || PH_O_IS_KBD_USB || PH_O_IS_MOUSE_USB) {
|
||||||
tud_init(0);
|
tud_init(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ph_usb_task(void) {
|
void ph_usb_task(void) {
|
||||||
if (PH_O_IS_KBD_USB || PH_O_IS_MOUSE_USB) {
|
if (ph_g_is_bridge || PH_O_IS_KBD_USB || PH_O_IS_MOUSE_USB) {
|
||||||
tud_task();
|
tud_task();
|
||||||
|
|
||||||
static u64 next_ts = 0;
|
static u64 next_ts = 0;
|
||||||
@ -298,10 +298,31 @@ const u8 *tud_hid_descriptor_report_cb(u8 iface) {
|
|||||||
return PH_USB_KBD_DESC; // _kbd_iface, PH_O_IS_KBD_USB
|
return PH_USB_KBD_DESC; // _kbd_iface, PH_O_IS_KBD_USB
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8 *tud_descriptor_configuration_cb(u8 index) {
|
const u8 *_bridge_tud_descriptor_configuration_cb(void) {
|
||||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
enum {num_cdc = 0, num_cdc_data, num_total};
|
||||||
(void)index;
|
static const u8 desc[] = {
|
||||||
|
TUD_CONFIG_DESCRIPTOR(
|
||||||
|
1, // Config number
|
||||||
|
num_total,// Interface count
|
||||||
|
0, // String index
|
||||||
|
(TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN), // Total length
|
||||||
|
0, // Attribute
|
||||||
|
100 // Power in mA
|
||||||
|
),
|
||||||
|
TUD_CDC_DESCRIPTOR(
|
||||||
|
num_cdc,// Interface number
|
||||||
|
4, // String index
|
||||||
|
0x81, // EPNUM_CDC_NOTIF - EP notification address
|
||||||
|
8, // EP notification size
|
||||||
|
0x02, // EPNUM_CDC_OUT - EP OUT data address
|
||||||
|
0x82, // EPNUM_CDC_IN - EP IN data address
|
||||||
|
64 // EP size
|
||||||
|
),
|
||||||
|
};
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 *_hid_tud_descriptor_configuration_cb(void) {
|
||||||
static u8 desc[TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN * 2] = {0};
|
static u8 desc[TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN * 2] = {0};
|
||||||
static bool filled = false;
|
static bool filled = false;
|
||||||
|
|
||||||
@ -338,10 +359,18 @@ const u8 *tud_descriptor_configuration_cb(u8 index) {
|
|||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u8 *tud_descriptor_configuration_cb(u8 index) {
|
||||||
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
|
(void)index;
|
||||||
|
if (ph_g_is_bridge) {
|
||||||
|
return _bridge_tud_descriptor_configuration_cb();
|
||||||
|
}
|
||||||
|
return _hid_tud_descriptor_configuration_cb();
|
||||||
|
}
|
||||||
|
|
||||||
const u8 *tud_descriptor_device_cb(void) {
|
const u8 *tud_descriptor_device_cb(void) {
|
||||||
// Invoked when received GET DEVICE DESCRIPTOR
|
// Invoked when received GET DEVICE DESCRIPTOR
|
||||||
|
static tusb_desc_device_t desc = {
|
||||||
static const tusb_desc_device_t desc = {
|
|
||||||
.bLength = sizeof(tusb_desc_device_t),
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
.bcdUSB = 0x0200,
|
.bcdUSB = 0x0200,
|
||||||
@ -362,6 +391,12 @@ const u8 *tud_descriptor_device_cb(void) {
|
|||||||
|
|
||||||
.bNumConfigurations = 1,
|
.bNumConfigurations = 1,
|
||||||
};
|
};
|
||||||
|
if (ph_g_is_bridge) {
|
||||||
|
desc.bDeviceClass = TUSB_CLASS_MISC;
|
||||||
|
desc.bDeviceSubClass = MISC_SUBCLASS_COMMON;
|
||||||
|
desc.bDeviceProtocol = MISC_PROTOCOL_IAD;
|
||||||
|
desc.idProduct = 0xEDA3;
|
||||||
|
}
|
||||||
return (const u8 *)&desc;
|
return (const u8 *)&desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,8 +414,15 @@ const u16 *tud_descriptor_string_cb(u8 index, u16 lang_id) {
|
|||||||
char str[32];
|
char str[32];
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 1: strcpy(str, "PiKVM"); break; // Manufacturer
|
case 1: strcpy(str, "PiKVM"); break; // Manufacturer
|
||||||
case 2: strcpy(str, "PiKVM HID"); break; // Product
|
case 2: strcpy(str, (ph_g_is_bridge ? "PiKVM HID Bridge" : "PiKVM HID")); break; // Product
|
||||||
case 3: pico_get_unique_board_id_string(str, 32); break; // Serial
|
case 3: pico_get_unique_board_id_string(str, 32); break; // Serial
|
||||||
|
case 4: {
|
||||||
|
if (ph_g_is_bridge) {
|
||||||
|
strcpy(str, "PiKVM HID Bridge CDC");
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
desc_str_len = strlen(str);
|
desc_str_len = strlen(str);
|
||||||
|
|||||||
@ -59,9 +59,21 @@
|
|||||||
# define CFG_TUD_ENDPOINT0_SIZE 64
|
# define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// HID: Keyboard + Mouse
|
||||||
#define CFG_TUD_HID 2
|
#define CFG_TUD_HID 2
|
||||||
|
|
||||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||||
#ifndef CFG_TUD_HID_EP_BUFSIZE
|
#ifndef CFG_TUD_HID_EP_BUFSIZE
|
||||||
# define CFG_TUD_HID_EP_BUFSIZE 16
|
# define CFG_TUD_HID_EP_BUFSIZE 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// CDC for the bridge mode
|
||||||
|
#define CFG_TUD_CDC 1
|
||||||
|
|
||||||
|
// CDC FIFO size of TX and RX
|
||||||
|
#define CFG_TUD_CDC_RX_BUFSIZE 4096
|
||||||
|
#define CFG_TUD_CDC_TX_BUFSIZE 4096
|
||||||
|
|
||||||
|
// CDC Endpoint transfer buffer size, more is faster
|
||||||
|
#define CFG_TUD_CDC_EP_BUFSIZE 64
|
||||||
|
|||||||
@ -71,6 +71,10 @@ from .proto import check_response
|
|||||||
|
|
||||||
|
|
||||||
# =====
|
# =====
|
||||||
|
class _SelfResetError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class _RequestError(Exception):
|
class _RequestError(Exception):
|
||||||
def __init__(self, msg: str) -> None:
|
def __init__(self, msg: str) -> None:
|
||||||
super().__init__(msg)
|
super().__init__(msg)
|
||||||
@ -302,18 +306,18 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many-
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def __hid_loop(self) -> None:
|
def __hid_loop(self) -> None:
|
||||||
|
reset = True
|
||||||
while not self.__stop_event.is_set():
|
while not self.__stop_event.is_set():
|
||||||
try:
|
try:
|
||||||
if not self.__hid_loop_wait_device():
|
if not self.__hid_loop_wait_device(reset):
|
||||||
continue
|
continue
|
||||||
|
reset = True
|
||||||
with self.__phy.connected() as conn:
|
with self.__phy.connected() as conn:
|
||||||
while not (self.__stop_event.is_set() and self.__events_queue.qsize() == 0):
|
while not (self.__stop_event.is_set() and self.__events_queue.qsize() == 0):
|
||||||
if self.__reset_required_event.is_set():
|
if self.__reset_required_event.is_set():
|
||||||
try:
|
self.__set_state_busy(True)
|
||||||
self.__set_state_busy(True)
|
self.__reset_required_event.clear()
|
||||||
self.__gpio.reset()
|
break # Проваливаемся и резетим в __hid_loop_wait_device()
|
||||||
finally:
|
|
||||||
self.__reset_required_event.clear()
|
|
||||||
try:
|
try:
|
||||||
event = self.__events_queue.get(timeout=0.1)
|
event = self.__events_queue.get(timeout=0.1)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
@ -323,17 +327,21 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many-
|
|||||||
self.__set_state_busy(True)
|
self.__set_state_busy(True)
|
||||||
if not self.__process_request(conn, event.make_request()):
|
if not self.__process_request(conn, event.make_request()):
|
||||||
self.clear_events()
|
self.clear_events()
|
||||||
|
except _SelfResetError:
|
||||||
|
time.sleep(1) # Pico перезагружается сам вскоре после ответа
|
||||||
|
reset = False
|
||||||
except Exception:
|
except Exception:
|
||||||
self.clear_events()
|
self.clear_events()
|
||||||
get_logger(0).exception("Unexpected error in the HID loop")
|
get_logger(0).exception("Unexpected error in the HID loop")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def __hid_loop_wait_device(self) -> bool:
|
def __hid_loop_wait_device(self, reset: bool) -> bool:
|
||||||
logger = get_logger(0)
|
logger = get_logger(0)
|
||||||
logger.info("Initial HID reset and wait for %s ...", self.__phy)
|
if reset:
|
||||||
self.__gpio.reset()
|
logger.info("Initial HID reset and wait for %s ...", self.__phy)
|
||||||
# На самом деле SPI и Serial-девайсы не пропадают, просто резет и ожидание
|
self.__gpio.reset()
|
||||||
# логичнее всего делать именно здесь. Ну и на будущее, да
|
# На самом деле SPI и Serial-девайсы не пропадают,
|
||||||
|
# а вот USB CDC (Pico HID Bridge) вполне себе пропадает
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
if self.__phy.has_device():
|
if self.__phy.has_device():
|
||||||
logger.info("Physical HID interface found: %s", self.__phy)
|
logger.info("Physical HID interface found: %s", self.__phy)
|
||||||
@ -342,6 +350,7 @@ class BaseMcuHid(BaseHid, multiprocessing.Process): # pylint: disable=too-many-
|
|||||||
break
|
break
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
logger.error("Missing physical HID interface: %s", self.__phy)
|
logger.error("Missing physical HID interface: %s", self.__phy)
|
||||||
|
self.__set_state_online(False)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __process_request(self, conn: BasePhyConnection, request: bytes) -> bool: # pylint: disable=too-many-branches
|
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)
|
self.__state_flags.update(online=1, busy=reset_required, status=status)
|
||||||
if reset_required:
|
if reset_required:
|
||||||
if self.__reset_self:
|
if self.__reset_self:
|
||||||
time.sleep(1) # Pico перезагружается сам вскоре после ответа
|
raise _SelfResetError()
|
||||||
else:
|
self.__reset_required_event.set()
|
||||||
self.__reset_required_event.set()
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user