This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 12ea47b10f arch/xtensa/esp32s3: add UART2 support
12ea47b10f is described below

commit 12ea47b10f7d52e2784aa1ff64ac27a750eca31a
Author: Petro Karashchenko <[email protected]>
AuthorDate: Sat Sep 2 17:17:17 2023 +0300

    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 <[email protected]>
---
 arch/xtensa/src/esp32s3/esp32s3_config.h  |   7 ++
 arch/xtensa/src/esp32s3/esp32s3_lowputc.c | 114 ++++++++++++++++++++++--------
 arch/xtensa/src/esp32s3/esp32s3_lowputc.h |   3 +
 arch/xtensa/src/esp32s3/esp32s3_periph.c  |  14 ++--
 arch/xtensa/src/esp32s3/esp32s3_serial.c  |  79 ++++++++++++++++++---
 5 files changed, 172 insertions(+), 45 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/esp32s3_config.h 
b/arch/xtensa/src/esp32s3/esp32s3_config.h
index 8305d587a2..17fcc7c09b 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_config.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_config.h
@@ -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
diff --git a/arch/xtensa/src/esp32s3/esp32s3_lowputc.c 
b/arch/xtensa/src/esp32s3/esp32s3_lowputc.c
index 334ce2e1d3..34bd8da912 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_lowputc.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_lowputc.c
@@ -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 */
diff --git a/arch/xtensa/src/esp32s3/esp32s3_lowputc.h 
b/arch/xtensa/src/esp32s3/esp32s3_lowputc.h
index 12ff2b5ec9..02ccd75eb5 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_lowputc.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_lowputc.h
@@ -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
diff --git a/arch/xtensa/src/esp32s3/esp32s3_periph.c 
b/arch/xtensa/src/esp32s3/esp32s3_periph.c
index a371c668e5..7b88878326 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_periph.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_periph.c
@@ -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. */
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_serial.c 
b/arch/xtensa/src/esp32s3/esp32s3_serial.c
index bc4ef4fe14..b948bc0dac 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_serial.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_serial.c
@@ -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

Reply via email to