arch/xtensa/esp32s3: add UART2 support

This commits adds support of UART2 for EPS32S3 and fixes pin mode
assignment for iomux mode

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Petro Karashchenko 2023-09-02 17:17:17 +03:00 committed by Xiang Xiao
parent 0efd4d0e12
commit 12ea47b10f
5 changed files with 172 additions and 45 deletions

View File

@ -52,13 +52,20 @@
#undef CONSOLE_UART
#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_ESP32S3_UART0)
# undef CONFIG_UART1_SERIAL_CONSOLE
# undef CONFIG_UART2_SERIAL_CONSOLE
# define CONSOLE_UART 1
#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_ESP32S3_UART1)
# undef CONFIG_UART0_SERIAL_CONSOLE
# undef CONFIG_UART2_SERIAL_CONSOLE
# define CONSOLE_UART 1
#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_ESP32S3_UART2)
# undef CONFIG_UART0_SERIAL_CONSOLE
# undef CONFIG_UART1_SERIAL_CONSOLE
# define CONSOLE_UART 1
#else
# undef CONFIG_UART0_SERIAL_CONSOLE
# undef CONFIG_UART1_SERIAL_CONSOLE
# undef CONFIG_UART2_SERIAL_CONSOLE
#endif
#ifdef CONFIG_ESP32S3_USBSERIAL

View File

@ -46,11 +46,12 @@
#include "hardware/esp32s3_soc.h"
#include "esp32s3_clockconfig.h"
#include "esp32s3_config.h"
#include "esp32s3_gpio.h"
#include "esp32s3_lowputc.h"
#include "esp32s3_periph.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -142,6 +143,45 @@ struct esp32s3_uart_s g_uart1_config =
};
#endif /* CONFIG_ESP32S3_UART1 */
#ifdef CONFIG_ESP32S3_UART2
struct esp32s3_uart_s g_uart2_config =
{
.periph = ESP32S3_PERIPH_UART2,
.id = 2,
.cpuint = -ENOMEM,
.irq = ESP32S3_IRQ_UART2,
.baud = CONFIG_UART2_BAUD,
.bits = CONFIG_UART2_BITS,
.parity = CONFIG_UART2_PARITY,
.stop_b2 = CONFIG_UART2_2STOP,
.int_pri = ESP32S3_INT_PRIO_DEF,
.txpin = CONFIG_ESP32S3_UART2_TXPIN,
.txsig = U2TXD_OUT_IDX,
.rxpin = CONFIG_ESP32S3_UART2_RXPIN,
.rxsig = U2RXD_IN_IDX,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.rtspin = CONFIG_ESP32S3_UART2_RTSPIN,
.rtssig = U2RTS_OUT_IDX,
#ifdef CONFIG_UART2_IFLOWCONTROL
.iflow = true, /* input flow control (RTS) enabled */
#else
.iflow = false, /* input flow control (RTS) disabled */
#endif
#endif
#ifdef CONFIG_SERIAL_OFLOWCONTROL
.ctspin = CONFIG_ESP32S3_UART2_CTSPIN,
.ctssig = U2CTS_IN_IDX,
#ifdef CONFIG_UART1_OFLOWCONTROL
.oflow = true, /* output flow control (CTS) enabled */
#else
.oflow = false, /* output flow control (CTS) disabled */
#endif
#endif
};
#endif /* CONFIG_ESP32S3_UART2 */
#endif /* HAVE_UART_DEVICE */
/****************************************************************************
@ -399,12 +439,11 @@ void esp32s3_lowputc_set_sclk(const struct esp32s3_uart_s *priv,
uint32_t esp32s3_lowputc_get_sclk(const struct esp32s3_uart_s * priv)
{
uint32_t clk_conf_reg;
uint32_t ret = -ENODATA;
clk_conf_reg = getreg32(UART_CLK_CONF_REG(priv->id));
clk_conf_reg &= UART_SCLK_SEL_M;
clk_conf_reg >>= UART_SCLK_SEL_S;
switch (clk_conf_reg)
uint32_t clk_conf;
uint32_t ret = -ENODATA;
clk_conf = REG_MASK(getreg32(UART_CLK_CONF_REG(priv->id)), UART_SCLK_SEL);
switch (clk_conf)
{
case 1:
ret = esp_clk_apb_freq();
@ -432,7 +471,7 @@ uint32_t esp32s3_lowputc_get_sclk(const struct esp32s3_uart_s * priv)
*
****************************************************************************/
void esp32s3_lowputc_baud(const struct esp32s3_uart_s * priv)
void esp32s3_lowputc_baud(const struct esp32s3_uart_s *priv)
{
int sclk_div;
uint32_t sclk_freq;
@ -495,7 +534,7 @@ void esp32s3_lowputc_baud(const struct esp32s3_uart_s * priv)
*
****************************************************************************/
void esp32s3_lowputc_normal_mode(const struct esp32s3_uart_s * priv)
void esp32s3_lowputc_normal_mode(const struct esp32s3_uart_s *priv)
{
/* Disable RS485 mode */
@ -520,7 +559,7 @@ void esp32s3_lowputc_normal_mode(const struct esp32s3_uart_s * priv)
*
****************************************************************************/
void esp32s3_lowputc_parity(const struct esp32s3_uart_s * priv)
void esp32s3_lowputc_parity(const struct esp32s3_uart_s *priv)
{
if (priv->parity == UART_PARITY_DISABLE)
{
@ -547,7 +586,7 @@ void esp32s3_lowputc_parity(const struct esp32s3_uart_s * priv)
*
****************************************************************************/
int esp32s3_lowputc_data_length(const struct esp32s3_uart_s * priv)
int esp32s3_lowputc_data_length(const struct esp32s3_uart_s *priv)
{
int ret = OK;
uint32_t length = priv->bits - 5;
@ -608,10 +647,8 @@ void esp32s3_lowputc_stop_length(const struct esp32s3_uart_s *priv)
void esp32s3_lowputc_set_tx_idle_time(const struct esp32s3_uart_s *priv,
uint32_t time)
{
time = time << UART_TX_IDLE_NUM_S;
time = time & UART_TX_IDLE_NUM_M; /* Just in case value overloads */
modifyreg32(UART_IDLE_CONF_REG(priv->id), UART_TX_IDLE_NUM_M,
time);
VALUE_TO_FIELD(time, UART_TX_IDLE_NUM));
}
/****************************************************************************
@ -626,10 +663,26 @@ void esp32s3_lowputc_set_tx_idle_time(const struct esp32s3_uart_s *priv,
*
****************************************************************************/
void esp32s3_lowputc_send_byte(const struct esp32s3_uart_s * priv,
void esp32s3_lowputc_send_byte(const struct esp32s3_uart_s *priv,
char byte)
{
putreg32((uint32_t) byte, UART_FIFO_REG(priv->id));
putreg32((uint32_t)byte, UART_FIFO_REG(priv->id));
}
/****************************************************************************
* Name: esp32s3_lowputc_enable_sysclk
*
* Description:
* Enable clock for the UART using the System register.
*
* Parameters:
* priv - Pointer to the private driver struct.
*
****************************************************************************/
void esp32s3_lowputc_enable_sysclk(const struct esp32s3_uart_s *priv)
{
esp32s3_periph_module_enable(PERIPH_UART0_MODULE + priv->id);
}
/****************************************************************************
@ -648,13 +701,9 @@ void esp32s3_lowputc_send_byte(const struct esp32s3_uart_s * priv,
bool esp32s3_lowputc_is_tx_fifo_full(const struct esp32s3_uart_s *priv)
{
uint32_t reg;
reg = getreg32(UART_STATUS_REG(priv->id));
reg = reg >> UART_TXFIFO_CNT_S;
reg = reg & UART_TXFIFO_CNT_V;
return !(reg < (UART_TX_FIFO_SIZE - 1));
uint32_t val;
val = REG_MASK(getreg32(UART_STATUS_REG(priv->id)), UART_TXFIFO_CNT);
return val >= (UART_TX_FIFO_SIZE - 1);
}
/****************************************************************************
@ -803,10 +852,12 @@ void esp32s3_lowputc_config_pins(const struct esp32s3_uart_s *priv)
if (uart_is_iomux(priv))
{
esp32s3_configgpio(priv->txpin, OUTPUT_FUNCTION_1);
esp32s3_gpio_matrix_out(priv->txpin, SIG_GPIO_OUT_IDX, 0, 0);
esp32s3_configgpio(priv->txpin, priv->id == 1 ? OUTPUT_FUNCTION_3 :
OUTPUT_FUNCTION_1);
esp32s3_configgpio(priv->rxpin, INPUT_FUNCTION_1);
esp32s3_configgpio(priv->rxpin, priv->id == 1 ? INPUT_FUNCTION_3 :
INPUT_FUNCTION_1);
esp32s3_gpio_matrix_out(priv->rxpin, SIG_GPIO_OUT_IDX, 0, 0);
#ifdef CONFIG_SERIAL_IFLOWCONTROL
@ -827,8 +878,8 @@ void esp32s3_lowputc_config_pins(const struct esp32s3_uart_s *priv)
}
else
{
esp32s3_configgpio(priv->txpin, OUTPUT_FUNCTION_2);
esp32s3_gpio_matrix_out(priv->txpin, priv->txsig, 0, 0);
esp32s3_configgpio(priv->txpin, OUTPUT_FUNCTION_2);
esp32s3_configgpio(priv->rxpin, INPUT_FUNCTION_2);
esp32s3_gpio_matrix_in(priv->rxpin, priv->rxsig, 0);
@ -893,6 +944,8 @@ void xtensa_lowputc(char ch)
struct esp32s3_uart_s *priv = &g_uart0_config;
#elif defined (CONFIG_UART1_SERIAL_CONSOLE)
struct esp32s3_uart_s *priv = &g_uart1_config;
#elif defined (CONFIG_UART2_SERIAL_CONSOLE)
struct esp32s3_uart_s *priv = &g_uart2_config;
#endif
/* Wait until the TX FIFO has space to insert new char */
@ -918,15 +971,18 @@ void esp32s3_lowsetup(void)
#ifndef CONFIG_SUPPRESS_UART_CONFIG
#ifdef CONFIG_ESP32S3_UART0
esp32s3_lowputc_enable_sysclk(&g_uart0_config);
esp32s3_lowputc_config_pins(&g_uart0_config);
#endif
#ifdef CONFIG_ESP32S3_UART1
esp32s3_lowputc_enable_sysclk(&g_uart1_config);
esp32s3_lowputc_config_pins(&g_uart1_config);
#endif
#ifdef CONFIG_ESP32S3_UART2
esp32s3_lowputc_enable_sysclk(&g_uart2_config);
esp32s3_lowputc_config_pins(&g_uart2_config);
#endif
#endif /* !CONFIG_SUPPRESS_UART_CONFIG */

View File

@ -44,6 +44,8 @@
#include "hardware/esp32s3_uart.h"
#include "hardware/esp32s3_gpio_sigmap.h"
#include "esp32s3_config.h"
/****************************************************************************
* Public Types
****************************************************************************/
@ -121,6 +123,7 @@ struct esp32s3_uart_s
extern struct esp32s3_uart_s g_uart0_config;
extern struct esp32s3_uart_s g_uart1_config;
extern struct esp32s3_uart_s g_uart2_config;
/****************************************************************************
* Public Function Prototypes

View File

@ -607,9 +607,6 @@ void IRAM_ATTR esp32s3_perip_clk_init(void)
#endif
#ifndef CONFIG_UART1_SERIAL_CONSOLE
SYSTEM_UART1_CLK_EN |
#endif
#ifndef CONFIG_UART2_SERIAL_CONSOLE
SYSTEM_UART2_CLK_EN |
#endif
SYSTEM_USB_CLK_EN |
SYSTEM_SPI2_CLK_EN |
@ -629,7 +626,9 @@ void IRAM_ATTR esp32s3_perip_clk_init(void)
SYSTEM_SPI3_DMA_CLK_EN |
SYSTEM_PWM2_CLK_EN |
SYSTEM_PWM3_CLK_EN;
common_perip_clk1 = 0;
#ifndef CONFIG_UART2_SERIAL_CONSOLE
common_perip_clk1 = SYSTEM_UART2_CLK_EN;
#endif
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
SYSTEM_CRYPTO_SHA_CLK_EN |
SYSTEM_CRYPTO_RSA_CLK_EN;
@ -650,9 +649,6 @@ void IRAM_ATTR esp32s3_perip_clk_init(void)
#endif
#ifndef CONFIG_UART1_SERIAL_CONSOLE
SYSTEM_UART1_CLK_EN |
#endif
#ifndef CONFIG_UART2_SERIAL_CONSOLE
SYSTEM_UART2_CLK_EN |
#endif
SYSTEM_USB_CLK_EN |
SYSTEM_SPI2_CLK_EN |
@ -666,7 +662,9 @@ void IRAM_ATTR esp32s3_perip_clk_init(void)
SYSTEM_I2S1_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
common_perip_clk1 = 0;
#ifndef CONFIG_UART2_SERIAL_CONSOLE
common_perip_clk1 |= SYSTEM_UART2_CLK_EN;
#endif
/* Disable some peripheral clocks. */

View File

@ -74,13 +74,17 @@
#ifdef CONSOLE_UART
# if defined(CONFIG_UART0_SERIAL_CONSOLE)
# define CONSOLE_DEV g_uart0_dev /* UART0 is console */
# define TTYS0_DEV g_uart0_dev /* UART0 is ttyS0 */
# define CONSOLE_DEV g_uart0_dev /* UART0 is console */
# define TTYS0_DEV g_uart0_dev /* UART0 is ttyS0 */
# define UART0_ASSIGNED 1
# elif defined(CONFIG_UART1_SERIAL_CONSOLE)
# define CONSOLE_DEV g_uart1_dev /* UART1 is console */
# define TTYS0_DEV g_uart1_dev /* UART1 is ttyS0 */
# define UART1_ASSIGNED 1
# elif defined(CONFIG_UART2_SERIAL_CONSOLE)
# define CONSOLE_DEV g_uart2_dev /* UART2 is console */
# define TTYS0_DEV g_uart2_dev /* UART2 is ttyS0 */
# define UART2_ASSIGNED 1
# endif /* CONFIG_UART0_SERIAL_CONSOLE */
#else /* No UART console */
# undef CONSOLE_DEV
@ -90,6 +94,9 @@
# elif defined(CONFIG_ESP32S3_UART1)
# define TTYS0_DEV g_uart1_dev /* UART1 is ttyS0 */
# define UART1_ASSIGNED 1
# elif defined(CONFIG_ESP32S3_UART2)
# define TTYS0_DEV g_uart2_dev /* UART2 is ttyS0 */
# define UART2_ASSIGNED 1
# endif
#endif /* CONSOLE_UART */
@ -106,6 +113,22 @@
#elif defined(CONFIG_ESP32S3_UART1) && !defined(UART1_ASSIGNED)
# define TTYS1_DEV g_uart1_dev /* UART1 is ttyS1 */
# define UART1_ASSIGNED 1
#elif defined(CONFIG_ESP32S3_UART2) && !defined(UART2_ASSIGNED)
# define TTYS1_DEV g_uart2_dev /* UART2 is ttyS1 */
# define UART2_ASSIGNED 1
#endif
/* Pick ttyS2 */
#if defined(CONFIG_ESP32S3_UART0) && !defined(UART0_ASSIGNED)
# define TTYS2_DEV g_uart0_dev /* UART0 is ttyS2 */
# define UART0_ASSIGNED 1
#elif defined(CONFIG_ESP32S3_UART1) && !defined(UART1_ASSIGNED)
# define TTYS2_DEV g_uart1_dev /* UART1 is ttyS2 */
# define UART1_ASSIGNED 1
#elif defined(CONFIG_ESP32S3_UART2) && !defined(UART2_ASSIGNED)
# define TTYS2_DEV g_uart2_dev /* UART2 is ttyS2 */
# define UART2_ASSIGNED 1
#endif
#ifdef HAVE_UART_DEVICE
@ -229,6 +252,39 @@ static uart_dev_t g_uart1_dev =
#endif
/* UART 2 */
#ifdef CONFIG_ESP32S3_UART2
static char g_uart2_rxbuffer[CONFIG_UART2_RXBUFSIZE];
static char g_uart2_txbuffer[CONFIG_UART2_TXBUFSIZE];
/* Fill only the requested fields */
static uart_dev_t g_uart2_dev =
{
#ifdef CONFIG_UART2_SERIAL_CONSOLE
.isconsole = true,
#else
.isconsole = false,
#endif
.xmit =
{
.size = CONFIG_UART2_TXBUFSIZE,
.buffer = g_uart2_txbuffer,
},
.recv =
{
.size = CONFIG_UART2_RXBUFSIZE,
.buffer = g_uart2_rxbuffer,
},
.ops = &g_uart_ops,
.priv = &g_uart2_config
};
#endif
#endif /* CONFIG_ESP32S3_UART */
/****************************************************************************
@ -616,9 +672,9 @@ static bool esp32s3_rxavailable(struct uart_dev_s *dev)
uint32_t bytes;
status_reg = getreg32(UART_STATUS_REG(priv->id));
bytes = status_reg & UART_RXFIFO_CNT_M;
bytes = REG_MASK(status_reg, UART_RXFIFO_CNT);
return (bytes > 0);
return bytes > 0;
}
/****************************************************************************
@ -665,9 +721,9 @@ static bool esp32s3_txempty(struct uart_dev_s *dev)
struct esp32s3_uart_s *priv = dev->priv;
reg = getreg32(UART_INT_RAW_REG(priv->id));
reg = reg & UART_TXFIFO_EMPTY_INT_RAW_M;
reg = REG_MASK(reg, UART_TX_DONE_INT_RAW);
return (reg > 0);
return reg > 0;
}
/****************************************************************************
@ -709,8 +765,7 @@ static int esp32s3_receive(struct uart_dev_s *dev, unsigned int *status)
uint32_t rx_fifo;
struct esp32s3_uart_s *priv = dev->priv;
rx_fifo = getreg32(UART_FIFO_REG(priv->id));
rx_fifo = rx_fifo & UART_RXFIFO_RD_BYTE_M;
rx_fifo = REG_MASK(getreg32(UART_FIFO_REG(priv->id)), UART_RXFIFO_RD_BYTE);
/* Since we don't have error bits associated with receipt, we set zero */
@ -1056,6 +1111,10 @@ void xtensa_earlyserialinit(void)
esp32s3_lowputc_disable_all_uart_int(TTYS1_DEV.priv, NULL);
#endif
#ifdef TTYS2_DEV
esp32s3_lowputc_disable_all_uart_int(TTYS2_DEV.priv, NULL);
#endif
/* Configure console in early step.
* Setup for other serials will be perfomed when the serial driver is
* open.
@ -1091,6 +1150,10 @@ void xtensa_serialinit(void)
uart_register("/dev/ttyS1", &TTYS1_DEV);
#endif
#ifdef TTYS2_DEV
uart_register("/dev/ttyS2", &TTYS2_DEV);
#endif
#ifdef CONFIG_ESP32S3_USBSERIAL
uart_register("/dev/ttyACM0", &TTYACM0_DEV);
#endif