Extend uart: with rx_buffer_size: (#1006)

* Extend `uart:` with `rx_buffer_size:`

This allows to configure `rx_buffer_size:`
to efficiently receive big payloads over UART

* lint

* remove old default value

* add test

Co-authored-by: Guillermo Ruffino <glm.net@gmail.com>
This commit is contained in:
Kamil Trzciński 2020-06-10 02:22:06 +02:00 committed by GitHub
parent 64bd33a94e
commit cd7af19e7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 20 additions and 5 deletions

View file

@ -1,7 +1,8 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome import pins, automation from esphome import pins, automation
from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN, CONF_UART_ID, CONF_DATA from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN, CONF_UART_ID, \
CONF_DATA, CONF_RX_BUFFER_SIZE
from esphome.core import CORE, coroutine from esphome.core import CORE, coroutine
uart_ns = cg.esphome_ns.namespace('uart') uart_ns = cg.esphome_ns.namespace('uart')
@ -44,6 +45,7 @@ CONFIG_SCHEMA = cv.All(cv.Schema({
cv.Required(CONF_BAUD_RATE): cv.int_range(min=1), cv.Required(CONF_BAUD_RATE): cv.int_range(min=1),
cv.Optional(CONF_TX_PIN): pins.output_pin, cv.Optional(CONF_TX_PIN): pins.output_pin,
cv.Optional(CONF_RX_PIN): validate_rx_pin, cv.Optional(CONF_RX_PIN): validate_rx_pin,
cv.Optional(CONF_RX_BUFFER_SIZE, default=256): cv.validate_bytes,
cv.Optional(CONF_STOP_BITS, default=1): cv.one_of(1, 2, int=True), cv.Optional(CONF_STOP_BITS, default=1): cv.one_of(1, 2, int=True),
cv.Optional(CONF_DATA_BITS, default=8): cv.int_range(min=5, max=8), cv.Optional(CONF_DATA_BITS, default=8): cv.int_range(min=5, max=8),
cv.Optional(CONF_PARITY, default="NONE"): cv.enum(UART_PARITY_OPTIONS, upper=True) cv.Optional(CONF_PARITY, default="NONE"): cv.enum(UART_PARITY_OPTIONS, upper=True)
@ -61,6 +63,7 @@ def to_code(config):
cg.add(var.set_tx_pin(config[CONF_TX_PIN])) cg.add(var.set_tx_pin(config[CONF_TX_PIN]))
if CONF_RX_PIN in config: if CONF_RX_PIN in config:
cg.add(var.set_rx_pin(config[CONF_RX_PIN])) cg.add(var.set_rx_pin(config[CONF_RX_PIN]))
cg.add(var.set_rx_buffer_size(config[CONF_RX_BUFFER_SIZE]))
cg.add(var.set_stop_bits(config[CONF_STOP_BITS])) cg.add(var.set_stop_bits(config[CONF_STOP_BITS]))
cg.add(var.set_data_bits(config[CONF_DATA_BITS])) cg.add(var.set_data_bits(config[CONF_DATA_BITS]))
cg.add(var.set_parity(config[CONF_PARITY])) cg.add(var.set_parity(config[CONF_PARITY]))

View file

@ -19,7 +19,7 @@ const char *parity_to_str(UARTParityOptions parity);
class ESP8266SoftwareSerial { class ESP8266SoftwareSerial {
public: public:
void setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate, uint8_t stop_bits, uint32_t nr_bits, void setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate, uint8_t stop_bits, uint32_t nr_bits,
UARTParityOptions parity); UARTParityOptions parity, size_t rx_buffer_size);
uint8_t read_byte(); uint8_t read_byte();
uint8_t peek_byte(); uint8_t peek_byte();
@ -44,7 +44,7 @@ class ESP8266SoftwareSerial {
uint32_t bit_time_{0}; uint32_t bit_time_{0};
uint8_t *rx_buffer_{nullptr}; uint8_t *rx_buffer_{nullptr};
size_t rx_buffer_size_{512}; size_t rx_buffer_size_;
volatile size_t rx_in_pos_{0}; volatile size_t rx_in_pos_{0};
size_t rx_out_pos_{0}; size_t rx_out_pos_{0};
uint8_t stop_bits_; uint8_t stop_bits_;
@ -93,6 +93,7 @@ class UARTComponent : public Component, public Stream {
void set_tx_pin(uint8_t tx_pin) { this->tx_pin_ = tx_pin; } void set_tx_pin(uint8_t tx_pin) { this->tx_pin_ = tx_pin; }
void set_rx_pin(uint8_t rx_pin) { this->rx_pin_ = rx_pin; } void set_rx_pin(uint8_t rx_pin) { this->rx_pin_ = rx_pin; }
void set_rx_buffer_size(size_t rx_buffer_size) { this->rx_buffer_size_ = rx_buffer_size; }
void set_stop_bits(uint8_t stop_bits) { this->stop_bits_ = stop_bits; } void set_stop_bits(uint8_t stop_bits) { this->stop_bits_ = stop_bits; }
void set_data_bits(uint8_t nr_bits) { this->nr_bits_ = nr_bits; } void set_data_bits(uint8_t nr_bits) { this->nr_bits_ = nr_bits; }
void set_parity(UARTParityOptions parity) { this->parity_ = parity; } void set_parity(UARTParityOptions parity) { this->parity_ = parity; }
@ -108,6 +109,7 @@ class UARTComponent : public Component, public Stream {
#endif #endif
optional<uint8_t> tx_pin_; optional<uint8_t> tx_pin_;
optional<uint8_t> rx_pin_; optional<uint8_t> rx_pin_;
size_t rx_buffer_size_;
uint32_t baud_rate_; uint32_t baud_rate_;
uint8_t stop_bits_; uint8_t stop_bits_;
uint8_t nr_bits_; uint8_t nr_bits_;

View file

@ -81,6 +81,7 @@ void UARTComponent::setup() {
int8_t tx = this->tx_pin_.has_value() ? *this->tx_pin_ : -1; int8_t tx = this->tx_pin_.has_value() ? *this->tx_pin_ : -1;
int8_t rx = this->rx_pin_.has_value() ? *this->rx_pin_ : -1; int8_t rx = this->rx_pin_.has_value() ? *this->rx_pin_ : -1;
this->hw_serial_->begin(this->baud_rate_, get_config(), rx, tx); this->hw_serial_->begin(this->baud_rate_, get_config(), rx, tx);
this->hw_serial_->setRxBufferSize(this->rx_buffer_size_);
} }
void UARTComponent::dump_config() { void UARTComponent::dump_config() {
@ -90,6 +91,7 @@ void UARTComponent::dump_config() {
} }
if (this->rx_pin_.has_value()) { if (this->rx_pin_.has_value()) {
ESP_LOGCONFIG(TAG, " RX Pin: GPIO%d", *this->rx_pin_); ESP_LOGCONFIG(TAG, " RX Pin: GPIO%d", *this->rx_pin_);
ESP_LOGCONFIG(TAG, " RX Buffer Size: %u", this->rx_buffer_size_);
} }
ESP_LOGCONFIG(TAG, " Baud Rate: %u baud", this->baud_rate_); ESP_LOGCONFIG(TAG, " Baud Rate: %u baud", this->baud_rate_);
ESP_LOGCONFIG(TAG, " Bits: %u", this->nr_bits_); ESP_LOGCONFIG(TAG, " Bits: %u", this->nr_bits_);

View file

@ -52,18 +52,22 @@ void UARTComponent::setup() {
if (this->tx_pin_.value_or(1) == 1 && this->rx_pin_.value_or(3) == 3) { if (this->tx_pin_.value_or(1) == 1 && this->rx_pin_.value_or(3) == 3) {
this->hw_serial_ = &Serial; this->hw_serial_ = &Serial;
this->hw_serial_->begin(this->baud_rate_, config); this->hw_serial_->begin(this->baud_rate_, config);
this->hw_serial_->setRxBufferSize(this->rx_buffer_size_);
} else if (this->tx_pin_.value_or(15) == 15 && this->rx_pin_.value_or(13) == 13) { } else if (this->tx_pin_.value_or(15) == 15 && this->rx_pin_.value_or(13) == 13) {
this->hw_serial_ = &Serial; this->hw_serial_ = &Serial;
this->hw_serial_->begin(this->baud_rate_, config); this->hw_serial_->begin(this->baud_rate_, config);
this->hw_serial_->setRxBufferSize(this->rx_buffer_size_);
this->hw_serial_->swap(); this->hw_serial_->swap();
} else if (this->tx_pin_.value_or(2) == 2 && this->rx_pin_.value_or(8) == 8) { } else if (this->tx_pin_.value_or(2) == 2 && this->rx_pin_.value_or(8) == 8) {
this->hw_serial_ = &Serial1; this->hw_serial_ = &Serial1;
this->hw_serial_->begin(this->baud_rate_, config); this->hw_serial_->begin(this->baud_rate_, config);
this->hw_serial_->setRxBufferSize(this->rx_buffer_size_);
} else { } else {
this->sw_serial_ = new ESP8266SoftwareSerial(); this->sw_serial_ = new ESP8266SoftwareSerial();
int8_t tx = this->tx_pin_.has_value() ? *this->tx_pin_ : -1; int8_t tx = this->tx_pin_.has_value() ? *this->tx_pin_ : -1;
int8_t rx = this->rx_pin_.has_value() ? *this->rx_pin_ : -1; int8_t rx = this->rx_pin_.has_value() ? *this->rx_pin_ : -1;
this->sw_serial_->setup(tx, rx, this->baud_rate_, this->stop_bits_, this->nr_bits_, this->parity_); this->sw_serial_->setup(tx, rx, this->baud_rate_, this->stop_bits_, this->nr_bits_, this->parity_,
this->rx_buffer_size_);
} }
} }
@ -74,6 +78,7 @@ void UARTComponent::dump_config() {
} }
if (this->rx_pin_.has_value()) { if (this->rx_pin_.has_value()) {
ESP_LOGCONFIG(TAG, " RX Pin: GPIO%d", *this->rx_pin_); ESP_LOGCONFIG(TAG, " RX Pin: GPIO%d", *this->rx_pin_);
ESP_LOGCONFIG(TAG, " RX Buffer Size: %u", this->rx_buffer_size_); // NOLINT
} }
ESP_LOGCONFIG(TAG, " Baud Rate: %u baud", this->baud_rate_); ESP_LOGCONFIG(TAG, " Baud Rate: %u baud", this->baud_rate_);
ESP_LOGCONFIG(TAG, " Bits: %u", this->nr_bits_); ESP_LOGCONFIG(TAG, " Bits: %u", this->nr_bits_);
@ -210,8 +215,9 @@ void ESP8266SoftwareSerial::begin() {
// this->gpio_rx_pin_->attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, FALLING); // this->gpio_rx_pin_->attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, FALLING);
} }
void ESP8266SoftwareSerial::setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate, uint8_t stop_bits, uint32_t nr_bits, void ESP8266SoftwareSerial::setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate, uint8_t stop_bits, uint32_t nr_bits,
UARTParityOptions parity) { UARTParityOptions parity, size_t rx_buffer_size) {
this->bit_time_ = F_CPU / baud_rate; this->bit_time_ = F_CPU / baud_rate;
this->rx_buffer_size_ = rx_buffer_size;
this->stop_bits_ = stop_bits; this->stop_bits_ = stop_bits;
this->nr_bits_ = nr_bits; this->nr_bits_ = nr_bits;
this->parity_ = parity; this->parity_ = parity;

View file

@ -395,6 +395,7 @@ CONF_RTD_WIRES = 'rtd_wires'
CONF_RUN_CYCLES = 'run_cycles' CONF_RUN_CYCLES = 'run_cycles'
CONF_RUN_DURATION = 'run_duration' CONF_RUN_DURATION = 'run_duration'
CONF_RW_PIN = 'rw_pin' CONF_RW_PIN = 'rw_pin'
CONF_RX_BUFFER_SIZE = 'rx_buffer_size'
CONF_RX_ONLY = 'rx_only' CONF_RX_ONLY = 'rx_only'
CONF_RX_PIN = 'rx_pin' CONF_RX_PIN = 'rx_pin'
CONF_SAFE_MODE = 'safe_mode' CONF_SAFE_MODE = 'safe_mode'

View file

@ -135,6 +135,7 @@ uart:
parity: NONE parity: NONE
data_bits: 8 data_bits: 8
stop_bits: 1 stop_bits: 1
rx_buffer_size: 512
ota: ota:
safe_mode: True safe_mode: True