1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-24 14:03:55 +01:00
19362: sys/usbus: handle exceeding number of endpoints r=dylad a=gschorcht

### Contribution description

This PR fixes issue #19359 for STM32 USB OTG cores partially:
1. It must not be silently ignored if the number of endpoints is not sufficient for an application. Instead of producing a non-working application, the application stops now with `kernel_panic` if the number of EPs is exhausted. This fixes the problem described in issue #19359 for USB cores with CID version 1.x, e.g. for STM32F439ZI FS interface (CID 1200) since they only have 4 IN and 4 OUT endpoints including the control endpoint EP0.
2. [Update: this part was fixed by PR #17086] ~If a feature is not supported, the device has to signal a STALL on the endpoint that should be used for the data phase in a control transaction. This means that for control read transactions the IN endpoint must signal a STALL and for control write transactions the OUT endpoint must signal a STALL. In former implementation, only the IN endpoint signaled a STALL independent on whether it was a control read or control write transaction. The change also fixes the problem that the enumeration stopped for about 5 seconds if module `usb_reset_board` isn't used. The reason is that the host sends a `SET LINE CODING` request to the CDC ACM interface and the device must signal a STALL on the OUT endpoint if it is not supported.~

### Testing procedure

1. Use a STM32 board with USB OTG version 1.x, for example a `nucleo-f439zi`:
   ```
   USEMODULE='stdio_cdc_acm' BOARD=nucleo-f439zi make -j8 -C tests/usbus_cdc_ecm flash
   ```
   Without this PR, the application seems to run but the CDC ECM interface is not working. The `ping` command can't be executed. With this PR, the application stops with `kernel_panic`. Because `stdio_cdc_acm` is used which doesn't work in this case, the `kernel_panic` has to be observed in debugger.
   ```
   USEMODULE='stdio_cdc_acm' BOARD=nucleo-f439zi make -j8 -C tests/usbus_cdc_ecm debug
   ```
2. [Update: this part was fixed by PR #17086] ~Use a STM32 board with USB OTG version 2.x and USB FS connector, for example a `nucleo-f767zi`:
   ```
   USEMODULE='stdio_cdc_acm' BOARD=nucleo-f767zi make -j8 -C tests/usbus_cdc_ecm flash
   ```
   Without this PR a delay of 5 seconds in enumeration of the CDC ACM interface can be observed before the CDC ECM interface is enumerated. With this PR there is no delay anymore.~

### Issues/PRs references

Fixes issue #19359 patially.

Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
This commit is contained in:
bors[bot] 2023-03-10 08:18:36 +00:00 committed by GitHub
commit 13d0895eae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 10 additions and 0 deletions

View File

@ -231,18 +231,21 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
usbus_endpoint_t *ep = usbus_add_endpoint(usbus, &cdcacm->iface_ctrl,
USB_EP_TYPE_INTERRUPT,
USB_EP_DIR_IN, 8);
assert(ep);
ep->interval = 255; /* Max interval */
usbus_enable_endpoint(ep);
ep = usbus_add_endpoint(usbus, &cdcacm->iface_data,
USB_EP_TYPE_BULK, USB_EP_DIR_IN,
CONFIG_USBUS_CDC_ACM_BULK_EP_SIZE);
ep->interval = 0; /* Interval is not used with bulk endpoints */
assert(ep);
usbus_enable_endpoint(ep);
/* Store the endpoint reference to activate it
* when DTE present is signalled by the host */
ep = usbus_add_endpoint(usbus, &cdcacm->iface_data,
USB_EP_TYPE_BULK, USB_EP_DIR_OUT,
CONFIG_USBUS_CDC_ACM_BULK_EP_SIZE);
assert(ep);
ep->interval = 0; /* Interval is not used with bulk endpoints */
usbus_enable_endpoint(ep);

View File

@ -218,6 +218,7 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
USB_EP_TYPE_INTERRUPT,
USB_EP_DIR_IN,
USBUS_CDCECM_EP_CTRL_SIZE);
assert(cdcecm->ep_ctrl);
cdcecm->ep_ctrl->interval = 0x10;
cdcecm->ep_out = usbus_add_endpoint(usbus,
@ -225,12 +226,14 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
USB_EP_TYPE_BULK,
USB_EP_DIR_OUT,
USBUS_CDCECM_EP_DATA_SIZE);
assert(cdcecm->ep_out);
cdcecm->ep_out->interval = 0; /* Must be 0 for bulk endpoints */
cdcecm->ep_in = usbus_add_endpoint(usbus,
(usbus_interface_t *)&cdcecm->iface_data_alt,
USB_EP_TYPE_BULK,
USB_EP_DIR_IN,
USBUS_CDCECM_EP_DATA_SIZE);
assert(cdcecm->ep_in);
cdcecm->ep_in->interval = 0; /* Must be 0 for bulk endpoints */
/* Add interfaces to the stack */

View File

@ -121,6 +121,7 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
USB_EP_TYPE_INTERRUPT,
USB_EP_DIR_IN,
CONFIG_USBUS_HID_INTERRUPT_EP_SIZE);
assert(hid->ep_in);
/* interrupt endpoint polling rate in ms */
hid->ep_in->interval = 0x05;
@ -131,6 +132,7 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
hid->ep_out = usbus_add_endpoint(usbus, &hid->iface,
USB_EP_TYPE_INTERRUPT, USB_EP_DIR_OUT,
CONFIG_USBUS_HID_INTERRUPT_EP_SIZE);
assert(hid->ep_out);
/* interrupt endpoint polling rate in ms */
hid->ep_out->interval = 0x05;

View File

@ -339,9 +339,11 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
/* Create required endpoints */
msc->ep_in = usbus_add_endpoint(usbus, &msc->iface, USB_EP_TYPE_BULK,
USB_EP_DIR_IN, CONFIG_USBUS_EP0_SIZE);
assert(msc->ep_in);
msc->ep_in->interval = 0;
msc->ep_out = usbus_add_endpoint(usbus, &msc->iface, USB_EP_TYPE_BULK,
USB_EP_DIR_OUT, CONFIG_USBUS_EP0_SIZE);
assert(msc->ep_out);
msc->ep_out->interval = 0;
/* Add interfaces to the stack */