-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Feature/usb report leds #899
Conversation
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 callback that gets called when there is new data to read? Possibly struct hid_ops::get_report
? If so, it would be nice if we could create a ZMK event from that, as that would be more reliable than reading after every key press. (For example, what if you have a keyboard and a separate numpad, and the OS shares num lock state between keyboards? It would be nice if the keyboard could immediately get the new num lock state without waiting for you to press something on it.)
app/src/usb.c
Outdated
#ifdef CONFIG_ZMK_USB_REPORT_LEDS | ||
|
||
int zmk_usb_hid_receive_report(uint8_t *report, size_t len) { | ||
k_sem_take(&hid_sem, K_MSEC(30)); |
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 looks copied from zmk_usb_hid_send_report()
, but I'm not sure that code makes sense.
If hid_int_ep_read()
requires the semaphore to be taken, then I would expect us to check the return value of k_sem_take()
to make sure we actually took the semaphore. As is, it looks like this code will try to take the semaphore for 30 ms, then continue regardless of whether it succeeded. Then if hid_int_ep_read()
fails, it could give a semaphore it never took.
@petejohanson could you explain how the semaphore code in zmk_usb_hid_send_report()
is supposed to work?
@@ -424,6 +424,10 @@ choice CBPRINTF_IMPLEMENTATION | |||
|
|||
endchoice | |||
|
|||
config ZMK_USB_REPORT_LEDS |
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.
Maybe it would make more sense to just always support reading the report? Unless there's some reason that the HID report descriptor might need to be kept short, I think making this conditional would just make things more confusing. Any features that depend on this would also need to be conditional, and then anyone who wants to use it in their code has to know to turn it on.
app/src/usb.c
Outdated
|
||
int zmk_usb_hid_receive_report(uint8_t *report, size_t len) { | ||
k_sem_take(&hid_sem, K_MSEC(30)); | ||
int err = hid_int_ep_read(hid_dev, report, len, NULL); |
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 the ret_bytes
parameter to hid_int_ep_read()
not necessary? I would expect calling code to need to be able to check how many bytes were actually read, since it might be smaller than len
.
app/include/zmk/hid.h
Outdated
HID_GI_REPORT_COUNT, | ||
0x05, | ||
/* REPORT_SIZE (1) */ | ||
HID_GI_REPORT_SIZE, |
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.
You should install clang-format (https://releases.llvm.org/download.html) and run your code through it. Otherwise the automated checks will complain that this isn't formatted correctly.
If you're using VS Code and clang-format is installed, Microsoft's C/C++ extension can format files with Shift+Alt+F or automatically on save by setting the editor.formatOnSave
setting.
app/src/usb.c
Outdated
@@ -38,6 +38,22 @@ static const struct hid_ops ops = { | |||
.int_in_ready = in_ready_cb, | |||
}; | |||
|
|||
#ifdef CONFIG_ZMK_USB_REPORT_LEDS | |||
|
|||
int zmk_usb_hid_receive_report(uint8_t *report, size_t len) { |
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.
Question for someone more familiar with USB/HID than I am: is it okay to attempt to read regardless of the USB status, or do we need a switch
like the one in zmk_usb_hid_send_report()
?
@@ -26,4 +26,7 @@ static inline bool zmk_usb_is_hid_ready() { return zmk_usb_get_conn_state() == Z | |||
|
|||
#ifdef CONFIG_ZMK_USB | |||
int zmk_usb_hid_send_report(const uint8_t *report, size_t len); | |||
#ifdef CONFIG_ZMK_USB_REPORT_LEDS | |||
int zmk_usb_hid_receive_report(uint8_t *report, size_t len); |
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.
Minor: it would be nice if the declarations in the .h file were in the same order as the definitions in the .c file.
@ci-bus Thoughts on the feedback from Nick and Joel? |
Yes, I have to make improvements, I need free time for this |
I made an improved version of this PR which is more user-friendly and works with both USB and BLE: #999 |
thanks, I will take a look at this |
Feature: Read report leds from usb
Example to test it
CONFIG_ZMK_USB_REPORT_LEDS=y
this example code will turn on the LEDs when caps is locked