1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

usbus: Implement endpoint halt condition.

Instead of directly stalling an endpoint, handlers should enable the
halt condition on an usbus endpoint to signal error condition.
This can then be cleared via a CLEAR FEATURE request from the host.
This commit is contained in:
Koen Zandberg 2021-10-31 21:16:52 +01:00
parent bbc5fc912e
commit 13b4f8de2c
No known key found for this signature in database
GPG Key ID: BA1718B37D79F51C
2 changed files with 46 additions and 0 deletions

View File

@ -327,6 +327,7 @@ typedef struct usbus_endpoint {
uint8_t interval; /**< Poll interval for interrupt endpoints */
bool active; /**< If the endpoint should be activated after
reset */
bool halted; /**< Endpoint is halted */
} usbus_endpoint_t;
/**
@ -676,6 +677,22 @@ void usbus_urb_submit(usbus_t *usbus, usbus_endpoint_t *endpoint, usbus_urb_t *u
*/
int usbus_urb_cancel(usbus_t *usbus, usbus_endpoint_t *endpoint, usbus_urb_t *urb);
/**
* @brief Set the halt condition on an endpoint.
*
* The endpoint will respond with stall to all packets and must explicitly be
* cleared by the host by clearing the halt condition or switching interfaces
*/
void usbus_endpoint_halt(usbus_endpoint_t *ep);
/**
* @brief Clear the halt condition on an endpoint
*
* @note Must only be used when the endpoint is halted and when the host issues
* a SetInterface request on the interface containing the endpoint
*/
void usbus_endpoint_clear_halt(usbus_endpoint_t *ep);
/**
* @brief Enable an endpoint
*

View File

@ -470,6 +470,34 @@ static void *_usbus_thread(void *args)
return NULL;
}
void usbus_endpoint_halt(usbus_endpoint_t *ep)
{
assert(ep->ep->num != 0); /* Not valid for endpoint 0 */
DEBUG("Endpoint %u halted\n", ep->ep->num);
ep->halted = 1;
usbdev_ep_stall(ep->ep, true);
}
void usbus_endpoint_clear_halt(usbus_endpoint_t *ep)
{
assert(ep->ep->num != 0); /* Not valid for endpoint 0 */
DEBUG("Endpoint %u unhalted\n", ep->ep->num);
ep->halted = 0;
usbdev_ep_stall(ep->ep, false);
}
/**
* @brief Reset the halted status on USB reset condition
*/
static void _usbus_endpoint_reset_halt(usbus_t *usbus)
{
/* Clear halted state. No need to notify usbdev, USB reset already resets those */
for (size_t i = 0; i < USBDEV_NUM_ENDPOINTS; i++) {
usbus->ep_out[i].halted = 0;
usbus->ep_in[i].halted = 0;
}
}
/* USB event callback */
static void _event_cb(usbdev_t *usbdev, usbdev_event_t event)
{
@ -487,6 +515,7 @@ static void _event_cb(usbdev_t *usbdev, usbdev_event_t event)
usbus->addr = 0;
usbdev_set(usbus->dev, USBOPT_ADDRESS, &usbus->addr,
sizeof(uint8_t));
_usbus_endpoint_reset_halt(usbus);
flag = USBUS_HANDLER_FLAG_RESET;
msg = USBUS_EVENT_USB_RESET;
DEBUG("usbus: USB reset detected\n");