Skip to content
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

usbus: Implement USB_FEATURE_DEVICE_REMOTE_WAKEUP handling #19800

Merged
merged 1 commit into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sys/include/usb/usbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ struct usbus {
usbus_state_t state; /**< Current state */
usbus_state_t pstate; /**< state to recover to from suspend */
uint8_t addr; /**< Address of the USB peripheral */
bool wakeup_enabled; /**< Remote wakeup device feature status */
#ifndef CONFIG_USB_SERIAL_STR
/**
* @brief Hex representation of the device serial number
Expand Down
29 changes: 27 additions & 2 deletions sys/usb/usbus/usbus_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ static usbus_string_t *_get_descriptor(usbus_t *usbus, uint16_t idx)

static int _req_status(usbus_t *usbus)
{
/* Signal self powered */
uint16_t status = (CONFIG_USB_SELF_POWERED) ? 1 : 0;
/* Signal self powered and remote wakeup status */
uint16_t status = (CONFIG_USB_SELF_POWERED) ? 1 : 0 | usbus->wakeup_enabled << 1;
usbus_control_slicer_put_bytes(usbus, (uint8_t*)&status, sizeof(status));
return sizeof(status);
}
Expand Down Expand Up @@ -219,6 +219,24 @@ static int _req_descriptor(usbus_t *usbus, usb_setup_t *pkt)
}
}

static int _req_dev_feature(usbus_t *usbus, uint16_t feature, bool enable)
{
int res = -1;

switch (feature) {
case USB_FEATURE_DEVICE_REMOTE_WAKEUP:
if (CONFIG_USB_REM_WAKEUP) {
usbus->wakeup_enabled = enable;
res = 1;
}
break;
default:
DEBUG("usbus: unknown device feature request: %u\n", feature);
break;
}
return res;
}

static int _recv_dev_setup(usbus_t *usbus, usb_setup_t *pkt)
{
int res = -1;
Expand Down Expand Up @@ -254,6 +272,12 @@ static int _recv_dev_setup(usbus_t *usbus, usb_setup_t *pkt)
_activate_endpoints(usbus);
res = 1;
break;
case USB_SETUP_REQ_SET_FEATURE:
res = _req_dev_feature(usbus, pkt->value, true);
break;
case USB_SETUP_REQ_CLEAR_FEATURE:
res = _req_dev_feature(usbus, pkt->value, false);
break;
default:
DEBUG("usbus: Unknown write request %u\n", pkt->request);
break;
Expand Down Expand Up @@ -480,6 +504,7 @@ static void _handler_ep0_event(usbus_t *usbus, usbus_handler_t *handler,
switch (event) {
case USBUS_EVENT_USB_RESET:
DEBUG("usbus_control: Reset event triggered\n");
usbus->wakeup_enabled = false;
ep0_handler->control_request_state = USBUS_CONTROL_REQUEST_STATE_READY;
_usbus_config_ep0(ep0_handler);
break;
Expand Down