-
Notifications
You must be signed in to change notification settings - Fork 488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: HID watchdog #1061
base: main
Are you sure you want to change the base?
Conversation
@RaulHuertas has agreed to test this with BLE. I know it's not very likely, but just in case, don't merge this before he does. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this relate to "fixing" NKRO? Is it that the auto-detect has to wait until there's a connection?
And what does the watchdog even accomplish? I get that it can do a delayed initialization of the HID buffers. But after that it just runs in the background and does nothing. It will never be the case that the number and type of endpoints will change during runtime.
kmk/hid.py
Outdated
report_bytes_default = 8 | ||
REPORT_BYTES = report_bytes_default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
report_bytes_default = 8 | |
REPORT_BYTES = report_bytes_default | |
REPORT_BYTES = 8 |
Probably an artifact? I don't see report_bytes_default
being used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
report_bytes_default
is used in setup_keyboard_hid
. It represents the number of bytes in the default descriptor, 8 for the base class, 9 for the USB HID. The REPORT_BYTES
is first set to report_bytes_default
, then as per NKRO autodetect, if hid_send()
fails, it's set to the value required by NKRO.
kmk/hid.py
Outdated
|
||
# from kmk.scheduler import create_task |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# from kmk.scheduler import create_task |
kmk/hid.py
Outdated
self._cc_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.CONSUMER] + 1) | ||
self._cc_report[0] = HIDReportTypes.CONSUMER | ||
self._cc_pending = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you didn't put that in a setup_consumer_control_hid()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only reason is that because there's only 1 CC descriptor, this doesn't need to be re-ran. After submitting this PR, I thought of putting this in a function for the sake of consistency, but since it were already submitted, I thought I'll wait for your opinion.
kmk/hid.py
Outdated
def show_debug(self): | ||
if debug.enabled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def show_debug(self): | |
if debug.enabled: | |
def show_debug(self): |
We can save a jump to subroutine if you do:
if debug.enabled:
self.show_debug()
kmk/hid.py
Outdated
def watchdog(self): | ||
if self.usb_status != supervisor.runtime.usb_connected: | ||
self.usb_status = supervisor.runtime.usb_connected | ||
self.find_devices() | ||
self.setup_keyboard_hid() | ||
self.setup_mouse_hid() | ||
self.show_debug() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def watchdog(self): | |
if self.usb_status != supervisor.runtime.usb_connected: | |
self.usb_status = supervisor.runtime.usb_connected | |
self.find_devices() | |
self.setup_keyboard_hid() | |
self.setup_mouse_hid() | |
self.show_debug() | |
def _connected(self): | |
return supervisor.runtime.usb_connected | |
# return self.ble.connected # for BLE | |
def watchdog(self): | |
if self.connected != self._connected(): | |
self.connected = self._connected() | |
self.find_devices() | |
self.setup_keyboard_hid() | |
self.setup_mouse_hid() | |
self.show_debug() |
Make a wrapper to check for connection, then use that wrapper in the watchdog and we can put the watchdog implementation into the base class.
This also triggers on disconnects / reconnects and reallocates buffers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense for the future, but as of right now that would be wasted on BLE since we don't support custom descriptors there.
debug('disable mouse') | ||
|
||
def find_devices(self): | ||
self.devices = {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This belongs in __init__()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First we blank out the dict, then we repopulate it. Blanking out might happen more than once.
This doesn't fix NKRO specifically, it fixes connecting and disconnecting USB, it's just that NKRO gave me trouble with its autodetect. It works as follows: The Watchdog makes it so that when connection is changed, we can detect that and rebuild Basically, watchdog serves the same function as |
Reconnecting while remaining bonded, rather. |
Autodetect has the potential to fail, we can mitigate that by doing the setup in a coroutine.
For reference: that is incorrect. I checked both in situ and in the CP code. The |
HID classes now can create periodic tasks that check for connection and after its status has changed, re-run parts of code as needed.