From 98792697824fb548744108b8bde6ed578a031a4c Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Sun, 1 Oct 2023 11:33:10 -0300 Subject: [PATCH] Reorganize RS485 Mode - FlowCtrl --- cores/esp32/HardwareSerial.cpp | 14 ++++-- cores/esp32/HardwareSerial.h | 43 ++++++++++++++++- cores/esp32/esp32-hal-uart.c | 6 +-- cores/esp32/esp32-hal-uart.h | 85 +++++----------------------------- 4 files changed, 66 insertions(+), 82 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 33014f13a66..5a725e991a5 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -570,14 +570,20 @@ bool HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t r } } -// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before) -bool HardwareSerial::setHwFlowCtrlMode(uint8_t mode, uint8_t threshold) +// Enables or disables Hardware Flow Control using RTS and/or CTS pins +// must use setAllPins() in order to set RTS/CTS pins +// SerialHwFlowCtrl = UART_HW_FLOWCTRL_DISABLE, UART_HW_FLOWCTRL_RTS, +// UART_HW_FLOWCTRL_CTS, UART_HW_FLOWCTRL_CTS_RTS +bool HardwareSerial::setHwFlowCtrlMode(SerialHwFlowCtrl 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) +// Sets the uart mode in the esp32 uart for use with RS485 modes +// HwFlowCtrl must be disabled and RTS pin set +// SerialMode = UART_MODE_UART, UART_MODE_RS485_HALF_DUPLEX, UART_MODE_IRDA, +// or testing mode: UART_MODE_RS485_COLLISION_DETECT, UART_MODE_RS485_APP_CTRL +bool HardwareSerial::setMode(SerialMode mode) { return uartSetMode(_uart, mode); } diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index 358264375e6..f7aaf79da94 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -56,6 +56,36 @@ #include "freertos/task.h" #include "freertos/semphr.h" +enum SerialConfig { + SERIAL_5N1 = 0x8000010, + SERIAL_6N1 = 0x8000014, + SERIAL_7N1 = 0x8000018, + SERIAL_8N1 = 0x800001c, + SERIAL_5N2 = 0x8000030, + SERIAL_6N2 = 0x8000034, + SERIAL_7N2 = 0x8000038, + SERIAL_8N2 = 0x800003c, + SERIAL_5E1 = 0x8000012, + SERIAL_6E1 = 0x8000016, + SERIAL_7E1 = 0x800001a, + SERIAL_8E1 = 0x800001e, + SERIAL_5E2 = 0x8000032, + SERIAL_6E2 = 0x8000036, + SERIAL_7E2 = 0x800003a, + SERIAL_8E2 = 0x800003e, + SERIAL_5O1 = 0x8000013, + SERIAL_6O1 = 0x8000017, + SERIAL_7O1 = 0x800001b, + SERIAL_8O1 = 0x800001f, + SERIAL_5O2 = 0x8000033, + SERIAL_6O2 = 0x8000037, + SERIAL_7O2 = 0x800003b, + SERIAL_8O2 = 0x800003f +}; + +typedef uart_mode_t SerialMode; +typedef uart_hw_flowcontrol_t SerialHwFlowCtrl; + typedef enum { UART_NO_ERROR, UART_BREAK_ERROR, @@ -163,9 +193,18 @@ class HardwareSerial: public Stream // SetPins shall be called after Serial begin() 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) - bool setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64); // 64 is half FIFO Length + // UART_HW_FLOWCTRL_DISABLE = 0x0 disable hardware flow control + // UART_HW_FLOWCTRL_RTS = 0x1 enable RX hardware flow control (rts) + // UART_HW_FLOWCTRL_CTS = 0x2 enable TX hardware flow control (cts) + // UART_HW_FLOWCTRL_CTS_RTS = 0x3 enable hardware flow control + bool setHwFlowCtrlMode(SerialHwFlowCtrl mode = UART_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); + // UART_MODE_UART = 0x00 mode: regular UART mode + // UART_MODE_RS485_HALF_DUPLEX = 0x01 mode: half duplex RS485 UART mode control by RTS pin + // UART_MODE_IRDA = 0x02 mode: IRDA UART mode + // UART_MODE_RS485_COLLISION_DETECT = 0x03 mode: RS485 collision detection UART mode (used for test purposes) + // UART_MODE_RS485_APP_CTRL = 0x04 mode: application control RS485 UART mode (used for test purposes) + bool setMode(SerialMode 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 149c8c40dcd..3bc4473e120 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -232,14 +232,14 @@ bool uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t } // -bool uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) { +bool uartSetHwFlowCtrlMode(uart_t *uart, uart_hw_flowcontrol_t mode, uint8_t threshold) { if(uart == NULL) { 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_MUTEX_LOCK(); - bool retCode = (ESP_OK == uart_set_hw_flow_ctrl(uart->num, (uart_hw_flowcontrol_t) mode, threshold)); + bool retCode = (ESP_OK == uart_set_hw_flow_ctrl(uart->num, mode, threshold)); UART_MUTEX_UNLOCK(); return retCode; } @@ -610,7 +610,7 @@ 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) +bool uartSetMode(uart_t *uart, uart_mode_t mode) { 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 a1531d6042d..4f24fb07962 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -27,77 +27,7 @@ extern "C" { #include #include "freertos/FreeRTOS.h" #include "freertos/queue.h" - -#ifdef __cplusplus -enum SerialConfig { -SERIAL_5N1 = 0x8000010, -SERIAL_6N1 = 0x8000014, -SERIAL_7N1 = 0x8000018, -SERIAL_8N1 = 0x800001c, -SERIAL_5N2 = 0x8000030, -SERIAL_6N2 = 0x8000034, -SERIAL_7N2 = 0x8000038, -SERIAL_8N2 = 0x800003c, -SERIAL_5E1 = 0x8000012, -SERIAL_6E1 = 0x8000016, -SERIAL_7E1 = 0x800001a, -SERIAL_8E1 = 0x800001e, -SERIAL_5E2 = 0x8000032, -SERIAL_6E2 = 0x8000036, -SERIAL_7E2 = 0x800003a, -SERIAL_8E2 = 0x800003e, -SERIAL_5O1 = 0x8000013, -SERIAL_6O1 = 0x8000017, -SERIAL_7O1 = 0x800001b, -SERIAL_8O1 = 0x800001f, -SERIAL_5O2 = 0x8000033, -SERIAL_6O2 = 0x8000037, -SERIAL_7O2 = 0x800003b, -SERIAL_8O2 = 0x800003f -}; -#else -#define SERIAL_5N1 0x8000010 -#define SERIAL_6N1 0x8000014 -#define SERIAL_7N1 0x8000018 -#define SERIAL_8N1 0x800001c -#define SERIAL_5N2 0x8000030 -#define SERIAL_6N2 0x8000034 -#define SERIAL_7N2 0x8000038 -#define SERIAL_8N2 0x800003c -#define SERIAL_5E1 0x8000012 -#define SERIAL_6E1 0x8000016 -#define SERIAL_7E1 0x800001a -#define SERIAL_8E1 0x800001e -#define SERIAL_5E2 0x8000032 -#define SERIAL_6E2 0x8000036 -#define SERIAL_7E2 0x800003a -#define SERIAL_8E2 0x800003e -#define SERIAL_5O1 0x8000013 -#define SERIAL_6O1 0x8000017 -#define SERIAL_7O1 0x800001b -#define SERIAL_8O1 0x800001f -#define SERIAL_5O2 0x8000033 -#define SERIAL_6O2 0x8000037 -#define SERIAL_7O2 0x800003b -#define SERIAL_8O2 0x800003f -#endif // __cplusplus - -// 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 - -// 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 +#include "hal/uart_types.h" struct uart_struct_t; typedef struct uart_struct_t uart_t; @@ -137,11 +67,20 @@ bool uartIsDriverInstalled(uart_t* uart); bool 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 -bool uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold); +// UART_HW_FLOWCTRL_DISABLE = 0x0 disable hardware flow control +// UART_HW_FLOWCTRL_RTS = 0x1 enable RX hardware flow control (rts) +// UART_HW_FLOWCTRL_CTS = 0x2 enable TX hardware flow control (cts) +// UART_HW_FLOWCTRL_CTS_RTS = 0x3 enable hardware flow control +bool uartSetHwFlowCtrlMode(uart_t *uart, uart_hw_flowcontrol_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); +// UART_MODE_UART = 0x00 mode: regular UART mode +// UART_MODE_RS485_HALF_DUPLEX = 0x01 mode: half duplex RS485 UART mode control by RTS pin +// UART_MODE_IRDA = 0x02 mode: IRDA UART mode +// UART_MODE_RS485_COLLISION_DETECT = 0x03 mode: RS485 collision detection UART mode (used for test purposes) +// UART_MODE_RS485_APP_CTRL = 0x04 mode: application control RS485 UART mode (used for test purposes) +bool uartSetMode(uart_t *uart, uart_mode_t mode); void uartStartDetectBaudrate(uart_t *uart); unsigned long uartDetectBaudrate(uart_t *uart);