Skip to content

Commit

Permalink
Merge branch 'feature/usb_host_lib_example' into 'master'
Browse files Browse the repository at this point in the history
feat(usb/host): Modifiy usb_host_lib example

Closes IDF-8411

See merge request espressif/esp-idf!26582
  • Loading branch information
peter-marcisovsky committed Oct 31, 2023
2 parents 1df3736 + 546b76b commit 5c89fa3
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 70 deletions.
46 changes: 30 additions & 16 deletions examples/peripherals/usb/host/usb_host_lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@

(See the README.md file in the upper level 'examples' directory for more information about examples.)

This example demonstrates the basic usage of the [USB Host Library API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_host.html) by implementing a pseudo class driver and a Host Library daemon task. The example does the following:
This example demonstrates the basic usage of the [USB Host Library API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_host.html) by implementing a pseudo class driver and a Host Library task. The example does the following:

1. Install Host Library and register a client
2. Waits for a device connection
3. Prints the device's information (such as device/configuration/string descriptors)
4. Waits for the device to disconnect
5. Deregister the client and uninstall the Host Library
5. Repeats steps 2 to 4 until a user pressess a button, which quits the `app`
6. If the button has been pressed, while a USB device is still connected, the user will be prompted to remove the device and push the button again to quit the `app`
7. Deregister the client, uninstall the Host Library and quit the `app`

The example demonstrates the following aspects of the USB Host Library API:

- How to use the Library API to:
- Install and uninstall the USB Host Library
- Run the library event handler function a daemon task
- Run the library event handler function and usb host library task
- How to handle library events
- How to use the Client API from a client task to:
- Register and deregister a client of the USB Host Library
Expand All @@ -30,7 +32,7 @@ The example demonstrates the following aspects of the USB Host Library API:

### Hardware Required

An ESP board that supports USB-OTG. The example uses the ESP's internal USB PHY, however the internal USB PHY's pins will need to be connected to a USB port (i.e., a USB breakout board) as follows:
An ESP board that has a push button and supports USB-OTG. The example uses the ESP's internal USB PHY, however the internal USB PHY's pins will need to be connected to a USB port (i.e., a USB breakout board) as follows:

- GND and 5V signals of the ESP board to the GND and 5V lines of the USB port
- GPIO 19 to D-
Expand All @@ -43,6 +45,7 @@ idf.py menuconfig
```

* The USB Host Stack has a maximum supported transfer size for control transfer during device enumeration. This size is specified via the USB_HOST_CONTROL_TRANSFER_MAX_SIZE configuration option and has a default value of 256 bytes. Therefore, if devices with length config/string descriptors are used, users may want to increase the size of this configuration.
* Push button GPIO selection

### Build and Flash

Expand All @@ -61,14 +64,17 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
## Example Output

```
I (261) cpu_start: Starting scheduler on PRO CPU.
I (267) DAEMON: Installing USB Host Library
I (297) CLASS: Registering Client
I (5067) CLASS: Opening device at address 1
I (5067) CLASS: Getting device information
I (5067) CLASS: Full speed
I (5067) CLASS: bConfigurationValue 1
I (5067) CLASS: Getting device descriptor
I (305) main_task: Started on CPU0
I (315) main_task: Calling app_main()
I (315) USB host lib: USB host library example
I (315) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2
I (325) USB host lib: Installing USB Host Library
I (365) CLASS: Registering Client
I (745) CLASS: Opening device at address 1
I (745) CLASS: Getting device information
I (745) CLASS: Full speed
I (745) CLASS: bConfigurationValue 1
I (745) CLASS: Getting device descriptor
*** Device descriptor ***
bLength 18
bDescriptorType 1
Expand All @@ -84,7 +90,7 @@ iManufacturer 1
iProduct 2
iSerialNumber 3
bNumConfigurations 1
I (5097) CLASS: Getting config descriptor
I (775) CLASS: Getting config descriptor
*** Configuration descriptor ***
bLength 9
bDescriptorType 2
Expand Down Expand Up @@ -153,12 +159,20 @@ bMaxPower 500mA
bmAttributes 0x2 BULK
wMaxPacketSize 64
bInterval 1
I (5227) CLASS: Getting Manufacturer string descriptor
I (855) CLASS: Getting Manufacturer string descriptor
Espressif
I (5237) CLASS: Getting Product string descriptor
I (855) CLASS: Getting Product string descriptor
USB JTAG/serial debug unit
I (5247) CLASS: Getting Serial Number string descriptor
I (865) CLASS: Getting Serial Number string descriptor
7C:DF:A1:E0:10:50
W (2855) USB host lib: To shutdown example, remove all USB devices and press button again.
E (6135) USBH: Device 1 gone
I (9545) CLASS: Deregistering Client
I (9545) USB host lib: No more clients
I (9545) USB host lib: All devices marked as free
I (9545) USB host lib: No more clients and devices
I (9645) USB host lib: End of the example
I (9645) main_task: Returned from app_main()
```

## Troubleshooting
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
idf_component_register(SRCS "usb_host_lib_main.c" "class_driver.c"
INCLUDE_DIRS "."
PRIV_REQUIRES usb
PRIV_REQUIRES usb driver
)
12 changes: 12 additions & 0 deletions examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
menu "Example Configuration"

orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"

config APP_QUIT_PIN
int "APP Quit button GPIO pin"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 0
help
GPIO pin number to be used as APP_QUIT button.

endmenu
48 changes: 30 additions & 18 deletions examples/peripherals/usb/host/usb_host_lib/main/class_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@

#define CLIENT_NUM_EVENT_MSG 5

#define ACTION_OPEN_DEV 0x01
#define ACTION_GET_DEV_INFO 0x02
#define ACTION_GET_DEV_DESC 0x04
#define ACTION_GET_CONFIG_DESC 0x08
#define ACTION_GET_STR_DESC 0x10
#define ACTION_CLOSE_DEV 0x20
#define ACTION_EXIT 0x40
typedef enum {
ACTION_OPEN_DEV = 0x01,
ACTION_GET_DEV_INFO = 0x02,
ACTION_GET_DEV_DESC = 0x04,
ACTION_GET_CONFIG_DESC = 0x08,
ACTION_GET_STR_DESC = 0x10,
ACTION_CLOSE_DEV = 0x20,
ACTION_EXIT = 0x40,
ACTION_RECONNECT = 0x80,
} action_t;

typedef struct {
usb_host_client_handle_t client_hdl;
Expand All @@ -28,6 +31,7 @@ typedef struct {
} class_driver_t;

static const char *TAG = "CLASS";
static class_driver_t *s_driver_obj;

static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg)
{
Expand Down Expand Up @@ -122,24 +126,20 @@ static void action_get_str_desc(class_driver_t *driver_obj)
driver_obj->actions &= ~ACTION_GET_STR_DESC;
}

static void aciton_close_dev(class_driver_t *driver_obj)
static void action_close_dev(class_driver_t *driver_obj)
{
ESP_ERROR_CHECK(usb_host_device_close(driver_obj->client_hdl, driver_obj->dev_hdl));
driver_obj->dev_hdl = NULL;
driver_obj->dev_addr = 0;
//We need to exit the event handler loop
//We need to connect a new device
driver_obj->actions &= ~ACTION_CLOSE_DEV;
driver_obj->actions |= ACTION_EXIT;
driver_obj->actions |= ACTION_RECONNECT;
}

void class_driver_task(void *arg)
{
SemaphoreHandle_t signaling_sem = (SemaphoreHandle_t)arg;
class_driver_t driver_obj = {0};

//Wait until daemon task has installed USB Host Library
xSemaphoreTake(signaling_sem, portMAX_DELAY);

ESP_LOGI(TAG, "Registering Client");
usb_host_client_config_t client_config = {
.is_synchronous = false, //Synchronous clients currently not supported. Set this to false
Expand All @@ -150,6 +150,7 @@ void class_driver_task(void *arg)
},
};
ESP_ERROR_CHECK(usb_host_client_register(&client_config, &driver_obj.client_hdl));
s_driver_obj = &driver_obj;

while (1) {
if (driver_obj.actions == 0) {
Expand All @@ -171,18 +172,29 @@ void class_driver_task(void *arg)
action_get_str_desc(&driver_obj);
}
if (driver_obj.actions & ACTION_CLOSE_DEV) {
aciton_close_dev(&driver_obj);
action_close_dev(&driver_obj);
}
if (driver_obj.actions & ACTION_EXIT) {
break;
}
if (driver_obj.actions & ACTION_RECONNECT) {
driver_obj.actions = 0;
}
}
}

ESP_LOGI(TAG, "Deregistering Client");
ESP_ERROR_CHECK(usb_host_client_deregister(driver_obj.client_hdl));

//Wait to be deleted
xSemaphoreGive(signaling_sem);
vTaskSuspend(NULL);
}

void class_driver_client_deregister(void)
{
if (s_driver_obj->dev_hdl != NULL) {
s_driver_obj->actions = ACTION_CLOSE_DEV;
}
s_driver_obj->actions |= ACTION_EXIT;

// Unblock, exit the loop and proceed to deregister client
ESP_ERROR_CHECK(usb_host_client_unblock(s_driver_obj->client_hdl));
}
Loading

0 comments on commit 5c89fa3

Please sign in to comment.