Compare commits

...
2 changed files with 11 additions and 67 deletions

No files matched your search

+7 -42
View File
@@ -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)
+4 -25
View File
@@ -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