Page 1 of 2

Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Wed Aug 03, 2022 3:55 pm
by mistermiser42
Hello! It's my first post here, and I'd like to apologize in advance for my incompetency!

I've been attempting to read serial data from the USB Type-A female "HOST" port on the ESP32-S3 USB OTG board in the Arduino core, however, the example code on the github repo seems to only use the USB DEV port instead of the USB HOST. I've done some documentation reading and I believe I have configured the correct pins to enable the USB HOST to work (shown below), but I am still unsure how I would go about actually programming the board to read serial data from this port (and if my configuration is even correct).

Code: Select all

void setup() {
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
  pinMode(17, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  digitalWrite(17, LOW);
  digitalWrite(18, HIGH);
}
I would really appreciate it if someone could point me in the right direction on how to properly set up the USB HOST and code for it!

Thank you!

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Thu Aug 04, 2022 4:11 am
by ESP_Dazz
I don't think the arduino-esp32 repo supports USB Host mode yet (I can only find Device mode examples). But it appears that IDF library included in arduino-esp32 is ESP-IDF v4.4, so you should have access to the ESP-IDF USB Host Library (docs here). The USB Host library is exposed via #include "usb/usb_host.h".

If you are aiming to use the ESP32-S3's internal USB PHY, then the usb_host_install() function should automatically configure the required GPIOs for you. But if you plan on using an external USB PHY, you can use the underlying #include "usb/usb_phy.h" to setup the GPIOs to the external PHY, then call usb_host_install().

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Thu Aug 04, 2022 4:59 am
by mistermiser42
That's good to hear, and thank you for the documentation! I've been looking at it for a bit, and I just want to make sure that I'm understanding some of this right.

If I wanted to treat the USB port as a typical dev board serial port (like a UART), would I have to allocate part of my memory to act as an rx buffer and use the usb_host_transfer_alloc, usb_host_transfer_free, and usb_host_transfer_submit functions? Or are there other functions that would allow me to read continuous bursts of data?

Once again, thanks for the help!

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Thu Aug 04, 2022 6:37 am
by ESP_Dazz
mistermiser42 wrote: If I wanted to treat the USB port as a typical dev board serial port (like a UART)
I don't think I'm understanding you correctly. Do you want the ESP32-S3 USB port to act as a USB Device or a USB Host? Typically if you want you to transfer serial data from the ESP32-S3 to a PC via the USB port, then the ESP32-S3 would be acting as a USB Device (of the CDC ACM class). However, if you want to connect other USB serial devices to the USB port of the ESP32-S3, then the ESP32-S3 would be acting as a USB Host running the CDC ACM Host Class driver.
mistermiser42 wrote: would I have to allocate part of my memory to act as an rx buffer and use the usb_host_transfer_alloc, usb_host_transfer_free, and usb_host_transfer_submit functions? Or are there other functions that would allow me to read continuous bursts of data?
If acting as USB Host, it depends on the connect USB device's class. Typically, serial of USB are of the CDC ACM class, so the serial data is sent as USB bulk transfers.

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Thu Aug 04, 2022 4:47 pm
by mistermiser42
Ah, sorry for the confusion! The link you posted seemed to be exactly what I was looking for: setting up the ESP32-S3 to be a USB Host for a serial device with ftdi.

If I wanted to set this up using the ftdi_usb.cpp, I would just need to include the ftdi_usb.hpp file as well as the usb_host.h, call usb_host_install()... and then call some of the functions in ftdi_usb? Is there any examples of actually calling these functions in code, and will they work for the Arduino core, or will I just have to dig deeper into the file's function calls?

Sorry for all the newbish questions!

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Thu Aug 04, 2022 11:16 pm
by chegewara
USB host should be working with arduino, or at least it has been working few months ago.
I even tested now and it is working, with v2.0.3 i think, but im not 100% sure, because i do have few versions installed.

https://github.com/chegewara/EspTinyUSB ... mples/host

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Fri Aug 05, 2022 1:56 am
by mistermiser42
Cool! I've seen your repo before on github when searching for answers to this problem, but I was unsure if it would work for my board which has the USB Host built in (but it seems now that it shouldn't be an issue?). I'm still a bit unsure how the INDATA() and OUTDATA() functions work in the usb_acm.cpp file (I'm still pretty new to all this USB host stuff). From my understanding, OUTDATA() is simply writing to the device, and INDATA() would be receiving from the device and returns 64 bytes read from a transfer buffer defined in the init function call?

Hopefully I am interpreting this code right, and I'm also wondering what might be the most essential functions to call from your library (and the esp-idf files) to get this USB Host up and running for acm?

Once again, thank you all so much for your help!

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Fri Aug 05, 2022 3:32 am
by chegewara
This is just example how you handle incoming data, in real app you will get binary data, thus the len:
https://github.com/chegewara/EspTinyUSB ... no#L18-L25
after data received it is required to call device->INDATA(); to queue xfer,
and here is how you send data to device:
https://github.com/chegewara/EspTinyUSB ... cm.ino#L85

There is one thing. It is pretty old code, and is not "bulletproof", because i didnt work with USB host for long time (it was early stage when espressif did not implement it fully yet).
I tested it with esp32 S2. Also test devices were S2 and C3.

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Mon Aug 08, 2022 3:34 pm
by mistermiser42
Sorry, it's just a bit hard to understand the core of what you are doing with these calls, so let me see if I understand this example code correctly.

Are the first two functions, "acm_events" and "client_event_callback", necessary? From my interpretation of the code, client_event_callback seems to essentially just give you a readout of the device's configuration? And acm_events is only called in the client_event_callback? So my takeaway from this, if I wanted to get extremely bare-bones and only read the incoming data from a USB device, would I simply just need to loop something like:

Code: Select all

    if (device && device->isConnected())
    {
        device->INDATA();
    }
after calling in the setup:

Code: Select all

    Serial.begin(115200);
    host.init(); // I assume this simply calls the usb_host_install() previously mentioned?
or are those functions actually essential to the operation of the USB host, and if so, how would you ever know if there is incoming data from the device and how would you read/write it from memory? Is the acm_events function actually required to do this functionality, and would I have to call the function to get incoming data, and if so, with what parameters?

For me as someone who has never seen this code and is new to configuring a USB Host, I have no idea what I am looking at, so I'm really sorry for my stupid questions.

Once again, thanks for the help!

Re: Getting the USB HOST port on the ESP32-S3-USB-OTG board to work

Posted: Mon Aug 08, 2022 5:43 pm
by chegewara
USB peripheral is not easy to work with and even harder to write the drivers.
My intention was to write library as easy to use as its possible for end user. Luckily ACM driver is easy to use.
It should be safe to call INDATA() the way you mentioned, but i may be wrong and it would cause memory leak or memory high usage.

The INDATA() is queuing IN XFER and is awaiting/pooling for incoming data from device. Until data is received this XFER is active in low level driver.

Another option to you may be to play with this component made by espressif:
https://components.espressif.com/compon ... st_cdc_acm