diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 20c10b932a5e7..27ec3166c8746 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -80,10 +80,9 @@ INC += -I$(TOP)/lib/tinyusb/src INC += -I$(TOP)/shared/tinyusb INC += -I. INC += -Ihal - -# All settings for Ethernet support are controller by the value of MICROPY_PY_LWIP -ifeq ($(MICROPY_PY_LWIP),1) INC += -Ilwip_inc + +ifeq ($(MICROPY_HW_ETHERNET),1) INC += -Ihal/phy endif @@ -106,8 +105,10 @@ SRC_TINYUSB_C += \ lib/tinyusb/src/portable/chipidea/ci_hs/dcd_ci_hs.c \ lib/tinyusb/src/tusb.c -# All settings for Ethernet support are controller by the value of MICROPY_PY_LWIP -ifeq ($(MICROPY_PY_LWIP),1) +# All settings for Ethernet support are controlled by the value of MICROPY_HW_ETHERNET +ifeq ($(MICROPY_HW_ETHERNET),1) +MICROPY_PY_LWIP = 1 + SRC_ETH_C += \ $(MCUX_SDK_DIR)/drivers/enet/fsl_enet.c \ hal/phy/device/phydp83825/fsl_phydp83825.c \ @@ -281,6 +282,7 @@ SHARED_SRC_C += \ shared/timeutils/timeutils.c \ shared/tinyusb/mp_usbd.c \ shared/tinyusb/mp_usbd_cdc.c \ + shared/tinyusb/mp_usbd_net.c \ shared/tinyusb/mp_usbd_descriptor.c \ # Set flash driver name, base address and internal flash flag, based on the flash type. @@ -447,8 +449,8 @@ else endif -# All settings for Ethernet support are controller by the value of MICROPY_PY_LWIP -ifeq ($(MICROPY_PY_LWIP),1) +# All settings for Ethernet support are controlled by the value of MICROPY_HW_ETHERNET +ifeq ($(MICROPY_HW_ETHERNET),1) CFLAGS += \ -DFSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE=1 endif @@ -470,7 +472,8 @@ LDFLAGS += \ --gc-sections \ --print-memory-usage \ -Map=$@.map \ - --wrap=LPUART_TransferHandleIRQ + --wrap=LPUART_TransferHandleIRQ \ + --wrap=dcd_event_handler # LDDEFINES are used for link time adaptation of linker scripts, utilizing # the C preprocessor. Therefore keep LDDEFINES separated from LDFLAGS! diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk index dd525859063d9..b64b37c01acc3 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk @@ -5,6 +5,8 @@ MICROPY_FLOAT_IMPL = single MICROPY_HW_FLASH_TYPE = qspi_nor_flash MICROPY_HW_FLASH_SIZE = 0x1000000 # 16MB +MICROPY_PY_LWIP = 0 + JLINK_PATH ?= /media/RT1010-EVK/ JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index c98843a1a3c3d..3f3507bd24dd6 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -8,7 +8,8 @@ MICROPY_HW_FLASH_SIZE = 0x800000 # 8MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB -MICROPY_PY_LWIP = 1 +MICROPY_HW_ETHERNET = 1 + MICROPY_PY_SSL = 1 MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk index ef7bbc8f56cb9..958b794f8221e 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.mk @@ -8,7 +8,7 @@ MICROPY_HW_FLASH_SIZE = 0x4000000 # 64MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB -MICROPY_PY_LWIP = 1 +MICROPY_HW_ETHERNET = 1 MICROPY_PY_SSL = 1 MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index 3af7cd231a2ab..06dc0390782db 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -8,7 +8,7 @@ MICROPY_HW_FLASH_SIZE = 0x800000 # 8MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB -MICROPY_PY_LWIP = 1 +MICROPY_HW_ETHERNET = 1 MICROPY_PY_SSL = 1 MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk index 95cfb4585acc1..7a81eb18f4cec 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.mk @@ -8,7 +8,7 @@ MICROPY_HW_FLASH_SIZE = 0x400000 # 4MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB -MICROPY_PY_LWIP = 1 +MICROPY_HW_ETHERNET = 1 MICROPY_PY_SSL = 1 MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/boards/MIMXRT1170_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1170_EVK/mpconfigboard.mk index 6e5ee56aa1081..be1f63deb65ea 100644 --- a/ports/mimxrt/boards/MIMXRT1170_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1170_EVK/mpconfigboard.mk @@ -10,7 +10,7 @@ MICROPY_HW_FLASH_RESERVED ?= 0x100000 # 1MB CM4 Code address space MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x4000000 # 64MB -MICROPY_PY_LWIP = 1 +MICROPY_HW_ETHERNET = 1 MICROPY_PY_SSL = 1 MICROPY_SSL_MBEDTLS = 1 MICROPY_PY_OPENAMP = 1 diff --git a/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk b/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk index d06e764bb69a5..4c9b3993a383d 100644 --- a/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk +++ b/ports/mimxrt/boards/SEEED_ARCH_MIX/mpconfigboard.mk @@ -8,7 +8,7 @@ MICROPY_HW_FLASH_SIZE = 0x800000 # 8MB MICROPY_HW_SDRAM_AVAIL = 1 MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB -MICROPY_PY_LWIP = 1 +MICROPY_HW_ETHERNET = 1 MICROPY_PY_SSL = 1 MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk index b297448a307e7..4afe9fb80f0bf 100755 --- a/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk +++ b/ports/mimxrt/boards/TEENSY41/mpconfigboard.mk @@ -6,7 +6,7 @@ MICROPY_HW_FLASH_TYPE = qspi_nor_flash MICROPY_HW_FLASH_SIZE = 0x800000 # 8MB MICROPY_HW_FLASH_RESERVED ?= 0x1000 # 4KB -MICROPY_PY_LWIP = 1 +MICROPY_HW_ETHERNET = 1 MICROPY_PY_SSL = 1 MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/mimxrt/modules/_boot.py b/ports/mimxrt/modules/_boot.py index fa3b780434a43..2bd56cd244ab5 100644 --- a/ports/mimxrt/modules/_boot.py +++ b/ports/mimxrt/modules/_boot.py @@ -6,7 +6,7 @@ import vfs import sys import mimxrt -from machine import Pin +from machine import Pin, UART bdev = mimxrt.Flash() try: @@ -19,6 +19,9 @@ sys.path.append("/flash") sys.path.append("/flash/lib") +os.dupterm(UART(0)) + + # do not mount the SD card if SKIPSD exists. try: os.stat("SKIPSD") diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 0e872a92349c2..f45d884c68a5f 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -152,6 +152,7 @@ uint32_t trng_random_u32(void); #define MICROPY_HW_ENABLE_USBDEV (1) #define MICROPY_HW_USB_CDC (1) +// #define MICROPY_HW_USB_NET (1) // Hooks to add builtins diff --git a/shared/tinyusb/mp_usbd.h b/shared/tinyusb/mp_usbd.h index 5c8f2a6095f30..c6dca12338ad7 100644 --- a/shared/tinyusb/mp_usbd.h +++ b/shared/tinyusb/mp_usbd.h @@ -35,6 +35,10 @@ #include "py/objarray.h" #include "py/runtime.h" +#if MICROPY_HW_USB_NET +#include "mp_usbd_net.h" +#endif + #ifndef NO_QSTR #include "tusb.h" #include "device/dcd.h" @@ -45,6 +49,10 @@ static inline void mp_usbd_init_tud(void) { tusb_init(); tud_cdc_configure_fifo_t cfg = { .rx_persistent = 0, .tx_persistent = 1 }; tud_cdc_configure_fifo(&cfg); + + #if MICROPY_HW_USB_NET + mp_usbd_net_init(); + #endif } // Run the TinyUSB device task @@ -64,9 +72,15 @@ void mp_usbd_hex_str(char *out_str, const uint8_t *bytes, size_t bytes_len); // Length of built-in configuration descriptor #define MP_USBD_BUILTIN_DESC_CFG_LEN (TUD_CONFIG_DESC_LEN + \ - (CFG_TUD_CDC ? (TUD_CDC_DESC_LEN) : 0) + \ - (CFG_TUD_MSC ? (TUD_MSC_DESC_LEN) : 0) \ - ) + (CFG_TUD_CDC ? (TUD_CDC_DESC_LEN) : 0) + \ + (CFG_TUD_MSC ? (TUD_MSC_DESC_LEN) : 0) + \ + (CFG_TUD_NCM ? (TUD_CDC_NCM_DESC_LEN) : 0) + \ + (CFG_TUD_ECM_RNDIS ? (TUD_RNDIS_DESC_LEN) : 0) \ +) + + +// Alternate config length used by ETH / ECM-RNDIS +#define MP_USBD_ALT_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) // Built-in USB device and configuration descriptor values extern const tusb_desc_device_t mp_usbd_builtin_desc_dev; diff --git a/shared/tinyusb/mp_usbd_descriptor.c b/shared/tinyusb/mp_usbd_descriptor.c index d0c8845b68087..634af948f3864 100644 --- a/shared/tinyusb/mp_usbd_descriptor.c +++ b/shared/tinyusb/mp_usbd_descriptor.c @@ -35,6 +35,7 @@ #define USBD_CDC_CMD_MAX_SIZE (8) #define USBD_CDC_IN_OUT_MAX_SIZE ((CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) ? 512 : 64) #define USBD_MSC_IN_OUT_MAX_SIZE ((CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) ? 512 : 64) +#define USBD_NET_IN_OUT_MAX_SIZE ((CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) ? 512 : 64) const tusb_desc_device_t mp_usbd_builtin_desc_dev = { .bLength = sizeof(tusb_desc_device_t), @@ -62,7 +63,16 @@ const uint8_t mp_usbd_builtin_desc_cfg[MP_USBD_BUILTIN_DESC_CFG_LEN] = { USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE), #endif #if CFG_TUD_MSC - TUD_MSC_DESCRIPTOR(USBD_ITF_MSC, USBD_STR_MSC, EPNUM_MSC_OUT, EPNUM_MSC_IN, USBD_MSC_IN_OUT_MAX_SIZE), + TUD_MSC_DESCRIPTOR(USBD_ITF_MSC, USBD_STR_MSC, USBD_MSC_EP_OUT, USBD_MSC_EP_IN, USBD_MSC_IN_OUT_MAX_SIZE), + #endif + #if CFG_TUD_ECM_RNDIS + TUD_CONFIG_DESCRIPTOR(2, USBD_ITF_BUILTIN_MAX, USBD_STR_0, ALT_CONFIG_TOTAL_LEN, 0, USBD_MAX_POWER_MA), + // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. + TUD_CDC_ECM_DESCRIPTOR(USBD_ITF_ETH, USBD_STR_ETH, USBD_STR_ETH_MAC, USBD_NET_EP_CMD, 64, USBD_NET_EP_OUT, USBD_NET_EP_IN, USBD_NET_IN_OUT_MAX_SIZE, CFG_TUD_NET_MTU), + #endif + #if CFG_TUD_NCM + // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. + TUD_CDC_NCM_DESCRIPTOR(USBD_ITF_ETH, USBD_STR_ETH, USBD_STR_ETH_MAC, USBD_NET_EP_CMD, 64, USBD_NET_EP_OUT, USBD_NET_EP_IN, USBD_NET_IN_OUT_MAX_SIZE, CFG_TUD_NET_MTU), #endif }; @@ -115,6 +125,19 @@ const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { desc_str = MICROPY_HW_USB_MSC_INTERFACE_STRING; break; #endif + #if CFG_TUD_NCM || CFG_TUD_ECM_RNDIS + case USBD_STR_ETH: + desc_str = MICROPY_HW_USB_ETH_INTERFACE_STRING; + break; + case USBD_STR_ETH_MAC: + // Convert MAC address into UTF-16 + mp_usbd_hex_str(desc_str, (uint8_t *)tud_network_mac_address, sizeof(tud_network_mac_address)); + // for (unsigned i=0; i> 4) & 0xf]; + // desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; + // } + break; + #endif default: break; } diff --git a/shared/tinyusb/mp_usbd_net.c b/shared/tinyusb/mp_usbd_net.c new file mode 100644 index 0000000000000..131583f86660e --- /dev/null +++ b/shared/tinyusb/mp_usbd_net.c @@ -0,0 +1,149 @@ + + +#include "py/runtime.h" +#include "py/mphal.h" + +#if MICROPY_HW_USB_NET + +#include "tusb.h" +// #include "lwip/ethip6.h" +// #include "lwip/init.h" +// #include "lwip/timeouts.h" +#include "shared/netutils/netutils.h" +#include "extmod/modnetwork.h" + +#include "lwip/etharp.h" +#include "lwip/dns.h" +#include "lwip/dhcp.h" +#include "netif/ethernet.h" + +// typedef struct _eth_t { +// uint32_t trace_flags; +// struct netif netif_data; +// struct dhcp dhcp_struct; +// } eth_t; + +#define INIT_IP4(a, b, c, d) \ + { PP_HTONL(LWIP_MAKEU32(a, b, c, d)) } + +/* lwip context */ +static struct netif netif_data; + +/* shared between tud_network_recv_cb() and service_traffic() */ +static struct pbuf *received_frame; + +/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ +/* ideally speaking, this should be generated from the hardware's unique ID (if available) */ +/* it is suggested that the first byte is 0x02 to indicate a link-local address */ +uint8_t tud_network_mac_address[6] = {0x02, 0x02, 0x84, 0x6A, 0x96, 0x00}; + + +static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { + (void) netif; + + for (;;) { + /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ + if (!tud_ready()) + return ERR_USE; + + /* if the network driver can accept another packet, we make it happen */ + if (tud_network_can_xmit(p->tot_len)) { + tud_network_xmit(p, 0 /* unused for this example */); + return ERR_OK; + } + + /* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */ + tud_task(); + } +} + +static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) { + return etharp_output(netif, p, addr); +} + +#if LWIP_IPV6 +static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) { + return ethip6_output(netif, p, addr); +} +#endif + +static err_t netif_init_cb(struct netif *netif) { + LWIP_ASSERT("netif != NULL", (netif != NULL)); + netif->mtu = CFG_TUD_NET_MTU; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_NETARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->linkoutput = linkoutput_fn; + netif->output = ip4_output_fn; +#if LWIP_IPV6 + netif->output_ip6 = ip6_output_fn; +#endif + return ERR_OK; +} + + +bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { + /* this shouldn't happen, but if we get another packet before + parsing the previous, we must signal our inability to accept it */ + if (received_frame) return false; + + if (size) { + struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); + + if (p) { + /* pbuf_alloc() has already initialized struct; all we need to do is copy the data */ + memcpy(p->payload, src, size); + + /* store away the pointer for service_traffic() to later handle */ + received_frame = p; + } + } + + return true; +} + +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) { + struct pbuf *p = (struct pbuf *) ref; + + (void) arg; /* unused for this example */ + + return pbuf_copy_partial(p, dst, p->tot_len, 0); +} + +static void service_traffic(void) { + /* handle any packet received by tud_network_recv_cb() */ + if (received_frame) { + ethernet_input(received_frame, &netif_data); + pbuf_free(received_frame); + received_frame = NULL; + tud_network_recv_renew(); + } + + sys_check_timeouts(); +} + +void tud_network_init_cb(void) { + /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ + if (received_frame) { + pbuf_free(received_frame); + received_frame = NULL; + } +} + +void mp_usbd_net_init(void) { + MICROPY_PY_LWIP_ENTER + netif->hwaddr_len = sizeof(tud_network_mac_address); + memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address)); + netif->hwaddr[5] ^= 0x01; + + netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input); + #if LWIP_IPV6 + netif_create_ip6_linklocal_address(netif, 1); + #endif + netif_set_default(netif); + MICROPY_PY_LWIP_EXIT + +} + +#endif \ No newline at end of file diff --git a/shared/tinyusb/mp_usbd_net.h b/shared/tinyusb/mp_usbd_net.h new file mode 100644 index 0000000000000..ee807352a954c --- /dev/null +++ b/shared/tinyusb/mp_usbd_net.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Blake W. Felt & Angus Gratton + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_NET_H +#define MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_NET_H + +//-------------------------------------------------------------------- +// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNING +//-------------------------------------------------------------------- + +// Must be >> MTU +// Can be set to 2048 without impact +#define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) + +// Must be >> MTU +// Can be set to smaller values if wNtbOutMaxDatagrams==1 +#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) + +// Number of NCM transfer blocks for reception side +#ifndef CFG_TUD_NCM_OUT_NTB_N + #define CFG_TUD_NCM_OUT_NTB_N 1 +#endif + +// Number of NCM transfer blocks for transmission side +#ifndef CFG_TUD_NCM_IN_NTB_N + #define CFG_TUD_NCM_IN_NTB_N 1 +#endif + +void mp_usbd_net_init(void); + + +#endif // MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_NET_H diff --git a/shared/tinyusb/tusb_config.h b/shared/tinyusb/tusb_config.h index 0cc5ef03985ef..b8240fb6dcbd6 100644 --- a/shared/tinyusb/tusb_config.h +++ b/shared/tinyusb/tusb_config.h @@ -94,16 +94,40 @@ #define CFG_TUD_MSC_BUFSIZE (MICROPY_FATFS_MAX_SS) #endif +#if MICROPY_HW_USB_NET +// TinyUSB supports both RNDIS and NCM protocols. +// RNDIS is older, NCM is now reccomended by Microsoft on Win 11 and above. +// Enable NCM unless MICROPY_HW_USB_NET_RNDIS is set. +#if MICROPY_HW_USB_NET_RNDIS +#define CFG_TUD_ECM_RNDIS (1) +#else +#define CFG_TUD_NCM (1) +#endif +#include "mp_usbd_net.h" +#ifndef MICROPY_HW_USB_NET_INTERFACE_STRING +#define MICROPY_HW_USB_NET_INTERFACE_STRING "Board ETH" +#endif +#else +#define CFG_TUD_ECM_RNDIS (0) +#define CFG_TUD_NCM (0) +#endif + #define USBD_RHPORT (0) // Currently only one port is supported // Define built-in interface, string and endpoint numbering based on the above config -#define USBD_STR_0 (0x00) -#define USBD_STR_MANUF (0x01) -#define USBD_STR_PRODUCT (0x02) -#define USBD_STR_SERIAL (0x03) -#define USBD_STR_CDC (0x04) -#define USBD_STR_MSC (0x05) +enum _USBD_STR { + + USBD_STR_0 = (0x00), + USBD_STR_MANUF = (0x01), + USBD_STR_PRODUCT = (0x02), + USBD_STR_SERIAL = (0x03), + USBD_STR_CDC, + USBD_STR_MSC, + USBD_STR_NET, + USBD_STR_NET_MAC, + USBD_STR_BUILTIN_MAX, +}; #define USBD_MAX_POWER_MA (250) @@ -111,41 +135,101 @@ #define MICROPY_HW_USB_DESC_STR_MAX (40) #endif -#if CFG_TUD_CDC -#define USBD_ITF_CDC (0) // needs 2 interfaces -#define USBD_CDC_EP_CMD (0x81) -#define USBD_CDC_EP_OUT (0x02) -#define USBD_CDC_EP_IN (0x82) -#endif // CFG_TUD_CDC - -#if CFG_TUD_MSC -// Interface & Endpoint numbers for MSC come after CDC, if it is enabled -#if CFG_TUD_CDC -#define USBD_ITF_MSC (2) -#define EPNUM_MSC_OUT (0x03) -#define EPNUM_MSC_IN (0x83) -#else -#define USBD_ITF_MSC (0) -#define EPNUM_MSC_OUT (0x01) -#define EPNUM_MSC_IN (0x81) -#endif // CFG_TUD_CDC -#endif // CFG_TUD_MSC +enum _USBD_ITF { + #if CFG_TUD_CDC + USBD_ITF_CDC, + USBD_ITF_CDC_I2, + #endif // CFG_TUD_CDC + #if CFG_TUD_MSC + USBD_ITF_MSC, + #endif // CFG_TUD_MSC + #if CFG_TUD_NCM || CFG_TUD_ECM_RNDIS + USBD_ITF_NET, + #endif +}; + +enum _USBD_EP { + __USBD_EP = 0x80, + #if CFG_TUD_CDC + USBD_CDC_EP_CMD, + USBD_CDC_EP_IN, + #endif // CFG_TUD_CDC + #if CFG_TUD_MSC + USBD_MSC_EP_IN, + #endif // CFG_TUD_MSC + #if CFG_TUD_NCM || CFG_TUD_ECM_RNDIS + USBD_NET_EP_CMD, + USBD_NET_EP_IN, + #endif // CFG_TUD_NET + USBD_EP_BUILTIN_MAX +}; + +// define the matching in endpoints to each EP_OUT +#define USBD_CDC_EP_OUT ((USBD_CDC_EP_IN) & ~TUSB_DIR_IN_MASK) +#define USBD_MSC_EP_OUT ((USBD_MSC_EP_IN) & ~TUSB_DIR_IN_MASK) +#define USBD_NET_EP_OUT ((USBD_NET_EP_IN) & ~TUSB_DIR_IN_MASK) + + +// #if CFG_TUD_CDC +// #define USBD_ITF_CDC (0) // needs 2 interfaces +// #define USBD_CDC_EP_CMD (0x81) +// #define USBD_CDC_EP_OUT (0x02) +// #define USBD_CDC_EP_IN (0x82) +// #endif // CFG_TUD_CDC + +// #if CFG_TUD_MSC +// // Interface & Endpoint numbers for MSC come after CDC, if it is enabled +// #if CFG_TUD_CDC +// #define USBD_ITF_MSC (2) +// #define USBD_MSC_EP_OUT (0x03) +// #define USBD_MSC_EP_IN (0x83) +// #else +// #define USBD_ITF_MSC (0) +// #define USBD_MSC_EP_OUT (0x01) +// #define USBD_MSC_EP_IN (0x81) +// #endif // CFG_TUD_CDC +// #endif // CFG_TUD_MSC /* Limits of builtin USB interfaces, endpoints, strings */ -#if CFG_TUD_MSC -#define USBD_ITF_BUILTIN_MAX (USBD_ITF_MSC + 1) -#define USBD_STR_BUILTIN_MAX (USBD_STR_MSC + 1) -#define USBD_EP_BUILTIN_MAX (EPNUM_MSC_OUT + 1) -#elif CFG_TUD_CDC -#define USBD_ITF_BUILTIN_MAX (USBD_ITF_CDC + 2) -#define USBD_STR_BUILTIN_MAX (USBD_STR_CDC + 1) -#define USBD_EP_BUILTIN_MAX (((USBD_CDC_EP_IN)&~TUSB_DIR_IN_MASK) + 1) -#else // !CFG_TUD_MSC && !CFG_TUD_CDC -#define USBD_ITF_BUILTIN_MAX (0) -#define USBD_STR_BUILTIN_MAX (0) -#define USBD_EP_BUILTIN_MAX (0) +// 1 plus the number of interfaces used by all enabled classes +#define USBD_ITF_BUILTIN_MAX 1 + \ + (CFG_TUD_MSC ? 1 : 0) + \ + (CFG_TUD_CDC ? 2 : 0) + \ + (CFG_TUD_ECM_RNDIS ? 2 : 0) + \ + (CFG_TUD_NCM ? 1 : 0) + +// 1 plus the max index of the string table used +#if 0 +#define USBD_STR_BUILTIN_MAX 1 + \ + (CFG_TUD_MSC ? USBD_STR_MSC : 0) + \ + (CFG_TUD_CDC ? USBD_STR_CDC : 0) + \ + (CFG_TUD_ECM_RNDIS ? USBD_STR_NET_MAC : 0) + \ + (CFG_TUD_NCM ? USBD_STR_NET_MAC : 0) #endif +// 1 plus the number of interfaces used by all enabled classes +#define USBD_EP_BUILTIN_MAX 1 + \ + (CFG_TUD_MSC ? 1 : 0) + \ + (CFG_TUD_CDC ? 2 : 0) + \ + (CFG_TUD_ECM_RNDIS ? 2 : 0) + \ + (CFG_TUD_NCM ? 2 : 0) + + +// #define USBD_EP_BUILTIN_MAX (USBD_MSC_EP_OUT + 1) + + +// #elif CFG_TUD_CDC +// #define USBD_ITF_BUILTIN_MAX (USBD_ITF_CDC + 2) +// #define USBD_STR_BUILTIN_MAX (USBD_STR_CDC + 1) +// #define USBD_EP_BUILTIN_MAX (((USBD_CDC_EP_IN)&~TUSB_DIR_IN_MASK) + 1) + + +// #else // !CFG_TUD_MSC && !CFG_TUD_CDC +// #define USBD_ITF_BUILTIN_MAX (0) +// #define USBD_STR_BUILTIN_MAX (0) +// #define USBD_EP_BUILTIN_MAX (0) +// #endif + #endif // MICROPY_HW_ENABLE_USBDEV #endif // MICROPY_INCLUDED_SHARED_TINYUSB_TUSB_CONFIG_H