Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for 1-level USB hub in USB host implementation (IDFGH-11416) #12554

Closed
dordnung opened this issue Nov 9, 2023 · 34 comments
Closed

Support for 1-level USB hub in USB host implementation (IDFGH-11416) #12554

dordnung opened this issue Nov 9, 2023 · 34 comments
Assignees
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Feature Request Feature request for IDF

Comments

@dordnung
Copy link

dordnung commented Nov 9, 2023

Is your feature request related to a problem?

The ESP32-S3 has only one USB port and furthermore some USB ICs integrate several devices/ports in one chip via a USB hub interface. The XR22800IL32TR-F, for example, has a USB 2.0 hub with 3 downstream ports. However, the host hub implementation currently only supports the root hub. It looks like the usbh.c already supports multiple devices via a USB hub, for example there are already methods like usbh_hub_add_dev. However, the hub implementation itself only supports the root hub. As a result, there are currently no options for integrating more than one device or accessing a specific device behind a hub

Describe the solution you'd like.

It would be handy if the USB host implementation would support at least a 1-level USB hub to connect more than one device to the ESP32 or to use ICs that use an internal USB hub interface

Describe alternatives you've considered.

TinyUSB already supports a 1-level hub in the host implementation, but TinyUSB does not provide host support for the ESP32. Unfortunately I do not have enough understanding of the USB specification to port the implementation of TinyUSB into the esp-idf implementation

Additional context.

No response

@dordnung dordnung added the Type: Feature Request Feature request for IDF label Nov 9, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label Nov 9, 2023
@github-actions github-actions bot changed the title Support for 1-level USB hub in USB host implementation Support for 1-level USB hub in USB host implementation (IDFGH-11416) Nov 9, 2023
@roma-jam roma-jam self-assigned this Nov 10, 2023
@espressif-bot espressif-bot assigned roma-jam and unassigned roma-jam Nov 10, 2023
@roma-jam
Copy link
Collaborator

Hi @dordnung,

Thank for the request!

Yes, that is true that it would be handy to support external HUBs and we have this task in TODO list.
At the moment, the focus is much more on the HS support for upcoming chips.

Meanwhile, do you have any specific request regarding external HUBs or any ideas that could help us to make the better requirements for implementation?
Please, feel free to share them.

Thanks.

@dordnung
Copy link
Author

Hello @roma-jam

good to hear that it's already on the todo list.

Currently I don't have any specific requirements for the implementation, except that it should happen in the background and no user control should be necessary

@roma-jam
Copy link
Collaborator

Hi @dordnung ,

Thanks for the information. Right, that is exactly how it suppose to be!

After the implementation is available, there will be an update in this ticket.

Thanks again for you request.

@rtek1000
Copy link

Following

@suryasid09
Copy link

following

@sramrajkar
Copy link

Following
This has been something I have been looking forward to for a long time. I develop a IoT gateway platform based on ESP32S3 and having way to add more than one USB device will greatly improve flexibility at hardware design level.

@spanky411
Copy link

Also interested.
My specific application is connecting to an integrated device that is behind a dedicated hub. I know its not a general solution, but if you know the details of the hub, is there a way (in the current framework) to connect to the device behind it?

@Docfch
Copy link

Docfch commented Feb 20, 2024

when it will be available ?

@Docfch
Copy link

Docfch commented Mar 1, 2024

still not available ?

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels Mar 1, 2024
@rtek1000
Copy link

rtek1000 commented Mar 3, 2024

"Status: In Progress" nice!

@rtek1000
Copy link

rtek1000 commented Mar 6, 2024

I don't know if it helps, but there are other libraries with USB HUB implementation, like this:
(It is for MAX3421 IC)

Current working USB interface drivers

HID RAW
MIDI
Hub
Mass storage
CDC-ACM serial
XR21B1411 serial
PROLIFIC serial
FTDI serial

https://github.com/felis/UHS30

@ramalhais
Copy link

Also waiting for hub support. Thanks!

@rtek1000
Copy link

rtek1000 commented Mar 7, 2024

I remembered another library that implements a USB Hub, it is the simplest library I found about Hub, apparently it expands the variables (arrays) to serve more than one device, which is why it seems to be so difficult to understand, and transparent at the same time:

https://github.com/mori-br/STM32F4HUB/tree/master/Project/Middlewares/ST/STM32_USB_Host_Library/Class/HUB

@emanuelelaface
Copy link

Still no news about this?

@roma-jam
Copy link
Collaborator

Hi @rtek1000,

Still in progress.
First release planned to June.

@alex-k8
Copy link

alex-k8 commented May 17, 2024

Hi @rtek1000,

Still in progress. First release planned to June.

Hey @roma-jam, good to hear that it's still in progress! In the meantime, I've been trying to handle it on my own, and I feel like I've hit a wall.
To summarize what I've done, I analyzed the packets sent to (and from) the HUB using Wireshark on MAC, and I'm replicating those control transfers on my ESP32S3. I'm able to enumerate the ports on the HUB and detect when a device is connected.

I can send commands to the HUB to get the HUB Descriptor, and I also send the PORT_RESET feature to reset the port and start the communication to the connected device. However this is where my issue is. When I use GET_DESCRIPTOR it returns the HUB descriptor instead of the device. From what I've read, after the PORT_RESET command, the connected device is assigned to the default address 0. I suspect the GET_DESCRIPTOR is returning the HUB Descriptor because I'm passing the saved device handle, which on the background has an address of not 0?

usb_transfer_t *transfer;
  usb_host_transfer_alloc(8 + 18 + 1, 0, &transfer); // Allocate transfer buffer

  transfer->num_bytes = 8 + 18;
  transfer->data_buffer[0] = 0x80;
  transfer->data_buffer[1] = 0x06; // bRequest (GET_DESCRIPTOR)
  transfer->data_buffer[2] = 0x00; // wValue (LSB) 
  transfer->data_buffer[3] = 0x01; // wValue (MSB) DEVICE
  transfer->data_buffer[4] = 0x00; // wIndex (LSB)
  transfer->data_buffer[5] = 0x00; // wIndex (MSB)
  transfer->data_buffer[6] = 0x12; // wLength (LSB) 18
  transfer->data_buffer[7] = 0x00; // wLength (MSB)

  transfer->device_handle = deviceHandle;
  transfer->bEndpointAddress = 0x00;
  transfer->callback = _onReceiveHubDescriptor;
  transfer->context = this;

  esp_err_t err = usb_host_transfer_submit_control(clientHandle, transfer);

I tried using the SET_ADDRESS command but it didn't seem to do much. Do I have to close and open the handle again with the new address? Even if that's the case, I suspect the SET_ADDRESS command will run on the HUB and not the device, since again I'm passing the deviceHandle as seen above (which is the HUB handle)?

Since I'm handling the enumeration by myself, do I have to call usb_host_device_open by myself to get the connected device handle? Can I have two handles open at the same time, or does this mean that I can't "Only supports a single device, but the Host Library's API is designed for multiple device support"?

If I try to use usb_host_device_open on address 0, I get the error: (0x102): Invalid argument
and if I try to use it on address 2 (after using SET_ADDRESS to change the address to 2), I get the error: (0x105): Requested resource not found

By using the usb_host_device_addr_list_fill command, I can only see one device which is the HUB at address 1, even after using the SET_ADDRESS to change it.

Lastly, if I try to use GET_DESCRIPTOR after SET_ADDRESS, I get an error: USBH: Dev 1 EP 0 Error
so I suppose the address of the HUB is indeed changing, but I have to update the device handle somehow? Not that I want to change the address of the HUB, I want to change the address of the connected device so I can communicate with it.
If I use the built in usb_host_get_device_descriptor it returns the HUB Descriptor, because it's probably cached.

Sorry for the lengthy reply, any tip is highly appreciated, thank you!

I'm using the Arduino IDE by the way.

Edit: I tried calling SET_ADDRESS and setting it to 2, and on its response I tried calling usb_host_device_open, and I got the error: (0x105): Requested resource not found. Actually this happens on every command I try to send, after SET_ADDRESS. I somehow have to call the enumeration again from scratch? How do I do that?

@archef2000
Copy link

archef2000 commented May 25, 2024

Following
Is there a way to see the progress? Wanting to try it out with a usbip implementation.

@Docfch
Copy link

Docfch commented May 28, 2024

Me too, i have to do it to send 3 hubs connected each other and 1 stm32 for each hub through wifi, usb ip as you said

@rtek1000
Copy link

rtek1000 commented Jun 2, 2024

Hi @rtek1000,

Still in progress. First release planned to June.

Please, there is no need to stress, the important thing is to achieve it, take as much time as you need. Thank you.

@espressif-bot espressif-bot added Status: Reviewing Issue is being reviewed and removed Status: In Progress Work is in progress labels Jun 5, 2024
@emanuelelaface
Copy link

Hi @rtek1000,

Still in progress. First release planned to June.

looking forward for it. I have several project that can use multiple USB and the HUB is really an important feature.

@devemin
Copy link

devemin commented Jun 28, 2024

I'm watching this thread 😆
i hope this Hub support!

By the way, I tried ESP32-S3 multi device plug and play.

https://x.com/devemin/status/1806618148449472649?t=dUanlXj-NXaKhUdyFNlA8A&s=19

I can't wait your supporting the USB Hub!
Thanks for fantastic Espressif devices.

@Docfch
Copy link

Docfch commented Jul 22, 2024

@devemin i saw your video, you are running one device at time but the idea is to run multi device and multi hubs at the same time of course

@archef2000
Copy link

@roma-jam Any updates?

@rtek1000
Copy link

We may need to see if there are resources for multiple HUB levels, such as RAM.

At first, I believe that it is already interesting to be able to operate with just 1 HUB (1 Level) and 4 devices.

Note: A 7-port HUB usually has 2 HUB levels.

@archef2000
Copy link

Maybe for that let the user decide what levels and devices should be available.

@roma-jam
Copy link
Collaborator

Hi @archef2000 ,

Its currently in the review state. Took a bit longer, than expected, but we are closer to complete this ticket than ever.

There will be a multiple Hubs support with a configurable option to have only 1 layer supported.

@archef2000
Copy link

Oh thats great to hear. I am looking forward to trying it out.

@bwhitman
Copy link
Contributor

I see that exthub.c and friends were committed to master a couple of months ago. And there are docs for external hubs available. It's my understanding that although this code is committed, it's still not all setup yet to work. I tested it out on my application, using the usb_host_lib, just the hub is being enumerated, not any devices connected to the hub. Please let me know if I've misunderstood anything, otherwise, i will wait for further commits!

I (2379) CLASS: Installing USB Host Library
W (2385) EXT_HUB: Port Driver has not been installed
D (2390) EXT_HUB: Driver installed
I (2424) CLASS: Registering Client
D (3274) HUB: Root port reset
D (3274) HUB: New device tree node (uid=1)
D (3274) ENUM: [0:0] Start processing, device address 0
D (3275) ENUM: [0:0] GET_SHORT_DEV_DESC OK
D (3279) USBH: Processing actions 0x4
D (3283) USBH: Default pipe device 0
D (3287) ENUM: [0:0] CHECK_SHORT_DEV_DESC OK
D (3891) ENUM: [0:0] SECOND_RESET OK
D (3891) ENUM: [0:0] SET_ADDR OK
D (3891) USBH: Processing actions 0x4
D (3891) USBH: Default pipe device 0
D (3894) ENUM: Assign address (dev_addr=1)
D (3898) ENUM: [0:0] CHECK_ADDR OK
D (3912) ENUM: [0:0] SET_ADDR_RECOVERY OK
D (3912) ENUM: [0:0] GET_FULL_DEV_DESC OK
D (3912) USBH: Processing actions 0x4
D (3914) USBH: Default pipe device 1
D (3917) ENUM: [0:0] CHECK_FULL_DEV_DESC OK
D (3921) ENUM: Selected bConfigurationValue=1
D (3926) ENUM: [0:0] SELECT_CONFIG OK
D (3929) ENUM: [0:0] GET_SHORT_CONFIG_DESC OK
D (3934) USBH: Processing actions 0x4
D (3938) USBH: Default pipe device 1
D (3941) ENUM: [0:0] CHECK_SHORT_CONFIG_DESC OK
D (3946) ENUM: [0:0] GET_FULL_CONFIG_DESC OK
D (3950) USBH: Processing actions 0x4
D (3954) USBH: Default pipe device 1
D (3958) ENUM: [0:0] CHECK_FULL_CONFIG_DESC OK
D (3962) ENUM: [0:0] GET_SHORT_LANGID_TABLE OK
D (3967) USBH: Processing actions 0x4
D (3970) USBH: Default pipe device 1
D (3974) ENUM: [0:0] CHECK_SHORT_LANGID_TABLE OK
D (3979) ENUM: [0:0] GET_FULL_LANGID_TABLE OK
D (3983) USBH: Processing actions 0x4
D (3987) USBH: Default pipe device 1
D (3991) ENUM: [0:0] CHECK_FULL_LANGID_TABLE OK
D (3995) ENUM: String iManufacturer not set, skip
D (4000) ENUM: [0:0] GET_SHORT_MANU_STR_DESC OK
D (4004) ENUM: String iManufacturer not set, skip
D (4009) ENUM: [0:0] CHECK_SHORT_MANU_STR_DESC OK
D (4014) ENUM: String iManufacturer not set, skip
D (4019) ENUM: [0:0] GET_FULL_MANU_STR_DESC OK
D (4023) ENUM: String iManufacturer not set, skip
D (4028) ENUM: [0:0] CHECK_FULL_MANU_STR_DESC OK
D (4033) ENUM: [0:0] GET_SHORT_PROD_STR_DESC OK
D (4037) USBH: Processing actions 0x4
D (4041) USBH: Default pipe device 1
D (4045) ENUM: [0:0] CHECK_SHORT_PROD_STR_DESC OK
D (4050) ENUM: [0:0] GET_FULL_PROD_STR_DESC OK
D (4054) USBH: Processing actions 0x4
D (4058) USBH: Default pipe device 1
D (4062) ENUM: [0:0] CHECK_FULL_PROD_STR_DESC OK
D (4066) ENUM: String iSerialNumber not set, skip
D (4071) ENUM: [0:0] GET_SHORT_SER_STR_DESC OK
D (4075) ENUM: String iSerialNumber not set, skip
D (4080) ENUM: [0:0] CHECK_SHORT_SER_STR_DESC OK
D (4085) ENUM: String iSerialNumber not set, skip
D (4090) ENUM: [0:0] GET_FULL_SER_STR_DESC OK
D (4094) ENUM: String iSerialNumber not set, skip
D (4099) ENUM: [0:0] CHECK_FULL_SER_STR_DESC OK
D (4104) ENUM: [0:0] SET_CONFIG OK
D (4107) USBH: Processing actions 0x4
D (4111) USBH: Default pipe device 1
D (4114) ENUM: [0:0] CHECK_CONFIG OK
D (4118) ENUM: [0:0] Processing complete, new device address 1
D (4124) ENUM: [0:0] COMPLETE OK
D (4127) USBH: Processing actions 0x40
D (4131) USBH: New device 1
I (4134) CLASS: Opening device at address 1
I (4139) CLASS: Getting device information
I (4143) CLASS: 	Full speed
I (4147) CLASS: 	bConfigurationValue 1
I (4151) CLASS: Getting device descriptor
*** Device descriptor ***
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0x9
bDeviceSubClass 0x0
bDeviceProtocol 0x0
bMaxPacketSize0 64
idVendor 0x1a40
idProduct 0x101
bcdDevice 1.00
iManufacturer 0
iProduct 1
iSerialNumber 0
bNumConfigurations 1
I (4179) CLASS: Getting config descriptor
*** Configuration descriptor ***
bLength 9
bDescriptorType 2
wTotalLength 25
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xe0
bMaxPower 100mA
	*** Interface descriptor ***
	bLength 9
	bDescriptorType 4
	bInterfaceNumber 0
	bAlternateSetting 0
	bNumEndpoints 1
	bInterfaceClass 0x9
	bInterfaceSubClass 0x0
	bInterfaceProtocol 0x0
	iInterface 0
		*** Endpoint descriptor ***
		bLength 7
		bDescriptorType 5
		bEndpointAddress 0x81	EP 1 IN
		bmAttributes 0x3	INT
		wMaxPacketSize 1
		bInterval 255
I (4231) CLASS: Getting Product string descriptor
USB2.0 HUB
D (4238) EXT_HUB: [1] New device (iface 0)
D (4242) EXT_HUB: [1] Processing actions 0x20
D (4247) EXT_HUB: Stage GET_HUB_DESCRIPTOR OK
D (4251) USBH: Processing actions 0x4
D (4255) USBH: Default pipe device 1
D (4258) EXT_HUB: [1] Processing actions 0x2
D (4263) EXT_HUB: [1] Device configure (iface 0)
D (4267) EXT_HUB: 	Standalone HUB
D (4271) EXT_HUB: 	4 external ports
D (4274) EXT_HUB: 	All ports power at once
D (4278) EXT_HUB: 	Global over-current protection
D (4283) EXT_HUB: 	Port indicators are supported
D (4288) EXT_HUB: 	Power on to power good time: 100ms
D (4293) EXT_HUB: 	Maximum current: 100 mA
D (4297) EXT_HUB: Stage CHECK_HUB_DESCRIPTOR OK

@archef2000
Copy link

You can talk to the hub but not the attached to it. It is not in any official release.

@rtek1000
Copy link

rtek1000 commented Aug 16, 2024

I remembered another driver that supports HUB, which might be a source of research:

ChibiOS Forum
"USB host stack and driver for STM32"

  • HUB driver, tightly integrated with the high level driver, to connect multiple devices to the USB port.

http://forum.chibios.org/viewtopic.php?f=16&t=2968&sid=afd037349cc1b55f54a428350fc8f5fc

Note: Unfortunately, there is a physical problem in STM32 IC so you may not be able to use HUB (appears to be related only to the internal PHY), but it is interesting to know that the code exists.

@archef2000
Copy link

It is already implemented in esp-idf master just not released as a version. https://github.com/espressif/esp-idf/blob/master/components/usb/private_include/ext_hub.h#L75

@roma-jam
Copy link
Collaborator

Hi @bwhitman ,

There will be the second part regarding external hubs’ ports available soon.
When the final release is done, we will notify about that and change the state of this ticket.

Sorry for the inconveniences.

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Reviewing Issue is being reviewed labels Sep 30, 2024
@maaamcube
Copy link

@roma-jam i see that the status is done, where is the release ? thanks

@roma-jam
Copy link
Collaborator

roma-jam commented Oct 1, 2024

Hi @maaamcube ,

The feature was added internally and usually it takes some time to pass the tests and synchronize them with the public repo.
When it will be done, the ticket should be closed.
The changes will be available soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Feature Request Feature request for IDF
Projects
None yet
Development

No branches or pull requests