diff --git a/drivers/Kconfig.net b/drivers/Kconfig.net index f62dbf2843a9..4b95e6460a47 100644 --- a/drivers/Kconfig.net +++ b/drivers/Kconfig.net @@ -36,6 +36,7 @@ rsource "$(RIOTCPU)/stm32/periph/Kconfig.eth" rsource "sx126x/Kconfig" rsource "sx127x/Kconfig" rsource "sx1280/Kconfig" +rsource "$(RIOTPKG)/tinyusb/netdev/Kconfig" rsource "tja1042/Kconfig" rsource "w5100/Kconfig" endmenu # Network Device Drivers diff --git a/drivers/include/net/netdev.h b/drivers/include/net/netdev.h index cc4048baf1fe..ab15342261b8 100644 --- a/drivers/include/net/netdev.h +++ b/drivers/include/net/netdev.h @@ -332,6 +332,7 @@ typedef enum { NETDEV_ESP_ETH, NETDEV_ESP_WIFI, NETDEV_CDC_ECM, + NETDEV_TINYUSB, /* add more if needed */ } netdev_type_t; /** @} */ diff --git a/pkg/tinyusb/Kconfig b/pkg/tinyusb/Kconfig index 5ea5dd4d61b1..01997a6047c7 100644 --- a/pkg/tinyusb/Kconfig +++ b/pkg/tinyusb/Kconfig @@ -126,6 +126,9 @@ config MODULE_TINYUSB_HOST help Select to enable tinyUSB host stack +config MODULE_TINYUSB_LIB_NETWORKING + bool + config MODULE_TINYUSB_PORTABLE_ESPRESSIF bool help @@ -170,13 +173,7 @@ menu "Device Classes" bool "Musical Instrument Digital Interface (MIDI)" depends on MODULE_TINYUSB_DEVICE - config MODULE_TINYUSB_CLASS_NET_ECM_RNDIS - bool "Network with RNDIS, Ethernet Control Model (ECM)" - depends on MODULE_TINYUSB_DEVICE - - config MODULE_TINYUSB_CLASS_NET_NCM - bool "Network with Network Control Model (NCM)" - depends on MODULE_TINYUSB_DEVICE + rsource "Kconfig.net" config MODULE_TINYUSB_CLASS_USBTMC bool "Test and Measurement Class (USBTMC)" diff --git a/pkg/tinyusb/Kconfig.net b/pkg/tinyusb/Kconfig.net new file mode 100644 index 000000000000..a349c056c7b8 --- /dev/null +++ b/pkg/tinyusb/Kconfig.net @@ -0,0 +1,60 @@ +# Copyright (c) 2022 Gunar Schorcht +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +menuconfig MODULE_TINYUSB_CLASS_NET + bool "Network Device Class" + depends on MODULE_TINYUSB_DEVICE + +if MODULE_TINYUSB_CLASS_NET + +config MODULE_TINYUSB_CLASS_NET_CDC_ECM + bool "CDC ECM network device" + default y + +config MODULE_TINYUSB_CLASS_NET_CDC_NCM + bool "CDC NCM network device" + +config MODULE_TINYUSB_CLASS_NET_RNDIS + bool "RNDIS network device" + select MODULE_TINYUSB_LIB_NETWORKING + +config TUSBD_NET_NUMOF + int + default 1 + +if TUSBD_NET_NUMOF > 0 + +config TUSBD_NET_NOTIF_EP_SIZE + int "Net Notification endpoint size [byte]" + default 64 + +config TUSBD_NET_FS_EP_SIZE + int "Net Full-Speed endpoint size [byte]" + default 64 + +config TUSBD_NET_HS_EP_SIZE + int "Net High-Speed endpoint size [byte]" + default 512 + +config TUSBD_NET_MTU_SIZE + int "MTU size [byte]" + default 1514 + +config TUSBD_NET_DESC_STRING + string "Class descriptor string" + default "TinyUSB Net" + +config TUSBD_NET_CUSTOM_MAC + bool "Use custom MAC address string" + +config TUSBD_NET_MAC_STRING + string "MAC address string" + depends on TUSBD_ECM_CUSTOM_MAC + default "0123456789ab" + +endif # TUSBD_NET_NUMOF > 0 +endif # MODULE_TINYUSB_CLASS_NET diff --git a/pkg/tinyusb/Makefile b/pkg/tinyusb/Makefile index f2b183a67aaf..cf92a5a3f997 100644 --- a/pkg/tinyusb/Makefile +++ b/pkg/tinyusb/Makefile @@ -8,10 +8,11 @@ PKG_LICENSE=MIT include $(RIOTBASE)/pkg/pkg.mk PSRC = $(PKG_SOURCE_DIR)/src +PLIB = $(PKG_SOURCE_DIR)/lib .PHONY: all -all: $(filter tinyusb_% stdio_tinyusb_cdc_acm,$(USEMODULE)) +all: $(filter tinyusb_% stdio_tinyusb_cdc_acm,$(filter-out tinyusb_class_net_%,$(USEMODULE))) $(QQ)"$(MAKE)" -C $(PSRC) -f $(RIOTBASE)/Makefile.base MODULE=tinyusb stdio_tinyusb_cdc_acm: @@ -26,6 +27,9 @@ tinyusb_dfu: tinyusb_hw: $(QQ)"$(MAKE)" -C $(RIOTPKG)/$(PKG_NAME)/hw +tinyusb_netdev: + $(QQ)"$(MAKE)" -C $(RIOTPKG)/$(PKG_NAME)/netdev + tinyusb_class_audio: $(QQ)"$(MAKE)" -C $(PSRC)/class/audio -f $(RIOTBASE)/Makefile.base MODULE=$@ @@ -50,10 +54,7 @@ tinyusb_class_midi: tinyusb_class_msc: $(QQ)"$(MAKE)" -C $(PSRC)/class/msc -f $(RIOTBASE)/Makefile.base MODULE=$@ -tinyusb_class_net_ecm_rndis: - $(QQ)"$(MAKE)" -C $(PSRC)/class/net -f $(RIOTBASE)/Makefile.base MODULE=$@ - -tinyusb_class_net_ncm: +tinyusb_class_net: $(QQ)"$(MAKE)" -C $(PSRC)/class/net -f $(RIOTBASE)/Makefile.base MODULE=$@ tinyusb_class_usbtmc: @@ -74,6 +75,9 @@ tinyusb_device: tinyusb_host: $(QQ)"$(MAKE)" -C $(PSRC)/host -f $(RIOTBASE)/Makefile.base MODULE=$@ +tinyusb_lib_networking: + $(QQ)"$(MAKE)" -C $(PLIB)/networking -f $(RIOTPKG)/$(PKG_NAME)/Makefile.lib_networking + tinyusb_portable_espressif: $(QQ)"$(MAKE)" -C $(PSRC)/portable/espressif/esp32sx -f $(RIOTBASE)/Makefile.base MODULE=$@ diff --git a/pkg/tinyusb/Makefile.dep b/pkg/tinyusb/Makefile.dep index d772ece099be..f48197dad292 100644 --- a/pkg/tinyusb/Makefile.dep +++ b/pkg/tinyusb/Makefile.dep @@ -30,6 +30,24 @@ ifneq (,$(filter tinyusb_dfu,$(USEMODULE))) endif endif +ifneq (,$(filter tinyusb_class_net_%,$(USEMODULE))) + USEMODULE += tinyusb_class_net +endif + +ifneq (,$(filter tinyusb_netdev,$(USEMODULE))) + USEMODULE += luid + USEMODULE += netdev_eth + USEMODULE += tinyusb_device + ifeq (,$(filter tinyusb_class_net_%,$(USEMODULE))) + # default to CDC ECM + USEMODULE += tinyusb_class_net_cdc_ecm + endif +endif + +ifneq (,$(filter tinyusb_class_net_rndis,$(USEMODULE))) + USEMODULE += tinyusb_lib_networking +endif + ifeq (,$(filter tinyusb_class_%,$(USEMODULE))) $(error At least one tinyusb_class_* module has to be enabled) endif @@ -60,10 +78,7 @@ endif ifneq (,$(filter tinyusb_class_midi,$(USEMODULE))) USEMODULE += tinyusb_device endif -ifneq (,$(filter tinyusb_class_net_ecm_rndis,$(USEMODULE))) - USEMODULE += tinyusb_device -endif -ifneq (,$(filter tinyusb_class_net_ncm,$(USEMODULE))) +ifneq (,$(filter tinyusb_class_net,$(USEMODULE))) USEMODULE += tinyusb_device endif ifneq (,$(filter tinyusb_class_usbtmc,$(USEMODULE))) diff --git a/pkg/tinyusb/Makefile.include b/pkg/tinyusb/Makefile.include index bf64577352b2..bcf048baae6a 100644 --- a/pkg/tinyusb/Makefile.include +++ b/pkg/tinyusb/Makefile.include @@ -1,3 +1,7 @@ +PSEUDOMODULES += tinyusb_class_net_cdc_ecm +PSEUDOMODULES += tinyusb_class_net_cdc_ncm +PSEUDOMODULES += tinyusb_class_net_rndis + INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/contrib INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/contrib/include INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/hw/include @@ -30,10 +34,14 @@ else $(error CPU $(CPU) or CPU family $(CPU_FAM) not supported) endif -ifneq (,$(filter tinyusb_class_net_ecm_rndis,$(USEMODULE))) +ifneq (,$(filter tinyusb_class_net tinyusb_lib_networking,$(USEMODULE))) INCLUDES += -I$(PKGDIRBASE)/tinyusb/lib/networking endif ifneq (,$(filter tinyusb_dfu,$(USEMODULE))) INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/dfu/include endif + +ifneq (,$(filter tinyusb_netdev,$(USEMODULE))) + INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/netdev/include +endif diff --git a/pkg/tinyusb/Makefile.lib_networking b/pkg/tinyusb/Makefile.lib_networking new file mode 100644 index 000000000000..e9ade168264f --- /dev/null +++ b/pkg/tinyusb/Makefile.lib_networking @@ -0,0 +1,5 @@ +MODULE = tinyusb_lib_networking + +SRC = rndis_reports.c + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/tinyusb/contrib/include/tinyusb.h b/pkg/tinyusb/contrib/include/tinyusb.h index 7919add26681..34679c696eea 100644 --- a/pkg/tinyusb/contrib/include/tinyusb.h +++ b/pkg/tinyusb/contrib/include/tinyusb.h @@ -46,6 +46,10 @@ extern "C" { #endif +#if MODULE_TINYUSB_CLASS_NET_RNDIS +#define SIZEOF_ETH_HDR 14 +#endif + /** * @brief Initialize the tinyUSB stack including used peripherals and start the tinyUSB thread * diff --git a/pkg/tinyusb/contrib/include/tinyusb_descriptors.h b/pkg/tinyusb/contrib/include/tinyusb_descriptors.h index 3b460c058d8c..92b909a83aa9 100644 --- a/pkg/tinyusb/contrib/include/tinyusb_descriptors.h +++ b/pkg/tinyusb/contrib/include/tinyusb_descriptors.h @@ -56,6 +56,10 @@ enum { #if CONFIG_TUSBD_MSC_NUMOF TUSBD_ITF_MSC, /**< MSC interface */ #endif +#if CONFIG_TUSBD_NET_NUMOF + TUSBD_ITF_NET, /**< NET Notification interface */ + TUSBD_ITF_NET_DATA, /**< NET Data interface */ +#endif #if CONFIG_TUSBD_VENDOR_NUMOF TUSBD_ITF_VENDOR, /**< Vendor interface */ #endif @@ -87,6 +91,11 @@ enum { TUSBD_EP_MSC_OUT = TUSBD_ITF_MSC + 0x01, /**< MSC EP OUT */ TUSBD_EP_MSC_IN = TUSBD_ITF_MSC + 0x81, /**< MSC EP IN */ #endif +#if CONFIG_TUSBD_NET_NUMOF + TUSBD_EP_NET_NOTIF = TUSBD_ITF_NET + 0x81, /**< NET Notification EP IN */ + TUSBD_EP_NET_OUT = TUSBD_ITF_NET_DATA + 0x01, /**< NET Data EP OUT */ + TUSBD_EP_NET_IN = TUSBD_ITF_NET_DATA + 0x81, /**< NET Data EP IN */ +#endif #if CONFIG_TUSBD_VENDOR_NUMOF TUSBD_EP_VENDOR_OUT = TUSBD_ITF_VENDOR + 0x01, /**< Vendor EP OUT */ TUSBD_EP_VENDOR_IN = TUSBD_ITF_VENDOR + 0x81, /**< Vendor EP IN */ @@ -123,6 +132,20 @@ enum { #if CONFIG_TUSBD_MSC_NUMOF TUSBD_STR_IDX_MSC, #endif + +#if CONFIG_TUSBD_NET_NUMOF +#if CONFIG_TUSBD_NET_CDC_ECM + TUSBD_STR_IDX_NET_CDC_ECM, +#endif /* CONFIG_TUSBD_NET_CDC_ECM */ +#if CONFIG_TUSBD_NET_CDC_NCM + TUSBD_STR_IDX_NET_CDC_NCM, +#endif /* CONFIG_TUSBD_NET_CDC_NCM */ +#if CONFIG_TUSBD_NET_RNDIS + TUSBD_STR_IDX_NET_RNDIS, +#endif /* CONFIG_TUSBD_NET_RNDIS */ + TUSBD_STR_IDX_NET_MAC, +#endif /* CONFIG_TUSBD_NET_NUMOF */ + #if CONFIG_TUSBD_VENDOR_NUMOF TUSBD_STR_IDX_VENDOR, #endif @@ -134,22 +157,46 @@ enum { #define CONFIG_TUSBD_DFU_ALT_NUMOF 2 #if !defined(TUSBD_DESC_TOTAL_LEN) + +#if CONFIG_TUSBD_NET_CDC_ECM +#define TUSBD_DESC_NET_LEN TUD_CDC_ECM_DESC_LEN +#elif CONFIG_TUSBD_NET_CDC_NCM +#define TUSBD_DESC_NET_LEN TUD_CDC_NCM_DESC_LEN +#elif CONFIG_TUSBD_NET_RNDIS +#define TUSBD_DESC_NET_LEN TUD_RNDIS_DESC_LEN +#else +#define TUSBD_DESC_NET_LEN 0 +#endif + #define TUSBD_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + \ (CONFIG_TUSBD_CDC_NUMOF * TUD_CDC_DESC_LEN) + \ (CONFIG_TUSBD_DFU_NUMOF * TUD_DFU_DESC_LEN(CONFIG_TUSBD_DFU_ALT_NUMOF)) + \ (CONFIG_TUSBD_DFU_RT_NUMOF * TUD_DFU_RT_DESC_LEN) + \ (CONFIG_TUSBD_HID_NUMOF * TUD_HID_INOUT_DESC_LEN) + \ (CONFIG_TUSBD_MSC_NUMOF * TUD_MSC_DESC_LEN) + \ - (CONFIG_TUSBD_VENDOR_NUMOF * TUD_VENDOR_DESC_LEN)) + (CONFIG_TUSBD_VENDOR_NUMOF * TUD_VENDOR_DESC_LEN) + \ + TUSBD_DESC_NET_LEN) + #endif /* !defined(TUSBD_DESC_TOTAL_LEN) */ +/* If CDC ECM and RNDIS are used simultaneously, an alternative configuration + * descriptor is required. In this case, the main configuration descriptor + * contains the CDC ECM interface descriptor and the alternative configuration + * descriptor contains the RNDIS interface descriptor. */ +#if CONFIG_TUSBD_NET_CDC_ECM && CONFIG_TUSBD_NET_RNDIS + +#define TUSBD_DESC_ALT_NET_LEN TUD_RNDIS_DESC_LEN + #define TUSBD_DESC_ALT_TOTAL_LEN (TUD_CONFIG_DESC_LEN + \ (CONFIG_TUSBD_CDC_NUMOF * TUD_CDC_DESC_LEN) + \ (CONFIG_TUSBD_DFU_NUMOF * TUD_DFU_DESC_LEN(CONFIG_TUSBD_DFU_ALT_NUMOF)) + \ (CONFIG_TUSBD_DFU_RT_NUMOF * TUD_DFU_RT_DESC_LEN) + \ (CONFIG_TUSBD_HID_NUMOF * TUD_HID_INOUT_DESC_LEN) + \ (CONFIG_TUSBD_MSC_NUMOF * TUD_MSC_DESC_LEN) + \ - (CONFIG_TUSBD_VENDOR_NUMOF * TUD_VENDOR_DESC_LEN)) + (CONFIG_TUSBD_VENDOR_NUMOF * TUD_VENDOR_DESC_LEN) + \ + TUSBD_DESC_ALT_NET_LEN) + +#endif /* CONFIG_TUSBD_NET_CDC_ECM && CONFIG_TUSBD_NET_RNDIS */ #endif /* !defined(CONFIG_TUSBD_USE_CUSTOM_DESC) */ diff --git a/pkg/tinyusb/contrib/include/tusb_config.h b/pkg/tinyusb/contrib/include/tusb_config.h index 4ecd00881d4b..14b2660e6569 100644 --- a/pkg/tinyusb/contrib/include/tusb_config.h +++ b/pkg/tinyusb/contrib/include/tusb_config.h @@ -40,8 +40,16 @@ #endif #include "tinyusb.h" +#if MODULE_TINYUSB_CLASS_NET +#include "net/ethernet.h" +#endif + #if !DOXYGEN +#if MODULE_TINYUSB_CLASS_NET_CDC_NCM && (MODULE_TINYUSB_CLASS_NET_CDC_ECM || MODULE_TINYUSB_CLASS_NET_RNDIS) +#error "CDC NCM device class cannot be used together with CDC ECM or RNDIS device class" +#endif + #ifndef CONFIG_TUSBD_AUDIO_NUMOF #if MODULE_TINYUSB_DEVICE && MODULE_TINYUSB_CLASS_AUDIO #define CONFIG_TUSBD_AUDIO_NUMOF 1 @@ -82,14 +90,6 @@ #endif #endif -#ifndef CONFIG_TUSBD_ECM_NUMOF -#if MODULE_TINYUSB_DEVICE && MODULE_TINYUSB_CLASS_ECM -#define CONFIG_TUSBD_ECM_NUMOF 1 -#else -#define CONFIG_TUSBD_ECM_NUMOF 0 -#endif -#endif - #ifndef CONFIG_TUSBD_HID_NUMOF #if MODULE_TINYUSB_DEVICE && MODULE_TINYUSB_CLASS_HID #define CONFIG_TUSBD_HID_NUMOF 1 @@ -114,14 +114,6 @@ #endif #endif -#ifndef CONFIG_TUSBD_NCM_NUMOF -#if MODULE_TINYUSB_DEVICE && MODULE_TINYUSB_CLASS_NCM -#define CONFIG_TUSBD_NCM_NUMOF 1 -#else -#define CONFIG_TUSBD_NCM_NUMOF 0 -#endif -#endif - #ifndef CONFIG_TUSBD_USBTMC_NUMOF #if MODULE_TINYUSB_DEVICE && MODULE_TINYUSB_CLASS_USBTMC #define CONFIG_TUSBD_USBTMC_NUMOF 1 @@ -272,6 +264,14 @@ #define CONFIG_TUSBD_MSC_HS_EP_SIZE CONFIG_TUSBD_HS_EP_SIZE #endif +#ifndef CONFIG_TUSBD_NET_FS_EP_SIZE +#define CONFIG_TUSBD_NET_FS_EP_SIZE CONFIG_TUSBD_FS_EP_SIZE +#endif + +#ifndef CONFIG_TUSBD_NET_HS_EP_SIZE +#define CONFIG_TUSBD_NET_HS_EP_SIZE CONFIG_TUSBD_HS_EP_SIZE +#endif + #ifndef CONFIG_TUSBD_VENDOR_FS_EP_SIZE #define CONFIG_TUSBD_VENDOR_FS_EP_SIZE CONFIG_TUSBD_FS_EP_SIZE #endif @@ -280,6 +280,38 @@ #define CONFIG_TUSBD_VENDOR_HS_EP_SIZE CONFIG_TUSBD_HS_EP_SIZE #endif +#ifndef CONFIG_TUSBD_NET_NOTIF_EP_SIZE +#define CONFIG_TUSBD_NET_NOTIF_EP_SIZE 64 +#endif + +#ifndef CONFIG_TUSBD_NET_MTU_SIZE +#define CONFIG_TUSBD_NET_MTU_SIZE ETHERNET_FRAME_LEN +#endif + +#if MODULE_TINYUSB_CLASS_NET_CDC_ECM +#define CONFIG_TUSBD_NET_CDC_ECM 1 +#else +#define CONFIG_TUSBD_NET_CDC_ECM 0 +#endif + +#if MODULE_TINYUSB_CLASS_NET_CDC_NCM +#define CONFIG_TUSBD_NET_CDC_NCM 1 +#else +#define CONFIG_TUSBD_NET_CDC_NCM 0 +#endif + +#if MODULE_TINYUSB_CLASS_NET_RNDIS +#define CONFIG_TUSBD_NET_RNDIS 1 +#else +#define CONFIG_TUSBD_NET_RNDIS 0 +#endif + +#if CONFIG_TUSBD_NET_CDC_ECM || CONFIG_TUSBD_NET_CDC_NCM || CONFIG_TUSBD_NET_RNDIS +#define CONFIG_TUSBD_NET_NUMOF 1 +#else +#define CONFIG_TUSBD_NET_NUMOF 0 +#endif + #ifndef CONFIG_TUSBH_ENUM_SIZE #define CONFIG_TUSBH_ENUM_SIZE 256 #endif @@ -333,6 +365,7 @@ #define CFG_TUD_AUDIO CONFIG_TUSBD_AUDIO_NUMOF #define CFG_TUD_BTH CONFIG_TUSBD_BTH_NUMOF #define CFG_TUD_CDC CONFIG_TUSBD_CDC_NUMOF +#define CFG_TUD_ECM_RNDIS (CONFIG_TUSBD_NET_CDC_ECM || CONFIG_TUSBD_NET_RNDIS) #define CFG_TUD_DFU CONFIG_TUSBD_DFU_NUMOF #define CFG_TUD_DFU_RUNTIME CONFIG_TUSBD_DFU_RT_NUMOF #define CFG_TUD_HID CONFIG_TUSBD_HID_NUMOF @@ -408,6 +441,12 @@ : CONFIG_TUSBD_MSC_FS_EP_SIZE) /** @} */ +/** + * @name Typical required NET device class configurations + * @{ + */ +#define CFG_TUD_NET_MTU CONFIG_TUSBD_NET_MTU_SIZE + /** * @name Typical required HID host class configurations * @{ diff --git a/pkg/tinyusb/contrib/tinyusb_descriptors.c b/pkg/tinyusb/contrib/tinyusb_descriptors.c index 18fe22974d8b..e36071b724be 100644 --- a/pkg/tinyusb/contrib/tinyusb_descriptors.c +++ b/pkg/tinyusb/contrib/tinyusb_descriptors.c @@ -30,6 +30,8 @@ #include "tusb.h" #include "usb.h" +#include "net/ethernet.h" + #ifdef MODULE_TINYUSB_DFU #include "riotboot/usb_dfu.h" #endif @@ -45,13 +47,12 @@ #if (MODULE_TINYUSB_CLASS_AUDIO || \ MODULE_TINYUSB_CLASS_BTH || \ MODULE_TINYUSB_CLASS_MIDI || \ - MODULE_TINYUSB_CLASS_NET_ECM_RNDIS || \ - MODULE_TINYUSB_CLASS_NET_NCM || \ MODULE_TINYUSB_CLASS_USBTMC || \ MODULE_TINYUSB_CLASS_VIDEO || \ (CONFIG_TUSBD_CDC_NUMOF > 2) || \ (CONFIG_TUSBD_DFU_NUMOF > 1) || \ (CONFIG_TUSBD_DFU_RT_NUMOF > 1) || \ + (CONFIG_TUSBD_NET_NUMOF > 1) || \ (CONFIG_TUSBD_HID_NUMOF > 2) || \ (CONFIG_TUSBD_MSC_NUMOF > 1) || \ (CONFIG_TUSBD_VENDOR_NUMOF > 1)) @@ -59,7 +60,13 @@ of device class interfaces. Custom descriptors have to be implemented. #endif +/* If CDC ECM and RNDIS are used simultaneously, an alternative configuration + * descriptor is required. */ +#if CONFIG_TUSBD_NET_CDC_ECM && CONFIG_TUSBD_NET_RNDIS +#define _TUD_CONFIG_DESC_NUMOF 2 +#else #define _TUD_CONFIG_DESC_NUMOF 1 +#endif enum { _TUD_CONFIG_DESC_ID = 0, @@ -266,6 +273,39 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, speed ? CONFIG_TUSBD_MSC_HS_EP_SIZE \ : CONFIG_TUSBD_MSC_FS_EP_SIZE) +#define _TUD_CDC_ECM_DESC(speed) \ + /* Interface number, Description string index, MAC address string index, + * EP notification address and size, EP Data Out & In, EP size, MTU size. */ \ + TUD_CDC_ECM_DESCRIPTOR(TUSBD_ITF_NET, \ + TUSBD_STR_IDX_NET_CDC_ECM, TUSBD_STR_IDX_NET_MAC, \ + TUSBD_EP_NET_NOTIF, \ + CONFIG_TUSBD_NET_NOTIF_EP_SIZE, \ + TUSBD_EP_NET_OUT, TUSBD_EP_NET_IN, \ + speed ? CONFIG_TUSBD_NET_HS_EP_SIZE \ + : CONFIG_TUSBD_NET_FS_EP_SIZE, \ + CONFIG_TUSBD_NET_MTU_SIZE) + +#define _TUD_CDC_NCM_DESC(speed) \ + /* Interface number, Description string index, MAC address string index, + * EP notification address and size, EP Data Out & In, EP size, MTU size. */ \ + TUD_CDC_NCM_DESCRIPTOR(TUSBD_ITF_NET, \ + TUSBD_STR_IDX_NET_CDC_NCM, TUSBD_STR_IDX_NET_MAC, \ + TUSBD_EP_NET_NOTIF, \ + CONFIG_TUSBD_NET_NOTIF_EP_SIZE, \ + TUSBD_EP_NET_OUT, TUSBD_EP_NET_IN, \ + speed ? CONFIG_TUSBD_NET_HS_EP_SIZE \ + : CONFIG_TUSBD_NET_FS_EP_SIZE, \ + CONFIG_TUSBD_NET_MTU_SIZE) + +#define _TUD_RNDIS_DESC(speed) \ + /* Interface number, Description string index, EP notification address and + * size, EP Data Out & In, EP size */ \ + TUD_RNDIS_DESCRIPTOR(TUSBD_ITF_NET, TUSBD_STR_IDX_NET_RNDIS, \ + TUSBD_EP_NET_NOTIF, 8, TUSBD_EP_NET_OUT, \ + TUSBD_EP_NET_IN, \ + speed ? CONFIG_TUSBD_NET_HS_EP_SIZE \ + : CONFIG_TUSBD_NET_FS_EP_SIZE) + #define _TUD_VENDOR_DESC(speed) \ /* Interface number, string index, EP Out & In address, EP size */ \ TUD_VENDOR_DESCRIPTOR(TUSBD_ITF_VENDOR, TUSBD_STR_IDX_VENDOR, \ @@ -298,6 +338,13 @@ uint8_t const tusb_desc_fs_config[] = { #if CONFIG_TUSBD_MSC_NUMOF _TUD_MSC_DESC(_tusb_speed_fs), #endif +#if CONFIG_TUSBD_NET_CDC_ECM + _TUD_CDC_ECM_DESC(_tusb_speed_fs), +#elif CONFIG_TUSBD_NET_CDC_NCM + _TUD_CDC_NCM_DESC(_tusb_speed_fs), +#elif CONFIG_TUSBD_NET_RNDIS + _TUD_RNDIS_DESC(_tusb_speed_fs), +#endif #if CONFIG_TUSBD_VENDOR_NUMOF _TUD_VENDOR_DESC(_tusb_speed_fs), #endif @@ -328,6 +375,11 @@ uint8_t const tusb_desc_fs_config_alt[] = { #if CONFIG_TUSBD_MSC_NUMOF _TUD_MSC_DESC(_tusb_speed_fs), #endif + /* The alternative configuration descriptor is only required if CDC ECM and + * RDNIS are used simultaneously. In this case, the main configuration + * descriptor contains the CDC ECM interface descriptor and the alternative + * configuration descriptor contains the RNDIS interface descriptor. */ + _TUD_RNDIS_DESC(_tusb_speed_fs), #if CONFIG_TUSBD_VENDOR_NUMOF _TUD_VENDOR_DESC(_tusb_speed_fs), #endif @@ -363,6 +415,13 @@ uint8_t const tusb_desc_hs_config[] = { #if CONFIG_TUSBD_MSC_NUMOF _TUD_MSC_DESC(_tusb_speed_hs), #endif +#if CONFIG_TUSBD_NET_CDC_ECM + _TUD_CDC_ECM_DESC(_tusb_speed_hs), +#elif CONFIG_TUSBD_NET_CDC_NCM + _TUD_CDC_NCM_DESC(_tusb_speed_hs), +#elif CONFIG_TUSBD_NET_RNDIS + _TUD_RNDIS_DESC(_tusb_speed_hs), +#endif #if CONFIG_TUSBD_VENDOR_NUMOF _TUD_VENDOR_DESC(_tusb_speed_hs), #endif @@ -393,6 +452,11 @@ uint8_t const tusb_desc_hs_config_alt[] = { #if CONFIG_TUSBD_MSC_NUMOF _TUD_MSC_DESC(_tusb_speed_hs), #endif + /* The alternative configuration descriptor is only required if CDC ECM and + * RDNIS are used simultaneously. In this case, the main configuration + * descriptor contains the CDC ECM interface descriptor and the alternative + * configuration descriptor contains the RNDIS interface descriptor. */ + _TUD_RNDIS_DESC(_tusb_speed_hs), #if CONFIG_TUSBD_VENDOR_NUMOF _TUD_VENDOR_DESC(_tusb_speed_hs), #endif @@ -535,6 +599,14 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) #define CONFIG_TUSBD_CDC_1_STRING "TinyUSB CDC1" #endif +#ifndef CONFIG_TUSBD_CDC_ECM_STRING +#define CONFIG_TUSBD_CDC_ECM_STRING "TinyUSB CDC ECM" +#endif + +#ifndef CONFIG_TUSBD_CDC_NCM_STRING +#define CONFIG_TUSBD_CDC_NCM_STRING "TinyUSB CDC NCM" +#endif + #ifndef CONFIG_TUSBD_DFU_0_STRING #define CONFIG_TUSBD_DFU_0_STRING USB_DFU_MODE_SLOT0_NAME #endif @@ -559,6 +631,14 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) #define CONFIG_TUSBD_MSC_STRING "TinyUSB MSC" #endif +#ifndef CONFIG_TUSBD_NET_DESC_STRING +#define CONFIG_TUSBD_NET_DESC_STRING "TinyUSB Net" +#endif + +#ifndef CONFIG_TUSBD_RNDIS_STRING +#define CONFIG_TUSBD_RNDIS_STRING "TinyUSB RNDIS" +#endif + #ifndef CONFIG_TUSBD_VENDOR_STRING #define CONFIG_TUSBD_VENDOR_STRING "TinyUSB Vendor" #endif @@ -602,6 +682,23 @@ char const* tusb_string_desc_array[] = { #if CONFIG_TUSBD_VENDOR_NUMOF CONFIG_TUSBD_VENDOR_STRING, /* Vendor Interface */ #endif + +#if CONFIG_TUSBD_NET_NUMOF +#if CONFIG_TUSBD_NET_CDC_ECM +CONFIG_TUSBD_CDC_ECM_STRING, /* CDC ECM Interface */ +#endif /* CONFIG_TUSBD_NET_CDC_ECM */ +#if CONFIG_TUSBD_NET_CDC_NCM +CONFIG_TUSBD_CDC_NCM_STRING, /* CDC NCM Interface */ +#endif /* CONFIG_TUSBD_NET_CDC_NCM */ +#if CONFIG_TUSBD_NET_RNDIS +CONFIG_TUSBD_RNDIS_STRING, /* RNDIS Interface */ +#endif /* CONFIG_TUSBD_NET_RNDIS */ +#ifdef CONFIG_TUSBD_NET_CUSTOM_MAC + CONFIG_TUSBD_NET_MAC_STRING, /* NET Interface MAC address */ +#else + NULL, +#endif /* CONFIG_TUSBD_NET_CUSTOM_MAC */ +#endif /* CONFIG_TUSBD_NET_NUMOF */ }; static uint16_t _desc_str[32]; @@ -645,6 +742,21 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) } str = _serial_str; } +#if CONFIG_TUSBD_NET_NUMOF + else if ((index == TUSBD_STR_IDX_NET_MAC) && + (tusb_string_desc_array[index] == NULL)) { + /* generated MAC address string is used */ + static char mac_str[(ETHERNET_ADDR_LEN << 1) + 1] = { }; + if (strlen(mac_str) == 0) { + /* generate the serial string if it is not yet generated */ + uint8_t luid_buf[ETHERNET_ADDR_LEN]; + luid_get_eui48((eui48_t*)luid_buf); + fmt_bytes_hex(mac_str, luid_buf, sizeof(luid_buf)); + mac_str[(ETHERNET_ADDR_LEN << 1)] = 0; + } + str = mac_str; + } +#endif else { str = tusb_string_desc_array[index]; } @@ -667,4 +779,26 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) return _desc_str; } +#if !CONFIG_TUSBD_RNDIS +__attribute__((weak)) +void rndis_class_set_handler(uint8_t *data, int size) +{ + (void)data; + (void)size; +} + +__attribute__((weak)) +void tud_network_init_cb(void) +{ + printf("tud_network_init_cb"); +} + +__attribute__((weak)) +bool tud_network_recv_cb(const uint8_t *src, uint16_t size) +{ + printf("tud_network_init_cb %p %u", src, size); + return true; +} +#endif + #endif /* !defined(CONFIG_TUSBD_USE_CUSTOM_DESC) */ diff --git a/pkg/tinyusb/doc.txt b/pkg/tinyusb/doc.txt index 23a610309107..5c098f9dc0b7 100644 --- a/pkg/tinyusb/doc.txt +++ b/pkg/tinyusb/doc.txt @@ -5,7 +5,7 @@ * @author Gunar Schorcht * @see https://github.com/hathach/tinyusb * - * # TinyUSB + * # TinyUSB {#pkg_tinyusb} * * tinyUSB is an open-source cross-platform USB Host/Device stack for * embedded systems. @@ -94,6 +94,7 @@ * - up to two interfaces of the Generic In/Out HID class, * - up to one DFU interface * - up to one MSC device interface and, + * - up to one Net device interface with CDC ECM, CDC NCM and RNDIS protocol, and * - up to one interface of the Vendor device class. * * Any other combination, either a different number of these device class diff --git a/pkg/tinyusb/netdev/Kconfig b/pkg/tinyusb/netdev/Kconfig new file mode 100644 index 000000000000..b163156dc23f --- /dev/null +++ b/pkg/tinyusb/netdev/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2022 Gunar Schorcht +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +config MODULE_TINYUSB_NETDEV + bool "TinyUSB Network Device Driver" + depends on HAS_TINYUSB_DEVICE + depends on TEST_KCONFIG + select MODULE_LUID + select MODULE_NETDEV_ETH + select MODULE_TINYUSB_CLASS_NET + select MODULE_TINYUSB_DEVICE + select PACKAGE_TINYUSB diff --git a/pkg/tinyusb/netdev/Makefile b/pkg/tinyusb/netdev/Makefile new file mode 100644 index 000000000000..71cbcb865504 --- /dev/null +++ b/pkg/tinyusb/netdev/Makefile @@ -0,0 +1,3 @@ +MODULE = tinyusb_netdev + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/tinyusb/netdev/include/tinyusb_netdev.h b/pkg/tinyusb/netdev/include/tinyusb_netdev.h new file mode 100644 index 000000000000..c26e0cf149d4 --- /dev/null +++ b/pkg/tinyusb/netdev/include/tinyusb_netdev.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2022 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup pkg_tinyusb_netdev TinyUSB netdev driver + * @ingroup pkg_tinyusb + * @ingroup drivers_netdev + * @brief TinyUSB netdev driver for CDC ECM, CDC NCM and RNDIS protocol + * + * The tinyUSB netdev driver is part of the \ref pkg_tinyusb "tinyUSB package" + * and is enabled by module `tinyusb_netdev`. It is available for boards that + * provide the `tinyusb_device` feature. + * + * @note Since the tinyUSB package is distinct from (and incompatible with) + * the USB stack provided around USBUS in RIOT (see USB), the tinyUSB netdev + * driver cannot be used together with with any USBUS device class. + * + * The tinyUSB netdev driver uses Ethernet over USB and supports the following + * protocols: + * + * - CDC ECM (Ethernet Control Model) + * - CDC NCM (Network Control Model) + * - RNDIS (Microsoft Remote NDIS) + * + * While Linux and macOS support all these protocols, Microsoft Windows + * only supports the RNDIS protocol and since Windows version 11 also the + * CDC NCM protocol. macOS supports the RNDIS protocol since version 10.15 + * (Catalina). + * + * Which protocol is used is selected by the corresponding + * pseudomodules `tinyusb_class_net_cdc_ecm`, `tinyusb_class_net_cdc_ncm` + * and `tinyusb_class_net_rndis`. + * + * The CDC ECM protocol (`tinyusb_class_net_cdc_ecm`) and the RNDIS protocol + * (`tinyusb_class_net_rndis`) can be used simultaneously to support all + * operating systems, for example : + * ``` + * USEMODULE='tinyusb_netdev tinyusb_class_net_rndis tinyusb_class_net_cdc_ecm' \ + * BOARD=... make -C ... flash + * ``` + * In this case, the CDC ECM protocol is the default protocol and the RNDIS + * protocol the alternative protocol defined as second device configuration. + * + * The CDC NCM protocol cannot be used together with the CDC ECM or the RNDIS + * protocol. + * + * @{ + * @file + * @brief TinyUSB netdev driver for CDC ECM, CDC NCM and RNDIS protocol + * + * @author Gunar Schorcht + */ + +#ifndef TINYUSB_NETDEV_H +#define TINYUSB_NETDEV_H + +#include "net/ethernet.h" +#include "net/netdev.h" +#include "mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Device descriptor for tinyUSB CDC ECM network devices + */ +typedef struct { + netdev_t netdev; /**< netdev parent struct */ + uint8_t mac_addr[ETHERNET_ADDR_LEN]; /**< device MAC address */ + uint8_t mac_host[ETHERNET_ADDR_LEN]; /**< host MAC address */ + + uint16_t rx_len; /**< number of bytes received */ + uint16_t tx_len; /**< number of bytes in transmit buffer */ + + const uint8_t *rx_buf; /**< receive buffer in tinyUSB stack */ + uint8_t tx_buf[ETHERNET_MAX_LEN]; /**< transmit buffer */ + + mutex_t lock; /**< device is already in use */ +} tinyusb_netdev_t; + +#ifdef __cplusplus +} +#endif + +#endif /* TINYUSB_NETDEV_H */ +/** @} */ diff --git a/pkg/tinyusb/netdev/tinyusb_netdev.c b/pkg/tinyusb/netdev/tinyusb_netdev.c new file mode 100644 index 000000000000..cfaf913e2bae --- /dev/null +++ b/pkg/tinyusb/netdev/tinyusb_netdev.c @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2022 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup pkg_tinyusb + * @{ + * @file TinyUSB Netdev implementation for CDC Ethernet Control Model + * + * @author Gunar Schorcht + * @} + */ + +#define USB_H_USER_IS_RIOT_INTERNAL + +#include "kernel_defines.h" +#include "iolist.h" +#include "net/eui_provider.h" +#include "net/netdev/eth.h" +#include "od.h" + +#include "device/usbd.h" +#include "class/net/net_device.h" + +#include "tinyusb_netdev.h" + +#define ENABLE_DEBUG_HEXDUMP 0 +#define ENABLE_DEBUG 0 +#include "debug.h" + +/* The symbol is needed by the tinyUSB stack but not used and shall be removed + * later on, see: https://github.com/hathach/tinyusb/issues/718 */ +const uint8_t tud_network_mac_address[6] = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; + +static const netdev_driver_t _tusb_driver; +tinyusb_netdev_t tinyusb_netdev; + +void tinyusb_netdev_setup(tinyusb_netdev_t *dev) +{ + DEBUG("[tinyusb_netdev] %s: %p\n", __func__, dev); + + mutex_init(&dev->lock); + dev->netdev.driver = &_tusb_driver; + dev->rx_len = 0; + dev->tx_len = 0; + netdev_register(&dev->netdev, NETDEV_TINYUSB, 0); +} + +static int _send(netdev_t *netdev, const iolist_t *iolist) +{ + DEBUG("[tinyusb_netdev] %s: %p %p\n", __func__, netdev, iolist); + + tinyusb_netdev_t *dev = (tinyusb_netdev_t *)netdev; + + assert(dev == &tinyusb_netdev); + assert(iolist); + + if (!tud_ready()) { + return -EBUSY; + } + + mutex_lock(&dev->lock); + + dev->tx_len = 0; + + /* load packet data into TX buffer */ + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + if (dev->tx_len + iol->iol_len > ETHERNET_MAX_LEN) { + mutex_unlock(&dev->lock); + return -EOVERFLOW; + } + if (iol->iol_len) { + memcpy (dev->tx_buf + dev->tx_len, iol->iol_base, iol->iol_len); + dev->tx_len += iol->iol_len; + } + } + + if (IS_ACTIVE(ENABLE_DEBUG)) { + printf("[tinyusb_netdev] %s: send %d byte from %p\n", + __func__, dev->tx_len, dev->tx_buf); + if (IS_ACTIVE(ENABLE_DEBUG_HEXDUMP) && IS_USED(MODULE_OD)) { + od_hex_dump(dev->tx_buf, dev->tx_len, OD_WIDTH_DEFAULT); + } + } + + mutex_unlock(&dev->lock); + + /* if the network driver can accept another packet, trigger the send */ + if (tud_network_can_xmit(dev->tx_len)) + { + tud_network_xmit(dev->tx_buf, dev->tx_len); + return 0; + } + + return -EBUSY; +} + +static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) +{ + (void)info; + + DEBUG("[tinyusb_netdev] %s: %p %p %u %p\n", __func__, netdev, buf, len, info); + + tinyusb_netdev_t *dev = (tinyusb_netdev_t *)netdev; + assert(dev == &tinyusb_netdev); + + mutex_lock(&dev->lock); + + int size = dev->rx_len; + + if (!buf) { + /* get the size of the frame; if len > 0 then also drop the frame */ + if (len > 0) { + /* drop frame requested */ + dev->rx_len = 0; + } + mutex_unlock(&dev->lock); + return size; + } + + if (dev->rx_len > len) { + /* buffer is smaller than the number of received bytes */ + DEBUG("[tinyusb_netdev] %s: Not enough space in receive buffer for %d bytes\n", + __func__, dev->rx_len); + mutex_unlock(&dev->lock); + return -ENOBUFS; + } + + if (IS_ACTIVE(ENABLE_DEBUG)) { + printf ("[tinyusb_netdev] %s: received %d byte\n", __func__, dev->rx_len); + if (IS_ACTIVE(ENABLE_DEBUG) && IS_USED(MODULE_OD)) { + od_hex_dump(dev->rx_buf, dev->rx_len, OD_WIDTH_DEFAULT); + } + } + + /* copy received date and reset the receive length */ + memcpy(buf, dev->rx_buf, dev->rx_len); + dev->rx_len = 0; + mutex_unlock(&dev->lock); + + /* indicate that receiving the frame has been finished */ + tud_network_recv_renew(); + + return size; +} + +static int _init(netdev_t *netdev) +{ + DEBUG("[tinyusb_netdev] %s: %p\n", __func__, netdev); + + tinyusb_netdev_t *dev = (tinyusb_netdev_t *)netdev; + assert(dev == &tinyusb_netdev); + + netdev_eui48_get(netdev, (eui48_t*)&dev->mac_addr); + netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP); + + return 0; +} + +static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len) +{ + DEBUG("[tinyusb_netdev] %s: %p %u %p %u\n", + __func__, netdev, opt, value, max_len); + + tinyusb_netdev_t *dev = (tinyusb_netdev_t *)netdev; + assert(dev == &tinyusb_netdev); + + (void)max_len; + + switch (opt) { + case NETOPT_ADDRESS: + assert(max_len >= ETHERNET_ADDR_LEN); + memcpy(value, dev->mac_addr, ETHERNET_ADDR_LEN); + return ETHERNET_ADDR_LEN; + default: + return netdev_eth_get(netdev, opt, value, max_len); + } +} + +static int _set(netdev_t *netdev, netopt_t opt, + const void *value, size_t len) +{ + DEBUG("[tinyusb_netdev] %s: %p %u %p %u\n", + __func__, netdev, opt, value, len); + + tinyusb_netdev_t *dev = (tinyusb_netdev_t *)netdev; + assert(dev == &tinyusb_netdev); + + switch (opt) { + case NETOPT_ADDRESS: + assert(len == ETHERNET_ADDR_LEN); + memcpy(dev->mac_addr, value, ETHERNET_ADDR_LEN); + return ETHERNET_ADDR_LEN; + default: + return netdev_eth_set(&dev->netdev, opt, value, len); + } +} + +static void _isr(netdev_t *netdev) +{ + tinyusb_netdev_t *dev = (tinyusb_netdev_t *)netdev; + assert(dev == &tinyusb_netdev); + + if (dev->rx_len) { + dev->netdev.event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); + } +} + +static const netdev_driver_t _tusb_driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .set = _set, +}; + +void tud_network_init_cb(void) +{ + DEBUG("[tinyusb_netdev] %s\n", __func__); + tinyusb_netdev.rx_len = 0; + tinyusb_netdev.tx_len = 0; +} + +bool tud_network_recv_cb(const uint8_t *src, uint16_t size) +{ + DEBUG("[tinyusb_netdev] %s: %p %u\n", __func__, src, size); + + /* if the previous packet is not handled just return with false */ + if (tinyusb_netdev.rx_len) { + return false; + } + + assert(size <= ETHERNET_MAX_LEN); + + if (size) + { + tinyusb_netdev.rx_buf = src; + tinyusb_netdev.rx_len = size; + } + + netdev_trigger_event_isr(&tinyusb_netdev.netdev); + + return true; +} + +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) +{ + DEBUG("[tinyusb_netdev] %s: %p %p %u\n", __func__, dst, ref, arg); + + memcpy(dst, ref, arg); + return arg; +} diff --git a/pkg/tinyusb/patches/0004-lib-networking-remove-include-of-lwIP-netif-ethernet.patch b/pkg/tinyusb/patches/0004-lib-networking-remove-include-of-lwIP-netif-ethernet.patch new file mode 100644 index 000000000000..5df5b039e3c6 --- /dev/null +++ b/pkg/tinyusb/patches/0004-lib-networking-remove-include-of-lwIP-netif-ethernet.patch @@ -0,0 +1,25 @@ +From dd97024edcb32e1a2c417c5a6aca02994a4277bc Mon Sep 17 00:00:00 2001 +From: Gunar Schorcht +Date: Thu, 10 Nov 2022 16:40:08 +0100 +Subject: [PATCH 4/4] lib/networking: remove include of lwIP netif/ethernet.h + +lwIP is not used in RIOT +--- + lib/networking/rndis_reports.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/networking/rndis_reports.c b/lib/networking/rndis_reports.c +index ee611c883..d1a563f0c 100644 +--- a/lib/networking/rndis_reports.c ++++ b/lib/networking/rndis_reports.c +@@ -31,7 +31,6 @@ + #include + #include "class/net/net_device.h" + #include "rndis_protocol.h" +-#include "netif/ethernet.h" + + #define RNDIS_LINK_SPEED 12000000 /* Link baudrate (12Mbit/s for USB-FS) */ + #define RNDIS_VENDOR "TinyUSB" /* NIC vendor name */ +-- +2.17.1 + diff --git a/sys/net/gnrc/netif/init_devs/auto_init_tinyusb_netdev.c b/sys/net/gnrc/netif/init_devs/auto_init_tinyusb_netdev.c new file mode 100644 index 000000000000..aece7bc08b55 --- /dev/null +++ b/sys/net/gnrc/netif/init_devs/auto_init_tinyusb_netdev.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 Koen Zandberg + * 2022 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + * + */ + +/** + * @ingroup sys_auto_init_gnrc_netif + * @{ + * + * @file + * @brief Auto initialization for tinyUSB CDC ECM module + * + * @author Koen Zandberg + * @author Gunar Schorcht + */ + +#define USB_H_USER_IS_RIOT_INTERNAL + +#include "include/init_devs.h" +#include "log.h" +#include "net/gnrc/netif/ethernet.h" +#include "tinyusb_netdev.h" + +/** + * @brief global cdc ecm object, declared in the usb auto init file + */ +extern tinyusb_netdev_t tinyusb_netdev; + +/** + * @brief Define stack parameters for the MAC layer thread + * @{ + */ +#define TUSB_NETDEV_STACKSIZE (GNRC_NETIF_STACKSIZE_DEFAULT) +#ifndef TUSB_NETDEV_PRIO +#define TUSB_NETDEV_PRIO (GNRC_NETIF_PRIO) +#endif + +/** + * @brief Stacks for the MAC layer threads + */ +static char _netdev_eth_stack[TUSB_NETDEV_STACKSIZE]; +static gnrc_netif_t _netif; + +extern void tinyusb_netdev_setup(tinyusb_netdev_t *dev); + +void auto_init_tinyusb_netdev(void) +{ + LOG_DEBUG("[auto_init_netif] initializing tinyUSB netdev #0\n"); + + tinyusb_netdev_setup(&tinyusb_netdev); + /* initialize netdev<->gnrc adapter state */ + gnrc_netif_ethernet_create(&_netif, _netdev_eth_stack, + TUSB_NETDEV_STACKSIZE, TUSB_NETDEV_PRIO, + "tinyusb_netdev", &tinyusb_netdev.netdev); +} +/** @} */ diff --git a/sys/net/gnrc/netif/init_devs/init.c b/sys/net/gnrc/netif/init_devs/init.c index 67df6e0a1a72..8360365cbf02 100644 --- a/sys/net/gnrc/netif/init_devs/init.c +++ b/sys/net/gnrc/netif/init_devs/init.c @@ -171,4 +171,10 @@ void gnrc_netif_init_devs(void) extern void auto_init_sx126x(void); auto_init_sx126x(); } + + if (IS_USED(MODULE_TINYUSB_NETDEV)) { + extern void auto_init_tinyusb_netdev(void); + auto_init_tinyusb_netdev(); + } + } diff --git a/tests/pkg_tinyusb_netdev/Makefile b/tests/pkg_tinyusb_netdev/Makefile new file mode 100644 index 000000000000..9938a3fb7169 --- /dev/null +++ b/tests/pkg_tinyusb_netdev/Makefile @@ -0,0 +1,21 @@ +BOARD ?= samr21-xpro + +include ../Makefile.tests_common + +USB_VID ?= $(USB_VID_TESTING) +USB_PID ?= $(USB_PID_TESTING) + +CLASS ?= tinyusb_class_net_rndis + +USEPKG += tinyusb + +USEMODULE += auto_init_gnrc_netif +USEMODULE += gnrc_ipv6_router_default +USEMODULE += gnrc_icmpv6_echo +USEMODULE += shell +USEMODULE += shell_cmds_default +USEMODULE += ps +USEMODULE += tinyusb_netdev +USEMODULE += $(CLASS) + +include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_tinyusb_netdev/Makefile.ci b/tests/pkg_tinyusb_netdev/Makefile.ci new file mode 100644 index 000000000000..7e8de47c599e --- /dev/null +++ b/tests/pkg_tinyusb_netdev/Makefile.ci @@ -0,0 +1,3 @@ +BOARD_INSUFFICIENT_MEMORY := \ + stm32f7508-dk \ + # diff --git a/tests/pkg_tinyusb_netdev/README.md b/tests/pkg_tinyusb_netdev/README.md new file mode 100644 index 000000000000..239d947908a2 --- /dev/null +++ b/tests/pkg_tinyusb_netdev/README.md @@ -0,0 +1,54 @@ +Overview +======== + +This test application can be used to check the implementation of the tinyUSB +netdev driver. The implementation of the tinyUSB netdev driver uses Ethernet +over USB and supports the following protocols: + +- CDC ECM (Ethernet Control Model) +- CDC NCM (Network Control Model) +- RNDIS (Microsoft Remote NDIS) + +While Linux and macOS support all these protocols, Microsoft Windows only +supports RNDIS and since Windows version 11 also CDC NCM. Which protocol is +used is selected by the corresponding pseudomodules `tinyusb_class_net_cdc_ecm`, +`tinyusb_class_net_cdc_ncm` and `tinyusb_class_net_rndis`. + +Configuration +============= +The test application use the protocol defined by the CLASS variable, which +defaults to the RNDIS protocol (`tinyusb_class_net_rndis`). This can be +changed by setting this variable in the make command line, for example: +``` +CLASS=tinyusb_class_net_cdc_ecm BOARD=... make -C tests/pkg_tinyusb_netdev flash +``` +The CDC ECM protocol (`tinyusb_class_net_cdc_ecm`) and the RNDIS protocol +(`tinyusb_class_net_rndis`) can be used simultaneously to support all operating +systems, for example : +``` +CLASS='tinyusb_class_net_rndis tinyusb_class_net_cdc_ecm' \ +BOARD=... make -C tests/pkg_tinyusb_netdev flash +``` +In this case, the CDC ECM protocol is the default protocol and the RNDIS +protocol the alternative protocol defined as second device configuration. + +The CDC NCM protocol cannot be used together with the CDC ECM or the RNDIS +protocol + +Expected result +=============== + +Use the network related shell commands to verify the network link between the +board under test and the host computer. Ping to the link local address from and +to the host computer must work. + +On the host computer, using tools such as `ethtool` must show the USB CDC ECM +interface as link detected: + +``` +# ethtool enp0s20u9u4 +Settings for enp0s20u9u4: + Current message level: 0x00000007 (7) + drv probe link + Link detected: yes +``` diff --git a/tests/pkg_tinyusb_netdev/main.c b/tests/pkg_tinyusb_netdev/main.c new file mode 100644 index 000000000000..2f2744d2442e --- /dev/null +++ b/tests/pkg_tinyusb_netdev/main.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 Koen Zandberg + * 2022 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Test application for the tinyUSB netdev + * + * @author Koen Zandberg + * @author Gunar Schorcht + * + * @} + */ + +#include + +#include "shell.h" +#include "msg.h" + +#define MAIN_QUEUE_SIZE (8U) +static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; + +int main(void) +{ + /* we need a message queue for the thread running the shell in order to + * receive potentially fast incoming networking packets */ + msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); + puts("Test application for the tinyUSB net device interface\n"); + puts("This test pulls in parts of the GNRC network stack, use the\n" + "provided shell commands (i.e. ifconfig, ping) to interact with\n" + "the tinyUSB based network interface.\n"); + + /* start shell */ + puts("Starting the shell now..."); + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); + + /* should be never reached */ + return 0; +}