From 18d2ae253c121f714d23cee5ef7de1caad3759d5 Mon Sep 17 00:00:00 2001 From: dechao_gong Date: Wed, 12 Aug 2026 13:55:09 +0800 Subject: [PATCH] arch/arm/rtl8720f: add UART master driver support Wire the shared common UART driver (arch/arm/src/common/ameba/ameba_uart.c) into RTL8720F. Add an ameba_uart_chip.h supplying the per-chip UART parameters: two general-purpose controllers (UART0/UART1), their non-secure register bases (0x401C3000 / 0x401C4000 -- the fwlib UART_DEV_TABLE points at the non-secure alias), NVIC vectors, APBPeriph function/clock masks and the crossbar TX/RX pad-mux function codes. The fwlib ROM UART routines index data tables (UART_DEV_TABLE, APBPeriph_UARTx) that live in fwlib ram_common/ameba_uart.c, so that source is compiled in when CONFIG_AMEBA_UART is set. Wire CONFIG_AMEBA_UART into Make.defs/CMakeLists/ameba_board.mk, add the board port table (UART0 at /dev/ttyS1, PA22 TX / PA23 RX, 115200 8N1) with bringup registration, a uart config and board documentation. Hardware-verified on rtl8720f_evb: serialrx/serialblaster over a PA22-to-PA23 TX/RX loopback transferred all 2600 bytes intact. Assisted-by: Claude Signed-off-by: dechao_gong --- .../rtl8720f/boards/rtl8720f_evb/index.rst | 21 ++++ arch/arm/src/rtl8720f/CMakeLists.txt | 13 +++ arch/arm/src/rtl8720f/Make.defs | 4 + arch/arm/src/rtl8720f/ameba_board.mk | 10 ++ arch/arm/src/rtl8720f/ameba_uart_chip.h | 78 +++++++++++++ .../rtl8720f_evb/configs/uart/defconfig | 54 +++++++++ .../rtl8720f/rtl8720f_evb/src/CMakeLists.txt | 6 +- boards/arm/rtl8720f/rtl8720f_evb/src/Makefile | 6 +- .../rtl8720f_evb/src/rtl8720f_bringup.c | 10 ++ .../rtl8720f_evb/src/rtl8720f_rtl8720f_evb.h | 14 +++ .../rtl8720f/rtl8720f_evb/src/rtl8720f_uart.c | 106 ++++++++++++++++++ 11 files changed, 320 insertions(+), 2 deletions(-) create mode 100644 arch/arm/src/rtl8720f/ameba_uart_chip.h create mode 100644 boards/arm/rtl8720f/rtl8720f_evb/configs/uart/defconfig create mode 100644 boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_uart.c diff --git a/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst b/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst index c81d12d9ae9..d28315b3489 100644 --- a/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst +++ b/Documentation/platforms/arm/rtl8720f/boards/rtl8720f_evb/index.rst @@ -33,6 +33,8 @@ Supported in this NuttX port: * DHCP client (STA) and DHCP server (SoftAP) * GPIO pins exposed as ``/dev/gpioN`` character devices (input, output and interrupt), driven directly on the SDK fwlib register layer +* General-purpose UARTs exposed as ``/dev/ttySN`` serial devices, driven + directly on the SDK fwlib register layer Buttons and LEDs ================ @@ -69,6 +71,25 @@ encoded with the ``AMEBA_PA()`` helper from ``arch/arm/src/common/ameba/ameba_gpio.h`` (pin 0-31), matching the Ameba SDK ``PinName`` layout. +uart +---- + +Minimal NSH with the general-purpose UART driver and the ``serialrx`` / +``serialblaster`` examples enabled (no Wi-Fi). The LOG-UART owns the console +and ``/dev/ttyS0``, so the board registers UART0 from its table (see +``boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_uart.c``) as ``/dev/ttyS1`` at +115200 8N1. Edit that table -- controller, TX/RX pads and baud -- to match a +board's wiring. The TX/RX pads use the same ``AMEBA_PA()`` encoding as the +GPIO table; the driver muxes them to the UART function and pulls RX high +through the SDK ROM. Exercise the port with the examples (loop TX back to RX, +or wire it to a host serial adapter):: + + nsh> serialrx /dev/ttyS1 2600 & # start the receiver first + nsh> serialblaster /dev/ttyS1 2600 # then loop TX back to RX + +The line format can be changed at runtime through ``tcsetattr()`` (the config +enables ``CONFIG_SERIAL_TERMIOS``). UART2 is not exposed by the driver. + nsh --- diff --git a/arch/arm/src/rtl8720f/CMakeLists.txt b/arch/arm/src/rtl8720f/CMakeLists.txt index ab633deb2bc..8b077a53bce 100644 --- a/arch/arm/src/rtl8720f/CMakeLists.txt +++ b/arch/arm/src/rtl8720f/CMakeLists.txt @@ -50,6 +50,10 @@ if(CONFIG_AMEBA_GPIO) list(APPEND SRCS ${AMEBA_COMMON}/ameba_gpio.c) endif() +if(CONFIG_AMEBA_UART) + list(APPEND SRCS ${AMEBA_COMMON}/ameba_uart.c) +endif() + target_include_directories(arch PRIVATE ${AMEBA_COMMON}) target_sources(arch PRIVATE ${SRCS}) @@ -96,6 +100,15 @@ if(CONFIG_RTL8720F_FLASH_FS) list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_flash_ram.c) endif() +# UART register layer. The UART driver (arch/.../common/ameba/ameba_uart.c) +# calls the fwlib UART API, all of which resolves to the ROM symbol table; but +# the ROM routines index the fwlib data tables (UART_DEV_TABLE, APBPeriph_UARTx) +# which live in this RAM source and must be compiled in (--gc-sections drops the +# unused DMA/monitor helpers). +if(CONFIG_AMEBA_UART) + list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_uart.c) +endif() + # Silence a couple of warnings the vendored SDK sources trip under NuttX's # warning set, scoped to this fwlib compile only (never relaxing NuttX's own): # -Wno-int-conversion: the SDK passes NULL to irq_register()'s u32 "Data" diff --git a/arch/arm/src/rtl8720f/Make.defs b/arch/arm/src/rtl8720f/Make.defs index 637aeca30b8..0ac126000c9 100644 --- a/arch/arm/src/rtl8720f/Make.defs +++ b/arch/arm/src/rtl8720f/Make.defs @@ -60,6 +60,10 @@ ifeq ($(CONFIG_AMEBA_GPIO),y) CHIP_CSRCS += ameba_gpio.c endif +ifeq ($(CONFIG_AMEBA_UART),y) +CHIP_CSRCS += ameba_uart.c +endif + ############################################################################ # Realtek RTL8720F SDK integration # diff --git a/arch/arm/src/rtl8720f/ameba_board.mk b/arch/arm/src/rtl8720f/ameba_board.mk index 28f9283943c..d9f841a48ad 100644 --- a/arch/arm/src/rtl8720f/ameba_board.mk +++ b/arch/arm/src/rtl8720f/ameba_board.mk @@ -117,6 +117,16 @@ AMEBA_FWLIB_SRCS += $(TOPDIR)/arch/arm/src/rtl8720f/ameba_app_start.c \ ifeq ($(CONFIG_RTL8720F_FLASH_FS),y) AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_flash_ram.c endif + +# UART register layer. The UART driver (arch/.../common/ameba/ameba_uart.c) +# calls the fwlib UART API, all of which resolves to the ROM symbol table; but +# the ROM routines index the fwlib data tables (UART_DEV_TABLE, APBPeriph_UARTx) +# which live in this RAM source and must be compiled in (--gc-sections drops +# the unused DMA/monitor helpers). +ifeq ($(CONFIG_AMEBA_UART),y) +AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_uart.c +endif + # -Wno-int-conversion: the vendored SDK passes NULL to irq_register()'s u32 # "Data" (interrupt context) argument in many places -- an intentional # NULL-as-context idiom. Silence -Wint-conversion for the SDK fwlib sources diff --git a/arch/arm/src/rtl8720f/ameba_uart_chip.h b/arch/arm/src/rtl8720f/ameba_uart_chip.h new file mode 100644 index 00000000000..a0b23df1cb6 --- /dev/null +++ b/arch/arm/src/rtl8720f/ameba_uart_chip.h @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/arm/src/rtl8720f/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_RTL8720F_AMEBA_UART_CHIP_H +#define __ARCH_ARM_SRC_RTL8720F_AMEBA_UART_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Per-chip UART wiring for RTL8720F. 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, NVIC vector and crossbar pad-mux codes. See + * the RTL8721DX version of this header for the full contract; the notes + * below cover only what differs on this chip. + * + * The AP core is km4tz (TrustZone secure) here, but the fwlib UART_DEV_TABLE + * (fwlib/ram_common/ameba_uart.c) points at the *non-secure* UARTx_DEV bases + * unconditionally, so -- exactly as on RTL8721DX/RTL8721F -- the driver + * programs the controllers through the non-secure alias (0x401C_3000 / + * 0x401C_4000). The chip exposes UART0/UART1/UART2, but the LOG-UART owns + * the console and only UART0/UART1 are wired here. + */ + +#define AMEBA_NUART 2 + +#define AMEBA_UART_PORT_BASES { 0x401c3000ul, 0x401c4000ul } + +#define AMEBA_UART_PORT_IRQS { RTL8720F_IRQ_UART0, RTL8720F_IRQ_UART1 } + +/* APBPeriph_UARTx (function) and APBPeriph_UARTx_CLOCK masks. Equal on this + * chip; kept as two lists so chips where they differ can supply both. + */ + +#define AMEBA_UART_APBPERIPH \ + { (((uint32_t)1 << 30) | ((uint32_t)1 << 6)), \ + (((uint32_t)1 << 30) | ((uint32_t)1 << 7)) } + +#define AMEBA_UART_APBPERIPH_CLK \ + { (((uint32_t)1 << 30) | ((uint32_t)1 << 6)), \ + (((uint32_t)1 << 30) | ((uint32_t)1 << 7)) } + +/* Direction-specific crossbar pad-mux function codes (PINMUX_FUNCTION_*). */ + +#define AMEBA_UART_TXFID { 65, 69 } /* UART0_TXD, UART1_TXD */ +#define AMEBA_UART_RXFID { 66, 70 } /* UART0_RXD, UART1_RXD */ + +#endif /* __ARCH_ARM_SRC_RTL8720F_AMEBA_UART_CHIP_H */ diff --git a/boards/arm/rtl8720f/rtl8720f_evb/configs/uart/defconfig b/boards/arm/rtl8720f/rtl8720f_evb/configs/uart/defconfig new file mode 100644 index 00000000000..966ba7509f3 --- /dev/null +++ b/boards/arm/rtl8720f/rtl8720f_evb/configs/uart/defconfig @@ -0,0 +1,54 @@ +# +# 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_DEBUG_WARN is not set +CONFIG_AMEBA_UART=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="rtl8720f_evb" +CONFIG_ARCH_BOARD_RTL8720F_EVB=y +CONFIG_ARCH_CHIP="rtl8720f" +CONFIG_ARCH_CHIP_RTL8720F=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV8M_SYSTICK=y +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_SERIALBLASTER_DEVPATH="/dev/ttyS1" +CONFIG_EXAMPLES_SERIALRX=y +CONFIG_EXAMPLES_SERIALRX_DEVPATH="/dev/ttyS1" +CONFIG_FS_PROCFS=y +CONFIG_FS_TMPFS=y +CONFIG_IDLETHREAD_STACKSIZE=4096 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_LIBC_MEMFD_ERROR=y +CONFIG_MM_DEFAULT_ALIGNMENT=32 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x30008000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=192 +CONFIG_SCHED_LPWORK=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=16 +CONFIG_START_MONTH=6 +CONFIG_START_YEAR=2026 +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=2500 +CONFIG_TIMER=y +CONFIG_TIMER_ARCH=y +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt b/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt index ce8753b2761..aeee1692e6d 100644 --- a/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt +++ b/boards/arm/rtl8720f/rtl8720f_evb/src/CMakeLists.txt @@ -26,9 +26,13 @@ if(CONFIG_AMEBA_GPIO) list(APPEND SRCS rtl8720f_gpio.c) endif() +if(CONFIG_AMEBA_UART) + list(APPEND SRCS rtl8720f_uart.c) +endif() + target_sources(board PRIVATE ${SRCS}) -if(CONFIG_AMEBA_GPIO) +if(CONFIG_AMEBA_GPIO OR CONFIG_AMEBA_UART) # The board pin tables pull in the shared drivers' public headers from # arch/arm/src/common/ameba/, not on the default board include path. target_include_directories(board diff --git a/boards/arm/rtl8720f/rtl8720f_evb/src/Makefile b/boards/arm/rtl8720f/rtl8720f_evb/src/Makefile index a4e6ba74fce..0c920798152 100644 --- a/boards/arm/rtl8720f/rtl8720f_evb/src/Makefile +++ b/boards/arm/rtl8720f/rtl8720f_evb/src/Makefile @@ -28,10 +28,14 @@ ifeq ($(CONFIG_AMEBA_GPIO),y) CSRCS += rtl8720f_gpio.c endif +ifeq ($(CONFIG_AMEBA_UART),y) +CSRCS += rtl8720f_uart.c +endif + # The board pin tables pull in the shared drivers' public headers from # arch/arm/src/common/ameba/, which is not on the default board include path. -ifneq ($(CONFIG_AMEBA_GPIO),) +ifneq ($(CONFIG_AMEBA_GPIO)$(CONFIG_AMEBA_UART),) CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)arm$(DELIM)src$(DELIM)common$(DELIM)ameba endif diff --git a/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_bringup.c b/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_bringup.c index 066a90983d7..7acc10bb528 100644 --- a/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_bringup.c +++ b/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_bringup.c @@ -130,6 +130,16 @@ int rtl8720f_bringup(void) } #endif +#ifdef CONFIG_AMEBA_UART + /* Register the board's general-purpose UART ports at /dev/ttySN. */ + + ret = rtl8720f_uart_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: rtl8720f_uart_initialize failed: %d\n", ret); + } +#endif + /* Install the inter-core HW IPC-semaphore RTOS hooks LAST -- after all the * flash / WHC bring-up above, and just before this (board_late_initialize) * path returns and nx_start() hands off to the init task. diff --git a/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_rtl8720f_evb.h b/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_rtl8720f_evb.h index d675e6b17e1..7a5728a5281 100644 --- a/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_rtl8720f_evb.h +++ b/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_rtl8720f_evb.h @@ -109,5 +109,19 @@ int ameba_flash_fs_initialize(void); int rtl8720f_gpio_initialize(void); #endif +#ifdef CONFIG_AMEBA_UART +/**************************************************************************** + * Name: rtl8720f_uart_initialize + * + * Description: + * Register the board's general-purpose UART ports with the NuttX serial + * upper half at /dev/ttyS1 and up + * (boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_uart.c). + * + ****************************************************************************/ + +int rtl8720f_uart_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_ARM_RTL8720F_RTL8720F_EVB_SRC_RTL8720F_RTL8720F_EVB_H */ diff --git a/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_uart.c b/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_uart.c new file mode 100644 index 00000000000..efa2fec57d8 --- /dev/null +++ b/boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_uart.c @@ -0,0 +1,106 @@ +/**************************************************************************** + * boards/arm/rtl8720f/rtl8720f_evb/src/rtl8720f_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 "rtl8720f_rtl8720f_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, so these ports are registered starting at + * /dev/ttyS1 in the order listed below. The TX/RX pads are examples used by + * the `uart` config (examples/serialrx / serialblaster) -- any pad can be + * routed to a UART through the pin mux, so adjust them to match your board's + * wiring. RTL8720F drives all GPIO through a single port A controller, so + * pads use AMEBA_PA(). + */ + +struct rtl8720f_uart_s +{ + const char *path; /* Device path (/dev/ttyS1, ...) */ + int uart; /* Controller index (AMEBA_UART0/AMEBA_UART1) */ + 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 rtl8720f_uart_s g_uart_ports[] = +{ + { + "/dev/ttyS1", AMEBA_UART0, AMEBA_PA(22), AMEBA_PA(23), 115200 + }, +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rtl8720f_uart_initialize + * + * Description: + * Register the board's general-purpose UART ports with the NuttX serial + * upper half. + * + ****************************************************************************/ + +int rtl8720f_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 */