diff --git a/esphome/components/uart/uart_component_esp8266.cpp b/esphome/components/uart/uart_component_esp8266.cpp index 0819a1bfb00..9316e90eda1 100644 --- a/esphome/components/uart/uart_component_esp8266.cpp +++ b/esphome/components/uart/uart_component_esp8266.cpp @@ -24,6 +24,8 @@ static constexpr uint32_t RX_TICKS_PER_SECOND = 16000000; __attribute__((always_inline)) static inline uint32_t rx_now() { return micros() << 4; } bool ESP8266UartComponent::serial0_in_use = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +bool ESP8266UartComponent::serial0_swapped = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + uint32_t ESP8266UartComponent::get_config() { uint32_t config = 0; @@ -111,6 +113,7 @@ void ESP8266UartComponent::setup() { this->hw_serial_->setRxBufferSize(this->rx_buffer_size_); this->hw_serial_->swap(); ESP8266UartComponent::serial0_in_use = true; + ESP8266UartComponent::serial0_swapped = true; } else #endif // USE_ESP8266_UART_SERIAL #ifdef USE_ESP8266_UART_SERIAL1 @@ -133,6 +136,11 @@ void ESP8266UartComponent::load_settings(bool dump_config) { SerialConfig config = static_cast(get_config()); this->hw_serial_->begin(this->baud_rate_, config); this->hw_serial_->setRxBufferSize(this->rx_buffer_size_); +#ifdef USE_ESP8266_UART_SERIAL + // begin() puts UART0 back on GPIO1/GPIO3, so swap it again like setup() did for GPIO15/GPIO13 + if (this->hw_serial_ == &Serial && ESP8266UartComponent::serial0_swapped) + this->hw_serial_->swap(); +#endif // USE_ESP8266_UART_SERIAL } else { this->sw_serial_->setup(this->tx_pin_, this->rx_pin_, this->baud_rate_, this->stop_bits_, this->data_bits_, this->parity_, this->rx_buffer_size_); diff --git a/esphome/components/uart/uart_component_esp8266.h b/esphome/components/uart/uart_component_esp8266.h index 3d4a2ba85bc..a29373a9d4b 100644 --- a/esphome/components/uart/uart_component_esp8266.h +++ b/esphome/components/uart/uart_component_esp8266.h @@ -92,7 +92,8 @@ class ESP8266UartComponent final : public UARTComponent, public Component { ESP8266SoftwareSerial *sw_serial_{nullptr}; private: - static bool serial0_in_use; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + static bool serial0_in_use; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) + static bool serial0_swapped; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) }; } // namespace esphome::uart diff --git a/tests/components/uart/test.esp8266-ard.yaml b/tests/components/uart/test.esp8266-ard.yaml index 4c9d6fd7367..09d23e2925e 100644 --- a/tests/components/uart/test.esp8266-ard.yaml +++ b/tests/components/uart/test.esp8266-ard.yaml @@ -7,6 +7,8 @@ esphome: - uart.write: id: uart_id data: [0x00, 0x20, 0x42] + - lambda: |- + id(uart_swapped).load_settings(false); uart: - id: uart_id @@ -23,6 +25,10 @@ uart: baud_rate: 115200 debug: debug_prefix: "[UART1] " + - id: uart_swapped + tx_pin: 15 + rx_pin: 13 + baud_rate: 9600 switch: - platform: uart