ESPHome 2026.2.4
Loading...
Searching...
No Matches
cp210x.cpp
Go to the documentation of this file.
1#if defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
2#include "usb_uart.h"
3#include "usb/usb_host.h"
4#include "esphome/core/log.h"
5
7
8namespace esphome {
9namespace usb_uart {
10
11using namespace bytebuffer;
16static constexpr uint8_t IFC_ENABLE = 0x00; // Enable or disable the interface.
17static constexpr uint8_t SET_BAUDDIV = 0x01; // Set the baud rate divisor.
18static constexpr uint8_t GET_BAUDDIV = 0x02; // Get the baud rate divisor.
19static constexpr uint8_t SET_LINE_CTL = 0x03; // Set the line control.
20static constexpr uint8_t GET_LINE_CTL = 0x04; // Get the line control.
21static constexpr uint8_t SET_BREAK = 0x05; // Set a BREAK.
22static constexpr uint8_t IMM_CHAR = 0x06; // Send character out of order.
23static constexpr uint8_t SET_MHS = 0x07; // Set modem handshaking.
24static constexpr uint8_t GET_MDMSTS = 0x08; // Get modem status.
25static constexpr uint8_t SET_XON = 0x09; // Emulate XON.
26static constexpr uint8_t SET_XOFF = 0x0A; // Emulate XOFF.
27static constexpr uint8_t SET_EVENTMASK = 0x0B; // Set the event mask.
28static constexpr uint8_t GET_EVENTMASK = 0x0C; // Get the event mask.
29static constexpr uint8_t GET_EVENTSTATE = 0x16; // Get the event state.
30static constexpr uint8_t SET_RECEIVE = 0x17; // Set receiver max timeout.
31static constexpr uint8_t GET_RECEIVE = 0x18; // Get receiver max timeout.
32static constexpr uint8_t SET_CHAR = 0x0D; // Set special character individually.
33static constexpr uint8_t GET_CHARS = 0x0E; // Get special characters.
34static constexpr uint8_t GET_PROPS = 0x0F; // Get properties.
35static constexpr uint8_t GET_COMM_STATUS = 0x10; // Get the serial status.
36static constexpr uint8_t RESET = 0x11; // Reset.
37static constexpr uint8_t PURGE = 0x12; // Purge.
38static constexpr uint8_t SET_FLOW = 0x13; // Set flow control.
39static constexpr uint8_t GET_FLOW = 0x14; // Get flow control.
40static constexpr uint8_t EMBED_EVENTS = 0x15; // Control embedding of events in the data stream.
41static constexpr uint8_t GET_BAUDRATE = 0x1D; // Get the baud rate.
42static constexpr uint8_t SET_BAUDRATE = 0x1E; // Set the baud rate.
43static constexpr uint8_t SET_CHARS = 0x19; // Set special characters.
44static constexpr uint8_t VENDOR_SPECIFIC = 0xFF; // Vendor specific command.
45
46std::vector<CdcEps> USBUartTypeCP210X::parse_descriptors(usb_device_handle_t dev_hdl) {
47 const usb_config_desc_t *config_desc;
48 const usb_device_desc_t *device_desc;
49 int conf_offset = 0, ep_offset;
50 std::vector<CdcEps> cdc_devs{};
51
52 // Get required descriptors
53 if (usb_host_get_device_descriptor(dev_hdl, &device_desc) != ESP_OK) {
54 ESP_LOGE(TAG, "get_device_descriptor failed");
55 return {};
56 }
57 if (usb_host_get_active_config_descriptor(dev_hdl, &config_desc) != ESP_OK) {
58 ESP_LOGE(TAG, "get_active_config_descriptor failed");
59 return {};
60 }
61 ESP_LOGD(TAG,
62 "bDeviceClass: %u, bDeviceSubClass: %u\n"
63 "bNumInterfaces: %u",
64 device_desc->bDeviceClass, device_desc->bDeviceSubClass, config_desc->bNumInterfaces);
65 if (device_desc->bDeviceClass != 0) {
66 ESP_LOGE(TAG, "bDeviceClass != 0");
67 return {};
68 }
69
70 for (uint8_t i = 0; i != config_desc->bNumInterfaces; i++) {
71 auto data_desc = usb_parse_interface_descriptor(config_desc, 0, 0, &conf_offset);
72 if (!data_desc) {
73 ESP_LOGE(TAG, "data_desc: usb_parse_interface_descriptor failed");
74 break;
75 }
76 if (data_desc->bNumEndpoints != 2 || data_desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) {
77 ESP_LOGE(TAG, "data_desc: bInterfaceClass == %u, bInterfaceSubClass == %u, bNumEndpoints == %u",
78 data_desc->bInterfaceClass, data_desc->bInterfaceSubClass, data_desc->bNumEndpoints);
79 continue;
80 }
81 ep_offset = conf_offset;
82 auto out_ep = usb_parse_endpoint_descriptor_by_index(data_desc, 0, config_desc->wTotalLength, &ep_offset);
83 if (!out_ep) {
84 ESP_LOGE(TAG, "out_ep: usb_parse_endpoint_descriptor_by_index failed");
85 continue;
86 }
87 ep_offset = conf_offset;
88 auto in_ep = usb_parse_endpoint_descriptor_by_index(data_desc, 1, config_desc->wTotalLength, &ep_offset);
89 if (!in_ep) {
90 ESP_LOGE(TAG, "in_ep: usb_parse_endpoint_descriptor_by_index failed");
91 continue;
92 }
93 if (in_ep->bEndpointAddress & usb_host::USB_DIR_IN) {
94 cdc_devs.push_back({CdcEps{nullptr, in_ep, out_ep, data_desc->bInterfaceNumber}});
95 } else {
96 cdc_devs.push_back({CdcEps{nullptr, out_ep, in_ep, data_desc->bInterfaceNumber}});
97 }
98 }
99 return cdc_devs;
100}
101
103 // enable the channels
104 for (auto channel : this->channels_) {
105 if (!channel->initialised_.load())
106 continue;
108 if (!status.success) {
109 ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
110 channel->initialised_.store(false);
111 }
112 };
113 this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, IFC_ENABLE, 1, channel->index_, callback);
114 uint16_t line_control = channel->stop_bits_;
115 line_control |= static_cast<uint8_t>(channel->parity_) << 4;
116 line_control |= channel->data_bits_ << 8;
117 ESP_LOGD(TAG, "Line control value 0x%X", line_control);
118 this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, SET_LINE_CTL, line_control, channel->index_,
119 callback);
120 auto baud = ByteBuffer::wrap(channel->baud_rate_, LITTLE);
121 this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, SET_BAUDRATE, 0, channel->index_, callback,
122 baud.get_data());
123 }
125}
126} // namespace usb_uart
127} // namespace esphome
128#endif // USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3
uint8_t status
Definition bl0942.h:8
static ByteBuffer wrap(T value, Endian endianness=LITTLE)
Definition bytebuffer.h:156
bool control_transfer(uint8_t type, uint8_t request, uint16_t value, uint16_t index, const transfer_cb_t &callback, const std::vector< uint8_t > &data={})
std::vector< USBUartChannel * > channels_
Definition usb_uart.h:143
std::vector< CdcEps > parse_descriptors(usb_device_handle_t dev_hdl) override
Definition cp210x.cpp:46
std::function< void(const TransferStatus &)> transfer_cb_t
Definition usb_host.h:84
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7