Skip to content

Commit

Permalink
Merge #19471
Browse files Browse the repository at this point in the history
19471: drivers/periph_usbdev: fix set device address r=bergzand a=gschorcht

### Contribution description

This PR allows to define when the device address is set on receipt of a SETUP with `SET ADDRESS Request`. It fixes the problem with enumeration of the Synopsys DWC2 USB OTG Core due to the wrong time of setting the device address.

Especially, it fixes the problem that the enumeration fails completely for the `stm32f723e-disco` board with CDC ECM if CDC ACM is not used and the additional reset cycles during the enumeration for a couple of platforms such as ESP32-S2 and ESP32-S3.

**Background**

The address in the USB device can be set either directly after the SETUP stage on receipt of the `SET ADDRESS Request` or after the associated STATUS stage. When the USB device address has to be set depends on the hardware implementation.
**Solution**

To control the time of setting the device address, a new define `USBDEV_SET_ADDR_AFTER_STATUS` is introduced.
If `USBDEV_SET_ADDR_AFTER_STATUS` has the value 1 (default), the address is set in the USB device after the STATUS stage. Since this is the default, existing `periph_usbdev` drivers shouldn't be affected. Overwriting `USBDEV_SET_ADDR_AFTER_STATUS`  with 0 in `periph_cpu.h` or in driver header file let the address set directly after the SETUP stage.

### Testing procedure

Use `tests/usbus_cdc_ecm`:

For `stm32f723e-disco` the enumeration doesn't work at all without this PR and works reliable with this PR.
```
USEMODULE='periph_usbdev_hs_utmi' BOARD=stm32f723e-disco make -C tests/usbus_cdc_ecm flash
```
For any ESP32-S2 or ESP32-S3 board, the enumeration requires an addition reset cycle in every third or fourth enumeration without this PR and doesn't require any reset cycle with this PR.
```
BOARD=esp32s2-devkit make -C tests/usbus_cdc_ecm flash
```
Other platforms should still work with this PR, for example ATSAM platform:
```
BOARD=arduino-mkr1000 make -C tests/usbus_cdc_ecm flash
```

### Issues/PRs references


Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
  • Loading branch information
bors[bot] and gschorcht committed Apr 16, 2023
2 parents 5a523ee + 88cabba commit 1961274
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
16 changes: 15 additions & 1 deletion drivers/include/periph/usbdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
#include <stddef.h>

#include "assert.h"
#include "periph_cpu.h"
#include "periph_conf.h"
#include "usb.h"
#include "usb/usbopt.h"

Expand Down Expand Up @@ -125,6 +125,20 @@ typedef struct usbdev_ep usbdev_ep_t;
*/
#define usbdev_ep_buf_t USBDEV_CPU_DMA_REQUIREMENTS uint8_t

/**
* @brief USBDEV specific requirement for setting the device address
*
* The address in the USB device can be set either directly after the SETUP
* stage on receipt of the `SET ADDRESS Request` or after the associated status
* stage. When the USB device address has to be set depends on the hardware.
* If `USBDEV_CPU_SET_ADDR_AFTER_STATUS` has the value 1 (default), the address
* is only set in the USB device after the status stage. Overwrite it with 0
* in `periph_cpu.h` to set the address already directly after the SETUP stage.
*/
#ifndef USBDEV_CPU_SET_ADDR_AFTER_STATUS
#define USBDEV_CPU_SET_ADDR_AFTER_STATUS 1
#endif

/**
* @brief Number of USB IN and OUT endpoints allocated
*
Expand Down
8 changes: 8 additions & 0 deletions drivers/include/usbdev_synopsys_dwc2.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
extern "C" {
#endif

/**
* @brief USB OTG peripheral requirement for setting the device address
*
* The address in the USB device has to be directly after the SETUP
* stage on receipt of the `SET ADDRESS Request`.
*/
#define USBDEV_CPU_SET_ADDR_AFTER_STATUS 0

/**
* @brief USB OTG peripheral type.
*
Expand Down
10 changes: 8 additions & 2 deletions sys/usb/usbus/usbus_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ static int _recv_dev_setup(usbus_t *usbus, usb_setup_t *pkt)
case USB_SETUP_REQ_SET_ADDRESS:
DEBUG("usbus_control: Setting address\n");
usbus->addr = (uint8_t)pkt->value;
if (!USBDEV_CPU_SET_ADDR_AFTER_STATUS) {
usbdev_set(usbus->dev, USBOPT_ADDRESS, &usbus->addr,
sizeof(usbus->addr));
}
res = 1;
break;
case USB_SETUP_REQ_SET_CONFIGURATION:
Expand Down Expand Up @@ -401,8 +405,10 @@ static int _handle_tr_complete(usbus_t *usbus,
case USBUS_CONTROL_REQUEST_STATE_INACK:
if (ep->dir == USB_EP_DIR_IN) {
if (usbus->addr && usbus->state == USBUS_STATE_RESET) {
usbdev_set(usbus->dev, USBOPT_ADDRESS, &usbus->addr,
sizeof(usbus->addr));
if (USBDEV_CPU_SET_ADDR_AFTER_STATUS) {
usbdev_set(usbus->dev, USBOPT_ADDRESS, &usbus->addr,
sizeof(usbus->addr));
}
/* Address configured */
usbus->state = USBUS_STATE_ADDR;
}
Expand Down

0 comments on commit 1961274

Please sign in to comment.