diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp
index e60588f931e..7d06f65dc93 100644
--- a/cores/esp32/HardwareSerial.cpp
+++ b/cores/esp32/HardwareSerial.cpp
@@ -233,7 +233,7 @@ void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout)
 // A low value of FIFO Full bytes will consume more CPU time within the ISR
 // A high value of FIFO Full bytes will make the application wait longer to have byte available for the Stkech in a streaming scenario
 // Both RX FIFO Full and RX Timeout may affect when onReceive() will be called
-void HardwareSerial::setRxFIFOFull(uint8_t fifoBytes)
+bool HardwareSerial::setRxFIFOFull(uint8_t fifoBytes)
 {
     HSERIAL_MUTEX_LOCK();
     // in case that onReceive() shall work only with RX Timeout, FIFO shall be high
@@ -242,14 +242,15 @@ void HardwareSerial::setRxFIFOFull(uint8_t fifoBytes)
         fifoBytes = 120;
         log_w("OnReceive is set to Timeout only, thus FIFO Full is now 120 bytes.");
     }
-    uartSetRxFIFOFull(_uart, fifoBytes); // Set new timeout
+    bool retCode = uartSetRxFIFOFull(_uart, fifoBytes); // Set new timeout
     if (fifoBytes > 0 && fifoBytes < SOC_UART_FIFO_LEN - 1) _rxFIFOFull = fifoBytes;
     HSERIAL_MUTEX_UNLOCK();
+    return retCode;
 }
 
 // timout is calculates in time to receive UART symbols at the UART baudrate.
 // the estimation is about 11 bits per symbol (SERIAL_8N1)
-void HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
+bool HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
 {
     HSERIAL_MUTEX_LOCK();
     
@@ -258,9 +259,10 @@ void HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
     _rxTimeout = symbols_timeout;   
     if (!symbols_timeout) _onReceiveTimeout = false;  // only when RX timeout is disabled, we also must disable this flag 
 
-    uartSetRxTimeout(_uart, _rxTimeout); // Set new timeout
+    bool retCode = uartSetRxTimeout(_uart, _rxTimeout); // Set new timeout
     
     HSERIAL_MUTEX_UNLOCK();
+    return retCode;
 }
 
 void HardwareSerial::eventQueueReset()
@@ -548,15 +550,16 @@ void HardwareSerial::setRxInvert(bool invert)
 }
 
 // negative Pin value will keep it unmodified
-void HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
+bool HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
 {
     if(_uart == NULL) {
         log_e("setPins() shall be called after begin() - nothing done\n");
-        return;
+        return false;
     }
 
-    // uartSetPins() checks if pins are valid for each function and for the SoC 
-    if (uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin)) {
+    // uartSetPins() checks if pins are valid for each function and for the SoC
+    bool retCode = uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin);
+    if (retCode) {
         _txPin = _txPin >= 0 ? txPin : _txPin;
         _rxPin = _rxPin >= 0 ? rxPin : _rxPin;
         _rtsPin = _rtsPin >= 0 ? rtsPin : _rtsPin;
@@ -564,12 +567,19 @@ void HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t r
     } else {
         log_e("Error when setting Serial port Pins. Invalid Pin.\n");
     }
+    return retCode;
 }
 
 // Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
-void HardwareSerial::setHwFlowCtrlMode(uint8_t mode, uint8_t threshold)
+bool HardwareSerial::setHwFlowCtrlMode(uint8_t mode, uint8_t threshold)
+{
+    return uartSetHwFlowCtrlMode(_uart, mode, threshold);
+}
+
+// Sets the uart mode in the esp32 uart for use with RS485 modes (HwFlowCtrl must be disabled and RTS pin set)
+bool HardwareSerial::setMode(uint8_t mode)
 {
-    uartSetHwFlowCtrlMode(_uart, mode, threshold);
+    return uartSetMode(_uart, mode);
 }
 
 size_t HardwareSerial::setRxBufferSize(size_t new_size) {
diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h
index 6291d241778..d6516f06f3e 100644
--- a/cores/esp32/HardwareSerial.h
+++ b/cores/esp32/HardwareSerial.h
@@ -80,13 +80,13 @@ class HardwareSerial: public Stream
     //                       Examples: Maximum for 11 bits symbol is 92 (SERIAL_8N2, SERIAL_8E1, SERIAL_8O1, etc), Maximum for 10 bits symbol is 101 (SERIAL_8N1).
     //                       For example symbols_timeout=1 defines a timeout equal to transmission time of one symbol (~11 bit) on current baudrate. 
     //                       For a baudrate of 9600, SERIAL_8N1 (10 bit symbol) and symbols_timeout = 3, the timeout would be 3 / (9600 / 10) = 3.125 ms
-    void setRxTimeout(uint8_t symbols_timeout);
+    bool setRxTimeout(uint8_t symbols_timeout);
 
     // setRxFIFOFull(uint8_t fifoBytes) will set the number of bytes that will trigger UART_INTR_RXFIFO_FULL interrupt and fill up RxRingBuffer
     // This affects some functions such as Serial::available() and Serial.read() because, in a UART flow of receiving data, Serial internal 
     // RxRingBuffer will be filled only after these number of bytes arrive or a RX Timeout happens.
     // This parameter can be set to 1 in order to receive byte by byte, but it will also consume more CPU time as the ISR will be activates often.
-    void setRxFIFOFull(uint8_t fifoBytes);
+    bool setRxFIFOFull(uint8_t fifoBytes);
 
     // onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
     // UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
@@ -161,10 +161,11 @@ class HardwareSerial: public Stream
 
     // Negative Pin Number will keep it unmodified, thus this function can set individual pins
     // SetPins shall be called after Serial begin()
-    void setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1);
+    bool setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1);
     // Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
-    void setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64);   // 64 is half FIFO Length
-
+    bool setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64);   // 64 is half FIFO Length
+    // Used to set RS485 modes such as UART_MODE_RS485_HALF_DUPLEX for Auto RTS function on ESP32
+    bool setMode(uint8_t mode);
     size_t setRxBufferSize(size_t new_size);
     size_t setTxBufferSize(size_t new_size);
 
diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c
index 7706f132d5e..ca212577891 100644
--- a/cores/esp32/esp32-hal-uart.c
+++ b/cores/esp32/esp32-hal-uart.c
@@ -160,13 +160,16 @@ bool uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t
 }
 
 // 
-void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) {
+bool uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) {
     if(uart == NULL) {
-        return;
+        return false;
     }
     // IDF will issue corresponding error message when mode or threshold are wrong and prevent crashing
     // IDF will check (mode > HW_FLOWCTRL_CTS_RTS || threshold >= SOC_UART_FIFO_LEN)
-    uart_set_hw_flow_ctrl(uart->num, (uart_hw_flowcontrol_t) mode, threshold);
+    UART_MUTEX_LOCK();
+    bool retCode = (ESP_OK == uart_set_hw_flow_ctrl(uart->num, (uart_hw_flowcontrol_t) mode, threshold));
+    UART_MUTEX_UNLOCK();  
+    return retCode;
 }
 
 
@@ -244,26 +247,28 @@ void uartSetFastReading(uart_t* uart)
 }
 
 
-void uartSetRxTimeout(uart_t* uart, uint8_t numSymbTimeout)
+bool uartSetRxTimeout(uart_t* uart, uint8_t numSymbTimeout)
 {
     if(uart == NULL) {
-        return;
+        return false;
     }
 
     UART_MUTEX_LOCK();
-    uart_set_rx_timeout(uart->num, numSymbTimeout);
+    bool retCode = (ESP_OK == uart_set_rx_timeout(uart->num, numSymbTimeout));
     UART_MUTEX_UNLOCK();
+    return retCode;
 }
 
-void uartSetRxFIFOFull(uart_t* uart, uint8_t numBytesFIFOFull)
+bool uartSetRxFIFOFull(uart_t* uart, uint8_t numBytesFIFOFull)
 {
     if(uart == NULL) {
-        return;
+        return false;
     }
 
     UART_MUTEX_LOCK();
-    uart_set_rx_full_threshold(uart->num, numBytesFIFOFull);
+    bool retCode = (ESP_OK == uart_set_rx_full_threshold(uart->num, numBytesFIFOFull));
     UART_MUTEX_UNLOCK();
+    return retCode;
 }
 
 void uartEnd(uart_t* uart)
@@ -518,6 +523,21 @@ void uart_install_putc()
     }
 }
 
+// Routines that take care of UART mode in the HardwareSerial Class code
+// used to set UART_MODE_RS485_HALF_DUPLEX auto RTS for TXD for ESP32 chips
+bool uartSetMode(uart_t *uart, uint8_t mode)
+{
+    if (uart == NULL || uart->num >= SOC_UART_NUM)
+    {
+        return false;
+    }
+    
+    UART_MUTEX_LOCK();
+    bool retCode = (ESP_OK == uart_set_mode(uart->num, mode));
+    UART_MUTEX_UNLOCK();
+    return retCode;
+}
+
 void uartSetDebug(uart_t* uart)
 {
     if(uart == NULL || uart->num >= SOC_UART_NUM) {
diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h
index 2b3268af966..2870c31ae61 100644
--- a/cores/esp32/esp32-hal-uart.h
+++ b/cores/esp32/esp32-hal-uart.h
@@ -58,6 +58,15 @@ extern "C" {
 #define HW_FLOWCTRL_CTS       0x2       // use only CTS PIN for HW Flow Control
 #define HW_FLOWCTRL_CTS_RTS   0x3       // use both CTS and RTS PIN for HW Flow Control
 
+// These are Hardware Uart Modes possible usage
+// equivalent to UDF enum uart_mode_t from
+// https://github.com/espressif/esp-idf/blob/master/components/hal/include/hal/uart_types.h#L34-L40
+#define MODE_UART 0x00                   // mode: regular UART mode
+#define MODE_RS485_HALF_DUPLEX 0x01      // mode: half duplex RS485 UART mode control by RTS pin
+#define MODE_IRDA 0x02                   // mode: IRDA  UART mode
+#define MODE_RS485_COLLISION_DETECT 0x03 // mode: RS485 collision detection UART mode (used for test purposes)
+#define MODE_RS485_APP_CTRL 0x04
+
 struct uart_struct_t;
 typedef struct uart_struct_t uart_t;
 
@@ -83,8 +92,8 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate);
 uint32_t uartGetBaudRate(uart_t* uart);
 
 void uartSetRxInvert(uart_t* uart, bool invert);
-void uartSetRxTimeout(uart_t* uart, uint8_t numSymbTimeout);
-void uartSetRxFIFOFull(uart_t* uart, uint8_t numBytesFIFOFull);
+bool uartSetRxTimeout(uart_t* uart, uint8_t numSymbTimeout);
+bool uartSetRxFIFOFull(uart_t* uart, uint8_t numBytesFIFOFull);
 void uartSetFastReading(uart_t* uart);
 
 void uartSetDebug(uart_t* uart);
@@ -97,7 +106,11 @@ bool uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t
 void uartDetachPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin);
 
 // Enables or disables HW Flow Control function -- needs also to set CTS and/or RTS pins
-void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold);
+bool uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold);
+
+// Used to set RS485 function -- needs to disable HW Flow Control and set RTS pin to use
+// RTS pin becomes RS485 half duplex RE/DE
+bool uartSetMode(uart_t *uart, uint8_t mode);
 
 void uartStartDetectBaudrate(uart_t *uart);
 unsigned long uartDetectBaudrate(uart_t *uart);