Skip to content

Commit 3ffb236

Browse files
committed
uart: support begin and end methods.
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 <[email protected]>
1 parent cac6117 commit 3ffb236

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

esphome/components/uart/uart.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ void UARTComponent::write_str(const char *str) {
9595
this->hw_serial_->write(str);
9696
ESP_LOGVV(TAG, " Wrote \"%s\"", str);
9797
}
98+
void UARTComponent::end() { this->hw_serial_->end(); }
99+
void UARTComponent::begin() { this->hw_serial_->begin(this->baud_rate_, get_config()); }
98100
bool UARTComponent::read_byte(uint8_t *data) {
99101
if (!this->check_read_timeout_())
100102
return false;
@@ -213,6 +215,18 @@ void UARTComponent::write_str(const char *str) {
213215
}
214216
ESP_LOGVV(TAG, " Wrote \"%s\"", str);
215217
}
218+
void UARTComponent::end() {
219+
if (this->hw_serial_ != nullptr)
220+
this->hw_serial_->end();
221+
else if (this->sw_serial_ != nullptr)
222+
this->sw_serial_->end();
223+
}
224+
void UARTComponent::begin() {
225+
if (this->hw_serial_ != nullptr)
226+
this->hw_serial_->begin(this->baud_rate_, static_cast<SerialConfig>(get_config()));
227+
else if (this->sw_serial_ != nullptr)
228+
this->sw_serial_->begin();
229+
}
216230
bool UARTComponent::read_byte(uint8_t *data) {
217231
if (!this->check_read_timeout_())
218232
return false;
@@ -278,20 +292,34 @@ void UARTComponent::flush() {
278292
this->sw_serial_->flush();
279293
}
280294
}
281-
282-
void ESP8266SoftwareSerial::setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate, uint8_t stop_bits, uint32_t nr_bits,
283-
std::string &parity) {
295+
void ESP8266SoftwareSerial::end() {
296+
/* Because of this bug: https://github.com/esp8266/Arduino/issues/6049
297+
* detach_interrupt can't called.
298+
* So simply reset rx_in_pos and rx_out_pos even if it's totally racy with
299+
* the interrupt.
300+
*/
301+
// this->gpio_rx_pin_->detach_interrupt();
302+
this->rx_in_pos_ = 0;
303+
this->rx_out_pos_ = 0;
304+
}
305+
void ESP8266SoftwareSerial::begin() {
306+
this->gpio_rx_pin_->attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, FALLING);
307+
}
308+
void ESP8266SoftwareSerial::setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate,
309+
uint8_t stop_bits, uint32_t nr_bits, std::string &parity) {
284310

285311
this->bit_time_ = F_CPU / baud_rate;
286312
if (tx_pin != -1) {
287313
auto pin = GPIOPin(tx_pin, OUTPUT);
314+
this->gpio_tx_pin_ = &pin;
288315
pin.setup();
289316
this->tx_pin_ = pin.to_isr();
290317
this->tx_pin_->digital_write(true);
291318
}
292319
if (rx_pin != -1) {
293320
auto pin = GPIOPin(rx_pin, INPUT);
294321
pin.setup();
322+
this->gpio_rx_pin_ = &pin;
295323
this->rx_pin_ = pin.to_isr();
296324
this->rx_buffer_ = new uint8_t[this->rx_buffer_size_];
297325
pin.attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, FALLING);

esphome/components/uart/uart.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ class ESP8266SoftwareSerial {
2222

2323
int available();
2424

25+
void begin();
26+
void end();
27+
GPIOPin *gpio_tx_pin_{nullptr};
28+
GPIOPin *gpio_rx_pin_{nullptr};
29+
2530
protected:
2631
static void gpio_intr(ESP8266SoftwareSerial *arg);
2732

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

6065
void write_str(const char *str);
66+
void end();
67+
void begin();
6168

6269
bool peek_byte(uint8_t *data);
6370

@@ -139,6 +146,8 @@ class UARTDevice : public Stream {
139146
size_t write(uint8_t data) override { return this->parent_->write(data); }
140147
int read() override { return this->parent_->read(); }
141148
int peek() override { return this->parent_->peek(); }
149+
void end() { this->parent_->end(); }
150+
void begin() { this->parent_->begin(); }
142151

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

0 commit comments

Comments
 (0)