Skip to content

Commit 386f984

Browse files
committed
Merge branch 'feat/add_cp210x_ch34x_support' into 'master'
feat: Add support for communication via CP210x and CH34x serial converters Closes ESF-112 See merge request espressif/esp-serial-flasher!160
2 parents ba7fd5c + 8c67fdc commit 386f984

File tree

4 files changed

+73
-30
lines changed

4 files changed

+73
-30
lines changed

examples/esp32_usb_cdc_acm_example/main/main.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
#include "usb/usb_host.h"
2121
#include "usb/cdc_acm_host.h"
2222

23-
#define ESPRESSIF_VID 0x303a
24-
#define ESP_SERIAL_JTAG_PID 0x1001
25-
2623
static const char *TAG = "usb_flasher";
2724
static SemaphoreHandle_t device_disconnected_sem;
2825

@@ -81,8 +78,8 @@ void app_main(void)
8178

8279
while (true) {
8380
const loader_esp32_usb_cdc_acm_config_t config = {
84-
.device_vid = ESPRESSIF_VID,
85-
.device_pid = ESP_SERIAL_JTAG_PID,
81+
.device_vid = USB_VID_PID_AUTO_DETECT,
82+
.device_pid = USB_VID_PID_AUTO_DETECT,
8683
.connection_timeout_ms = 1000,
8784
.out_buffer_size = 4096,
8885
.device_disconnected_callback = device_disconnected_callback,

idf_component.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@ dependencies:
88
rules:
99
- if: "idf_version >=4.4"
1010
- if: "target in [esp32s2, esp32s3, esp32p4]"
11+
usb_host_cp210x_vcp:
12+
version: "^2.2"
13+
rules:
14+
- if: "idf_version >=4.4"
15+
- if: "target in [esp32s2, esp32s3, esp32p4]"
16+
usb_host_ch34x_vcp:
17+
version: "^2.2"
18+
rules:
19+
- if: "idf_version >=4.4"
20+
- if: "target in [esp32s2, esp32s3, esp32p4]"

port/esp32_usb_cdc_acm_port.c

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
#include <stdio.h>
1818
#include "esp_log.h"
1919
#include "esp_timer.h"
20+
#include "usb/cdc_acm_host.h"
21+
#include "usb/vcp_cp210x.h"
22+
#include "usb/vcp_ch34x.h"
23+
#include "esp_loader_io.h"
2024
#include "esp32_usb_cdc_acm_port.h"
2125

22-
#define ESP_SERIAL_JTAG_PID 0x1001
23-
2426
static const char *TAG = "usb_cdc_acm_port";
2527

2628
static cdc_acm_dev_hdl_t s_acm_device;
@@ -104,18 +106,18 @@ static void usb_serial_jtag_enter_booloader(void)
104106
static void usb_serial_converter_reset_target(void)
105107
{
106108
xStreamBufferReset(s_rx_stream_buffer);
107-
cdc_acm_host_set_control_line_state(s_acm_device, true, true);
109+
cdc_acm_host_set_control_line_state(s_acm_device, false, true);
108110
loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
109-
cdc_acm_host_set_control_line_state(s_acm_device, true, false);
111+
cdc_acm_host_set_control_line_state(s_acm_device, false, false);
110112
}
111113

112114
static void usb_serial_converter_enter_bootloader(void)
113115
{
114-
cdc_acm_host_set_control_line_state(s_acm_device, true, false);
115-
116-
usb_serial_converter_reset_target();
117-
116+
xStreamBufferReset(s_rx_stream_buffer);
117+
cdc_acm_host_set_control_line_state(s_acm_device, false, true);
118118
loader_port_delay_ms(SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
119+
cdc_acm_host_set_control_line_state(s_acm_device, true, false);
120+
loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
119121
cdc_acm_host_set_control_line_state(s_acm_device, false, false);
120122
}
121123

@@ -169,11 +171,6 @@ esp_loader_error_t loader_port_esp32_usb_cdc_acm_init(const loader_esp32_usb_cdc
169171
s_device_disconnected_callback = config->device_disconnected_callback;
170172
s_acm_host_serial_state_callback = config->acm_host_serial_state_callback;
171173

172-
/* Different reset and enter bootloader sequences are needed depending on whether the target
173-
* device is connected via internal USB Serial/JTAG or an USB to serial converter which
174-
* connects to target UART and BOOT/RST pins. See pages 1207 and 1208 of the ESP32-S3 TRM */
175-
s_is_usb_serial_jtag = config->device_pid == ESP_SERIAL_JTAG_PID;
176-
177174
s_rx_stream_buffer = xStreamBufferCreate(1024, 1);
178175

179176
if (s_rx_stream_buffer == NULL) {
@@ -189,20 +186,42 @@ esp_loader_error_t loader_port_esp32_usb_cdc_acm_init(const loader_esp32_usb_cdc
189186
.data_cb = handle_usb_data
190187
};
191188

192-
esp_err_t err = cdc_acm_host_open(config->device_vid,
193-
config->device_pid,
194-
0,
195-
&dev_config,
196-
&s_acm_device);
189+
const bool auto_detect = (config->device_vid == USB_VID_PID_AUTO_DETECT ||
190+
config->device_pid == USB_VID_PID_AUTO_DETECT);
197191

198-
if (err != ESP_OK) {
199-
ESP_LOGE(TAG, "Failed to open the USB device");
200-
esp_loader_error_t deinit_status = loader_port_esp32_usb_cdc_acm_deinit();
201-
assert(deinit_status == ESP_LOADER_SUCCESS);
202-
return ESP_LOADER_ERROR_FAIL;
192+
if (auto_detect) {
193+
if (cdc_acm_host_open(ESPRESSIF_VID, ESP_SERIAL_JTAG_PID, 0, &dev_config, &s_acm_device) == ESP_OK) {
194+
s_is_usb_serial_jtag = true;
195+
return ESP_LOADER_SUCCESS;
196+
}
197+
if (cp210x_vcp_open(CP210X_PID_AUTO, 0, &dev_config, &s_acm_device) == ESP_OK) {
198+
s_is_usb_serial_jtag = false;
199+
return ESP_LOADER_SUCCESS;
200+
}
201+
if (ch34x_vcp_open(CH34X_PID_AUTO, 0, &dev_config, &s_acm_device) == ESP_OK) {
202+
s_is_usb_serial_jtag = false;
203+
return ESP_LOADER_SUCCESS;
204+
}
205+
} else {
206+
esp_err_t err;
207+
if (config->device_vid == SILICON_LABS_VID) {
208+
err = cp210x_vcp_open(config->device_pid, 0, &dev_config, &s_acm_device);
209+
} else if (config->device_vid == NANJING_QINHENG_MICROE_VID) {
210+
err = ch34x_vcp_open(config->device_pid, 0, &dev_config, &s_acm_device);
211+
} else {
212+
err = cdc_acm_host_open(config->device_vid, config->device_pid, 0, &dev_config, &s_acm_device);
213+
}
214+
215+
if (err == ESP_OK) {
216+
s_is_usb_serial_jtag = (config->device_vid == ESPRESSIF_VID);
217+
return ESP_LOADER_SUCCESS;
218+
}
203219
}
204220

205-
return ESP_LOADER_SUCCESS;
221+
ESP_LOGE(TAG, "Failed to open any USB device");
222+
esp_loader_error_t deinit_status = loader_port_esp32_usb_cdc_acm_deinit();
223+
assert(deinit_status == ESP_LOADER_SUCCESS);
224+
return ESP_LOADER_ERROR_FAIL;
206225
}
207226

208227

port/esp32_usb_cdc_acm_port.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#pragma once
1717

18-
#include "esp_loader_io.h"
18+
#include "esp_loader.h"
1919
#include "usb/usb_host.h"
2020
#include "usb/cdc_acm_host.h"
2121
#include "freertos/stream_buffer.h"
@@ -24,6 +24,23 @@
2424
extern "C" {
2525
#endif
2626

27+
#define USB_VID_PID_AUTO_DETECT (0) // Use for VID/PID in config to enable auto-detection
28+
29+
#define ESPRESSIF_VID (0x303a)
30+
#define ESP_SERIAL_JTAG_PID (0x1001)
31+
32+
// VID and PID definitions from esp-usb library, only these are supported
33+
#define SILICON_LABS_VID (0x10C4) // Silicon Labs
34+
#define CP210X_PID (0xEA60) // Single i.e. CP2101 - CP2104
35+
#define CP2105_PID (0xEA70) // Dual
36+
#define CP2108_PID (0xEA71) // Quad
37+
38+
#define NANJING_QINHENG_MICROE_VID (0x1A86) // Nanjing Qinheng Microelectronics
39+
#define CH340_PID (0x7522)
40+
#define CH340_PID_1 (0x7523)
41+
#define CH341_PID (0x5523)
42+
43+
2744
typedef void (*loader_port_esp32_usb_cdc_acm_callback_t) (void);
2845

2946
typedef struct {

0 commit comments

Comments
 (0)