Skip to content

Add setMode function HardwareSerial.c to set the esp32 uart mode for use with RS485 auto RTS #7935

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

Merged
merged 6 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Added setMode function to set the esp32 uart mode
Used to set the esp32 uart mode for use with RS485 Half Duplex and the auto RTS pin mode. This will set/clear the RTS pin output to control the RE/DE pin on most RS485 chips.
  • Loading branch information
jamesarm97 committed Mar 6, 2023
commit 0bae7140039b0fdc64e871b88951982487d73812
10 changes: 10 additions & 0 deletions cores/esp32/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,16 @@ void HardwareSerial::setHwFlowCtrlMode(uint8_t mode, uint8_t threshold)
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)
int HardwareSerial::setMode(uart_mode_t mode)
{
if (_uart == 0)
{
return -1;
}
return uartSetMode(_uart, mode);
}

size_t HardwareSerial::setRxBufferSize(size_t new_size) {

if (_uart) {
Expand Down
3 changes: 2 additions & 1 deletion cores/esp32/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ class HardwareSerial: public Stream
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

// Used to set RS485 modes such as UART_MODE_RS485_HALF_DUPLEX for Auto RTS function on ESP32
int setMode(uint8_t mode);
size_t setRxBufferSize(size_t new_size);
size_t setTxBufferSize(size_t new_size);

Expand Down
11 changes: 11 additions & 0 deletions cores/esp32/esp32-hal-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,17 @@ 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
int uartSetMode(uart_t *uart, uint8_t mode)
{
if (uart == NULL || uart->num >= SOC_UART_NUM)
{
return -1;
}
return uart_set_mode(uart->num, mode);
}

void uartSetDebug(uart_t* uart)
{
if(uart == NULL || uart->num >= SOC_UART_NUM) {
Expand Down
13 changes: 13 additions & 0 deletions cores/esp32/esp32-hal-uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -99,6 +108,10 @@ void uartDetachPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int
// 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);

// 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
int uartSetMode(uart_t *uart, uint8_t mode);

void uartStartDetectBaudrate(uart_t *uart);
unsigned long uartDetectBaudrate(uart_t *uart);

Expand Down