mirror of
https://github.com/apache/nuttx.git
synced 2025-05-08 22:32:04 +08:00
arch/risc-v/espressif: Add RS485 support for esp32[c3|c6|h2]
Add RS485 support for Risc-V based Espressif devices Signed-off-by: Eren Terzioglu <eren.terzioglu@espressif.com>
This commit is contained in:
parent
4d70fa74e8
commit
929c6313ff
@ -1090,7 +1090,7 @@ config ESPRESSIF_WIFI_RX_BA_WIN
|
||||
Set the size of WiFi Block Ack RX window. Generally a bigger value means higher throughput and better
|
||||
compatibility but more memory. Most of time we should NOT change the default value unless special
|
||||
reason, e.g. test the maximum UDP RX throughput with iperf etc. For iperf test in shieldbox, the
|
||||
recommended value is 9~12. If PSRAM is used and WiFi memory is prefered to allocat in PSRAM first,
|
||||
recommended value is 9~12. If PSRAM is used and WiFi memory is preferred to allocate in PSRAM first,
|
||||
the default and minimum value should be 16 to achieve better throughput and compatibility with both
|
||||
stations and APs.
|
||||
|
||||
@ -1193,6 +1193,31 @@ menu "UART Configuration"
|
||||
|
||||
if ESPRESSIF_UART0
|
||||
|
||||
config ESPRESSIF_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 ESPRESSIF_UART0_RS485_DIR_PIN
|
||||
int "UART0 RS-485 DIR pin"
|
||||
default 10
|
||||
range 0 46
|
||||
depends on ESPRESSIF_UART0_RS485
|
||||
---help---
|
||||
DIR pin for RS-485 on UART0. This pin will control the RS485 enable
|
||||
TX of the RS485 transceiver.
|
||||
|
||||
config ESPRESSIF_UART0_RS485_DIR_POLARITY
|
||||
int "UART0 RS-485 DIR pin polarity"
|
||||
default 1
|
||||
range 0 1
|
||||
depends on ESPRESSIF_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 ESPRESSIF_UART0_TXPIN
|
||||
int "UART0 TX Pin"
|
||||
default 21 if ESPRESSIF_ESP32C3
|
||||
@ -1235,6 +1260,31 @@ endif # ESPRESSIF_UART0
|
||||
|
||||
if ESPRESSIF_UART1
|
||||
|
||||
config ESPRESSIF_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 ESPRESSIF_UART1_RS485_DIR_PIN
|
||||
int "UART1 RS-485 DIR pin"
|
||||
default 4
|
||||
range 0 46
|
||||
depends on ESPRESSIF_UART1_RS485
|
||||
---help---
|
||||
DIR pin for RS-485 on UART1. This pin will control the RS485 enable
|
||||
TX of the RS485 transceiver.
|
||||
|
||||
config ESPRESSIF_UART1_RS485_DIR_POLARITY
|
||||
int "UART1 RS-485 DIR pin polarity"
|
||||
default 1
|
||||
range 0 1
|
||||
depends on ESPRESSIF_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 ESPRESSIF_UART1_TXPIN
|
||||
int "UART1 TX Pin"
|
||||
default 8 if ESPRESSIF_ESP32C3 || ESPRESSIF_ESP32C6 || ESPRESSIF_ESP32H2
|
||||
|
@ -44,6 +44,13 @@
|
||||
# define HAVE_UART_DEVICE 1 /* Flag to indicate a UART has been selected */
|
||||
#endif
|
||||
|
||||
/* Is RS-485 used? */
|
||||
|
||||
#if defined(CONFIG_ESPRESSIF_UART0_RS485) || \
|
||||
defined(CONFIG_ESPRESSIF_UART1_RS485)
|
||||
# define HAVE_RS485 1
|
||||
#endif
|
||||
|
||||
/* Serial Console ***********************************************************/
|
||||
|
||||
/* Is there a serial console? There should be no more than one defined. It
|
||||
|
@ -101,6 +101,14 @@ struct esp_uart_s g_uart0_config =
|
||||
#else
|
||||
.oflow = false, /* output flow control (CTS) disabled */
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_UART0_RS485
|
||||
.rs485_dir_gpio = CONFIG_ESPRESSIF_UART0_RS485_DIR_PIN,
|
||||
#if (CONFIG_ESPRESSIF_UART0_RS485_DIR_POLARITY == 0)
|
||||
.rs485_dir_polarity = false,
|
||||
#else
|
||||
.rs485_dir_polarity = true,
|
||||
#endif
|
||||
#endif
|
||||
.hal = &g_uart0_hal,
|
||||
.lock = SP_UNLOCKED
|
||||
@ -147,6 +155,14 @@ struct esp_uart_s g_uart1_config =
|
||||
#else
|
||||
.oflow = false, /* output flow control (CTS) disabled */
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_UART1_RS485
|
||||
.rs485_dir_gpio = CONFIG_ESPRESSIF_UART1_RS485_DIR_PIN,
|
||||
#if (CONFIG_ESPRESSIF_UART1_RS485_DIR_POLARITY == 0)
|
||||
.rs485_dir_polarity = false,
|
||||
#else
|
||||
.rs485_dir_polarity = true,
|
||||
#endif
|
||||
#endif
|
||||
.hal = &g_uart1_hal,
|
||||
.lock = SP_UNLOCKED
|
||||
@ -289,6 +305,15 @@ void esp_lowputc_config_pins(const struct esp_uart_s *priv)
|
||||
esp_gpio_matrix_in(priv->ctspin, priv->ctssig, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RS485
|
||||
if (priv->rs485_dir_gpio != 0)
|
||||
{
|
||||
esp_configgpio(priv->rs485_dir_gpio, OUTPUT);
|
||||
esp_gpio_matrix_out(priv->rs485_dir_gpio, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -75,6 +75,10 @@ struct esp_uart_s
|
||||
uint8_t ctspin; /* CTS pin number */
|
||||
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
|
||||
uart_hal_context_t *hal; /* HAL context */
|
||||
spinlock_t lock; /* Spinlock */
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "esp_config.h"
|
||||
#include "esp_irq.h"
|
||||
#include "esp_lowputc.h"
|
||||
#include "esp_gpio.h"
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_USBSERIAL
|
||||
# include "esp_usbserial.h"
|
||||
@ -273,6 +274,19 @@ static int uart_handler(int irq, void *context, void *arg)
|
||||
uint32_t rx_mask = UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_FULL;
|
||||
uint32_t int_status = uart_hal_get_intsts_mask(priv->hal);
|
||||
|
||||
#ifdef HAVE_RS485
|
||||
if ((int_status & UART_INTR_TX_BRK_IDLE) != 0 &&
|
||||
esp_txempty(dev))
|
||||
{
|
||||
uart_hal_clr_intsts_mask(priv->hal, UART_INTR_TX_BRK_IDLE);
|
||||
if (dev->xmit.tail == dev->xmit.head)
|
||||
{
|
||||
esp_gpiowrite(priv->rs485_dir_gpio,
|
||||
!priv->rs485_dir_polarity);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Tx fifo empty interrupt or UART tx done int */
|
||||
|
||||
if ((int_status & tx_mask) != 0)
|
||||
@ -437,6 +451,17 @@ static int esp_setup(uart_dev_t *dev)
|
||||
uart_hal_set_hw_flow_ctrl(priv->hal, flow_ctrl, rx_thrs);
|
||||
#endif /* CONFIG_SERIAL_IFLOWCONTROL || CONFIG_SERIAL_OFLOWCONTROL */
|
||||
|
||||
#ifdef HAVE_RS485
|
||||
|
||||
/* Configure the idle time between transfers */
|
||||
|
||||
if (priv->rs485_dir_gpio != 0)
|
||||
{
|
||||
uart_hal_set_tx_idle_num(priv->hal, 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
/* Clear FIFOs */
|
||||
|
||||
uart_hal_rxfifo_rst(priv->hal);
|
||||
@ -575,6 +600,16 @@ static void esp_txint(uart_dev_t *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)
|
||||
{
|
||||
uart_hal_ena_intr_mask(priv->hal, UART_INTR_TX_BRK_IDLE);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Set to receive an interrupt when the TX holding register register
|
||||
* is empty
|
||||
*/
|
||||
@ -711,7 +746,16 @@ static bool esp_txempty(uart_dev_t *dev)
|
||||
|
||||
static void esp_send(uart_dev_t *dev, int ch)
|
||||
{
|
||||
esp_lowputc_send_byte(dev->priv, ch);
|
||||
struct esp_uart_s *priv = dev->priv;
|
||||
|
||||
#ifdef HAVE_RS485
|
||||
if (priv->rs485_dir_gpio != 0)
|
||||
{
|
||||
esp_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity);
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_lowputc_send_byte(priv, ch);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1058,7 +1102,7 @@ static bool esp_rxflowcontrol(uart_dev_t *dev, unsigned int nbuffered,
|
||||
*
|
||||
* Description:
|
||||
* Performs the low level UART initialization early in debug so that the
|
||||
* serial console will be available during bootup. This must be called
|
||||
* serial console will be available during boot-up. This must be called
|
||||
* before riscv_serialinit.
|
||||
* NOTE: This function depends on GPIO pin configuration performed in
|
||||
* in up_consoleinit() and main clock initialization performed in
|
||||
@ -1089,7 +1133,7 @@ void riscv_earlyserialinit(void)
|
||||
#endif
|
||||
|
||||
/* Configure console in early step.
|
||||
* Setup for other serials will be perfomed when the serial driver is
|
||||
* Setup for other serials will be performed when the serial driver is
|
||||
* open.
|
||||
*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user