Skip to content

Commit

Permalink
uart: support begin and end methods.
Browse files Browse the repository at this point in the history
A component may need to reset uart buffer/status by using begin() and
end() methods. This is useful for example when a component needs to be
sure it is not reading garbage from previously received data over uart.
For end() methods with software serial, disabling interrupt is
currently impossible because of a bug in esp8266 Core:
esp8266/Arduino#6049

Signed-off-by: 0hax <0hax@protonmail.com>
  • Loading branch information
0hax committed Apr 25, 2020
1 parent 64f6c9d commit f933c28
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
30 changes: 29 additions & 1 deletion esphome/components/uart/uart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ void UARTComponent::write_str(const char *str) {
this->hw_serial_->write(str);
ESP_LOGVV(TAG, " Wrote \"%s\"", str);
}
void UARTComponent::end() { this->hw_serial_->end(); }
void UARTComponent::begin() { this->hw_serial_->begin(this->baud_rate_, get_config()); }
bool UARTComponent::read_byte(uint8_t *data) {
if (!this->check_read_timeout_())
return false;
Expand Down Expand Up @@ -272,6 +274,18 @@ void UARTComponent::write_str(const char *str) {
}
ESP_LOGVV(TAG, " Wrote \"%s\"", str);
}
void UARTComponent::end() {
if (this->hw_serial_ != nullptr)
this->hw_serial_->end();
else if (this->sw_serial_ != nullptr)
this->sw_serial_->end();
}
void UARTComponent::begin() {
if (this->hw_serial_ != nullptr)
this->hw_serial_->begin(this->baud_rate_, static_cast<SerialConfig>(get_config()));
else if (this->sw_serial_ != nullptr)
this->sw_serial_->begin();
}
bool UARTComponent::read_byte(uint8_t *data) {
if (!this->check_read_timeout_())
return false;
Expand Down Expand Up @@ -337,7 +351,19 @@ void UARTComponent::flush() {
this->sw_serial_->flush();
}
}

void ESP8266SoftwareSerial::end() {
/* Because of this bug: https://github.com/esp8266/Arduino/issues/6049
* detach_interrupt can't called.
* So simply reset rx_in_pos and rx_out_pos even if it's totally racy with
* the interrupt.
*/
// this->gpio_rx_pin_->detach_interrupt();
this->rx_in_pos_ = 0;
this->rx_out_pos_ = 0;
}
void ESP8266SoftwareSerial::begin() {
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,
std::string &parity) {
this->bit_time_ = F_CPU / baud_rate;
Expand All @@ -346,13 +372,15 @@ void ESP8266SoftwareSerial::setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_ra
this->parity_ = parity;
if (tx_pin != -1) {
auto pin = GPIOPin(tx_pin, OUTPUT);
this->gpio_tx_pin_ = &pin;
pin.setup();
this->tx_pin_ = pin.to_isr();
this->tx_pin_->digital_write(true);
}
if (rx_pin != -1) {
auto pin = GPIOPin(rx_pin, INPUT);
pin.setup();
this->gpio_rx_pin_ = &pin;
this->rx_pin_ = pin.to_isr();
this->rx_buffer_ = new uint8_t[this->rx_buffer_size_];
pin.attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, FALLING);
Expand Down
9 changes: 9 additions & 0 deletions esphome/components/uart/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class ESP8266SoftwareSerial {

int available();

void begin();
void end();
GPIOPin *gpio_tx_pin_{nullptr};
GPIOPin *gpio_rx_pin_{nullptr};

protected:
static void gpio_intr(ESP8266SoftwareSerial *arg);

Expand Down Expand Up @@ -58,6 +63,8 @@ class UARTComponent : public Component, public Stream {
void write_array(const std::vector<uint8_t> &data) { this->write_array(&data[0], data.size()); }

void write_str(const char *str);
void end();
void begin();

bool peek_byte(uint8_t *data);

Expand Down Expand Up @@ -139,6 +146,8 @@ class UARTDevice : public Stream {
size_t write(uint8_t data) override { return this->parent_->write(data); }
int read() override { return this->parent_->read(); }
int peek() override { return this->parent_->peek(); }
void end() { this->parent_->end(); }
void begin() { this->parent_->begin(); }

/// Check that the configuration of the UART bus matches the provided values and otherwise print a warning
void check_uart_settings(uint32_t baud_rate, uint8_t stop_bits = 1);
Expand Down

0 comments on commit f933c28

Please sign in to comment.