10using namespace bytebuffer;
22static const CH34xEntry CH34X_TABLE[] = {
55 this->
defer([
this, error_code =
status.error_code]() {
56 ESP_LOGE(TAG,
"CH34x chip detection failed: %s", esp_err_to_name(error_code));
57 this->apply_line_settings_();
62 uint8_t num_ports = 1;
63 for (
const auto &e : CH34X_TABLE) {
64 if (e.pid != this->pid_)
66 if (e.match != 0xFF && (
status.data[e.byte_idx] & e.mask) != e.match)
68 chiptype = e.chiptype;
69 num_ports = e.num_ports;
75 const char *name =
"unknown";
76 for (
const auto &e : CH34X_TABLE) {
77 if (e.chiptype == chiptype) {
82 this->
defer([
this, chiptype, num_ports, name]() {
83 this->chiptype_ = chiptype;
84 this->chip_name_ = name;
85 this->num_ports_ = num_ports;
86 ESP_LOGD(TAG,
"CH34x chip: %s, ports: %u", name, this->num_ports_);
87 this->apply_line_settings_();
92 this->
control_transfer(USB_VENDOR_DEV | usb_host::USB_DIR_IN, 0x5F, 0, 0, cb, {0, 0, 0, 0, 0, 0, 0, 0});
97 ESP_LOGCONFIG(TAG,
" CH34x chip: %s", this->chip_name_);
100void USBUartTypeCH34X::apply_line_settings_() {
102 if (!channel->initialised_.load())
106 ESP_LOGE(TAG,
"Control transfer failed, status=%s", esp_err_to_name(
status.error_code));
107 channel->initialised_.store(
false);
114 auto baud_rate = channel->baud_rate_;
115 if (baud_rate < 256000) {
116 if (baud_rate > 6000000 / 255) {
119 }
else if (baud_rate > 750000 / 255) {
122 }
else if (baud_rate > 93750 / 255) {
130 ESP_LOGV(TAG,
"baud_rate: %" PRIu32
", divisor: %d, clk: %" PRIu32, baud_rate, divisor, clk);
131 auto factor =
static_cast<uint8_t
>(clk / baud_rate);
132 if (factor == 0 || factor == 0xFF) {
133 ESP_LOGE(TAG,
"Invalid baud rate %" PRIu32, baud_rate);
134 channel->initialised_.store(
false);
137 if ((clk / factor - baud_rate) > (baud_rate - clk / (factor + 1)))
139 factor = 256 - factor;
141 uint16_t value = 0xC0;
144 switch (channel->parity_) {
148 value |= 8 | ((channel->parity_ - 1) << 4);
151 value |= channel->data_bits_ - 5;
154 uint8_t cmd = 0xA1 + channel->index_;
155 if (channel->index_ >= 2)
157 this->
control_transfer(USB_VENDOR_DEV | usb_host::USB_DIR_OUT, cmd, value, (factor << 8) | divisor, callback);
158 this->
control_transfer(USB_VENDOR_DEV | usb_host::USB_DIR_OUT, cmd + 3, 0x80, 0, callback);
166 for (
auto &cdc_dev : result) {
167 cdc_dev.interrupt_interface_number = 0xFF;
ESPDEPRECATED("Use const char* overload instead. Removed in 2026.7.0", "2026.1.0") void defer(const std voi defer)(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call.