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

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

commit ec7ee53f6ffab943195f81841600eebbb2aabb05
Author: dechao_gong <[email protected]>
AuthorDate: Thu Sep 24 16:39:10 2026 +0800

    arch/arm/rtl8730e: add UART character driver support
    
    Expose the RTL8730E general-purpose UARTs through the shared Ameba
    serial driver (arch/arm/src/common/ameba/ameba_uart.c) by adding the
    chip-specific glue, build wiring and a board port table.  The change is
    gated by CONFIG_AMEBA_UART (default disabled); the LOG-UART keeps the
    console and /dev/ttyS0.
    
    Chip glue (ameba_uart_chip.h) supplies the three UART controller
    register bases, GIC IRQ numbers (SPI 50/51/52 -> NuttX IRQ 82/83/84),
    APB clock masks and pin-mux codes.  The board registers UART0-2 as
    /dev/ttyS1-3 at 115200 8N1; UART3 is reserved for Bluetooth.  Pads are
    picked from the EVB break-out (the UART crossbar maps each controller to
    many pads, so this is purely a board choice).
    
    Also fix an RX-timeout interrupt storm in the shared driver: the
    RX-timeout status (LSR bit9) is latched and is not cleared by draining
    the RX FIFO, so on a level-triggered GIC (RTL8730E) the ISR must
    explicitly write TOICF, matching the vendor SDK serial_api.c.  The
    extra register write is harmless on the NVIC-based M33 Ameba parts and
    was regression-tested on them.
    
    Signed-off-by: dechao_gong <[email protected]>
    Assisted-by: Claude <[email protected]>
---
 arch/arm/include/rtl8730e/irq.h                    |   3 +
 arch/arm/src/common/ameba/ameba_uart.c             |  39 ++++++-
 arch/arm/src/common/ameba/ameba_uart.h             |   1 +
 arch/arm/src/rtl8730e/CMakeLists.txt               |  19 +++-
 arch/arm/src/rtl8730e/Make.defs                    |  15 ++-
 arch/arm/src/rtl8730e/ameba_board.mk               |   8 ++
 arch/arm/src/rtl8730e/ameba_uart_chip.h            | 101 ++++++++++++++++++
 .../rtl8730e/rtl8730e_evb/configs/uart/defconfig   |  64 ++++++++++++
 boards/arm/rtl8730e/rtl8730e_evb/scripts/Make.defs |   2 +-
 .../arm/rtl8730e/rtl8730e_evb/src/CMakeLists.txt   |   6 ++
 boards/arm/rtl8730e/rtl8730e_evb/src/Makefile      |   6 +-
 .../rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c   |   9 ++
 .../arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h   |   4 +
 .../arm/rtl8730e/rtl8730e_evb/src/rtl8730e_uart.c  | 114 +++++++++++++++++++++
 14 files changed, 382 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/rtl8730e/irq.h b/arch/arm/include/rtl8730e/irq.h
index 16ee3caeff5..1426d7bebe1 100644
--- a/arch/arm/include/rtl8730e/irq.h
+++ b/arch/arm/include/rtl8730e/irq.h
@@ -42,6 +42,9 @@
  */
 
 #define RTL8730E_IRQ_IPC_AP     56   /* GIC SPI 24: CA32 AP-IPC (WHC WiFi) */
+#define RTL8730E_IRQ_UART0      82   /* GIC SPI 50: UART0 */
+#define RTL8730E_IRQ_UART1      83   /* GIC SPI 51: UART1 */
+#define RTL8730E_IRQ_UART2      84   /* GIC SPI 52: UART2 */
 
 /****************************************************************************
  * Public Types
diff --git a/arch/arm/src/common/ameba/ameba_uart.c 
b/arch/arm/src/common/ameba/ameba_uart.c
index 41acddfd6ac..96656221fa0 100644
--- a/arch/arm/src/common/ameba/ameba_uart.c
+++ b/arch/arm/src/common/ameba/ameba_uart.c
@@ -108,6 +108,17 @@
 /* Line status register (LSR) bits. */
 
 #define AMEBA_UART_LSR_TX_EMPTY ((uint32_t)1 << 5)  /* Tx FIFO empty        */
+#define AMEBA_UART_LSR_TIMEOUT  ((uint32_t)1 << 9)  /* Rx timeout (latched) */
+
+/* Interrupt clear register bit for the RX-timeout source (TOICF).  The
+ * RX-timeout interrupt is latched and is NOT cleared by draining the FIFO;
+ * it must be acknowledged explicitly.  On the GIC-based RTL8730E this
+ * matters because a still-asserted level line re-enters the handler and
+ * live-locks the system; the Cortex-M33 members are unaffected but the
+ * extra write is benign.
+ */
+
+#define AMEBA_UART_INT_TOICF    ((uint32_t)1 << 1)
 
 /* Second/third argument to fwlib "state" style APIs. */
 
@@ -182,6 +193,7 @@ extern void UART_CharPut(void *uartx, uint8_t txdata);
 extern void UART_CharGet(void *uartx, uint8_t *rxbyte);
 extern void UART_INTConfig(void *uartx, uint32_t uart_it, uint32_t newstate);
 extern uint32_t UART_LineStatusGet(void *uartx);
+extern void UART_INT_Clear(void *uartx, uint32_t uart_it);
 
 /* Serial lower-half operations. */
 
@@ -309,19 +321,31 @@ static int ameba_uart_interrupt(int irq, void *context, 
void *arg)
   struct uart_dev_s *dev = (struct uart_dev_s *)arg;
   struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
   void *uartx = (void *)priv->base;
+  uint32_t lsr;
 
   UNUSED(irq);
   UNUSED(context);
 
   /* Reading the line status register clears any latched RX error bits. */
 
-  UART_LineStatusGet(uartx);
+  lsr = UART_LineStatusGet(uartx);
 
   if (UART_Readable(uartx))
     {
       uart_recvchars(dev);
     }
 
+  /* The RX-timeout interrupt is a latched source: draining the FIFO does
+   * not clear it, so acknowledge it explicitly.  Otherwise, on the
+   * level-triggered GIC (RTL8730E), the still-asserted line immediately
+   * re-enters this handler and live-locks the CPU.
+   */
+
+  if (lsr & AMEBA_UART_LSR_TIMEOUT)
+    {
+      UART_INT_Clear(uartx, AMEBA_UART_INT_TOICF);
+    }
+
   if (priv->txint && UART_Writable(uartx))
     {
       uart_xmitchars(dev);
@@ -497,6 +521,13 @@ static void ameba_uart_rxint(struct uart_dev_s *dev, bool 
enable)
   struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
   irqstate_t flags;
 
+  /* UART_INTConfig() is a read-modify-write of the interrupt-enable
+   * register that the ISR also touches (uart_xmitchars() disables the TX
+   * source when the buffer drains).  Guard the RMW with the per-instance
+   * spinlock, which also disables local interrupts so the ISR cannot preempt
+   * the update on this core, and serializes against the other CPU under SMP.
+   */
+
   flags = spin_lock_irqsave(&priv->lock);
 
   /* Enable both the RX-trigger and RX-timeout sources so that bytes still
@@ -547,6 +578,12 @@ static void ameba_uart_txint(struct uart_dev_s *dev, bool 
enable)
   struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
   irqstate_t flags;
 
+  /* Guard the interrupt-enable RMW with the per-instance spinlock (see
+   * ameba_uart_rxint()); the ISR also calls back here through
+   * uart_xmitchars() to disable the TX source, and this is safe on the other
+   * CPU under SMP.
+   */
+
   flags = spin_lock_irqsave(&priv->lock);
 
   priv->txint = enable;
diff --git a/arch/arm/src/common/ameba/ameba_uart.h 
b/arch/arm/src/common/ameba/ameba_uart.h
index c69691473dd..10a98775773 100644
--- a/arch/arm/src/common/ameba/ameba_uart.h
+++ b/arch/arm/src/common/ameba/ameba_uart.h
@@ -44,6 +44,7 @@
 
 #define AMEBA_UART0           0
 #define AMEBA_UART1           1
+#define AMEBA_UART2           2
 
 /****************************************************************************
  * Public Function Prototypes
diff --git a/arch/arm/src/rtl8730e/CMakeLists.txt 
b/arch/arm/src/rtl8730e/CMakeLists.txt
index ab97bdd5646..4a44a81d8e8 100644
--- a/arch/arm/src/rtl8730e/CMakeLists.txt
+++ b/arch/arm/src/rtl8730e/CMakeLists.txt
@@ -68,6 +68,13 @@ if(CONFIG_AMEBA_GPIO)
   endif()
 endif()
 
+if(CONFIG_AMEBA_UART)
+  list(APPEND SRCS ${AMEBA_COMMON}/ameba_uart.c)
+  if(NOT CONFIG_RTL8730E_FLASH_FS AND NOT CONFIG_AMEBA_GPIO)
+    list(APPEND SRCS rtl8730e_flash_stubs.c)
+  endif()
+endif()
+
 target_include_directories(arch PRIVATE ${AMEBA_COMMON})
 target_sources(arch PRIVATE ${SRCS})
 
@@ -151,6 +158,10 @@ if(CONFIG_RTL8730E_FLASH_FS OR CONFIG_RTL8730E_WIFI)
          ${AMEBA_SOC}/fwlib/ram_common/ameba_flash_ram.c)
   endif()
 
+  if(CONFIG_AMEBA_UART)
+    list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_hp/ameba_uart.c)
+  endif()
+
   # Silence SDK warnings, activate CA32 code paths.  No -mcmse (ARMv7-A).
   set(AMEBA_FWLIB_INC
       -Wno-int-conversion
@@ -186,13 +197,15 @@ set(AMEBA_EXTRA_LIBS)
 
 # lib_rom.a: prebuilt AP ROM stubs (GPIO_Init, RCC_PeriphClockCmd, 
PAD_PullCtrl,
 # Pinmux_Config, flash MTD primitives).
-if(CONFIG_AMEBA_GPIO OR CONFIG_RTL8730E_FLASH_FS)
+if(CONFIG_AMEBA_GPIO
+   OR CONFIG_AMEBA_UART
+   OR CONFIG_RTL8730E_FLASH_FS)
   list(APPEND AMEBA_EXTRA_LIBS
        ${AMEBA_SOC}/project/${AMEBA_KM_PROJ}/lib/soc/lib_rom.a)
 endif()
 
-# fwlib archive linked for flash MTD (provides ameba_flash_ram.c symbols).
-if(CONFIG_RTL8730E_FLASH_FS)
+# fwlib archive linked whenever any driver needs its RAM-side tables/code.
+if(CONFIG_RTL8730E_FLASH_FS OR CONFIG_AMEBA_UART)
   list(APPEND AMEBA_EXTRA_LIBS ${AMEBA_FWLIB_A})
 endif()
 
diff --git a/arch/arm/src/rtl8730e/Make.defs b/arch/arm/src/rtl8730e/Make.defs
index 5e724f56b14..7a20d2fff79 100644
--- a/arch/arm/src/rtl8730e/Make.defs
+++ b/arch/arm/src/rtl8730e/Make.defs
@@ -65,15 +65,20 @@ AMEBA_AP_SOC_LIB = 
$(TOPDIR)/arch/arm/src/common/ameba/ameba-rtos/component/soc/
 # rtl8730e_flash_stubs.c supplies the RAM-side symbols that lib_rom.a objects
 # expect (DiagPrintfNano, irq_enable, Pinmux_Config, etc.).  Compile them once
 # whenever any driver needing ROM is enabled.
-ifneq ($(filter y,$(CONFIG_AMEBA_GPIO) $(CONFIG_RTL8730E_FLASH_FS)),)
+ifneq ($(filter y,$(CONFIG_AMEBA_GPIO) $(CONFIG_AMEBA_UART) 
$(CONFIG_RTL8730E_FLASH_FS)),)
 CHIP_CSRCS += rtl8730e_flash_stubs.c
 EXTRA_LIBS += $(AMEBA_AP_SOC_LIB)$(DELIM)lib_rom.a
+
 endif
 
 ifeq ($(CONFIG_AMEBA_GPIO),y)
 CHIP_CSRCS += ameba_gpio.c
 endif
 
+ifeq ($(CONFIG_AMEBA_UART),y)
+CHIP_CSRCS += ameba_uart.c
+endif
+
 # WiFi (WHC host, CA32 side).
 ifeq ($(CONFIG_RTL8730E_WIFI),y)
 CHIP_CSRCS += rtl8730e_wifi_init.c
@@ -100,12 +105,16 @@ ifeq ($(CONFIG_RTL8730E_FLASH_FS),y)
 # VPATH + INCLUDES at the top of this file).
 CHIP_CSRCS += ameba_flash_mtd.c
 
+endif
+
+# fwlib archive is needed whenever any driver uses RAM-side SDK tables
+# (flash MTD, UART, ...).  Link it once for all such configs.
+ifneq ($(filter y,$(CONFIG_RTL8730E_FLASH_FS) $(CONFIG_AMEBA_UART)),)
+
 # Prebuilt staging area (within the board tree, gitignored).
 AMEBA_PREBUILT      = $(BOARD_DIR)$(DELIM)prebuilt
 AMEBA_PREBUILT_LIBS = $(AMEBA_PREBUILT)$(DELIM)libs
 
-# fwlib archive built by PREBUILD from SDK source (FLASH_ReadStream/
-# WriteStream/EraseXIP + IPC layer for the CA32 write-lock protocol).
 EXTRA_LIBS += $(AMEBA_PREBUILT_LIBS)$(DELIM)libameba_fwlib.a
 
 endif
diff --git a/arch/arm/src/rtl8730e/ameba_board.mk 
b/arch/arm/src/rtl8730e/ameba_board.mk
index dff8117a407..432ed8b0135 100644
--- a/arch/arm/src/rtl8730e/ameba_board.mk
+++ b/arch/arm/src/rtl8730e/ameba_board.mk
@@ -66,6 +66,14 @@ ifeq ($(CONFIG_RTL8730E_FLASH_FS),y)
 AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_flash_ram.c
 endif
 
+# UART_DEV_TABLE / APBPeriph_UARTx / APBPeriph_UARTx_CLOCK are defined in
+# ram_hp/ameba_uart.c (not in lib_rom.a).  The ROM UART_Init/SetBaud
+# functions look up the register base and clock via these tables, so the
+# file must be compiled into libameba_fwlib.a whenever UART is enabled.
+ifeq ($(CONFIG_AMEBA_UART),y)
+AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_hp/ameba_uart.c
+endif
+
 # Include paths scoped to the fwlib compile only (never leaked to NuttX core).
 # -DCONFIG_ARM_CORE_CA32 activates the CA32 code paths in ameba_flash_ram.c.
 # No -mcmse (that is Cortex-M33 TrustZone; CA32 is ARMv7-A non-secure EL1).
diff --git a/arch/arm/src/rtl8730e/ameba_uart_chip.h 
b/arch/arm/src/rtl8730e/ameba_uart_chip.h
new file mode 100644
index 00000000000..2bb9ae327c9
--- /dev/null
+++ b/arch/arm/src/rtl8730e/ameba_uart_chip.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+ * arch/arm/src/rtl8730e/ameba_uart_chip.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_RTL8730E_AMEBA_UART_CHIP_H
+#define __ARCH_ARM_SRC_RTL8730E_AMEBA_UART_CHIP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <nuttx/irq.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Per-chip UART wiring for RTL8730E (amebasmart CA32).  The shared driver
+ * (arch/arm/src/common/ameba/ameba_uart.c) includes this header to learn how
+ * many general-purpose UARTs the chip exposes and, for each, its register
+ * base, peripheral-clock masks, GIC interrupt vector and pad-mux codes.
+ *
+ * RTL8730E exposes UART0-2 to the CA32 domain.  UART3 is reserved for
+ * Bluetooth and is not registered here.  The LOG-UART (LOGUART_REG_BASE
+ * 0x4200c000) is the NuttX console (/dev/ttyS0) and is managed by
+ * rtl8730e_serial.c; UART0-2 appear as /dev/ttyS1-3.
+ *
+ * GIC SPI numbers come from SDK ameba_vector_table.h (CA32 section):
+ *   UART0_IRQ = 50, UART1_IRQ = 51, UART2_IRQ = 52.
+ * NuttX IRQ = GIC SPI number + 32.
+ *
+ * APBPeriph and APBPeriph_CLOCK values differ on amebasmart; both lists are
+ * supplied so RCC_PeriphClockCmd() receives correct distinct arguments.
+ * Source: component/soc/amebasmart/fwlib/include/sysreg_lsys.h.
+ *
+ * amebasmart uses a single PINMUX_FUNCTION_UART (1) for both TX and RX;
+ * there are no separate TXD/RXD function codes (unlike amebalite/green2).
+ */
+
+#define AMEBA_NUART               3
+
+#define AMEBA_UART_PORT_BASES     \
+        { 0x41004000ul, 0x41005000ul, 0x41006000ul }
+
+/* NuttX IRQ = GIC SPI + 32 */
+
+#define AMEBA_UART_PORT_IRQS      \
+        { 82, 83, 84 }
+
+/* APBPeriph_UARTx (function reset) masks:
+ *   UART0: (2<<30)|(1<<4)|(1<<0)
+ *   UART1: (2<<30)|(1<<5)|(1<<0)
+ *   UART2: (2<<30)|(1<<6)|(1<<0)
+ */
+
+#define AMEBA_UART_APBPERIPH      \
+        { ((uint32_t)(2 << 30) | (1u << 4) | (1u << 0)), \
+          ((uint32_t)(2 << 30) | (1u << 5) | (1u << 0)), \
+          ((uint32_t)(2 << 30) | (1u << 6) | (1u << 0)) }
+
+/* APBPeriph_UARTx_CLOCK masks:
+ *   UART0: (2<<30)|(1<<0)
+ *   UART1: (2<<30)|(1<<1)
+ *   UART2: (2<<30)|(1<<2)
+ */
+
+#define AMEBA_UART_APBPERIPH_CLK  \
+        { ((uint32_t)(2 << 30) | (1u << 0)), \
+          ((uint32_t)(2 << 30) | (1u << 1)), \
+          ((uint32_t)(2 << 30) | (1u << 2)) }
+
+/* amebasmart uses PINMUX_FUNCTION_UART (1) for both TX and RX pads.
+ * No direction-specific codes exist on this chip family.
+ */
+
+#define AMEBA_UART_TXFID          { 1, 1, 1 }  /* PINMUX_FUNCTION_UART */
+#define AMEBA_UART_RXFID          { 1, 1, 1 }  /* PINMUX_FUNCTION_UART */
+
+#endif /* __ARCH_ARM_SRC_RTL8730E_AMEBA_UART_CHIP_H */
diff --git a/boards/arm/rtl8730e/rtl8730e_evb/configs/uart/defconfig 
b/boards/arm/rtl8730e/rtl8730e_evb/configs/uart/defconfig
new file mode 100644
index 00000000000..757dbabfdcd
--- /dev/null
+++ b/boards/arm/rtl8730e/rtl8730e_evb/configs/uart/defconfig
@@ -0,0 +1,64 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+# CONFIG_NSH_DISABLE_MB is not set
+# CONFIG_NSH_DISABLE_MH is not set
+# CONFIG_NSH_DISABLE_MW is not set
+CONFIG_ALARM_ARCH=y
+CONFIG_AMEBA_UART=y
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="rtl8730e_evb"
+CONFIG_ARCH_BOARD_RTL8730E_EVB=y
+CONFIG_ARCH_CHIP="rtl8730e"
+CONFIG_ARCH_CHIP_RTL8730E=y
+CONFIG_ARCH_CHIP_RTL8730E_CA32=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_LOWVECTORS=y
+CONFIG_ARM_PSCI=y
+CONFIG_BOARD_LOOPSPERMSEC=393693
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4096
+CONFIG_EXAMPLES_HELLO=y
+CONFIG_EXAMPLES_SERIALBLASTER=y
+CONFIG_EXAMPLES_SERIALRX=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FLASH_SIZE=1048576
+CONFIG_FLASH_START=0x60300000
+CONFIG_FLASH_VSTART=0x60300000
+CONFIG_FS_PROCFS=y
+CONFIG_FS_TMPFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=4096
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_LIBC_MEMFD_ERROR=y
+CONFIG_MM_DEFAULT_ALIGNMENT=64
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PRIORITY_INHERITANCE=y
+CONFIG_RAM_SIZE=3145728
+CONFIG_RAM_START=0x60400000
+CONFIG_RAM_VSTART=0x60400000
+CONFIG_RAW_BINARY=y
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_HPWORKPRIORITY=192
+CONFIG_SMP=y
+CONFIG_SMP_NCPUS=2
+CONFIG_STACK_COLORATION=y
+CONFIG_START_DAY=25
+CONFIG_START_MONTH=4
+CONFIG_START_YEAR=2023
+CONFIG_SYSTEM_NSH=y
+CONFIG_USEC_PER_TICK=1000
diff --git a/boards/arm/rtl8730e/rtl8730e_evb/scripts/Make.defs 
b/boards/arm/rtl8730e/rtl8730e_evb/scripts/Make.defs
index f5d182d3f3f..2e8ad81df25 100644
--- a/boards/arm/rtl8730e/rtl8730e_evb/scripts/Make.defs
+++ b/boards/arm/rtl8730e/rtl8730e_evb/scripts/Make.defs
@@ -62,7 +62,7 @@ include 
$(TOPDIR)$(DELIM)arch$(DELIM)arm$(DELIM)src$(DELIM)rtl8730e$(DELIM)ameba
 # lib_rom.a and the RTK toolchain's libgcc.a are compiled without VFP ABI
 # flags; suppress the harmless mismatch so the linker does not abort on it
 # whenever libameba_fwlib.a is in the link (GPIO, WiFi, or flash-FS config).
-ifneq ($(filter y,$(CONFIG_AMEBA_GPIO) $(CONFIG_RTL8730E_WIFI) 
$(CONFIG_RTL8730E_FLASH_FS)),)
+ifneq ($(filter y,$(CONFIG_AMEBA_GPIO) $(CONFIG_AMEBA_UART) 
$(CONFIG_RTL8730E_WIFI) $(CONFIG_RTL8730E_FLASH_FS)),)
 LDFLAGS += --no-warn-mismatch
 endif
 
diff --git a/boards/arm/rtl8730e/rtl8730e_evb/src/CMakeLists.txt 
b/boards/arm/rtl8730e/rtl8730e_evb/src/CMakeLists.txt
index 26dc588e411..afdebb491af 100644
--- a/boards/arm/rtl8730e/rtl8730e_evb/src/CMakeLists.txt
+++ b/boards/arm/rtl8730e/rtl8730e_evb/src/CMakeLists.txt
@@ -27,6 +27,12 @@ if(CONFIG_AMEBA_GPIO)
                              PRIVATE ${NUTTX_DIR}/arch/arm/src/common/ameba)
 endif()
 
+if(CONFIG_AMEBA_UART)
+  list(APPEND SRCS rtl8730e_uart.c)
+  target_include_directories(board
+                             PRIVATE ${NUTTX_DIR}/arch/arm/src/common/ameba)
+endif()
+
 if(CONFIG_LIBC_FDT)
   target_include_directories(board
                              PRIVATE ${NUTTX_DIR}/libs/libc/fdt/dtc/libfdt)
diff --git a/boards/arm/rtl8730e/rtl8730e_evb/src/Makefile 
b/boards/arm/rtl8730e/rtl8730e_evb/src/Makefile
index 045cf28e21a..013336f409b 100644
--- a/boards/arm/rtl8730e/rtl8730e_evb/src/Makefile
+++ b/boards/arm/rtl8730e/rtl8730e_evb/src/Makefile
@@ -34,7 +34,7 @@ ifeq ($(CONFIG_LIBC_FDT),y)
 CFLAGS += 
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)fdt$(DELIM)dtc$(DELIM)libfdt
 endif
 
-ifneq ($(CONFIG_RTL8730E_FLASH_FS)$(CONFIG_AMEBA_GPIO),)
+ifneq ($(CONFIG_RTL8730E_FLASH_FS)$(CONFIG_AMEBA_GPIO)$(CONFIG_AMEBA_UART),)
 CFLAGS += 
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)arm$(DELIM)src$(DELIM)common$(DELIM)ameba
 endif
 
@@ -42,4 +42,8 @@ ifeq ($(CONFIG_AMEBA_GPIO),y)
 CSRCS += rtl8730e_gpio.c
 endif
 
+ifeq ($(CONFIG_AMEBA_UART),y)
+CSRCS += rtl8730e_uart.c
+endif
+
 include $(TOPDIR)/boards/Board.mk
diff --git a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c 
b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c
index bcfa303dcba..d54f4263ecc 100644
--- a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c
+++ b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c
@@ -251,6 +251,15 @@ int rtl8730e_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_AMEBA_UART
+  ret = rtl8730e_uart_initialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize UART: %d\n", ret);
+    }
+#endif
+
   UNUSED(ret);
   return OK;
 }
diff --git a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h 
b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h
index ee06613d01f..38616432dc1 100644
--- a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h
+++ b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h
@@ -61,5 +61,9 @@ int rtl8730e_bringup(void);
 int rtl8730e_gpio_initialize(void);
 #endif
 
+#ifdef CONFIG_AMEBA_UART
+int rtl8730e_uart_initialize(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_RTL8730E_RTL8730E_EVB_SRC_RTL8730E_EVB_H */
diff --git a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_uart.c 
b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_uart.c
new file mode 100644
index 00000000000..517343f44c3
--- /dev/null
+++ b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_uart.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_uart.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/param.h>
+#include <syslog.h>
+
+#include "ameba_gpio.h"
+#include "ameba_uart.h"
+#include "rtl8730e_evb.h"
+
+#ifdef CONFIG_AMEBA_UART
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* One entry per general-purpose UART exposed to NuttX.  The LOG-UART owns
+ * the console and /dev/ttyS0; these ports are registered starting at
+ * /dev/ttyS1.
+ *
+ * amebasmart routes UART TX/RX through a crossbar, so each controller can be
+ * mapped to many different pads.  The pairs chosen below are simply the ones
+ * broken out on this EVB; short each TX/RX pair for loopback validation.
+ */
+
+struct rtl8730e_uart_s
+{
+  const char *path;             /* Device path (/dev/ttyS1, ...) */
+  int         uart;             /* Controller index (AMEBA_UART0 ...) */
+  uint8_t     txpin;            /* TX pad (AMEBA_PA() encoding) */
+  uint8_t     rxpin;            /* RX pad (AMEBA_PA() encoding) */
+  uint32_t    baud;             /* Initial baud rate */
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rtl8730e_uart_s g_uart_ports[] =
+{
+  {
+    "/dev/ttyS1", AMEBA_UART0, AMEBA_PA(3), AMEBA_PA(2), 115200
+  },
+  {
+    "/dev/ttyS2", AMEBA_UART1, AMEBA_PA(5), AMEBA_PA(4), 115200
+  },
+  {
+    "/dev/ttyS3", AMEBA_UART2, AMEBA_PA(1), AMEBA_PA(0), 115200
+  },
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rtl8730e_uart_initialize
+ *
+ * Description:
+ *   Register the board's general-purpose UART ports with the NuttX serial
+ *   upper half.
+ *
+ ****************************************************************************/
+
+int rtl8730e_uart_initialize(void)
+{
+  int ret;
+  size_t i;
+
+  for (i = 0; i < nitems(g_uart_ports); i++)
+    {
+      ret = ameba_uart_register(g_uart_ports[i].path,
+                                g_uart_ports[i].uart,
+                                g_uart_ports[i].txpin,
+                                g_uart_ports[i].rxpin,
+                                g_uart_ports[i].baud);
+      if (ret < 0)
+        {
+          syslog(LOG_ERR,
+                 "ERROR: ameba_uart_register(%s) failed: %d\n",
+                 g_uart_ports[i].path, ret);
+          return ret;
+        }
+    }
+
+  return OK;
+}
+
+#endif /* CONFIG_AMEBA_UART */

Reply via email to