mirror of
https://github.com/esphome/esphome.git
synced 2026-10-23 14:38:52 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc79bf1ad2 | ||
|
|
77aa518265 | ||
|
|
02b4548ad8 | ||
|
|
3ce75e3fb8 | ||
|
|
7f3fa434ee | ||
|
|
4605a0c4a2 | ||
|
|
f6aeca28e0 | ||
|
|
c8404a6493 |
No files matched your search
@@ -108,35 +108,6 @@ std::vector<CdcEps> USBUartTypeCdcAcm::parse_descriptors(usb_device_handle_t dev
|
||||
return cdc_devs;
|
||||
}
|
||||
|
||||
void RingBuffer::push(uint8_t item) {
|
||||
if (this->get_free_space() == 0)
|
||||
return;
|
||||
this->buffer_[this->insert_pos_] = item;
|
||||
this->insert_pos_ = (this->insert_pos_ + 1) % this->buffer_size_;
|
||||
}
|
||||
void RingBuffer::push(const uint8_t *data, size_t len) {
|
||||
size_t free = this->get_free_space();
|
||||
if (len > free)
|
||||
len = free;
|
||||
for (size_t i = 0; i != len; i++) {
|
||||
this->buffer_[this->insert_pos_] = *data++;
|
||||
this->insert_pos_ = (this->insert_pos_ + 1) % this->buffer_size_;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RingBuffer::pop() {
|
||||
uint8_t item = this->buffer_[this->read_pos_];
|
||||
this->read_pos_ = (this->read_pos_ + 1) % this->buffer_size_;
|
||||
return item;
|
||||
}
|
||||
size_t RingBuffer::pop(uint8_t *data, size_t len) {
|
||||
len = std::min(len, this->get_available());
|
||||
for (size_t i = 0; i != len; i++) {
|
||||
*data++ = this->buffer_[this->read_pos_];
|
||||
this->read_pos_ = (this->read_pos_ + 1) % this->buffer_size_;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
void USBUartChannelBase::write_array(const uint8_t *data, size_t len) {
|
||||
if (!this->initialised_.load()) {
|
||||
ESP_LOGD(TAG, "Channel not initialised - write ignored");
|
||||
@@ -188,10 +159,10 @@ uart::UARTFlushResult USBUartChannelBase::flush() {
|
||||
}
|
||||
|
||||
bool USBUartChannelBase::peek_byte(uint8_t *data) {
|
||||
if (this->input_buffer_.is_empty()) {
|
||||
if (this->input_buffer_.empty()) {
|
||||
return false;
|
||||
}
|
||||
*data = this->input_buffer_.peek();
|
||||
*data = this->input_buffer_.front();
|
||||
return true;
|
||||
}
|
||||
bool USBUartChannelBase::read_array(uint8_t *data, size_t len) {
|
||||
@@ -199,18 +170,12 @@ bool USBUartChannelBase::read_array(uint8_t *data, size_t len) {
|
||||
ESP_LOGV(TAG, "Channel not initialised - read ignored");
|
||||
return false;
|
||||
}
|
||||
auto available = this->available();
|
||||
bool status = true;
|
||||
if (len > available) {
|
||||
ESP_LOGV(TAG, "underflow: requested %zu but returned %d, bytes", len, available);
|
||||
len = available;
|
||||
status = false;
|
||||
}
|
||||
for (size_t i = 0; i != len; i++) {
|
||||
*data++ = this->input_buffer_.pop();
|
||||
const size_t got = this->input_buffer_.pop(data, len);
|
||||
if (got < len) {
|
||||
ESP_LOGV(TAG, "underflow: requested %zu but returned %zu bytes", len, got);
|
||||
}
|
||||
this->parent_->start_input(this);
|
||||
return status;
|
||||
return got == len;
|
||||
}
|
||||
void USBUartComponent::setup() { USBClient::setup(); }
|
||||
void USBUartComponent::loop() {
|
||||
@@ -233,7 +198,7 @@ void USBUartComponent::loop() {
|
||||
|
||||
// If there is not enough space for the full chunk, let the device subclass
|
||||
// handle it (e.g. FTDI clears the buffer to prevent mid-telegram corruption).
|
||||
if (channel->input_buffer_.get_free_space() < chunk->length) {
|
||||
if (channel->input_buffer_.free_space() < chunk->length) {
|
||||
this->on_rx_overflow(channel);
|
||||
}
|
||||
// Push data to ring buffer (now safe in main loop)
|
||||
|
||||
@@ -112,28 +112,6 @@ enum class ConfigMode : uint8_t {
|
||||
CONFIG_MODE_MODEM, ///< Apply the DTR/RTS state of one already-open channel
|
||||
};
|
||||
|
||||
class RingBuffer {
|
||||
public:
|
||||
RingBuffer(uint16_t buffer_size) : buffer_size_(buffer_size), buffer_(new uint8_t[buffer_size]) {}
|
||||
bool is_empty() const { return this->read_pos_ == this->insert_pos_; }
|
||||
size_t get_available() const {
|
||||
return (this->insert_pos_ + this->buffer_size_ - this->read_pos_) % this->buffer_size_;
|
||||
};
|
||||
size_t get_free_space() const { return this->buffer_size_ - 1 - this->get_available(); }
|
||||
uint8_t peek() const { return this->buffer_[this->read_pos_]; }
|
||||
void push(uint8_t item);
|
||||
void push(const uint8_t *data, size_t len);
|
||||
uint8_t pop();
|
||||
size_t pop(uint8_t *data, size_t len);
|
||||
void clear() { this->read_pos_ = this->insert_pos_ = 0; }
|
||||
|
||||
protected:
|
||||
uint16_t insert_pos_ = 0;
|
||||
uint16_t read_pos_ = 0;
|
||||
uint16_t buffer_size_;
|
||||
uint8_t *buffer_;
|
||||
};
|
||||
|
||||
// Structure for queuing received USB data chunks
|
||||
struct UsbDataChunk {
|
||||
uint8_t data[usb_host::USB_MAX_PACKET_SIZE];
|
||||
@@ -174,7 +152,7 @@ class USBUartChannelBase : public uart::UARTComponent, public Parented<USBUartCo
|
||||
void write_array(const uint8_t *data, size_t len) override;
|
||||
bool peek_byte(uint8_t *data) override;
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
size_t available() override { return this->input_buffer_.get_available(); }
|
||||
size_t available() override { return this->input_buffer_.size(); }
|
||||
bool is_connected() override { return this->initialised_.load(); }
|
||||
uart::UARTFlushResult flush() override;
|
||||
// Re-apply the current line settings (baud, parity, etc) to this already-open channel.
|
||||
@@ -215,12 +193,13 @@ class USBUartChannelBase : public uart::UARTComponent, public Parented<USBUartCo
|
||||
|
||||
protected:
|
||||
// Not directly instantiable; construct a concrete channel type instead.
|
||||
USBUartChannelBase(uint8_t index, uint16_t buffer_size) : input_buffer_(RingBuffer(buffer_size)), index_(index) {}
|
||||
USBUartChannelBase(uint8_t index, uint16_t buffer_size) : index_(index) { this->input_buffer_.init(buffer_size); }
|
||||
void check_logger_conflict() override {}
|
||||
LineStopBits line_stop_bits_() const;
|
||||
LineParity line_parity_() const;
|
||||
// Larger structures first (8+ bytes)
|
||||
RingBuffer input_buffer_;
|
||||
// Only the main loop touches it; the USB task hands data over through usb_data_queue_
|
||||
FixedRingBuffer<uint8_t> input_buffer_;
|
||||
LockFreeQueue<UsbOutputChunk, USB_OUTPUT_CHUNK_COUNT> output_queue_;
|
||||
// Pool sized to queue capacity (SIZE-1) because LockFreeQueue<T,N> is a ring
|
||||
// buffer that holds N-1 elements. This guarantees allocate() returns nullptr
|
||||
|
||||
Reference in new issue
Block a user