diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp
index 6d762da21fb..42acdb742b7 100644
--- a/cores/esp32/HardwareSerial.cpp
+++ b/cores/esp32/HardwareSerial.cpp
@@ -578,6 +578,10 @@ void HardwareSerial::setRxInvert(bool invert) {
   uartSetRxInvert(_uart, invert);
 }
 
+void HardwareSerial::setTxInvert(bool invert) {
+  uartSetTxInvert(_uart, invert);
+}
+
 // negative Pin value will keep it unmodified
 // can be called after or before begin()
 bool HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h
index e974f112701..c6dc917706d 100644
--- a/cores/esp32/HardwareSerial.h
+++ b/cores/esp32/HardwareSerial.h
@@ -349,6 +349,7 @@ class HardwareSerial : public Stream {
   void setDebugOutput(bool);
 
   void setRxInvert(bool);
+  void setTxInvert(bool);
 
   // Negative Pin Number will keep it unmodified, thus this function can set individual pins
   // setPins() can be called after or before begin()
diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c
index 5311aff4f37..745fbace533 100644
--- a/cores/esp32/esp32-hal-uart.c
+++ b/cores/esp32/esp32-hal-uart.c
@@ -847,6 +847,30 @@ void uartSetRxInvert(uart_t *uart, bool invert) {
 #endif
 }
 
+void uartSetTxInvert(uart_t *uart, bool invert) {
+  if (uart == NULL) {
+    return;
+  }
+#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
+  // POTENTIAL ISSUE :: original code only set/reset txd_inv bit
+  // IDF or LL set/reset the whole inv_mask!
+  // if (invert)
+  //     ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_TXD_INV));
+  // else
+  //     ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_INV_DISABLE));
+  log_e("uartSetTxInvert is not supported in ESP32C6, ESP32H2 and ESP32P4");
+#else
+  // this implementation is better over IDF API because it only affects TXD
+  // this is supported in ESP32, ESP32-S2 and ESP32-C3
+  uart_dev_t *hw = UART_LL_GET_HW(uart->num);
+  if (invert) {
+    hw->conf0.txd_inv = 1;
+  } else {
+    hw->conf0.txd_inv = 0;
+  }
+#endif
+}
+
 uint32_t uartAvailable(uart_t *uart) {
 
   if (uart == NULL) {
diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h
index 41b005aa151..4f23ab629f5 100644
--- a/cores/esp32/esp32-hal-uart.h
+++ b/cores/esp32/esp32-hal-uart.h
@@ -62,6 +62,7 @@ bool uartSetBaudRate(uart_t *uart, uint32_t baud_rate);
 uint32_t uartGetBaudRate(uart_t *uart);
 
 void uartSetRxInvert(uart_t *uart, bool invert);
+void uartSetTxInvert(uart_t *uart, bool invert);
 bool uartSetRxTimeout(uart_t *uart, uint8_t numSymbTimeout);
 bool uartSetRxFIFOFull(uart_t *uart, uint8_t numBytesFIFOFull);
 void uartSetFastReading(uart_t *uart);
diff --git a/tests/validation/uart/uart.ino b/tests/validation/uart/uart.ino
index 794fc9affc2..18da797659b 100644
--- a/tests/validation/uart/uart.ino
+++ b/tests/validation/uart/uart.ino
@@ -276,6 +276,10 @@ void enabled_uart_calls_test(void) {
   Serial1.setRxInvert(true);
   Serial1.setRxInvert(false);
 
+  log_d("Checking if Serial 1 TX can be inverted while running");
+  Serial1.setTxInvert(true);
+  Serial1.setTxInvert(false);
+
   Serial.println("Enabled UART calls test successful");
 }
 
@@ -351,6 +355,10 @@ void disabled_uart_calls_test(void) {
   Serial1.setRxInvert(true);
   Serial1.setRxInvert(false);
 
+  log_d("Checking if Serial 1 TX can be inverted when stopped");
+  Serial1.setTxInvert(true);
+  Serial1.setTxInvert(false);
+
   Serial.println("Disabled UART calls test successful");
 }