Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Documentation/components/drivers/special/usbhost.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,37 @@ USB Host-Side Drivers
**Examples**: See the call to ``register_blockdriver()`` in
the function ``usbhost_initvolume()`` in the file
``drivers/usbhost/usbhost_storage.c``.

CDC-ECM Host Class Driver
=========================

The CDC-ECM (Ethernet Control Model) host class driver
(``drivers/usbhost/usbhost_cdcecm.c``) supports USB devices that expose
a network interface using the USB Communications Device Class Ethernet
Control Model. Common device types include:

- **USB-to-Ethernet adapters** that implement CDC-ECM, providing wired
Ethernet connectivity over a USB port.

- **Cellular modems and similar devices** that expose a CDC-ECM
interface for IP connectivity, such as LTE modems operating in USB
tethering mode.

When a compatible device is connected and enumerated, the driver
registers a standard NuttX Ethernet network interface — for example
``eth0`` — and integrates with the NuttX networking stack in exactly the
same way as any on-board Ethernet driver. Normal network configuration
can then be applied to the interface using standard NSH commands::

ifup eth0
ifconfig eth0 192.168.1.10 netmask 255.255.255.0

Or with DHCP via the ``netinit`` daemon when
``CONFIG_NETINIT_DHCPC=y`` is selected.

The driver is registered by calling ``usbhost_cdcecm_initialize()``
during board initialization, before the USB host waiter thread begins
enumerating devices.

**Examples**: ``drivers/usbhost/usbhost_cdcecm.c``,
``boards/arm/stm32h5/nucleo-h563zi/configs/nshusbnet/defconfig``.
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,75 @@ This configuration configures the digital temperature sensor (DTS)
at /dev/uorb/sensor_temp0 and provides the test application
sensortest. E.g. sensortest -n 10 temp0

usbmsc:
--------

This configuration enables USB Host support with the Mass Storage Class
(MSC) driver. It is intended to test USB Host operation by connecting a
USB mass-storage device (e.g. a USB flash drive) to the board's USB-C
connector. Key options enabled:

- ``CONFIG_STM32H5_USBFS_HOST`` — STM32H5 USB full-speed host controller
- ``CONFIG_USBHOST_MSC`` — USB Mass Storage Class host driver
- ``CONFIG_USBHOST_HUB`` — USB hub support
- ``CONFIG_FS_FAT`` — FAT filesystem for mounting the storage device

The serial console remains on USART3 (ST-Link VCOM). NSH
``ifup``/``ifdown`` commands are disabled because no network interface is
configured in this build.

.. note::

USB Host requires a stable 48 MHz clock. HSI48 is not accurate enough
for reliable USB operation, so this configuration uses the external
high-speed oscillator (HSE) as the USB clock source
(``CONFIG_STM32H5_USE_HSE=y``). On the Nucleo-H563ZI development board
HSE is not connected by default; to enable it you must:

- **Connect** solder bridges **SB3** and **SB4**
- **Disconnect** solder bridge **SB49**

The board also does not support software control of VBUS power. To
supply power to the USB host port, fit a second jumper on the **PWR SEL**
header that bridges the **STLK** and **USB USER** pins together.

nshusbnet:
-----------

This configuration is based on the standard ``nsh`` configuration but adds
full networking support and the CDC-ECM USB Ethernet host driver. It is
intended to test USB Host operation with a USB-to-Ethernet adapter that
uses the CDC-ECM (Ethernet Control Model) protocol. Key options enabled:

- ``CONFIG_STM32H5_USBFS_HOST`` — STM32H5 USB full-speed host controller
- ``CONFIG_USBHOST_CDCECM`` — USB CDC-ECM Ethernet host driver
- ``CONFIG_USBHOST_COMPOSITE`` — composite USB device support
- ``CONFIG_USBHOST_HUB`` — USB hub support
- ``CONFIG_NET``, ``CONFIG_NET_TCP``, ``CONFIG_NET_UDP`` — IPv4 networking stack
- ``CONFIG_NETINIT_DHCPC`` / ``CONFIG_NETUTILS_DHCPC`` — DHCP client for automatic IP configuration
- ``CONFIG_NETUTILS_TELNETD`` — Telnet daemon for remote NSH access
- ``CONFIG_SYSTEM_PING`` — ping utility for connectivity testing

Plug a CDC-ECM USB Ethernet adapter into the board's USB-C host port.
NuttX will enumerate the device, assign it a network interface, and obtain
an IP address via DHCP. The ``ping`` application can then be used to
verify network connectivity.

.. note::

USB Host requires a stable 48 MHz clock. HSI48 is not accurate enough
for reliable USB operation, so this configuration uses the external
high-speed oscillator (HSE) as the USB clock source
(``CONFIG_STM32H5_USE_HSE=y``). On the Nucleo-H563ZI development board
HSE is not connected by default; to enable it you must:

- **Connect** solder bridges **SB3** and **SB4**
- **Disconnect** solder bridge **SB49**

The board also does not support software control of VBUS power. To
supply power to the USB host port, fit a second jumper on the **PWR SEL**
header that bridges the **STLK** and **USB USER** pins together.

References
===========

Expand Down
71 changes: 71 additions & 0 deletions boards/arm/stm32h5/nucleo-h563zi/configs/nshusbnet/defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="nucleo-h563zi"
CONFIG_ARCH_BOARD_NUCLEO_H563ZI=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="stm32h5"
CONFIG_ARCH_CHIP_STM32H563ZI=y
CONFIG_ARCH_CHIP_STM32H5=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARMV8M_STACKCHECK_NONE=y
CONFIG_BOARD_LOOPSPERMSEC=9251
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEBUG_USB=y
CONFIG_DEBUG_USB_ERROR=y
CONFIG_DEBUG_USB_WARN=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_LINE_MAX=64
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NETINIT_DHCPC=y
CONFIG_NETUTILS_DHCPC=y
CONFIG_NETUTILS_TELNETD=y
CONFIG_NET_ETH_PKTSIZE=1514
CONFIG_NET_ICMP_SOCKET=y
CONFIG_NET_PKT=y
CONFIG_NET_ROUTE=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=655360
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_STM32H5_USART3=y
CONFIG_STM32H5_USBFS_HOST=y
CONFIG_STM32H5_USE_HSE=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_PING=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_USART3_SERIAL_CONSOLE=y
CONFIG_USBHOST_CDCECM=y
CONFIG_USBHOST_COMPOSITE=y
CONFIG_USBHOST_CONFIGURATION_SELECTION=y
CONFIG_USBHOST_HUB=y
36 changes: 34 additions & 2 deletions boards/arm/stm32h5/nucleo-h563zi/src/stm32_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,17 @@ int stm32_usbhost_initialize(void)
}
#endif

#ifdef CONFIG_USBHOST_CDCECM
/* Register the CDC-ECM class driver */

ret = usbhost_cdcecm_initialize();
if (ret < 0)
{
uerr("ERROR: Failed to register CDC-ACM class: %d\n", ret);
return ret;
}
#endif

/* Then get an instance of the USB host interface */

uinfo("Initialize USB host\n");
Expand Down Expand Up @@ -226,11 +237,32 @@ void stm32h5_usbhost_vbusdrive(int port, bool enable)
/* The Nucleo-h563zi doesn't have hardware for a vbus drive.
* Instead to get host working, you need to put an extra jumper
* on the "PWR SEL" to jump "STLK" and "USB USER".
* This effectively supplies 5V power form the STLink to the USB device.
* The power output is limited so only relatively low power
* This effectively supplies 5V power from the STLink to the USB device.
* The power output is limited, so only relatively low power
* devices can work.
*/
}
#endif

#ifdef CONFIG_USBHOST_CONFIGURATION_SELECTION
int board_usbhost_select_configuration(FAR struct usbhost_hubport_s *hport,
FAR const struct usb_devdesc_s *devdesc,
FAR const struct usbhost_id_s *id)
{
if (id->vid == 0x0bda && id->pid == 0x8153)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a callback to usbhost_registry_s or usbhost_class_s to select

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that the configuration needs to be selected before the host drivers are called.

Right now the code is:

set config X
for each host driver {
  if(host matches){
    break
  }
}

The other approach I tried is to cycle the configs until we find a host driver that matches.
Something like:

for each config c {
  set config c
  for each host driver {
    if(host matches){
      goto exit
    }
  }
}

But I ran into some problems with certain host class drivers failing the 2nd time it was iniitalized for a given device. Likely a bug that could be solved if we think that is a better approach.

The other thing to note is that I dont really need this configuration selection. I added CDC-ECM since certain modems I need support ECM. On the modems they are configuration 0.

I added this configuration selection because the CDC-ECM USB-Ethernet adapters that I have present ECM as the 2nd interface and I wanted to provide testing logs using a standard off the shelf product.

But if we can accept logs from a custom board with modems (or a build where I temporarily hard-code it to 1 instead of 0) then I could revert the configuration selection portion until it is actually needed.

{
/* Use interface 1 (CDC-ECM) for this ethernet adapter.
* vid - Realtek Semiconductor Corp
* pid - RTL8153 Gigabit Ethernet Adapter
*/

return 1;
}

/* All other USB deices use configurion 0 */

return 0;
}
#endif

#endif /* CONFIG_STM32H5_USBFS_HOST */
4 changes: 4 additions & 0 deletions drivers/usbhost/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ if(CONFIG_USBHOST)
list(APPEND SRCS usbhost_cdcacm.c)
endif()

if(CONFIG_USBHOST_CDCECM)
list(APPEND SRCS usbhost_cdcecm.c)
endif()

if(CONFIG_USBHOST_CDCMBIM)
list(APPEND SRCS usbhost_cdcmbim.c)
endif()
Expand Down
30 changes: 30 additions & 0 deletions drivers/usbhost/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ config USBHOST_ASYNCH
I/O transfer. This may be required, for example, to receive
infrequent, asynchronous input from an interrupt pipe.

config USBHOST_CONFIGURATION_SELECTION
bool "Per device configuration selection"
default n
---help---
Some devices have multiple USB configuration. By default the enumeration
selects the first configuration which may not be the desired configuration.
This features enables a board specific callback where it may choose which
configuration to apply based on the USB device descriptor. The callback may
choose by VID/PID or any other info it can acquire from a USB descriptor.
Board file must supply board_usbhost_select_configuration().

config USBHOST_WAITER
bool "USB Host Waiter Support"
default n
Expand Down Expand Up @@ -293,6 +304,25 @@ config USBHOST_CDCACM_TXBUFSIZE

endif # USBHOST_CDCACM

config USBHOST_CDCECM
bool "CDC/ECM support"
default n
depends on USBHOST_HAVE_ASYNCH && !USBHOST_BULK_DISABLE && !USBHOST_INT_DISABLE
select USBHOST_ASYNCH
select NET_ETHERNET
---help---
Select this option to build in host support for CDC/ECM serial
devices.

config USBHOST_CDCECM_PACKET_PRINT
bool "Print raw CDC/ECM packets"
default n
depends on DEBUG_USB_INFO
---help---
Print all raw RX and TX packets send and received in the CDC/ECM driver.
This can be useful for analysing with programs such as wireshark.


config USBHOST_CDCMBIM
bool "CDC/MBIM support"
default n
Expand Down
4 changes: 4 additions & 0 deletions drivers/usbhost/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ ifeq ($(CONFIG_USBHOST_CDCACM),y)
CSRCS += usbhost_cdcacm.c
endif

ifeq ($(CONFIG_USBHOST_CDCECM),y)
CSRCS += usbhost_cdcecm.c
endif

ifeq ($(CONFIG_USBHOST_CDCMBIM),y)
CSRCS += usbhost_cdcmbim.c
endif
Expand Down
Loading
Loading