Skip to content

Commit 1f2f6a1

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 1fc3466 commit 1f2f6a1

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

esphome/components/uart/uart.cpp

+33-1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ 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() {
99+
this->hw_serial_->end();
100+
}
101+
void UARTComponent::begin() {
102+
this->hw_serial_->begin(this->baud_rate_, get_config());
103+
}
98104
bool UARTComponent::read_byte(uint8_t *data) {
99105
if (!this->check_read_timeout_())
100106
return false;
@@ -214,6 +220,18 @@ void UARTComponent::write_str(const char *str) {
214220
}
215221
ESP_LOGVV(TAG, " Wrote \"%s\"", str);
216222
}
223+
void UARTComponent::end() {
224+
if (this->hw_serial_ != nullptr)
225+
this->hw_serial_->end();
226+
else if (this->sw_serial_ != nullptr)
227+
this->sw_serial_->end();
228+
}
229+
void UARTComponent::begin() {
230+
if (this->hw_serial_ != nullptr)
231+
this->hw_serial_->begin(this->baud_rate_, static_cast<SerialConfig>(get_config()));
232+
else if (this->sw_serial_ != nullptr)
233+
this->sw_serial_->begin();
234+
}
217235
bool UARTComponent::read_byte(uint8_t *data) {
218236
if (!this->check_read_timeout_())
219237
return false;
@@ -279,20 +297,34 @@ void UARTComponent::flush() {
279297
this->sw_serial_->flush();
280298
}
281299
}
282-
300+
void ESP8266SoftwareSerial::end(void) {
301+
/* Because of this bug: https://github.com/esp8266/Arduino/issues/6049
302+
* detach_interrupt can't called.
303+
* So simply reset rx_in_pos and rx_out_pos even if it's totally racy with
304+
* the interrupt.
305+
*/
306+
//this->gpio_rx_pin_->detach_interrupt();
307+
this->rx_in_pos_ = 0;
308+
this->rx_out_pos_ = 0;
309+
}
310+
void ESP8266SoftwareSerial::begin(void) {
311+
this->gpio_rx_pin_->attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, FALLING);
312+
}
283313
void ESP8266SoftwareSerial::setup(int8_t tx_pin, int8_t rx_pin, uint32_t baud_rate,
284314
uint8_t stop_bits, uint32_t nr_bits, std::string &parity) {
285315

286316
this->bit_time_ = F_CPU / baud_rate;
287317
if (tx_pin != -1) {
288318
auto pin = GPIOPin(tx_pin, OUTPUT);
319+
this->gpio_tx_pin_ = &pin;
289320
pin.setup();
290321
this->tx_pin_ = pin.to_isr();
291322
this->tx_pin_->digital_write(true);
292323
}
293324
if (rx_pin != -1) {
294325
auto pin = GPIOPin(rx_pin, INPUT);
295326
pin.setup();
327+
this->gpio_rx_pin_ = &pin;
296328
this->rx_pin_ = pin.to_isr();
297329
this->rx_buffer_ = new uint8_t[this->rx_buffer_size_];
298330
pin.attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, FALLING);

esphome/components/uart/uart.h

+9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ class ESP8266SoftwareSerial {
2222

2323
int available();
2424

25+
void begin(void);
26+
void end(void);
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)