From ec7ee53f6ffab943195f81841600eebbb2aabb05 Mon Sep 17 00:00:00 2001 From: dechao_gong Date: Thu, 24 Sep 2026 16:39:10 +0800 Subject: [PATCH] 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 Assisted-by: Claude --- 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_evb/configs/uart/defconfig | 64 ++++++++++ .../rtl8730e/rtl8730e_evb/scripts/Make.defs | 2 +- .../rtl8730e/rtl8730e_evb/src/CMakeLists.txt | 6 + boards/arm/rtl8730e/rtl8730e_evb/src/Makefile | 6 +- .../rtl8730e_evb/src/rtl8730e_bringup.c | 9 ++ .../rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h | 4 + .../rtl8730e/rtl8730e_evb/src/rtl8730e_uart.c | 114 ++++++++++++++++++ 14 files changed, 382 insertions(+), 9 deletions(-) create mode 100644 arch/arm/src/rtl8730e/ameba_uart_chip.h create mode 100644 boards/arm/rtl8730e/rtl8730e_evb/configs/uart/defconfig create mode 100644 boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_uart.c 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 + +#include + +#include + +/**************************************************************************** + * 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 + +#include +#include + +#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 */