mirror of
https://github.com/esphome/esphome.git
synced 2025-09-26 23:22:21 +01:00
ato
This commit is contained in:
@@ -16,12 +16,12 @@ using namespace bytebuffer;
|
|||||||
void USBUartTypeCH34X::enable_channels() {
|
void USBUartTypeCH34X::enable_channels() {
|
||||||
// enable the channels
|
// enable the channels
|
||||||
for (auto channel : this->channels_) {
|
for (auto channel : this->channels_) {
|
||||||
if (!channel->initialised_)
|
if (!channel->initialised_.load())
|
||||||
continue;
|
continue;
|
||||||
usb_host::transfer_cb_t callback = [=](const usb_host::TransferStatus &status) {
|
usb_host::transfer_cb_t callback = [=](const usb_host::TransferStatus &status) {
|
||||||
if (!status.success) {
|
if (!status.success) {
|
||||||
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
||||||
channel->initialised_ = false;
|
channel->initialised_.store(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ void USBUartTypeCH34X::enable_channels() {
|
|||||||
auto factor = static_cast<uint8_t>(clk / baud_rate);
|
auto factor = static_cast<uint8_t>(clk / baud_rate);
|
||||||
if (factor == 0 || factor == 0xFF) {
|
if (factor == 0 || factor == 0xFF) {
|
||||||
ESP_LOGE(TAG, "Invalid baud rate %" PRIu32, baud_rate);
|
ESP_LOGE(TAG, "Invalid baud rate %" PRIu32, baud_rate);
|
||||||
channel->initialised_ = false;
|
channel->initialised_.store(false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((clk / factor - baud_rate) > (baud_rate - clk / (factor + 1)))
|
if ((clk / factor - baud_rate) > (baud_rate - clk / (factor + 1)))
|
||||||
|
@@ -100,12 +100,12 @@ std::vector<CdcEps> USBUartTypeCP210X::parse_descriptors(usb_device_handle_t dev
|
|||||||
void USBUartTypeCP210X::enable_channels() {
|
void USBUartTypeCP210X::enable_channels() {
|
||||||
// enable the channels
|
// enable the channels
|
||||||
for (auto channel : this->channels_) {
|
for (auto channel : this->channels_) {
|
||||||
if (!channel->initialised_)
|
if (!channel->initialised_.load())
|
||||||
continue;
|
continue;
|
||||||
usb_host::transfer_cb_t callback = [=](const usb_host::TransferStatus &status) {
|
usb_host::transfer_cb_t callback = [=](const usb_host::TransferStatus &status) {
|
||||||
if (!status.success) {
|
if (!status.success) {
|
||||||
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
||||||
channel->initialised_ = false;
|
channel->initialised_.store(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, IFC_ENABLE, 1, channel->index_, callback);
|
this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, IFC_ENABLE, 1, channel->index_, callback);
|
||||||
|
@@ -130,7 +130,7 @@ size_t RingBuffer::pop(uint8_t *data, size_t len) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
void USBUartChannel::write_array(const uint8_t *data, size_t len) {
|
void USBUartChannel::write_array(const uint8_t *data, size_t len) {
|
||||||
if (!this->initialised_) {
|
if (!this->initialised_.load()) {
|
||||||
ESP_LOGV(TAG, "Channel not initialised - write ignored");
|
ESP_LOGV(TAG, "Channel not initialised - write ignored");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ bool USBUartChannel::peek_byte(uint8_t *data) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool USBUartChannel::read_array(uint8_t *data, size_t len) {
|
bool USBUartChannel::read_array(uint8_t *data, size_t len) {
|
||||||
if (!this->initialised_) {
|
if (!this->initialised_.load()) {
|
||||||
ESP_LOGV(TAG, "Channel not initialised - read ignored");
|
ESP_LOGV(TAG, "Channel not initialised - read ignored");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ void USBUartComponent::dump_config() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void USBUartComponent::start_input(USBUartChannel *channel) {
|
void USBUartComponent::start_input(USBUartChannel *channel) {
|
||||||
if (!channel->initialised_ || channel->input_started_)
|
if (!channel->initialised_.load() || channel->input_started_.load())
|
||||||
return;
|
return;
|
||||||
// Note: We no longer check ring buffer space here since this may be called from USB task
|
// Note: We no longer check ring buffer space here since this may be called from USB task
|
||||||
// The lock-free queue provides backpressure instead
|
// The lock-free queue provides backpressure instead
|
||||||
@@ -234,7 +234,7 @@ void USBUartComponent::start_input(USBUartChannel *channel) {
|
|||||||
if (chunk == nullptr) {
|
if (chunk == nullptr) {
|
||||||
ESP_LOGW(TAG, "No free chunks available, dropping %u bytes", status.data_len);
|
ESP_LOGW(TAG, "No free chunks available, dropping %u bytes", status.data_len);
|
||||||
// Mark input as not started so we can retry
|
// Mark input as not started so we can retry
|
||||||
channel->input_started_ = false;
|
channel->input_started_.store(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,15 +250,15 @@ void USBUartComponent::start_input(USBUartChannel *channel) {
|
|||||||
|
|
||||||
// Always restart input immediately from USB task
|
// Always restart input immediately from USB task
|
||||||
// The lock-free queue will handle backpressure
|
// The lock-free queue will handle backpressure
|
||||||
channel->input_started_ = false;
|
channel->input_started_.store(false);
|
||||||
this->start_input(channel);
|
this->start_input(channel);
|
||||||
};
|
};
|
||||||
channel->input_started_ = true;
|
channel->input_started_.store(true);
|
||||||
this->transfer_in(ep->bEndpointAddress, callback, ep->wMaxPacketSize);
|
this->transfer_in(ep->bEndpointAddress, callback, ep->wMaxPacketSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBUartComponent::start_output(USBUartChannel *channel) {
|
void USBUartComponent::start_output(USBUartChannel *channel) {
|
||||||
if (channel->output_started_)
|
if (channel->output_started_.load())
|
||||||
return;
|
return;
|
||||||
if (channel->output_buffer_.is_empty()) {
|
if (channel->output_buffer_.is_empty()) {
|
||||||
return;
|
return;
|
||||||
@@ -267,11 +267,11 @@ void USBUartComponent::start_output(USBUartChannel *channel) {
|
|||||||
// CALLBACK CONTEXT: This lambda is executed in USB task via transfer_callback
|
// CALLBACK CONTEXT: This lambda is executed in USB task via transfer_callback
|
||||||
auto callback = [this, channel](const usb_host::TransferStatus &status) {
|
auto callback = [this, channel](const usb_host::TransferStatus &status) {
|
||||||
ESP_LOGV(TAG, "Output Transfer result: length: %u; status %X", status.data_len, status.error_code);
|
ESP_LOGV(TAG, "Output Transfer result: length: %u; status %X", status.data_len, status.error_code);
|
||||||
channel->output_started_ = false;
|
channel->output_started_.store(false);
|
||||||
// Defer restart to main loop (defer is thread-safe)
|
// Defer restart to main loop (defer is thread-safe)
|
||||||
this->defer([this, channel] { this->start_output(channel); });
|
this->defer([this, channel] { this->start_output(channel); });
|
||||||
};
|
};
|
||||||
channel->output_started_ = true;
|
channel->output_started_.store(true);
|
||||||
uint8_t data[ep->wMaxPacketSize];
|
uint8_t data[ep->wMaxPacketSize];
|
||||||
auto len = channel->output_buffer_.pop(data, ep->wMaxPacketSize);
|
auto len = channel->output_buffer_.pop(data, ep->wMaxPacketSize);
|
||||||
this->transfer_out(ep->bEndpointAddress, callback, data, len);
|
this->transfer_out(ep->bEndpointAddress, callback, data, len);
|
||||||
@@ -314,7 +314,7 @@ void USBUartTypeCdcAcm::on_connected() {
|
|||||||
channel->cdc_dev_ = cdc_devs[i++];
|
channel->cdc_dev_ = cdc_devs[i++];
|
||||||
fix_mps(channel->cdc_dev_.in_ep);
|
fix_mps(channel->cdc_dev_.in_ep);
|
||||||
fix_mps(channel->cdc_dev_.out_ep);
|
fix_mps(channel->cdc_dev_.out_ep);
|
||||||
channel->initialised_ = true;
|
channel->initialised_.store(true);
|
||||||
auto err =
|
auto err =
|
||||||
usb_host_interface_claim(this->handle_, this->device_handle_, channel->cdc_dev_.bulk_interface_number, 0);
|
usb_host_interface_claim(this->handle_, this->device_handle_, channel->cdc_dev_.bulk_interface_number, 0);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
@@ -343,9 +343,9 @@ void USBUartTypeCdcAcm::on_disconnected() {
|
|||||||
usb_host_endpoint_flush(this->device_handle_, channel->cdc_dev_.notify_ep->bEndpointAddress);
|
usb_host_endpoint_flush(this->device_handle_, channel->cdc_dev_.notify_ep->bEndpointAddress);
|
||||||
}
|
}
|
||||||
usb_host_interface_release(this->handle_, this->device_handle_, channel->cdc_dev_.bulk_interface_number);
|
usb_host_interface_release(this->handle_, this->device_handle_, channel->cdc_dev_.bulk_interface_number);
|
||||||
channel->initialised_ = false;
|
channel->initialised_.store(false);
|
||||||
channel->input_started_ = false;
|
channel->input_started_.store(false);
|
||||||
channel->output_started_ = false;
|
channel->output_started_.store(false);
|
||||||
channel->input_buffer_.clear();
|
channel->input_buffer_.clear();
|
||||||
channel->output_buffer_.clear();
|
channel->output_buffer_.clear();
|
||||||
}
|
}
|
||||||
@@ -354,10 +354,10 @@ void USBUartTypeCdcAcm::on_disconnected() {
|
|||||||
|
|
||||||
void USBUartTypeCdcAcm::enable_channels() {
|
void USBUartTypeCdcAcm::enable_channels() {
|
||||||
for (auto *channel : this->channels_) {
|
for (auto *channel : this->channels_) {
|
||||||
if (!channel->initialised_)
|
if (!channel->initialised_.load())
|
||||||
continue;
|
continue;
|
||||||
channel->input_started_ = false;
|
channel->input_started_.store(false);
|
||||||
channel->output_started_ = false;
|
channel->output_started_.store(false);
|
||||||
this->start_input(channel);
|
this->start_input(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include "esphome/components/usb_host/usb_host.h"
|
#include "esphome/components/usb_host/usb_host.h"
|
||||||
#include "esphome/core/lock_free_queue.h"
|
#include "esphome/core/lock_free_queue.h"
|
||||||
#include "esphome/core/event_pool.h"
|
#include "esphome/core/event_pool.h"
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace usb_uart {
|
namespace usb_uart {
|
||||||
@@ -111,12 +112,12 @@ class USBUartChannel : public uart::UARTComponent, public Parented<USBUartCompon
|
|||||||
RingBuffer input_buffer_;
|
RingBuffer input_buffer_;
|
||||||
RingBuffer output_buffer_;
|
RingBuffer output_buffer_;
|
||||||
UARTParityOptions parity_{UART_CONFIG_PARITY_NONE};
|
UARTParityOptions parity_{UART_CONFIG_PARITY_NONE};
|
||||||
bool input_started_{true};
|
std::atomic<bool> input_started_{true};
|
||||||
bool output_started_{true};
|
std::atomic<bool> output_started_{true};
|
||||||
CdcEps cdc_dev_{};
|
CdcEps cdc_dev_{};
|
||||||
bool debug_{};
|
bool debug_{};
|
||||||
bool dummy_receiver_{};
|
bool dummy_receiver_{};
|
||||||
bool initialised_{};
|
std::atomic<bool> initialised_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
class USBUartComponent : public usb_host::USBClient {
|
class USBUartComponent : public usb_host::USBClient {
|
||||||
|
Reference in New Issue
Block a user