-
Notifications
You must be signed in to change notification settings - Fork 1.3k
applications: nrf_desktop: Integrate USB next stack #15557
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
Conversation
Test specificationCI/Jenkins/NRF
CI/Jenkins/integration
Detailed information of selected test modules Note: This message is automatically posted and updated by the CI |
You can find the documentation preview for this PR at this link. It will be updated about 10 minutes after the documentation build succeeds. Note: This comment is automatically posted by the Documentation Publishing GitHub Action. |
f23c724
to
8062475
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.
Why do we add support for all of our nRF Desktop USB targets? Didn't we agree to add support for one legacy platform in one configuration variant(e.g. gaming mouse / nrf52840dk) to reduce the scope of this change right before the release?
We need to add supported platforms to sample.yaml file so they run in CI
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.
I think we can add DTS configuration to all of the platforms (change is quite simple and allows testing locally on any supported board by just setting a single Kconfig option during build). Keep in mind that legacy USB stack ignores the USB HID instances configured in DTS anyway, so this part should not have negative impact on default configurations.
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.
I agree that we should add configurations to CI. What do you think about the following set?
- nrf52840dk (prj.conf + prj_keyboard.conf + prj_dongle.conf)
- nrf52840gmouse (prj.conf)
- nrf52840dongle (prj.conf)
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 configuration set looks good.
We can do many things at the cost of the execution speed. Bigger PRs tend to be merged more slowly (harder to review, more conflict-prone, more review discussion points). However, let's keep these configurations as you already added them.
The sole purpose for adding support for this feature in the nRF Desktop right before the NCS release is to unlock the USB support for the nRF54H20 and we should keep this in mind.
@@ -77,6 +93,8 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_DESKTOP_HID_STATE_ENABLE) || | |||
IS_ENABLED(CONFIG_DESKTOP_USB_SELECTIVE_REPORT_SUBSCRIPTION) || | |||
(ARRAY_SIZE(usb_hid_device) <= 1)); | |||
|
|||
static struct usbd_contex *usbd_ctx; |
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 typo in USBD API? it would be great to report this to @jfischer-no
static struct usbd_contex *usbd_ctx; | |
static struct usbd_context *usbd_ctx; |
or
static struct usbd_contex *usbd_ctx; | |
static struct usbd_ctx *usbd_ctx; |
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.
Hi @jfischer-no, @tmon-nordic
Could you explain the naming scheme here please? I guess there is a reason why it's called usbd_contex
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.
static struct usbd_ctx *usbd_ctx;
is wrong, there is no struct usbd_ctx
defined anywhere.
The struct is called struct usbd_contex
. If you want to rename it (I prefer struct usbd_context
), then the rename should first go upstream.
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 question is: Do you recall why it's currently called usbd_contex
in upstream? It seems a bit like a typo, but I guess there is a reason why it's named like that.
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 is just a typo and the only reason it stays is that it needs a rather big PR to change it everywhere. But if you send PR upstream, I believe it can go in rather quickly (and we could cherry-pick it to NCS as nrf fromtree).
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.
We are just letting you know about the potential improvement for the upstream USB API. This typo isn't in any way a blocker for this PR. We can align it once it is patched upstream
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.
{ | ||
int err; | ||
|
||
USBD_DEVICE_DEFINE(usbd, DEVICE_DT_GET(DT_NODELABEL(usbd)), |
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.
Can we simplify this part and simply define the USBD instance at the file-level scope instead of passing it in return 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.
I wanted to keep all of the functions and macros that are specific to USB next stack separated from implementation of generic functionalities. Whole USB next configuration is currently kept together too. That's why I would prefer to keep it as is.
The usbd_ctx
pointer is an exception here, because we need to access it if we want to trigger USB remote wakeup with USB next stack.
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.
I think the remote wakeup should rather be up to the stack, which is precisely what zephyrproject-rtos/zephyr#73362 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.
I wanted to keep all of the functions and macros that are specific to USB next stack separated from implementation of generic functionalities. Whole USB next configuration is currently kept together too. That's why I would prefer to keep it as is. The
usbd_ctx
pointer is an exception here, because we need to access it if we want to trigger USB remote wakeup with USB next stack.
I don't understand why defining the instance in the same line as you define currently pointer to it would invalidate your assumptions
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.
I think the remote wakeup should rather be up to the stack, which is precisely what zephyrproject-rtos/zephyr#73362 does.
That may be a nice improvement. I will look into it more in my subsequent PRs.
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.
I wanted to keep all of the functions and macros that are specific to USB next stack separated from implementation of generic functionalities. Whole USB next configuration is currently kept together too. That's why I would prefer to keep it as is. The
usbd_ctx
pointer is an exception here, because we need to access it if we want to trigger USB remote wakeup with USB next stack.I don't understand why defining the instance in the same line as you define currently pointer to it would invalidate your assumptions
It is "bundled" with assigning VID and PID. I prefer to assign all of the properties in one place if possible. Once improvement linked by @tmon-nordic goes in, we will hopefully be able to get rid of the global reference pointer.
USBD_DESC_SERIAL_NUMBER_DEFINE(serial_number); | ||
|
||
/* Maximum power consumption of a device: 250 * 2 mA = 500 mA. */ | ||
static const uint8_t max_power = 250; |
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.
shouldn't we make this setting configurable?
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.
We need to actually align it for both USB stacks. Added follow-up ticket: https://nordicsemi.atlassian.net/browse/NCSDK-27658
@@ -480,8 +487,8 @@ static void usb_wakeup(void) | |||
{ | |||
int err = 0; | |||
|
|||
if (IS_ENABLED(CONFIG_DESKTOP_USB_STACK_NEXT)) { | |||
LOG_WRN("usb_wakeup not integrated for USB next"); | |||
if (IS_ENABLED(CONFIG_DESKTOP_USB_STACK_NEXT) && usbd_ctx) { |
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.
If we get rid of this usbd_ctx pointer and define the instance at the file scope, we can use the instance status
field to check if it is 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.
See #15557 (comment)
@@ -1016,15 +1154,21 @@ static struct usbd_contex *usb_init_next_usbd_init(void) | |||
|
|||
static int usb_init_next(void) | |||
{ | |||
int err = usb_init_next_hids_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.
why _hids_
and not _hid_
suffix in the name of this function?
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.
We initialize multiple USB HID instances here. It's also consistent with naming used for legacy USB stack: usb_init_legacy_hids_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.
HIDS is the Bluetooth construct as far as I can tell HID service
USB uses HID classes HIDC would be more sutiable
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.
I used HIDs and plural form of HID (actually I didn't even think about HIDS GATT Service here). I can rename if needed
if ((state == USB_STATE_SUSPENDED) && is_usb_active_next()) { | ||
broadcast_usb_state(USB_STATE_ACTIVE); | ||
} else { | ||
broadcast_usb_state(new_state); | ||
} |
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 could move this change to the previous commit and declare a placeholder function is_usb_active_next
function that always returns 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.
Since USB_STATE_ACTIVE
support was introduced together with adding USB HID support, I think we could keep it as is. The changes go in together anyway.
uint8_t temp[report_size] __aligned(sizeof(void *)); | ||
|
||
memcpy(temp, report_buffer, report_size); | ||
err = hid_device_submit_report(usb_hid->dev, report_size, temp); |
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.
Can we require the report-sending modules to always align the report buffer in memory so it is aligned? Then, we could simply assert on unaligned 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.
The modules rely on allocator function from app Event Manager (this eventually leads to k_malloc
). The k_malloc
allocations are aligned by default so it should be fine. The only problem here is HID boot protocol handling. For the boot protocol, we omit the first byte which "breaks" the alignment. That's why we apply this simple workaround here.
Memory footprint analysis revealed the following potential issuesapplications.nrf_desktop.zdebug_4llpmconn[nrf52840dongle/nrf52840]: RAM size increased by 312[B] in comparison to the main[643c3f4] branch. - link (cc: @MarekPieta) Note: This message is automatically posted and updated by the CI (latest/sdk-nrf/PR-15557/6) |
Do not enable legacy USB stack by default. It is not required for the board and leads to problems with using USB next stack. Jira: NCSDK-27014 Signed-off-by: Marek Pieta <Marek.Pieta@nordicsemi.no>
Change integrates USB next stack to the application. Jira: NCSDK-27014 Signed-off-by: Marek Pieta <Marek.Pieta@nordicsemi.no>
Change adds USB HID next APIs to the application. Jira: NCSDK-27014 Signed-off-by: Marek Pieta <Marek.Pieta@nordicsemi.no>
…B next Change adds USB HID next configuration to DTS configurations. Jira: NCSDK-27014 Signed-off-by: Marek Pieta <Marek.Pieta@nordicsemi.no>
Change expands `sample.yaml` file to build some of the configurations with USB next stack. Jira: NCSDK-27014 Signed-off-by: Marek Pieta <Marek.Pieta@nordicsemi.no>
Change integrates USB next stack to the application. USB HID next class is supported too.
Jira: NCSDK-27014