Skip to content

Commit

Permalink
xtensa/esp32s2: add UART RS485 support
Browse files Browse the repository at this point in the history
  • Loading branch information
eren-terzioglu authored and pkarashchenko committed Oct 4, 2023
1 parent 2ffb729 commit 071fb18
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 1 deletion.
50 changes: 50 additions & 0 deletions arch/xtensa/src/esp32s2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,31 @@ menu "UART Configuration"

if ESP32S2_UART0

config ESP32S2_UART0_RS485
bool "RS-485 on UART0"
default n
---help---
Enable RS-485 interface on UART0. Your board config will have to
provide GPIO_UART0_RS485_DIR pin definition.

config ESP32S2_UART0_RS485_DIR_PIN
int "UART0 RS-485 DIR pin"
default 25
range 0 46
depends on ESP32S2_UART0_RS485
---help---
DIR pin for RS-485 on UART0. This pin will control the RS485 enable
TX of the RS485 transceiver.

config ESP32S2_UART0_RS485_DIR_POLARITY
int "UART0 RS-485 DIR pin polarity"
default 1
range 0 1
depends on ESP32S2_UART0_RS485
---help---
Polarity of DIR pin for RS-485 on UART0. Set to state on DIR pin which
enables TX (0 - low / nTXEN, 1 - high / TXEN).

config ESP32S2_UART0_TXPIN
int "UART0 Tx Pin"
default 43
Expand All @@ -609,6 +634,31 @@ endif # ESP32S2_UART0

if ESP32S2_UART1

config ESP32S2_UART1_RS485
bool "RS-485 on UART1"
default n
---help---
Enable RS-485 interface on UART1. Your board config will have to
provide GPIO_UART1_RS485_DIR pin definition.

config ESP32S2_UART1_RS485_DIR_PIN
int "UART1 RS-485 DIR pin"
default 14
range 0 46
depends on ESP32S2_UART1_RS485
---help---
DIR pin for RS-485 on UART1. This pin will control the RS485 enable
TX of the RS485 transceiver.

config ESP32S2_UART1_RS485_DIR_POLARITY
int "UART1 RS-485 DIR pin polarity"
default 1
range 0 1
depends on ESP32S2_UART1_RS485
---help---
Polarity of DIR pin for RS-485 on UART1. Set to state on DIR pin which
enables TX (0 - low / nTXEN, 1 - high / TXEN).

config ESP32S2_UART1_TXPIN
int "UART1 Tx Pin"
default 17
Expand Down
7 changes: 7 additions & 0 deletions arch/xtensa/src/esp32s2/esp32s2_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
# define HAVE_UART_DEVICE 1
#endif

/* Is RS-485 used? */

#if defined(CONFIG_ESP32S2_UART0_RS485) || \
defined(CONFIG_ESP32S2_UART1_RS485)
# define HAVE_RS485 1
#endif

/* Serial Console ***********************************************************/

/* Is there a serial console? There should be no more than one defined. It
Expand Down
44 changes: 44 additions & 0 deletions arch/xtensa/src/esp32s2/esp32s2_lowputc.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ struct esp32s2_uart_s g_uart0_config =
.oflow = false, /* output flow control (CTS) disabled */
#endif
#endif
#ifdef CONFIG_ESP32S2_UART0_RS485
.rs485_dir_gpio = CONFIG_ESP32S2_UART0_RS485_DIR_PIN,
#if (CONFIG_ESP32S2_UART0_RS485_DIR_POLARITY == 0)
.rs485_dir_polarity = false,
#else
.rs485_dir_polarity = true,
#endif
#endif
};

#endif /* CONFIG_ESP32S2_UART0 */
Expand Down Expand Up @@ -129,6 +137,14 @@ struct esp32s2_uart_s g_uart1_config =
.oflow = false, /* output flow control (CTS) disabled */
#endif
#endif
#ifdef CONFIG_ESP32S2_UART1_RS485
.rs485_dir_gpio = CONFIG_ESP32S2_UART1_RS485_DIR_PIN,
#if (CONFIG_ESP32S2_UART1_RS485_DIR_POLARITY == 0)
.rs485_dir_polarity = false,
#else
.rs485_dir_polarity = true,
#endif
#endif
};

#endif /* CONFIG_ESP32S2_UART1 */
Expand Down Expand Up @@ -501,6 +517,25 @@ void esp32s2_lowputc_stop_length(const struct esp32s2_uart_s *priv)
}
}

/****************************************************************************
* Name: esp32s2_lowputc_set_tx_idle_time
*
* Description:
* Set the idle time between transfers.
*
* Parameters:
* priv - Pointer to the private driver struct.
* time - Desired time interval between the transfers.
*
****************************************************************************/

void esp32s2_lowputc_set_tx_idle_time(const struct esp32s2_uart_s *priv,
uint32_t time)
{
modifyreg32(UART_IDLE_CONF_REG(priv->id), UART_TX_IDLE_NUM_M,
VALUE_TO_FIELD(time, UART_TX_IDLE_NUM));
}

/****************************************************************************
* Name: esp32s2_lowputc_send_byte
*
Expand Down Expand Up @@ -716,6 +751,15 @@ void esp32s2_lowputc_config_pins(const struct esp32s2_uart_s *priv)
esp32s2_gpio_matrix_in(priv->ctspin, priv->ctssig, 0);
}
#endif

#ifdef HAVE_RS485
if (priv->rs485_dir_gpio != 0)
{
esp32s2_configgpio(priv->rs485_dir_gpio, OUTPUT);
esp32s2_gpio_matrix_out(priv->rs485_dir_gpio, SIG_GPIO_OUT_IDX, 0, 0);
esp32s2_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity);
}
#endif
}

/****************************************************************************
Expand Down
19 changes: 19 additions & 0 deletions arch/xtensa/src/esp32s2/esp32s2_lowputc.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ struct esp32s2_uart_s
uint8_t ctssig; /* CTS signal */
bool oflow; /* Output flow control (CTS) enabled */
#endif
#ifdef HAVE_RS485
uint8_t rs485_dir_gpio; /* UART RS-485 DIR GPIO pin cfg */
bool rs485_dir_polarity; /* UART RS-485 DIR TXEN polarity */
#endif
};

extern struct esp32s2_uart_s g_uart0_config;
Expand Down Expand Up @@ -297,6 +301,21 @@ int esp32s2_lowputc_data_length(const struct esp32s2_uart_s *priv);

void esp32s2_lowputc_stop_length(const struct esp32s2_uart_s *priv);

/****************************************************************************
* Name: esp32s2_lowputc_set_tx_idle_time
*
* Description:
* Set the idle time between transfers.
*
* Parameters:
* priv - Pointer to the private driver struct.
* time - Desired time interval between the transfers.
*
****************************************************************************/

void esp32s2_lowputc_set_tx_idle_time(const struct esp32s2_uart_s *priv,
uint32_t time);

/****************************************************************************
* Name: esp32s2_lowputc_send_byte
*
Expand Down
51 changes: 50 additions & 1 deletion arch/xtensa/src/esp32s2/esp32s2_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "esp32s2_config.h"
#include "esp32s2_irq.h"
#include "esp32s2_lowputc.h"
#include "esp32s2_gpio.h"
#include "hardware/esp32s2_uart.h"
#include "hardware/esp32s2_system.h"

Expand Down Expand Up @@ -237,6 +238,18 @@ static int uart_handler(int irq, void *context, void *arg)

int_status = getreg32(UART_INT_ST_REG(priv->id));

#ifdef HAVE_RS485
if ((int_status & UART_TX_BRK_IDLE_DONE_INT_ST_M) != 0 &&
esp32s2_txempty(dev))
{
if (dev->xmit.tail == dev->xmit.head)
{
esp32s2_gpiowrite(priv->rs485_dir_gpio,
!priv->rs485_dir_polarity);
}
}
#endif

/* TX FIFO empty interrupt or UART TX done int */

if (int_status & tx_mask)
Expand Down Expand Up @@ -369,6 +382,21 @@ static int esp32s2_setup(struct uart_dev_s *dev)
esp32s2_lowputc_set_oflow(priv, false);
}
#endif
#ifdef HAVE_RS485

/* Configure the idle time between transfers */

if (priv->rs485_dir_gpio != 0)
{
esp32s2_lowputc_set_tx_idle_time(priv, 1);
}
else
#endif
{
/* No Tx idle interval */

esp32s2_lowputc_set_tx_idle_time(priv, 0);
}

/* Reset FIFOs */

Expand Down Expand Up @@ -513,6 +541,18 @@ static void esp32s2_txint(struct uart_dev_s *dev, bool enable)

if (enable)
{
/* After all bytes physically transmitted in the RS485 bus
* the TX_BRK_IDLE will indicate we can disable the TX pin.
*/

#ifdef HAVE_RS485
if (priv->rs485_dir_gpio != 0)
{
modifyreg32(UART_INT_ENA_REG(priv->id),
0, UART_TX_BRK_IDLE_DONE_INT_ENA);
}
#endif

/* Set to receive an interrupt when the TX holding FIFO is empty or
* a transmission is done.
*/
Expand Down Expand Up @@ -658,7 +698,16 @@ static bool esp32s2_txempty(struct uart_dev_s *dev)

static void esp32s2_send(struct uart_dev_s *dev, int ch)
{
esp32s2_lowputc_send_byte(dev->priv, ch);
struct esp32s2_uart_s *priv = dev->priv;

#ifdef HAVE_RS485
if (priv->rs485_dir_gpio != 0)
{
esp32s2_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity);
}
#endif

esp32s2_lowputc_send_byte(priv, (char)ch);
}

/****************************************************************************
Expand Down

0 comments on commit 071fb18

Please sign in to comment.