From 56da1260873574db31600aa8f350378d91256478 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Sat, 12 Feb 2022 17:05:46 -0300 Subject: [PATCH 1/6] fixes setPins and begin to keep rx/tx unmodified --- cores/esp32/HardwareSerial.cpp | 56 ++++++++++++++++++++++------------ cores/esp32/HardwareSerial.h | 7 ++++- cores/esp32/esp32-hal-uart.c | 16 +++++----- cores/esp32/esp32-hal-uart.h | 4 ++- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 3cbcf264fcc..aab5dd61384 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -114,37 +114,46 @@ void serialEventRun(void) } #endif - HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256) {} +enum { UART_NUM_0, UART_NUM_1, UART_NUM_2 }; + void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd) { if(0 > _uart_nr || _uart_nr >= SOC_UART_NUM) { log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1); return; } + + // First Time or after end() --> set default Pins + if (!uartIsDriverInstalled(_uart)) { + switch (_uart_nr) { + case UART_NUM_0: + rxPin = rxPin < 0 ? SOC_RX0 : rxPin; + txPin = txPin < 0 ? SOC_TX0 : txPin; + break; +#if SOC_UART_NUM > 1 // may save some flash bytes... + case UART_NUM_1: + rxPin = rxPin < 0 ? RX1 : rxPin; + txPin = txPin < 0 ? TX1 : txPin; + break; +#endif +#if SOC_UART_NUM > 2 // may save some flash bytes... + case UART_NUM_2: + rxPin = rxPin < 0 ? RX2 : rxPin; + txPin = txPin < 0 ? TX2 : txPin; + break; +#endif + } + } + if(_uart) { // in this case it is a begin() over a previous begin() - maybe to change baud rate // thus do not disable debug output end(false); } - if(_uart_nr == 0 && rxPin < 0 && txPin < 0) { - rxPin = SOC_RX0; - txPin = SOC_TX0; - } -#if SOC_UART_NUM > 1 - if(_uart_nr == 1 && rxPin < 0 && txPin < 0) { - rxPin = RX1; - txPin = TX1; - } -#endif -#if SOC_UART_NUM > 2 - if(_uart_nr == 2 && rxPin < 0 && txPin < 0) { - rxPin = RX2; - txPin = TX2; - } -#endif + // IDF UART driver keeps Pin setting on restarting. Negative Pin number will keep it unmodified. _uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd); if (!baud) { // using baud rate as zero, forces it to try to detect the current baud rate in place @@ -159,7 +168,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in if(detectedBaudRate) { delay(100); // Give some time... - _uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd); + _uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd); } else { log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible"); _uart = NULL; @@ -280,9 +289,16 @@ void HardwareSerial::setRxInvert(bool invert) uartSetRxInvert(_uart, invert); } -void HardwareSerial::setPins(uint8_t rxPin, uint8_t txPin) +// negative Pin value will keep it unmodified +void HardwareSerial::setPins(int8_t rxPin, int8_t txPin) +{ + uartSetPins(_uart, rxPin, txPin, -1, -1); +} + +// negative Pin value will keep it unmodified +void HardwareSerial::setAllPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { - uartSetPins(_uart, rxPin, txPin); + uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin); } size_t HardwareSerial::setRxBufferSize(size_t new_size) { diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 796412c8ce3..15f22f88adc 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -107,7 +107,12 @@ class HardwareSerial: public Stream void setDebugOutput(bool); void setRxInvert(bool); - void setPins(uint8_t rxPin, uint8_t txPin); + + // 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); + void setAllPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin); + size_t setRxBufferSize(size_t new_size); protected: diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 84992e7f05d..fab5ce3c67f 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -155,15 +155,17 @@ bool uartIsDriverInstalled(uart_t* uart) return false; } -void uartSetPins(uart_t* uart, uint8_t rxPin, uint8_t txPin) +// Valid pin UART_PIN_NO_CHANGE is defined to (-1) +// Negative Pin Number will keep it unmodified, thus this function can set individual pins +void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { - if(uart == NULL || rxPin >= SOC_GPIO_PIN_COUNT || txPin >= SOC_GPIO_PIN_COUNT) { + if(uart == NULL) { return; } UART_MUTEX_LOCK(); - ESP_ERROR_CHECK(uart_set_pin(uart->num, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); - UART_MUTEX_UNLOCK(); - + // IDF uart_set_pin() will issue necessary Error Message and take care of all GPIO Number validation. + uart_set_pin(uart->num, txPin, rxPin, ctsPin, rtsPin); + UART_MUTEX_UNLOCK(); } @@ -173,10 +175,6 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx return NULL; } - if(rxPin == -1 && txPin == -1) { - return NULL; - } - uart_t* uart = &_uart_bus_array[uart_nr]; if (uart_is_driver_installed(uart_nr)) { diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index ff790bf6691..af80d7c51f1 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -76,7 +76,9 @@ void uartSetDebug(uart_t* uart); int uartGetDebug(); bool uartIsDriverInstalled(uart_t* uart); -void uartSetPins(uart_t* uart, uint8_t rxPin, uint8_t txPin); + +// Negative Pin Number will keep it unmodified, thus this function can set individual pins +void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin); void uartStartDetectBaudrate(uart_t *uart); unsigned long uartDetectBaudrate(uart_t *uart); From 2e70fc8030d8534f27070b915190d2d24b4b49bb Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Sat, 12 Feb 2022 18:12:59 -0300 Subject: [PATCH 2/6] adds Hardware Flow Control mode and CTS/RTS pin setting --- cores/esp32/HardwareSerial.cpp | 6 ++++++ cores/esp32/HardwareSerial.h | 8 +++++--- cores/esp32/esp32-hal-uart.c | 10 ++++++++++ cores/esp32/esp32-hal-uart.h | 11 +++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index aab5dd61384..d304ed72d7e 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -301,6 +301,12 @@ void HardwareSerial::setAllPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_ uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin); } +// 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) +{ + uartSetHwFlowCtrlMode(_uart, mode, threshold); +} + size_t HardwareSerial::setRxBufferSize(size_t new_size) { if (_uart) { diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 15f22f88adc..7f37c95a2d0 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -110,9 +110,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); - void setAllPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin); - + void setPins(int8_t rxPin = -1, int8_t txPin = -1); + void setAllPins(int8_t rxPin = -1, int8_t txPin = -1, 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 + size_t setRxBufferSize(size_t new_size); protected: diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index fab5ce3c67f..157c3640830 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -168,6 +168,16 @@ void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t UART_MUTEX_UNLOCK(); } +// +void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) { + if(uart == NULL) { + return; + } + // 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_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd) { diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index af80d7c51f1..22a3a74c86a 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -48,6 +48,14 @@ extern "C" { #define SERIAL_7O2 0x800003b #define SERIAL_8O2 0x800003f +// These are Hardware Flow Contol possible usage +// equivalent to UDF enum uart_hw_flowcontrol_t from +// https://github.com/espressif/esp-idf/blob/master/components/hal/include/hal/uart_types.h#L75-L81 +#define HW_FLOWCTRL_DISABLE 0x0 // disable HW Flow Control +#define HW_FLOWCTRL_RTS 0x1 // use only RTS PIN for HW Flow Control +#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 + struct uart_struct_t; typedef struct uart_struct_t uart_t; @@ -80,6 +88,9 @@ bool uartIsDriverInstalled(uart_t* uart); // Negative Pin Number will keep it unmodified, thus this function can set individual pins void uartSetPins(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); + void uartStartDetectBaudrate(uart_t *uart); unsigned long uartDetectBaudrate(uart_t *uart); From 6ab86c687ce330020c8ac694ebf5fef72365a026 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Sat, 12 Feb 2022 18:39:52 -0300 Subject: [PATCH 3/6] adds Hardware Flow Control mode and CTS/RTS pin setting --- cores/esp32/HardwareSerial.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 7f37c95a2d0..1339155f4c9 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -110,8 +110,8 @@ 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 = -1, int8_t txPin = -1); - void setAllPins(int8_t rxPin = -1, int8_t txPin = -1, int8_t ctsPin = -1, int8_t rtsPin = -1); + void setPins(int8_t rxPin, int8_t txPin); + void setAllPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin); // 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 From 01921d268f06d51bf1e1944de72bdf346f10d673 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Sat, 12 Feb 2022 18:43:41 -0300 Subject: [PATCH 4/6] adds Hardware Flow Control mode and CTS/RTS pin setting --- cores/esp32/HardwareSerial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index d304ed72d7e..1c31efe9e50 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -168,7 +168,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in if(detectedBaudRate) { delay(100); // Give some time... - _uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd); + _uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd); } else { log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible"); _uart = NULL; From d926df639661b786950cd240ed259d70f4b7001c Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Sun, 13 Feb 2022 21:37:27 -0300 Subject: [PATCH 5/6] adds Hardware Flow Control mode and CTS/RTS pin setting --- cores/esp32/HardwareSerial.cpp | 8 +------- cores/esp32/HardwareSerial.h | 3 +-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 1c31efe9e50..9984ea0d76e 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -290,13 +290,7 @@ void HardwareSerial::setRxInvert(bool invert) } // negative Pin value will keep it unmodified -void HardwareSerial::setPins(int8_t rxPin, int8_t txPin) -{ - uartSetPins(_uart, rxPin, txPin, -1, -1); -} - -// negative Pin value will keep it unmodified -void HardwareSerial::setAllPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) +void HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin); } diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 1339155f4c9..b1e21bc6b27 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -110,8 +110,7 @@ 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); - void setAllPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin); + void 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 From a7d2bf07bdd8b288b8020ed7b11eb679410eaab7 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Wed, 16 Feb 2022 21:36:03 -0300 Subject: [PATCH 6/6] Code Review --- cores/esp32/HardwareSerial.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 9984ea0d76e..313d0f784ef 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -6,6 +6,7 @@ #include "pins_arduino.h" #include "HardwareSerial.h" #include "soc/soc_caps.h" +#include "driver/uart.h" #ifndef SOC_RX0 #if CONFIG_IDF_TARGET_ESP32 @@ -116,8 +117,6 @@ void serialEventRun(void) HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256) {} -enum { UART_NUM_0, UART_NUM_1, UART_NUM_2 }; - void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd) { if(0 > _uart_nr || _uart_nr >= SOC_UART_NUM) { @@ -144,6 +143,9 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in txPin = txPin < 0 ? TX2 : txPin; break; #endif + default: + log_e("Bad UART Number"); + return; } }