From 86e29534704d0e6e99b3a51c06f9987185bc8dee Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 31 Mar 2023 14:26:58 +0200 Subject: [PATCH 1/6] usbopt: add USBOPT_ENUMERATED_SPEED --- sys/include/usb/usbopt.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/include/usb/usbopt.h b/sys/include/usb/usbopt.h index db684ebb97..ec976d2335 100644 --- a/sys/include/usb/usbopt.h +++ b/sys/include/usb/usbopt.h @@ -70,6 +70,15 @@ typedef enum { */ USBOPT_MAX_SPEED, + /** + * @brief (usb_version_t) Speed at which the usb peripheral got enumerated by the host + * + * Should be equal or slower than @ref USBOPT_MAX_SPEED + * + * Setting this option must return -ENOTSUP + */ + USBOPT_ENUMERATED_SPEED, + /* expand list if required */ } usbopt_t; From aa67c98a4aa3f870258f7c1e4f8a52890ba39296 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 31 Mar 2023 14:27:32 +0200 Subject: [PATCH 2/6] synopsys_dwc2: implement USBOPT_ENUMERATED_SPEED --- .../usbdev_synopsys_dwc2.c | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c b/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c index 92a08d22db..8bfc4338e3 100644 --- a/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c +++ b/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c @@ -1021,10 +1021,36 @@ static void _usbdev_init(usbdev_t *dev) #endif } +static usb_speed_t _get_max_speed(const usbdev_t *dev) +{ + dwc2_usb_otg_fshs_t *usbdev = (dwc2_usb_otg_fshs_t *)dev; + const dwc2_usb_otg_fshs_config_t *conf = usbdev->config; + if (IS_USED(DWC2_USB_OTG_HS_ENABLED) && (conf->type == DWC2_USB_OTG_HS)) { + return USB_SPEED_HIGH; + } + return USB_SPEED_FULL; +} + +static usb_speed_t _get_enumeration_speed(const usbdev_t *dev) +{ + dwc2_usb_otg_fshs_t *usbdev = (dwc2_usb_otg_fshs_t *)dev; + const dwc2_usb_otg_fshs_config_t *conf = usbdev->config; + unsigned speed = (_device_regs(conf)->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> + USB_OTG_DSTS_ENUMSPD_Pos; + switch (speed) { + case 0x00: + return USB_SPEED_HIGH; + case 0x03: + return USB_SPEED_FULL; + default: + assert(false); /* reserved values by peripheral */ + } + return USB_SPEED_FULL; /* Should not be reached */ +} + static int _usbdev_get(usbdev_t *dev, usbopt_t opt, void *value, size_t max_len) { - (void)dev; (void)max_len; int res = -ENOTSUP; switch (opt) { @@ -1035,7 +1061,12 @@ static int _usbdev_get(usbdev_t *dev, usbopt_t opt, break; case USBOPT_MAX_SPEED: assert(max_len == sizeof(usb_speed_t)); - *(usb_speed_t *)value = USB_SPEED_FULL; + *(usb_speed_t *)value = _get_max_speed(dev); + res = sizeof(usb_speed_t); + break; + case USBOPT_ENUMERATED_SPEED: + assert(max_len == sizeof(usb_speed_t)); + *(usb_speed_t *)value = _get_enumeration_speed(dev); res = sizeof(usb_speed_t); break; default: From 8b4144391338c294b0796c31aca54e7d1c25a385 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 31 Mar 2023 14:28:12 +0200 Subject: [PATCH 3/6] usbus: Add functions to query max packet sizes --- sys/include/usb.h | 20 +++++++++++++++++++ sys/include/usb/usbus.h | 16 +++++++++++++++ sys/usb/usbus/usbus.c | 44 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/sys/include/usb.h b/sys/include/usb.h index 73d3599545..da96abac4c 100644 --- a/sys/include/usb.h +++ b/sys/include/usb.h @@ -239,6 +239,26 @@ typedef enum { USB_EP_DIR_IN, /**< Host in, device out */ } usb_ep_dir_t; +/** + * @brief Maximum transfer size for interrupt endpoints at full speed + */ +#define USB_ENDPOINT_INTERRUPT_FS_MAX_SIZE (64) + +/** + * @brief Maximum transfer size for interrupt endpoints at high speed + */ +#define USB_ENDPOINT_INTERRUPT_HS_MAX_SIZE (1024) + +/** + * @brief Maximum transfer size for bulk endpoints at full speed + */ +#define USB_ENDPOINT_BULK_FS_MAX_SIZE (64) + +/** + * @brief Maximum transfer size for bulk endpoints at high speed + */ +#define USB_ENDPOINT_BULK_HS_MAX_SIZE (512) + #ifdef __cplusplus } #endif diff --git a/sys/include/usb/usbus.h b/sys/include/usb/usbus.h index 98fc1e948f..3a46575012 100644 --- a/sys/include/usb/usbus.h +++ b/sys/include/usb/usbus.h @@ -589,6 +589,22 @@ void usbus_register_event_handler(usbus_t *usbus, usbus_handler_t *handler); */ void usbus_init(usbus_t *usbus, usbdev_t *usbdev); +/** + * @brief Get the maximum supported bulk endpoint transfer size based on the enumeration speed + * + * Should only be called after enumeration has finished by the peripheral. Calling this in response + * to the @ref USBUS_EVENT_USB_RESET is valid + */ +size_t usbus_max_bulk_endpoint_size(usbus_t *usbus); + +/** + * @brief Get the maximum supported interrupt endpoint transfer size based on the enumeration speed + * + * Should only be called after enumeration has finished by the peripheral. Calling this in response + * to the @ref USBUS_EVENT_USB_RESET is valid + */ +size_t usbus_max_interrupt_endpoint_size(usbus_t *usbus); + /** * @brief Create and start the USBUS thread * diff --git a/sys/usb/usbus/usbus.c b/sys/usb/usbus/usbus.c index 6e2800f826..abba08e809 100644 --- a/sys/usb/usbus/usbus.c +++ b/sys/usb/usbus/usbus.c @@ -162,6 +162,50 @@ usbus_endpoint_t *usbus_interface_find_endpoint(usbus_interface_t *interface, return NULL; } +size_t usbus_max_bulk_endpoint_size(usbus_t *usbus) +{ + usb_speed_t speed; + int res = usbdev_get(usbus->dev, USBOPT_ENUMERATED_SPEED, &speed, + sizeof(speed)); + if (res == -ENOTSUP) { + res = usbdev_get(usbus->dev, USBOPT_MAX_SPEED, &speed, + sizeof(speed)); + } + + if (res < 0) { + return 0; /* Misbehaving usbdev device not implementing any speed indication */ + } + + switch (speed) { + case USB_SPEED_HIGH: + return USB_ENDPOINT_BULK_HS_MAX_SIZE; + default: + return USB_ENDPOINT_BULK_FS_MAX_SIZE; + } +} + +size_t usbus_max_interrupt_endpoint_size(usbus_t *usbus) +{ + usb_speed_t speed; + int res = usbdev_get(usbus->dev, USBOPT_ENUMERATED_SPEED, &speed, + sizeof(speed)); + if (res == -ENOTSUP) { + res = usbdev_get(usbus->dev, USBOPT_MAX_SPEED, &speed, + sizeof(speed)); + } + + if (res < 0) { + assert(false); /* Misbehaving usbdev device not implementing mandatory USBOPTS */ + } + + switch (speed) { + case USB_SPEED_HIGH: + return USB_ENDPOINT_INTERRUPT_HS_MAX_SIZE; + default: + return USB_ENDPOINT_INTERRUPT_FS_MAX_SIZE; + } +} + usbus_endpoint_t *usbus_add_endpoint(usbus_t *usbus, usbus_interface_t *iface, usb_ep_type_t type, usb_ep_dir_t dir, size_t len) From 8044e578b5a6b0ac6d772aa642e42ff77da37c11 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 31 Mar 2023 14:28:39 +0200 Subject: [PATCH 4/6] cdc_ecm: Update max supported transfer size after reset --- sys/usb/usbus/cdc/ecm/cdc_ecm.c | 6 ++++++ sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/usb/usbus/cdc/ecm/cdc_ecm.c b/sys/usb/usbus/cdc/ecm/cdc_ecm.c index 7fa4f8cd8f..9d0ff886de 100644 --- a/sys/usb/usbus/cdc/ecm/cdc_ecm.c +++ b/sys/usb/usbus/cdc/ecm/cdc_ecm.c @@ -336,6 +336,12 @@ static void _handle_reset(usbus_t *usbus, usbus_handler_t *handler) { usbus_cdcecm_device_t *cdcecm = (usbus_cdcecm_device_t *)handler; + /* Set the max packet size advertised to the host to something compatible with the enumerated + * size */ + size_t maxpacketsize = usbus_max_bulk_endpoint_size(usbus); + cdcecm->ep_in->maxpacketsize = maxpacketsize; + cdcecm->ep_out->maxpacketsize = maxpacketsize; + DEBUG("CDC ECM: Reset\n"); _handle_in_complete(usbus, handler); cdcecm->notif = USBUS_CDCECM_NOTIF_NONE; diff --git a/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c b/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c index 5cdfdc2c40..070352d017 100644 --- a/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c +++ b/sys/usb/usbus/cdc/ecm/cdc_ecm_netdev.c @@ -71,7 +71,7 @@ static int _send(netdev_t *netdev, const iolist_t *iolist) /* load packet data into FIFO */ size_t iol_offset = 0; size_t usb_offset = 0; - size_t usb_remain = cdcecm->ep_in->ep->len; + size_t usb_remain = cdcecm->ep_in->maxpacketsize; DEBUG("CDC_ECM_netdev: cur iol: %d\n", iolist->iol_len); while (len) { mutex_lock(&cdcecm->out_lock); From 329727784b8613a022d506ca0242757c7718ac3f Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 31 Mar 2023 16:43:51 +0200 Subject: [PATCH 5/6] Revert "boards/stm32f429-disc*: do not use periph_usbdev_hs" This reverts commit 05160f9c2adc372f09ea4b7d1213a2ba8327a003. --- boards/common/stm32/include/cfg_usb_otg_hs_phy_fs.h | 2 +- boards/stm32f429i-disc1/Kconfig | 3 +++ boards/stm32f429i-disc1/Makefile.dep | 4 ++++ boards/stm32f429i-disc1/Makefile.features | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/boards/common/stm32/include/cfg_usb_otg_hs_phy_fs.h b/boards/common/stm32/include/cfg_usb_otg_hs_phy_fs.h index 6e2b2b63e1..aa3e77cfeb 100644 --- a/boards/common/stm32/include/cfg_usb_otg_hs_phy_fs.h +++ b/boards/common/stm32/include/cfg_usb_otg_hs_phy_fs.h @@ -36,7 +36,7 @@ extern "C" { #define DWC2_USB_OTG_HS_ENABLED /** - * @brief Common USB OTG HS configuration with on-chip FS PHY + * @brief Common USB OTG FS configuration */ static const dwc2_usb_otg_fshs_config_t dwc2_usb_otg_fshs_config[] = { { diff --git a/boards/stm32f429i-disc1/Kconfig b/boards/stm32f429i-disc1/Kconfig index ff05e0293c..33303137a9 100644 --- a/boards/stm32f429i-disc1/Kconfig +++ b/boards/stm32f429i-disc1/Kconfig @@ -20,6 +20,7 @@ config BOARD_STM32F429I_DISC1 select HAS_PERIPH_TIMER select HAS_PERIPH_UART select HAS_PERIPH_USBDEV + select HAS_PERIPH_USBDEV_HS # Put other features for this board (in alphabetical order) select HAS_RIOTBOOT @@ -38,4 +39,6 @@ config BOARD_STM32F429I_DISC1 select HAVE_I3G4250D select HAVE_L3GD20 + select MODULE_PERIPH_USBDEV_HS if MODULE_PERIPH_USBDEV + source "$(RIOTBOARD)/common/stm32/Kconfig" diff --git a/boards/stm32f429i-disc1/Makefile.dep b/boards/stm32f429i-disc1/Makefile.dep index 1b5ae322af..18b88c7611 100644 --- a/boards/stm32f429i-disc1/Makefile.dep +++ b/boards/stm32f429i-disc1/Makefile.dep @@ -1,3 +1,7 @@ +ifneq (,$(filter periph_usbdev,$(USEMODULE))) + USEMODULE += periph_usbdev_hs +endif + ifneq (,$(filter saul_default,$(USEMODULE))) USEMODULE += saul_gpio USEMODULE += l3gxxxx diff --git a/boards/stm32f429i-disc1/Makefile.features b/boards/stm32f429i-disc1/Makefile.features index 8ce979e427..3ddc733cbf 100644 --- a/boards/stm32f429i-disc1/Makefile.features +++ b/boards/stm32f429i-disc1/Makefile.features @@ -8,6 +8,7 @@ FEATURES_PROVIDED += periph_spi FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_uart FEATURES_PROVIDED += periph_usbdev +FEATURES_PROVIDED += periph_usbdev_hs # Put other features for this board (in alphabetical order) FEATURES_PROVIDED += riotboot From ca0d0758bf276d1bd4bc7f2cbe879cc4e00a2449 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 31 Mar 2023 16:44:03 +0200 Subject: [PATCH 6/6] Revert "tests/usbus_cdc_ecm: blacklist stm32f429i-disco" This reverts commit 281db4bfa80e4911a3de2154722aad4bb2502d82. --- tests/usbus_cdc_ecm/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/usbus_cdc_ecm/Makefile b/tests/usbus_cdc_ecm/Makefile index b25c9e7699..fc1a96e1e4 100644 --- a/tests/usbus_cdc_ecm/Makefile +++ b/tests/usbus_cdc_ecm/Makefile @@ -12,7 +12,6 @@ USEMODULE += ps # Boards that don't have enough endpoints to use CDC ACM together with CDC ECM ifeq (,$(filter stdio_%,$(filter-out stdio_cdc_acm,$(USEMODULE)))) BOARD_BLACKLIST += \ - stm32f429i-disco \ stm32f4discovery \ weact-f401cc \ weact-f401ce \