Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serial reorganization code for RS-485 Mode, Flow Control Mode and Serial Mode #8718

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions cores/esp32/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
43 changes: 41 additions & 2 deletions cores/esp32/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions cores/esp32/esp32-hal-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand Down
85 changes: 12 additions & 73 deletions cores/esp32/esp32-hal-uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,77 +27,7 @@ extern "C" {
#include <stdlib.h>
#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;
Expand Down Expand Up @@ -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);
Expand Down