Skip to content

Commit

Permalink
usb: device_next: fix Get Status request response
Browse files Browse the repository at this point in the history
We need to track the self-powered status of the device independently of
the D6 bit in the bmAttributes value of the configuration descriptor
because the Get Status request about the self-powered status is valid in
address state and we support multiple configurations.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
  • Loading branch information
jfischer-no authored and kartben committed Feb 28, 2025
1 parent 467e15d commit 9cb0fbf
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 0 deletions.
13 changes: 13 additions & 0 deletions include/zephyr/usb/usbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ struct usbd_status {
unsigned int suspended : 1;
/** USB remote wake-up feature is enabled */
unsigned int rwup : 1;
/** USB device is self-powered */
unsigned int self_powered : 1;
/** USB device speed */
enum usbd_speed speed : 2;
};
Expand Down Expand Up @@ -1066,6 +1068,17 @@ bool usbd_is_suspended(struct usbd_context *uds_ctx);
*/
int usbd_wakeup_request(struct usbd_context *uds_ctx);

/**
* @brief Set the self-powered status of the USB device
*
* The status is used in the Self Powered field of the Get Status request
* response to indicate whether the device is currently self-powered.
*
* @param[in] uds_ctx Pointer to a device context
* @param[in] status Sets self-powered status if true, clears it otherwise
*/
void usbd_self_powered(struct usbd_context *uds_ctx, const bool status);

/**
* @brief Get actual device speed
*
Expand Down
1 change: 1 addition & 0 deletions samples/subsys/usb/common/sample_usbd_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ struct usbd_context *sample_usbd_setup_device(usbd_msg_cb_t msg_cb)
/* doc functions register end */

sample_fix_code_triple(&sample_usbd, USBD_SPEED_FS);
usbd_self_powered(&sample_usbd, attributes & USB_SCD_SELF_POWERED);

if (msg_cb != NULL) {
/* doc device init-and-msg start */
Expand Down
2 changes: 2 additions & 0 deletions subsys/usb/device_next/usbd_ch9.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ static int sreq_get_status(struct usbd_context *const uds_ctx,

response = uds_ctx->status.rwup ?
USB_GET_STATUS_REMOTE_WAKEUP : 0;
response |= uds_ctx->status.self_powered ?
USB_GET_STATUS_SELF_POWERED : 0;
break;
case USB_REQTYPE_RECIPIENT_ENDPOINT:
response = usbd_ep_is_halted(uds_ctx, ep) ? BIT(0) : 0;
Expand Down
7 changes: 7 additions & 0 deletions subsys/usb/device_next/usbd_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ int usbd_wakeup_request(struct usbd_context *const uds_ctx)
return ret;
}

void usbd_self_powered(struct usbd_context *uds_ctx, const bool status)
{
usbd_device_lock(uds_ctx);
uds_ctx->status.self_powered = status;
usbd_device_unlock(uds_ctx);
}

bool usbd_is_suspended(struct usbd_context *uds_ctx)
{
return uds_ctx->status.suspended;
Expand Down

0 comments on commit 9cb0fbf

Please sign in to comment.