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 c36e45eb6fc6bfd0712b52914b932a3cd6a796ac Author: dechao_gong <[email protected]> AuthorDate: Mon Aug 31 10:20:37 2026 +0800 arch/arm/rtl8721f: add timer driver support Wire the RTL8721F (amebagreen2) into the shared Ameba timer driver (arch/arm/src/common/ameba/ameba_timer.c), registered at /dev/timer0 (TIM1) and /dev/timer1 (TIM2). Only the per-chip base addresses, RCC masks and IRQs differ, so this adds a small ameba_timer_chip.h (the two 32-bit basic LTIM timers at 0x40819200 / 0x40819400, 32.768 kHz, APBPeriph_LTIM1/2, IRQ_TIMER1/2, verified against the SoC hal_platform.h / sysreg_lsys.h / vector table) plus the Make.defs/CMakeLists build hooks, the fwlib ram_common/ameba_tim.c RAM source (now also pulled in by CONFIG_AMEBA_TIMER, matching the PWM rule), the board bring-up registration and a timer defconfig. The shared driver is unchanged. TIM0 is left untouched because the boot ROM claims it as the always-on system timer; reprogramming it would break every SDK delay. Assisted-by: Claude <[email protected]> Signed-off-by: dechao_gong <[email protected]> --- .../arm/rtl8721f/boards/rtl8721f_evb/index.rst | 16 +++ arch/arm/src/rtl8721f/CMakeLists.txt | 4 + arch/arm/src/rtl8721f/Make.defs | 4 + arch/arm/src/rtl8721f/ameba_board.mk | 11 ++- arch/arm/src/rtl8721f/ameba_timer_chip.h | 109 +++++++++++++++++++++ .../rtl8721f/rtl8721f_evb/configs/timer/defconfig | 46 +++++++++ .../arm/rtl8721f/rtl8721f_evb/src/CMakeLists.txt | 7 +- boards/arm/rtl8721f/rtl8721f_evb/src/Makefile | 6 +- .../rtl8721f/rtl8721f_evb/src/rtl8721f_bringup.c | 10 ++ .../rtl8721f_evb/src/rtl8721f_rtl8721f_evb.h | 13 +++ .../arm/rtl8721f/rtl8721f_evb/src/rtl8721f_timer.c | 75 ++++++++++++++ 11 files changed, 294 insertions(+), 7 deletions(-) diff --git a/Documentation/platforms/arm/rtl8721f/boards/rtl8721f_evb/index.rst b/Documentation/platforms/arm/rtl8721f/boards/rtl8721f_evb/index.rst index d56b85fa6a6..cfbc28429b2 100644 --- a/Documentation/platforms/arm/rtl8721f/boards/rtl8721f_evb/index.rst +++ b/Documentation/platforms/arm/rtl8721f/boards/rtl8721f_evb/index.rst @@ -48,6 +48,8 @@ Supported in this NuttX port: alarm support, driven directly on the SDK fwlib register layer * On-chip watchdog exposed as a ``/dev/watchdog0`` character device, driven directly on the SDK fwlib register layer +* General-purpose timers exposed as ``/dev/timer0`` and ``/dev/timer1`` + character devices, driven directly on the SDK fwlib register layer Buttons and LEDs ================ @@ -193,6 +195,20 @@ which opens the device, sets a timeout, and pings it:: nsh> wdog # run the watchdog example +timer +----- + +Minimal NSH with the on-chip general-purpose timer driver and the ``timer`` +example enabled (no Wi-Fi). Two 32-bit basic timers clocked at 32.768 kHz are +registered from the board bring-up +(``boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_timer.c``) as ``/dev/timer0`` +(TIM1) and ``/dev/timer1`` (TIM2); they have no board wiring (they are +internal). TIM0 is reserved by the boot ROM as the system timer and is not +exposed. Exercise a device with the example, which sets an interval and counts +the update interrupts:: + + nsh> timer -d /dev/timer0 # run the timer example on TIM1 + nsh --- diff --git a/arch/arm/src/rtl8721f/CMakeLists.txt b/arch/arm/src/rtl8721f/CMakeLists.txt index b873cd91c62..48131cf2d14 100644 --- a/arch/arm/src/rtl8721f/CMakeLists.txt +++ b/arch/arm/src/rtl8721f/CMakeLists.txt @@ -78,6 +78,10 @@ if(CONFIG_AMEBA_WDG) list(APPEND SRCS ${AMEBA_COMMON}/ameba_wdg.c) endif() +if(CONFIG_AMEBA_TIMER) + list(APPEND SRCS ${AMEBA_COMMON}/ameba_timer.c) +endif() + target_include_directories(arch PRIVATE ${AMEBA_COMMON}) target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm/src/rtl8721f/Make.defs b/arch/arm/src/rtl8721f/Make.defs index 55461ca3465..0c2fce0fd84 100644 --- a/arch/arm/src/rtl8721f/Make.defs +++ b/arch/arm/src/rtl8721f/Make.defs @@ -88,6 +88,10 @@ ifeq ($(CONFIG_AMEBA_WDG),y) CHIP_CSRCS += ameba_wdg.c endif +ifeq ($(CONFIG_AMEBA_TIMER),y) +CHIP_CSRCS += ameba_timer.c +endif + ############################################################################ # Realtek RTL8721F SDK integration # diff --git a/arch/arm/src/rtl8721f/ameba_board.mk b/arch/arm/src/rtl8721f/ameba_board.mk index a8f47443747..3b4148e71d7 100644 --- a/arch/arm/src/rtl8721f/ameba_board.mk +++ b/arch/arm/src/rtl8721f/ameba_board.mk @@ -167,12 +167,13 @@ ifeq ($(CONFIG_AMEBA_SPI),y) AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_spi.c endif -# PWM timer register layer. The time-base entry points (RTIM_TimeBaseInit/ -# StructInit/Cmd) are in ROM, but the compare/period helpers the PWM driver -# (arch/.../common/ameba/ameba_pwm.c) calls -- RTIM_CCStructInit/CCxInit/ -# CCRxSet/CCxCmd/ChangePeriod/PrescalerConfig -- are compiled from this RAM +# PWM/timer register layer. The time-base entry points (RTIM_TimeBaseInit/ +# StructInit/Cmd/INTConfig/GetCount) are in ROM, but the compare/period and +# interrupt-clear helpers the PWM driver (ameba_pwm.c: RTIM_CCStructInit/ +# CCxInit/CCRxSet/CCxCmd/ChangePeriod/PrescalerConfig) and the timer driver +# (ameba_timer.c: RTIM_INTClear/ChangePeriod) call are compiled from this RAM # source and linked in (--gc-sections drops the unused input-capture paths). -ifeq ($(CONFIG_AMEBA_PWM),y) +ifneq (,$(filter y,$(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER))) AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_tim.c endif diff --git a/arch/arm/src/rtl8721f/ameba_timer_chip.h b/arch/arm/src/rtl8721f/ameba_timer_chip.h new file mode 100644 index 00000000000..364548f800a --- /dev/null +++ b/arch/arm/src/rtl8721f/ameba_timer_chip.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/rtl8721f/ameba_timer_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_RTL8721F_AMEBA_TIMER_CHIP_H +#define __ARCH_ARM_SRC_RTL8721F_AMEBA_TIMER_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/irq.h> + +#include <stdint.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Per-chip general-purpose timer wiring for RTL8721F (amebagreen2). The + * shared driver (arch/arm/src/common/ameba/ameba_timer.c) includes this + * header to learn which timer instances it may expose and, for each one, its + * register base, input clock, RCC clock masks and interrupt line. A port to + * another Ameba chip supplies a same-named header on the chip include path; + * the shared driver is never edited -- it reads only the macros below and + * the instance table, computing the period from clkfreq with one formula. + * + * The Ameba SoC carries a bank of timers that all share the one RTIM + * register layout and fwlib API, so the register access, the + * microsecond<->tick conversion and the whole lower-half live in the shared + * driver. What differs per instance -- and per chip -- is only data: the + * base address, the clock that feeds it, its RCC gate masks and its NuttX + * IRQ number. These sit in AMEBA_TIMER_CONFIG_TABLE so a new chip (or + * a different instance choice) edits this header alone. + * + * This port exposes two of the 32-bit "basic" (LTIM) timers so a single + * lower-half serves them uniformly (verified against the SoC hal_platform.h + * / sysreg_lsys.h / vector table, not guessed): + * + * instance timer base clock RCC gate NuttX IRQ + * -------- ------ ---------- --------- -------------- ---------- + * 0 TIM1 0x40819200 32.768 kHz APBPeriph_LTIM1 IRQ_TIMER1 + * 1 TIM2 0x40819400 32.768 kHz APBPeriph_LTIM2 IRQ_TIMER2 + * + * TIM1 and TIM2 are two of the six "basic" (LTIM) timers clocked from the + * 32.768 kHz LS clock: ~30.5 us per tick, up to ~36 h in one shot. A full + * 32-bit auto-reload lets them cover the whole microsecond API range, which + * is why the driver exposes this bank rather than the "high" (HTIM) timers, + * whose 16-bit auto-reload suits sub-millisecond fine timing only. The + * non-secure base alias (0x40xxxxxx) is used, matching the core this port + * runs on. + * + * TIM0 is deliberately NOT exposed: the boot ROM claims it as the always-on + * system timer (see the vendor ameba_delay.h), and DelayUs/DelayMs and the + * SYSTIMER_* helpers all rely on it. Reprogramming TIM0 would break every + * SDK delay, so the + * driver starts the basic bank at TIM1. + * + * The RCC gate masks are the fwlib APBPeriph_LTIM1 / APBPeriph_LTIM2 values + * (function and clock masks are identical on this chip). They are written + * out here rather than pulled from <sysreg_lsys.h> to keep the vendor + * headers out of the NuttX include world (same rule as the PWM chip header). + */ + +/* RCC "function" and "clock" masks, bit30 group selector then bit index. */ + +#define AMEBA_TIMER_LTIM1_MASK (((uint32_t)1 << 30) | ((uint32_t)1 << 13)) +#define AMEBA_TIMER_LTIM2_MASK (((uint32_t)1 << 30) | ((uint32_t)1 << 14)) + +/* Number of timer instances this chip exposes and the data table that + * describes each one. The shared driver defines struct ameba_timer_config_s + * and instantiates this table; each row is + * { base, periph, clk, clkfreq, irq, idx }. + */ + +#define AMEBA_TIMER_NINSTANCES 2 + +#define AMEBA_TIMER_CONFIG_TABLE \ +{ \ + { \ + 0x40819200ul, AMEBA_TIMER_LTIM1_MASK, AMEBA_TIMER_LTIM1_MASK, \ + 32768ul, RTL8721F_IRQ_TIMER1, 1 \ + }, \ + { \ + 0x40819400ul, AMEBA_TIMER_LTIM2_MASK, AMEBA_TIMER_LTIM2_MASK, \ + 32768ul, RTL8721F_IRQ_TIMER2, 2 \ + }, \ +} + +#endif /* __ARCH_ARM_SRC_RTL8721F_AMEBA_TIMER_CHIP_H */ diff --git a/boards/arm/rtl8721f/rtl8721f_evb/configs/timer/defconfig b/boards/arm/rtl8721f/rtl8721f_evb/configs/timer/defconfig new file mode 100644 index 00000000000..c56abd7590b --- /dev/null +++ b/boards/arm/rtl8721f/rtl8721f_evb/configs/timer/defconfig @@ -0,0 +1,46 @@ +# +# 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_AMEBA_TIMER=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="rtl8721f_evb" +CONFIG_ARCH_BOARD_RTL8721F_EVB=y +CONFIG_ARCH_CHIP="rtl8721f" +CONFIG_ARCH_CHIP_RTL8721F=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV8M_SYSTICK=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +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_TIMER=y +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=401408 +CONFIG_RAM_START=0x20006000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=192 +CONFIG_SCHED_LPWORK=y +CONFIG_STACK_COLORATION=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=2500 +CONFIG_TIMER_ARCH=y +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/arm/rtl8721f/rtl8721f_evb/src/CMakeLists.txt b/boards/arm/rtl8721f/rtl8721f_evb/src/CMakeLists.txt index 3f113535008..8a3de07c5fa 100644 --- a/boards/arm/rtl8721f/rtl8721f_evb/src/CMakeLists.txt +++ b/boards/arm/rtl8721f/rtl8721f_evb/src/CMakeLists.txt @@ -54,6 +54,10 @@ if(CONFIG_AMEBA_WDG) list(APPEND SRCS rtl8721f_wdg.c) endif() +if(CONFIG_AMEBA_TIMER) + list(APPEND SRCS rtl8721f_timer.c) +endif() + target_sources(board PRIVATE ${SRCS}) if(CONFIG_AMEBA_GPIO @@ -63,7 +67,8 @@ if(CONFIG_AMEBA_GPIO OR CONFIG_AMEBA_PWM OR CONFIG_AMEBA_ADC OR CONFIG_AMEBA_RTC - OR CONFIG_AMEBA_WDG) + OR CONFIG_AMEBA_WDG + OR CONFIG_AMEBA_TIMER) # 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/rtl8721f/rtl8721f_evb/src/Makefile b/boards/arm/rtl8721f/rtl8721f_evb/src/Makefile index f07897e486b..d9c0a627764 100644 --- a/boards/arm/rtl8721f/rtl8721f_evb/src/Makefile +++ b/boards/arm/rtl8721f/rtl8721f_evb/src/Makefile @@ -56,10 +56,14 @@ ifeq ($(CONFIG_AMEBA_WDG),y) CSRCS += rtl8721f_wdg.c endif +ifeq ($(CONFIG_AMEBA_TIMER),y) +CSRCS += rtl8721f_timer.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)$(CONFIG_AMEBA_UART)$(CONFIG_AMEBA_I2C)$(CONFIG_AMEBA_SPI)$(CONFIG_AMEBA_PWM)$(CONFIG_AMEBA_ADC)$(CONFIG_AMEBA_RTC)$(CONFIG_AMEBA_WDG),) +ifneq ($(CONFIG_AMEBA_GPIO)$(CONFIG_AMEBA_UART)$(CONFIG_AMEBA_I2C)$(CONFIG_AMEBA_SPI)$(CONFIG_AMEBA_PWM)$(CONFIG_AMEBA_ADC)$(CONFIG_AMEBA_RTC)$(CONFIG_AMEBA_WDG)$(CONFIG_AMEBA_TIMER),) CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)arm$(DELIM)src$(DELIM)common$(DELIM)ameba endif diff --git a/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_bringup.c b/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_bringup.c index a8506819977..955f11caed4 100644 --- a/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_bringup.c +++ b/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_bringup.c @@ -214,6 +214,16 @@ int rtl8721f_bringup(void) } #endif +#ifdef CONFIG_AMEBA_TIMER + /* Register the board's timers at /dev/timer0 and /dev/timer1. */ + + ret = rtl8721f_timer_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: rtl8721f_timer_initialize failed: %d\n", ret); + } +#endif + IPC_patch_function(rtos_critical_enter, rtos_critical_exit, AMEBA_RTOS_CRITICAL_SEMA); IPC_SEMDelayStub(rtos_time_delay_ms); diff --git a/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_rtl8721f_evb.h b/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_rtl8721f_evb.h index 01ce0923c4c..9d38c8b7b8d 100644 --- a/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_rtl8721f_evb.h +++ b/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_rtl8721f_evb.h @@ -186,6 +186,19 @@ int rtl8721f_rtc_initialize(void); int rtl8721f_wdg_initialize(void); #endif +#ifdef CONFIG_AMEBA_TIMER +/**************************************************************************** + * Name: rtl8721f_timer_initialize + * + * Description: + * Register the board's timers at /dev/timer0 (TIM1) and /dev/timer1 + * (TIM2) (boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_timer.c). + * + ****************************************************************************/ + +int rtl8721f_timer_initialize(void); +#endif + #ifdef CONFIG_RTL8721F_FLASH_FS /**************************************************************************** * Name: ameba_flash_fs_initialize diff --git a/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_timer.c b/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_timer.c new file mode 100644 index 00000000000..1aa67149030 --- /dev/null +++ b/boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_timer.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * boards/arm/rtl8721f/rtl8721f_evb/src/rtl8721f_timer.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 <syslog.h> +#include <errno.h> + +#include "ameba_timer.h" +#include "rtl8721f_rtl8721f_evb.h" + +#ifdef CONFIG_AMEBA_TIMER + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rtl8721f_timer_initialize + * + * Description: + * Register the board's general-purpose timers. Both timers are internal + * (no board wiring), so this just binds the two exposed instances to their + * device nodes: /dev/timer0 is TIM1 and /dev/timer1 is TIM2, both 32-bit + * basic timers at 32.768 kHz. TIM0 is reserved by the ROM as the system + * timer and is not exposed. A failure on either is logged but does not + * abort the other. + * + ****************************************************************************/ + +int rtl8721f_timer_initialize(void) +{ + int ret; + + ret = ameba_timer_initialize("/dev/timer0", 0); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: ameba_timer_initialize(/dev/timer0) failed: %d\n", ret); + } + + ret = ameba_timer_initialize("/dev/timer1", 1); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: ameba_timer_initialize(/dev/timer1) failed: %d\n", ret); + } + + return ret; +} + +#endif /* CONFIG_AMEBA_TIMER */
