Page 1 of 1

ESP32-S3-USB_OTG host mode

Posted: Mon Apr 21, 2025 3:17 pm
by mirmit
Hi,

I'm trying to have ESP32-S3 working as USB Host for USB HID peripherals in order to receive keystrokes and/or mouse events.

I'm using an ESP32-S3-USB-OTG dev board with the usb_host_lib_example code. The program start correctly on the board, and is alive, as when presing the BOOT button, the program quit.

USB Lib seems correctly ruuning, as I see:

Code: Select all

I (289) USB host lib: Installing USB Host Library
I (319) CLASS: Registering Client
in the log.

However, when connecting a mouse or a keyboard on the USB HOST port of the board, nothing happen. No power is provided to teh peripheral.

The dev board is connected through the mini USB serial interface for logging and powering.

What could I be missing, is I cannot imagine o better platform to start experimenting on this kind of peripheral.

ESP-IDF is in version v5.4.1, reinstalled this week-end.

Thanks in advance for any hints/tips

Re: ESP32-S3-USB_OTG host mode (solved)

Posted: Tue Apr 22, 2025 8:17 am
by mirmit
Hi,

Quite ashamed of the simple solution and the hours lost on this one.

The boars is powered by USB Debug port (micro-USB) or USB DEV(or battery if present).

However, the USB Host port is only powered by the VUSB line coming exclusively from the USB DEV port of the battery.

So, to have USB Host powered, the USB board needs to be plugged to an USB port using the USB DEV connector.

It was that simple.

I hope this post save few minutes to someone someday.

Re: ESP32-S3-USB_OTG host mode

Posted: Wed Apr 23, 2025 2:12 am
by Sprite
Glad you solved it, and thanks for posting what the issue was.

Re: ESP32-S3-USB_OTG host mode

Posted: Sat Apr 26, 2025 3:19 pm
by mirmit
Hi there,

After trying with a different example, I failed again with the same symptoms.

Turn out in addition to bring power on the proper route, the power needs to be routed to the port.

I used this code snippet from the SDK

Code: Select all

#include "driver/gpio.h"

static const char *USB_ADDITIONS_TAG = "ESP32-S3-USB-ADDITIONS";

#define DEV_VBUS_EN GPIO_NUM_12     // DEV_VBUS_EN: High level to enable DEV_VBUS power supply. (power the board from the device port by connecting to a computer)
#define BOOST_EN GPIO_NUM_13        // BOOST_EN: High level to enable Boost boost circuit. Low to enable USB_DEV as the power source
#define IDEV_LIMIT_EN GPIO_NUM_17   // LIMIT_EN: Enable current limiting IC, high level enable.
#define USB_SEL GPIO_NUM_18         // USB_SEL: Used to switch the USB interface. When high level, the USB_HOST interface is enabled. When low level, the USB_DEV interface is enabled.

#define GPIO_OUTPUT_PIN_SEL  ((1ULL<<DEV_VBUS_EN) | (1ULL<<BOOST_EN)| (1ULL<<IDEV_LIMIT_EN) | (1ULL<<USB_SEL))

void usb_host_power_init(){   
    gpio_config_t io_conf = {
        io_conf.intr_type = GPIO_INTR_DISABLE,      //disable interrupt
        io_conf.mode = GPIO_MODE_OUTPUT,            //set as output mode
        io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL, //bit mask of the pins to set,e.g.GPIO12/18
        io_conf.pull_down_en = 0,                   //disable pull-down mode
        io_conf.pull_up_en = 0                      //disable pull-up mode
    };
    
    gpio_config(&io_conf);              //configure GPIO with the given settings
    gpio_set_level(DEV_VBUS_EN, 1);     // Purpose: Powers USB_HOST (USB-A socket/receptacle) with power from the USB_DEV port (USB-A plug) as opposed to the battery [Therefore we should set the battery switch to OFF when using this mode]
    ESP_LOGI(USB_ADDITIONS_TAG, "   DEV_VBUS_EN (GPIO_NUM_12) configured as HIGH.");
    gpio_set_level(BOOST_EN, 0);        // Purpose: Avoids undefined behavior. Disable when using USB power, as we do not need the boost functionality. The boost IC can raise the battery voltage from 3.5 to 5 when enabled.
    ESP_LOGI(USB_ADDITIONS_TAG, "      BOOST_EN (GPIO_NUM_13) configured as LOW.");
    gpio_set_level(IDEV_LIMIT_EN, 1);   // Purpose: Enables voltage to leave the current limiting IC (Vout)
    ESP_LOGI(USB_ADDITIONS_TAG, " IDEV_LIMIT_EN (GPIO_NUM_17) configured as HIGH.");
    gpio_set_level(USB_SEL, 1);         // Purpose: Determines whether signals are routed to either the USB_HOST or the USB_DEV
    ESP_LOGI(USB_ADDITIONS_TAG, "           USB_SEL (GPIO 18) configured as HIGH.");
}
I'm calling this after the initialization of the usb_task_lib complete.

This plus using the USB_DEV port make the USB HOST able to use some USB peripherals.