Skip to content

Commit

Permalink
example: add usb host usb_cdc_basic
Browse files Browse the repository at this point in the history
  • Loading branch information
leeebo committed Dec 18, 2023
1 parent 3d3d8b8 commit 4408a2d
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 4 deletions.
11 changes: 11 additions & 0 deletions .gitlab/ci/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,17 @@ build_example_usb_host_usb_cdc_4g_module:
variables:
EXAMPLE_DIR: examples/usb/host/usb_cdc_4g_module

build_example_usb_host_usb_cdc_basic:
extends:
- .build_examples_template
- .rules:build:example_usb_host_usb_cdc_basic
parallel:
matrix:
- IMAGE: espressif/idf:release-v4.4
- IMAGE: espressif/idf:release-v5.1
variables:
EXAMPLE_DIR: examples/usb/host/usb_cdc_basic

build_example_utilities_xz_decompress_file:
extends:
- .build_examples_template
Expand Down
17 changes: 17 additions & 0 deletions .gitlab/ci/rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@
.patterns-example_usb_host_usb_cdc_4g_module: &patterns-example_usb_host_usb_cdc_4g_module
- "examples/usb/host/usb_cdc_4g_module/**/*"

.patterns-example_usb_host_usb_cdc_basic: &patterns-example_usb_host_usb_cdc_basic
- "examples/usb/host/usb_cdc_basic/**/*"

.patterns-example_utilities_xz_decompress_file: &patterns-example_utilities_xz_decompress_file
- "examples/utilities/xz_decompress_file/**/*"

Expand Down Expand Up @@ -911,6 +914,20 @@
- <<: *if-dev-push
changes: *patterns-example_usb_host_usb_cdc_4g_module

.rules:build:example_usb_host_usb_cdc_basic:
rules:
- <<: *if-protected
- <<: *if-label-build
- <<: *if-trigger-job
- <<: *if-dev-push
changes: *patterns-build_system
- <<: *if-dev-push
changes: *patterns-components_usb_iot_usbh
- <<: *if-dev-push
changes: *patterns-components_usb_iot_usbh_cdc
- <<: *if-dev-push
changes: *patterns-example_usb_host_usb_cdc_basic

.rules:build:example_utilities_xz_decompress_file:
rules:
- <<: *if-protected
Expand Down
2 changes: 2 additions & 0 deletions components/usb/iot_usbh_cdc/idf_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ dependencies:
version: "0.*"
public: true
override_path: "../iot_usbh"
examples:
- path: ../../../examples/usb/host/usb_cdc_basic
8 changes: 4 additions & 4 deletions examples/.build-rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,10 @@ examples/usb/host/usb_audio_player:
examples/usb/host/usb_cdc_4g_module:
enable:
- if: IDF_TARGET in ["esp32s2","esp32s3"]
disable:
- if: IDF_VERSION_MAJOR == 5 and IDF_VERSION_MINOR == 0
temporary: true
reason: IDF Bug '#36'

examples/usb/host/usb_cdc_basic:
enable:
- if: IDF_TARGET in ["esp32s2","esp32s3"]

examples/utilities/xz_decompress_file:
enable:
Expand Down
6 changes: 6 additions & 0 deletions examples/usb/host/usb_cdc_basic/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(usb_cdc_basic)
85 changes: 85 additions & 0 deletions examples/usb/host/usb_cdc_basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# USB Host CDC Basic Example

This example demonstrates how to use [iot_usbh_cdc](https://components.espressif.com/components/espressif/iot_usbh_cdc) to communicate with USB CDC device.

## How to use the example

### Hardware Required

The example can be run on ESP32-S2 or ESP32-S3 based development board with USB interface.

### Setup the Hardware

Connect the external USB device to ESP32-S USB interface directly.

| ESP32-Sx GPIO | USB Device |
| ------------- | ----------- |
| 20 | D+ (green) |
| 19 | D- (white) |
| GND | GND (black) |
| +5V | +5V (red) |

### Configure the project

1. The example enables one bulk interface by default.
2. Users can modify the `EXAMPLE_BULK_ITF_NUM` to `2` in `usb_cdc_basic_main.c` to enable two bulk interfaces.
3. Users need to modify the endpoint address `EXAMPLE_BULK_OUTx_EP_ADDR` and `EXAMPLE_BULK_INx_EP_ADDR` to the actual endpoint address of the USB device.
4. Use the command below to set build target to `esp32s2` or `esp32s3`.

```
idf.py set-target esp32s3
```

### Build and Flash

Build the project and flash it to the board, then run monitor tool to view serial output:

```
idf.py -p PORT build flash monitor
```

(To exit the serial monitor, type ``Ctrl-]``.)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

## Example Output

If your USB device (eg. 4G Module) supports AT command, When host send `AT`, the device usually returns `OK` in most cases.

```
I (408) USB_HCDC: Waitting Device Connection
I (438) USB_HCDC: Port=1 init succeed
W (438) USB_HCDC: Waitting USB Connection
I (688) USB_HCDC: line 261 HCD_PORT_EVENT_CONNECTION
I (688) USB_HCDC: Resetting Port
I (748) USB_HCDC: Port speed = 1
I (748) USB_HCDC: Set Device Addr = 1
I (748) USB_HCDC: Set Device Addr Done
I (748) USB_HCDC: Set Device Configuration = 1
I (748) USB_HCDC: Set Device Configuration Done
I (758) USB_HCDC: Set Device Line State: dtr 1, rts 0
I (758) USB_HCDC: Set Device Line State Done
I (768) USB_HCDC: Creating bulk in pipe
I (768) USB_HCDC: Creating bulk out pipe
I (808) USB_HCDC: usb driver install succeed
I (6059) cdc_basic_demo: Send itf0 len=4: AT
I (6069) cdc_basic_demo: Send itf1 len=4: AT
I (6079) cdc_basic_demo: Itf 0, Receive len=6:
OK
I (6079) cdc_basic_demo: Itf 1, Receive len=6:
OK
I (7089) cdc_basic_demo: Send itf0 len=4: AT
I (7089) cdc_basic_demo: Send itf1 len=4: AT
I (7109) cdc_basic_demo: Itf 0, Receive len=6:
OK
I (7109) cdc_basic_demo: Itf 1, Receive len=6:
OK
```
3 changes: 3 additions & 0 deletions examples/usb/host/usb_cdc_basic/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

idf_component_register(SRCS usb_cdc_basic_main.c
INCLUDE_DIRS ".")
8 changes: 8 additions & 0 deletions examples/usb/host/usb_cdc_basic/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
targets:
- esp32s2
- esp32s3
dependencies:
idf: ">=4.4.1"
iot_usbh_cdc:
version: "0.2.*"
override_path: "../../../../../components/usb/iot_usbh_cdc"
142 changes: 142 additions & 0 deletions examples/usb/host/usb_cdc_basic/main/usb_cdc_basic_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "iot_usbh_cdc.h"

static const char *TAG = "cdc_basic_demo";
/* USB PIN fixed in esp32-s2/s3, can not use io matrix */
#define BOARD_USB_DP_PIN 20
#define BOARD_USB_DN_PIN 19

/* ringbuffer size */
#define IN_RINGBUF_SIZE (1024 * 1)
#define OUT_RINGBUF_SIZE (1024 * 1)

/* enable interface num */
#define EXAMPLE_BULK_ITF_NUM 1
/* bulk endpoint address */
#define EXAMPLE_BULK_IN0_EP_ADDR 0x81
#define EXAMPLE_BULK_OUT0_EP_ADDR 0x01
#define EXAMPLE_BULK_IN1_EP_ADDR 0x82
#define EXAMPLE_BULK_OUT1_EP_ADDR 0x02
/* bulk endpoint max package size */
#define EXAMPLE_BULK_EP_MPS 64

/* choose if use user endpoint descriptors */
#define EXAMPLE_CONFIG_USER_EP_DESC

/*
the basic demo skip the standred get descriptors process,
users need to get params from cdc device descriptors from PC side,
eg. run `lsusb -v` in linux, then hardcode the related params below
*/
#ifdef EXAMPLE_CONFIG_USER_EP_DESC
static usb_ep_desc_t bulk_out_ep_desc = {
.bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = EXAMPLE_BULK_OUT0_EP_ADDR,
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = EXAMPLE_BULK_EP_MPS,
};

static usb_ep_desc_t bulk_in_ep_desc = {
.bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = EXAMPLE_BULK_IN0_EP_ADDR,
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = EXAMPLE_BULK_EP_MPS,
};
#endif

static void usb_receive_task(void *param)
{
size_t data_len = 0;
uint8_t buf[IN_RINGBUF_SIZE];

while (1) {
/* Polling USB receive buffer to get data */
for (size_t i = 0; i < EXAMPLE_BULK_ITF_NUM; i++) {
if (usbh_cdc_get_itf_state(i) == false) {
continue;
}
usbh_cdc_itf_get_buffered_data_len(i, &data_len);
if (data_len > 0) {
usbh_cdc_itf_read_bytes(i, buf, data_len, 10);
ESP_LOGI(TAG, "Itf %d, Receive len=%d: %.*s", i, data_len, data_len, buf);
} else {
vTaskDelay(1);
}
}
}
}

static void usb_connect_callback(void *arg)
{
ESP_LOGI(TAG, "Device Connected!");
}

static void usb_disconnect_callback(void *arg)
{
ESP_LOGW(TAG, "Device Disconnected!");
}

void app_main(void)
{
/* install usbh cdc driver with bulk endpoint configs
and size of internal ringbuffer*/
#ifdef EXAMPLE_CONFIG_USER_EP_DESC
ESP_LOGI(TAG, "using user bulk endpoint descriptor");
static usbh_cdc_config_t config = {
/* use user endpoint descriptor */
.bulk_in_ep = &bulk_in_ep_desc,
.bulk_out_ep = &bulk_out_ep_desc,
#else
ESP_LOGI(TAG, "using default bulk endpoint descriptor");
static usbh_cdc_config_t config = {
/* use default endpoint descriptor with user address */
.bulk_in_ep_addr = EXAMPLE_BULK_IN0_EP_ADDR,
.bulk_out_ep_addr = EXAMPLE_BULK_OUT0_EP_ADDR,
#endif
.rx_buffer_size = IN_RINGBUF_SIZE,
.tx_buffer_size = OUT_RINGBUF_SIZE,
.conn_callback = usb_connect_callback,
.disconn_callback = usb_disconnect_callback,
};

#if (EXAMPLE_BULK_ITF_NUM > 1)
ESP_LOGI(TAG, "itf %d using default bulk endpoint descriptor", 1);
config.itf_num = 2;
/* test config with only ep addr */
config.bulk_in_ep_addrs[1] = EXAMPLE_BULK_IN1_EP_ADDR;
config.bulk_out_ep_addrs[1] = EXAMPLE_BULK_OUT1_EP_ADDR;
config.rx_buffer_sizes[1] = IN_RINGBUF_SIZE;
config.tx_buffer_sizes[1] = OUT_RINGBUF_SIZE;
#endif

/* install USB host CDC driver */
ESP_ERROR_CHECK(usbh_cdc_driver_install(&config));
/* Waiting for USB device connected */
ESP_ERROR_CHECK(usbh_cdc_wait_connect(portMAX_DELAY));
/* Create a task for USB data processing */
xTaskCreate(usb_receive_task, "usb_rx", 4096, NULL, 2, NULL);

/* Repeatly sent AT through USB */
char buff[32] = "AT\r\n";
while (1) {
int len = usbh_cdc_write_bytes((uint8_t *)buff, strlen(buff));
ESP_LOGI(TAG, "Send itf0 len=%d: %s", len, buff);
#if (EXAMPLE_BULK_ITF_NUM > 1)
len = usbh_cdc_itf_write_bytes(1, (uint8_t *)buff, strlen(buff));
ESP_LOGI(TAG, "Send itf1 len=%d: %s", len, buff);
#endif
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

0 comments on commit 4408a2d

Please sign in to comment.