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
samples: hid-mouse: rework sample to use input subsys #61104
samples: hid-mouse: rework sample to use input subsys #61104
Conversation
Btw, we need fewer HID samples. diff --git a/samples/sensor/fxos8700-hid/src/main.c b/samples/sensor/fxos8700-hid/src/main.c
index 14845ac3b33..fbf580560b4 100644
--- a/samples/sensor/fxos8700-hid/src/main.c
+++ b/samples/sensor/fxos8700-hid/src/main.c
@@ -170,7 +170,8 @@ int main(void)
{
int ret;
uint8_t report[4] = { 0x00 };
- const struct device *accel_dev, *hid_dev;
+ const struct device *hid_dev;
+ const struct device *const accel_dev = DEVICE_DT_GET(DT_ALIAS(accel0));
if (!device_is_ready(led_gpio.port)) {
LOG_ERR("%s: device not ready.", led_gpio.port->name);
@@ -197,7 +198,6 @@ int main(void)
}
#endif
- accel_dev = DEVICE_DT_GET_ONE(nxp_fxos8700);
if (!device_is_ready(accel_dev)) {
LOG_ERR("%s: device not ready.", accel_dev->name);
return 0; But it might be better to add a new relative X/Y input driver (FYI @fabiobaltieri) based on the accelerometer code in fxos8700-hid and use that new input driver in this example, and finally remove fxos8700-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.
Hey cool, I think it makes sense to use this for samples other than the buttons
one rather than copying the gpio callback stuff all over, plus you get debouncing.
Actually one step further, how about using the LED APIs for the LEDs?
About the overlay, I was thinking about proposing to get rid of the two templates and have the input driver using the plain gpio-keys
one directly. The driver would only use it if CONFIG_INPUT
is enabled anyway, which is the same as gpio-leds
, then in cases like these you could just grab the keycodes from the child nodes and use them for the sample. What do you think?
The only thing that spoiled my fun were the two extra inflexible overlays. With your suggestion, we would have to add a |
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.
Confirmed to work fine on nRF52840DK.
I used west build -d build-usb-hid-mouse -b nrf52840dk_nrf52840 samples/subsys/usb/hid-mouse/ -DDTC_OVERLAY_FILE=four_buttons.overlay
to build. The only gotcha was that I initially had SW7 switch in Alt position (instead of Def) which disconnects BUTTON 1 and 2 (as marked on DK). Switching SW7 switch to Def makes all four button work as intended.
Yes #61115 |
Sorted. Now the problem is that you can't rely on a specific code for boards. For the purpose of the sample, if you just want to grab "the first button" I was thinking, how about enumerating the specific board codes with something like: #define GPIO_KEYS_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(gpio_keys)
#define DT_GPIO_KEYS_CODE(node_id) DT_PROP(node_id, zephyr_code)
static const int codes[] = {DT_FOREACH_CHILD_SEP(GPIO_KEYS_NODE, DT_GPIO_KEYS_CODE, (,))};
#define BUTTON_COUNT ARRAY_SIZE(codes) Separately from this, I was thinking it'd be cool if the HID stuff was a general library with macros and stuff to help defining HID descriptors and flipping bits in HID reports, and then it'd be cool to have a single HID sample that implements, for example, a mouse-keyboard-gamepad combination on both USB and Bluetooth. |
5933c59
to
001913b
Compare
I have updated sample key mapping in the README. We could also just map the first 1...4 keys to L,R,X,Y, not sure it is worth it.
We already have include/zephyr/usb/class/hid.h. Not sure "flipping bits" could be generic, perhaps for mouse/keyboards.
I am currently working on reducing the number of hidden samples and lines of code there :-) (Working on HID implementation for the new device support). What you are suggesting is more of an application example. |
if (report[idx] != value) { | ||
report[idx] = value; |
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 about memcpy'ing a local copy of the report at the function start and memcmp compare it at the end? Would save the idx
and value
variables, you could just WRITE_BIT
or set the right report
byte, would make the various case
more compact.
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.
It increased flash consumption by 64 bytes (nRF52840).
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.
Just 996472 to go before running out flash! 😱
Yeah I was thinking about a function to map events to report bits and one to handle the 6 bytes keyboard report. I have some code already, will try to fit it to a sample and send it out in the future. |
001913b
to
aa69e03
Compare
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.
Cool! I would also rip off the custom LED part and use LED_GPIO
instead, would drop few more lines and it would be right way of doing it for a proper Zephyr application.
LOG_ERR("Failed to get the state of port %s pin %u, error: %d", | ||
gpio->name, sw3.pin, ret); | ||
break; | ||
default: | ||
return; |
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.
Should there be a LOG_INF for "unrecognized code" here? May help out if someone is trying this on a custom board with different codes.
I looked at it, nobody uses it just to toggle the LED, more overhead compared to gpio. |
aa69e03
to
4faef6d
Compare
|
||
return 0; | ||
} | ||
INPUT_LISTENER_CB_DEFINE(NULL, input_cb); |
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 needs to be updated (sorry...) ;-)
What you describe is pretty much impossible because the keycodes are reported as values (unless I am missing something or misunderstanding what you wrote). Only the modifiers are reported as bits, e.g. CTRL or ALT. In the report you can have multiple keycodes, which determines how many keys can be simultaneously pressed (6 slots in the Boot Keyboard interface). Note that the actual values reported in scan code do not necessarily have to be equal to the scancodes because the logical min/max and usage min/max can be different (these are fixed in the Boot Keyboard interface, but can be arbitrarily chosen in "proper" keyboard). |
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.
(blocking on the input macro definition change)
Overall, this makes the sample code much simpler and smaller. Whit the changes introduced in commit commit 57e0da4 ("boards: add zephyr,code properties to the various gpio-keys nodes")' this example will work out of the box with any board that has at least zephyr,code = <INPUT_KEY_0>; in its devicetree. Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
4faef6d
to
22648fc
Compare
Overall, this makes the sample much simpler and smaller.
The problem is different naming for compatible
gpio-keys
parent nodes and that we have to describe the same number of child nodes.