This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit bed51ede9bc0e423ccb931a7943874812398a9d0 Author: dechao_gong <[email protected]> AuthorDate: Thu Oct 22 10:03:37 2026 +0800 arch/arm/rtl8730e: add CA32 ADC driver on /dev/adc0 Wire the shared Ameba ADC driver up on the AmebaSmart CA32 and register the converter at /dev/adc0. The chip has ten channels, of which CH0-CH5 are external and bound to the fixed pads PA0-PA5. PA0 and PA1 are not bonded out on the RTL8730EAM/EAH packages, so the board lists CH2-CH5. Chip specifics go in ameba_adc_chip.h, as for the other Ameba chips: - The pads reach the converter through the cap-touch function (pinmux function 18), and the CTC clock is gated together with the ADC one. - ADC_Read() keeps only the low 16 bits of the global data register here, so the channel id is in [15:12] and the 12-bit sample in [11:0]. The shared driver defaults assume [19:16] and 16 bits, so let a chip header override AMEBA_ADC_GET_CHNO and AMEBA_ADC_GET_DATA. - PAD_InputCtrl() is a header-only inline in the SDK on this chip, so the ROM has no symbol for it. Let a chip header supply its own via AMEBA_ADC_PAD_INPUTCTRL. ADC_Init() reads the vref calibration byte from the OTP, which needs two more things the port did not have: - SYSCFG_RLVersion(), which IPC_SEMTake()/IPC_SEMFree() use to pick their semaphore register layout. The SDK only ships it inside an object that cannot be linked alone, so mirror its logic. - DelayUs(). The ROM version busy-waits with DelayNop() and only knows the LP and NP cores. On the CA32 (CPUID 2) the RBSS_UDELAY_FLAG == 0 fallback indexes its Clk[]/Div[] tables out of bounds, so the divisor is stack garbage. OTP_Read8() polls with DelayUs(5), and the first ADC_Init() spun for between 11 and 33 seconds, delaying the NSH prompt by as much after every reset. Use up_udelay() instead, which is bounded by CONFIG_BOARD_LOOPSPERMSEC. Signed-off-by: dechao_gong <[email protected]> Assisted-by: Claude <[email protected]> --- arch/arm/include/rtl8730e/irq.h | 1 + arch/arm/src/common/ameba/ameba_adc.c | 27 ++++- arch/arm/src/rtl8730e/CMakeLists.txt | 37 +++++- arch/arm/src/rtl8730e/Make.defs | 8 +- arch/arm/src/rtl8730e/ameba_adc_chip.h | 124 +++++++++++++++++++++ arch/arm/src/rtl8730e/ameba_board.mk | 14 ++- arch/arm/src/rtl8730e/rtl8730e_flash_stubs.c | 43 +++++++ .../rtl8730e/rtl8730e_evb/configs/adc/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 +- .../src/{rtl8730e_evb.h => rtl8730e_adc.c} | 100 +++++++++-------- .../rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c | 11 ++ .../arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h | 4 + 14 files changed, 384 insertions(+), 63 deletions(-) diff --git a/arch/arm/include/rtl8730e/irq.h b/arch/arm/include/rtl8730e/irq.h index 00c639e181e..d0132e46a36 100644 --- a/arch/arm/include/rtl8730e/irq.h +++ b/arch/arm/include/rtl8730e/irq.h @@ -43,6 +43,7 @@ #define RTL8730E_IRQ_TIMER2 34 /* GIC SPI 2: TIM2 (LP basic timer) */ #define RTL8730E_IRQ_TIMER3 35 /* GIC SPI 3: TIM3 (LP basic timer) */ +#define RTL8730E_IRQ_ADC 46 /* GIC SPI 14: ADC */ #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 */ diff --git a/arch/arm/src/common/ameba/ameba_adc.c b/arch/arm/src/common/ameba/ameba_adc.c index 9ba17598e26..c3cf08b52cf 100644 --- a/arch/arm/src/common/ameba/ameba_adc.c +++ b/arch/arm/src/common/ameba/ameba_adc.c @@ -92,10 +92,19 @@ #define AMEBA_ADC_CLKDIV_24 0x3 /* ADC_CLK_DIV_24 */ #define AMEBA_PAD_NOPULL 0x0 /* GPIO_PuPd_NOPULL */ -/* 16-bit conversion word layout: channel id in [19:16], data in [15:0]. */ +/* Conversion word layout as returned by ADC_Read(): channel id in [19:16], + * data in [15:0] on most chips. A chip whose ADC_ID_AND_DATA() keeps fewer + * bits (amebasmart: id in [15:12], data in [11:0]) overrides both macros in + * its ameba_adc_chip.h. + */ -#define AMEBA_ADC_GET_CHNO(x) (((x) >> 16) & 0x0f) -#define AMEBA_ADC_GET_DATA(x) ((x) & 0xffff) +#ifndef AMEBA_ADC_GET_CHNO +# define AMEBA_ADC_GET_CHNO(x) (((x) >> 16) & 0x0f) +#endif + +#ifndef AMEBA_ADC_GET_DATA +# define AMEBA_ADC_GET_DATA(x) ((x) & 0xffff) +#endif /**************************************************************************** * Private Types @@ -188,7 +197,17 @@ extern void RCC_PeriphClockCmd(uint32_t periph, uint32_t clock, extern void Pinmux_Config(uint8_t pin, uint32_t func); extern void PAD_PullCtrl(uint8_t pin, uint8_t pulltype); extern void PAD_SleepPullCtrl(uint8_t pin, uint8_t pulltype); + +/* PAD_InputCtrl() is a ROM function on some chips and a header-only inline + * on others (amebasmart), so a chip that has no linkable symbol defines + * AMEBA_ADC_PAD_INPUTCTRL in its ameba_adc_chip.h to supply its own. + */ + +#ifndef AMEBA_ADC_PAD_INPUTCTRL extern void PAD_InputCtrl(uint8_t pin, uint32_t newstate); +# define AMEBA_ADC_PAD_INPUTCTRL(pin, state) PAD_InputCtrl(pin, state) +#endif + extern void ADC_StructInit(struct ameba_adc_init_s *init); extern void ADC_Init(struct ameba_adc_init_s *init); extern void ADC_Cmd(uint32_t newstate); @@ -477,7 +496,7 @@ int ameba_adc_register(const char *path, const uint8_t *channels, Pinmux_Config(pins[i], AMEBA_ADC_PINMUX_FID); PAD_PullCtrl(pins[i], AMEBA_PAD_NOPULL); PAD_SleepPullCtrl(pins[i], AMEBA_PAD_NOPULL); - PAD_InputCtrl(pins[i], AMEBA_DISABLE); + AMEBA_ADC_PAD_INPUTCTRL(pins[i], AMEBA_DISABLE); } } diff --git a/arch/arm/src/rtl8730e/CMakeLists.txt b/arch/arm/src/rtl8730e/CMakeLists.txt index 61723ef22b6..e4cbade7b2f 100644 --- a/arch/arm/src/rtl8730e/CMakeLists.txt +++ b/arch/arm/src/rtl8730e/CMakeLists.txt @@ -130,6 +130,20 @@ if(CONFIG_AMEBA_WDG) endif() endif() +if(CONFIG_AMEBA_ADC) + list(APPEND SRCS ${AMEBA_COMMON}/ameba_adc.c) + if(NOT CONFIG_RTL8730E_FLASH_FS + AND NOT CONFIG_AMEBA_GPIO + AND NOT CONFIG_AMEBA_UART + AND NOT CONFIG_AMEBA_I2C + AND NOT CONFIG_AMEBA_SPI + AND NOT CONFIG_AMEBA_PWM + AND NOT CONFIG_AMEBA_TIMER + AND NOT CONFIG_AMEBA_WDG) + list(APPEND SRCS rtl8730e_flash_stubs.c) + endif() +endif() + target_include_directories(arch PRIVATE ${AMEBA_COMMON}) target_sources(arch PRIVATE ${SRCS}) @@ -215,14 +229,18 @@ if(CONFIG_RTL8730E_FLASH_FS OR CONFIG_AMEBA_I2C OR CONFIG_AMEBA_SPI OR CONFIG_AMEBA_PWM - OR CONFIG_AMEBA_TIMER) + OR CONFIG_AMEBA_TIMER + OR CONFIG_AMEBA_ADC) set(AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_arch.c ${AMEBA_SOC}/swlib/log.c ${AMEBA_SOC}/swlib/sscanf_minimal.c) - # IPC layer is needed by both WiFi (WHC) and Flash FS (write-lock protocol). - # Include it once regardless of which feature(s) are enabled. - if(CONFIG_RTL8730E_FLASH_FS OR CONFIG_RTL8730E_WIFI) + # IPC layer is needed by WiFi (WHC), Flash FS (write-lock protocol) and the + # ADC (OTP reads take the cross-core IPC_SEM_OTP semaphore). Include it once + # regardless of which feature(s) are enabled. + if(CONFIG_RTL8730E_FLASH_FS + OR CONFIG_RTL8730E_WIFI + OR CONFIG_AMEBA_ADC) list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_ipc_api.c ${AMEBA_SOC}/fwlib/ram_common/ameba_ipc_ram.c) endif() @@ -251,6 +269,13 @@ if(CONFIG_RTL8730E_FLASH_FS list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_tim.c) endif() + # The AP ROM has no ADC; the whole fwlib ADC layer is RAM-side, and it reads + # its calibration data through OTP_Read8() from ameba_otp.c. + if(CONFIG_AMEBA_ADC) + list(APPEND AMEBA_FWLIB_SRCS ${AMEBA_SOC}/fwlib/ram_common/ameba_adc.c + ${AMEBA_SOC}/fwlib/ram_common/ameba_otp.c) + endif() + # Silence SDK warnings, activate CA32 code paths. No -mcmse (ARMv7-A). set(AMEBA_FWLIB_INC -Wno-int-conversion @@ -293,6 +318,7 @@ if(CONFIG_AMEBA_GPIO OR CONFIG_AMEBA_PWM OR CONFIG_AMEBA_TIMER OR CONFIG_AMEBA_WDG + OR CONFIG_AMEBA_ADC OR CONFIG_RTL8730E_FLASH_FS) list(APPEND AMEBA_EXTRA_LIBS ${AMEBA_SOC}/project/${AMEBA_KM_PROJ}/lib/soc/lib_rom.a) @@ -304,7 +330,8 @@ if(CONFIG_RTL8730E_FLASH_FS OR CONFIG_AMEBA_I2C OR CONFIG_AMEBA_SPI OR CONFIG_AMEBA_PWM - OR CONFIG_AMEBA_TIMER) + OR CONFIG_AMEBA_TIMER + OR CONFIG_AMEBA_ADC) 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 c7d6353dbbd..aef5babb761 100644 --- a/arch/arm/src/rtl8730e/Make.defs +++ b/arch/arm/src/rtl8730e/Make.defs @@ -65,7 +65,7 @@ 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_AMEBA_UART) $(CONFIG_AMEBA_I2C) $(CONFIG_AMEBA_SPI) $(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER) $(CONFIG_AMEBA_WDG) $(CONFIG_RTL8730E_FLASH_FS)),) +ifneq ($(filter y,$(CONFIG_AMEBA_GPIO) $(CONFIG_AMEBA_UART) $(CONFIG_AMEBA_I2C) $(CONFIG_AMEBA_SPI) $(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER) $(CONFIG_AMEBA_WDG) $(CONFIG_AMEBA_ADC) $(CONFIG_RTL8730E_FLASH_FS)),) CHIP_CSRCS += rtl8730e_flash_stubs.c EXTRA_LIBS += $(AMEBA_AP_SOC_LIB)$(DELIM)lib_rom.a @@ -99,6 +99,10 @@ ifeq ($(CONFIG_AMEBA_WDG),y) CHIP_CSRCS += ameba_wdg.c endif +ifeq ($(CONFIG_AMEBA_ADC),y) +CHIP_CSRCS += ameba_adc.c +endif + # WiFi (WHC host, CA32 side). ifeq ($(CONFIG_RTL8730E_WIFI),y) CHIP_CSRCS += rtl8730e_wifi_init.c @@ -129,7 +133,7 @@ endif # fwlib archive is needed whenever any driver uses RAM-side SDK tables # (flash MTD, UART, I2C, ...). Link it once for all such configs. -ifneq ($(filter y,$(CONFIG_RTL8730E_FLASH_FS) $(CONFIG_AMEBA_UART) $(CONFIG_AMEBA_I2C) $(CONFIG_AMEBA_SPI) $(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER)),) +ifneq ($(filter y,$(CONFIG_RTL8730E_FLASH_FS) $(CONFIG_AMEBA_UART) $(CONFIG_AMEBA_I2C) $(CONFIG_AMEBA_SPI) $(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER) $(CONFIG_AMEBA_ADC)),) # Prebuilt staging area (within the board tree, gitignored). AMEBA_PREBUILT = $(BOARD_DIR)$(DELIM)prebuilt diff --git a/arch/arm/src/rtl8730e/ameba_adc_chip.h b/arch/arm/src/rtl8730e/ameba_adc_chip.h new file mode 100644 index 00000000000..19a745fbfbd --- /dev/null +++ b/arch/arm/src/rtl8730e/ameba_adc_chip.h @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/rtl8730e/ameba_adc_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_ADC_CHIP_H +#define __ARCH_ARM_SRC_RTL8730E_AMEBA_ADC_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Per-chip ADC wiring for RTL8730E (AmebaSmart, Cortex-A32), read out of the + * SoC ameba_adc.h, sysreg_lsys.h, ameba_pinmux.h and the CA32 section of + * ameba_vector_table.h. The shared driver + * (arch/arm/src/common/ameba/ameba_adc.c) drives the converter through the + * SDK fwlib API, so no register base appears here. + * + * Channels: ADC_CH_NUM is 10. CH0..CH5 are external and bound to fixed pads + * PA0..PA5 (ADC_CHx_PIN); the remaining channels are internal and have no + * pad. On the RTL8730EAM/EAH packages PA0 and PA1 are not bonded out, so + * only CH2..CH5 (PA2..PA5) are usable there. + * + * Pad mux: the pads reach the ADC through the cap-touch function + * (PINMUX_FUNCTION_CAPTOUCH, FUNC_ID18, "TOUCHn_ADCn" in the pinmux table). + * PINMUX_FUNCTION_AUXIN is 16 here, which is FUNC_ID16 = SPK, so it must + * not be used. The ADC and the cap-touch controller share these pads, and + * the SDK enables the cap-touch (CTC) clock together with the ADC clock, so + * AMEBA_ADC_AUXCLK_* gate APBPeriph_CTC as well. + * + * Conversion word: ADC_Read() keeps only the low 16 bits of the global data + * register on this chip, so the channel id is in [15:12] and the 12-bit + * sample in [11:0]. Other chips keep 20 bits (id in [19:16]); the shared + * driver's defaults assume that, hence the overrides below. + */ + +#define AMEBA_ADC_NCHAN 10 /* ADC_CH_NUM: CH0..CH5 ext pads */ +#define AMEBA_ADC_MAXLIST 16 /* Channel-switch list depth (Cvlist) */ +#define AMEBA_ADC_PINMUX_FID 18 /* PINMUX_FUNCTION_CAPTOUCH */ +#define AMEBA_ADC_IRQ 46 /* ADC_IRQ (unused by this polling drv) */ + +/* sizeof(fwlib ADC_InitTypeDef): OpMode/CvlistLen/Cvlist[16]/ClkDiv/ + * RxThresholdLevel/SpecialCh (21 bytes), ChanInType (u32, 4-aligned at 24), + * ChIDEn -> 32 bytes. + */ + +#define AMEBA_ADC_INIT_SIZE 32 + +/* APBPeriph_ADC / APBPeriph_ADC_CLOCK: bit 20 / bit 15 of the LSYS block, + * with the bit30 group selector clear. APBPeriph_CTC / _CTC_CLOCK are bit + * 21 / bit 14. + */ + +#define AMEBA_ADC_APBPERIPH ((uint32_t)1 << 20) +#define AMEBA_ADC_APBPERIPH_CLK ((uint32_t)1 << 15) +#define AMEBA_ADC_AUXCLK_PERIPH ((uint32_t)1 << 21) +#define AMEBA_ADC_AUXCLK_CLK ((uint32_t)1 << 14) + +/* ADC_InitTypeDef has a ClkDiv field at offset 18 on this chip. */ + +#define AMEBA_ADC_HAS_CLKDIV 1 + +/* Conversion word layout, see above. */ + +#define AMEBA_ADC_GET_CHNO(x) (((x) >> 12) & 0x0f) +#define AMEBA_ADC_GET_DATA(x) ((x) & 0x0fff) + +/* PAD_InputCtrl() is a header-only inline in the SDK on this chip, so the + * ROM has no symbol for it. It gates the digital input path of the ADC/CTC + * pads (PA0..PA8) with one bit per pad in REG_LSYS_DUMMY_094 of the LSYS + * block (SYSTEM_CTRL_BASE for the CA32 is 0x42008000, offset 0x2f8). + */ + +#define RTL8730E_ADC_PADIN_REG 0x420082f8 +#define RTL8730E_ADC_PADIN_MAXPAD 8 /* _PA_8 */ + +static inline void rtl8730e_adc_padinput(uint8_t pin, uint32_t enable) +{ + volatile uint32_t *reg = (volatile uint32_t *)RTL8730E_ADC_PADIN_REG; + + if (pin > RTL8730E_ADC_PADIN_MAXPAD) + { + return; + } + + if (enable) + { + *reg |= (uint32_t)1 << pin; + } + else + { + *reg &= ~((uint32_t)1 << pin); + } +} + +#define AMEBA_ADC_PAD_INPUTCTRL(pin, state) \ + rtl8730e_adc_padinput(pin, state) + +#endif /* __ARCH_ARM_SRC_RTL8730E_AMEBA_ADC_CHIP_H */ diff --git a/arch/arm/src/rtl8730e/ameba_board.mk b/arch/arm/src/rtl8730e/ameba_board.mk index dcd4b0fbcdd..bc461d4c02d 100644 --- a/arch/arm/src/rtl8730e/ameba_board.mk +++ b/arch/arm/src/rtl8730e/ameba_board.mk @@ -54,9 +54,10 @@ AMEBA_FWLIB_SRCS = $(AMEBA_SOC)/fwlib/ram_common/ameba_arch.c \ $(AMEBA_SOC)/swlib/log.c \ $(AMEBA_SOC)/swlib/sscanf_minimal.c -# IPC layer is needed by both WiFi (WHC) and Flash FS (write-lock protocol). -# Include it once regardless of which feature(s) are enabled. -ifneq ($(filter y,$(CONFIG_RTL8730E_WIFI) $(CONFIG_RTL8730E_FLASH_FS)),) +# IPC layer is needed by WiFi (WHC), Flash FS (write-lock protocol) and the +# ADC (OTP reads take the cross-core IPC_SEM_OTP semaphore). Include it +# once regardless of which feature(s) are enabled. +ifneq ($(filter y,$(CONFIG_RTL8730E_WIFI) $(CONFIG_RTL8730E_FLASH_FS) $(CONFIG_AMEBA_ADC)),) AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_ipc_api.c \ $(AMEBA_SOC)/fwlib/ram_common/ameba_ipc_ram.c endif @@ -97,6 +98,13 @@ ifneq ($(filter y,$(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER)),) AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_tim.c endif +# The AP ROM has no ADC; the whole fwlib ADC layer is RAM-side, and it +# reads its calibration data through OTP_Read8() from ameba_otp.c. +ifeq ($(CONFIG_AMEBA_ADC),y) +AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_adc.c +AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_otp.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/rtl8730e_flash_stubs.c b/arch/arm/src/rtl8730e/rtl8730e_flash_stubs.c index dd9083673f6..47399fc8869 100644 --- a/arch/arm/src/rtl8730e/rtl8730e_flash_stubs.c +++ b/arch/arm/src/rtl8730e/rtl8730e_flash_stubs.c @@ -349,6 +349,49 @@ void Pinmux_Config(uint32_t pinname, uint32_t pinfunc) _Pinmux_Config(pinname, pinfunc); } +/* DelayUs: the ROM version busy-waits with DelayNop() and only knows the LP + * (CPUID 0) and NP (CPUID 1) cores. On the CA32 (CPUID 2) the + * RBSS_UDELAY_FLAG == 0 fallback indexes its Clk[]/Div[] tables out of + * bounds, so the divisor is stack garbage and a DelayUs(5) can spin for + * ~38 billion iterations. OTP_Read8() polls with DelayUs(5), so the first + * ADC_Init() (vref calibration read) stalled boot for ~33 seconds. Use the + * NuttX delay instead, which is bounded by CONFIG_BOARD_LOOPSPERMSEC. + */ + +void DelayUs(uint32_t us) +{ + up_udelay(us); +} + +/* SYSCFG_RLVersion: silicon cut (A=0, B=1, C=2, D=3). The SDK only ships + * it inside lib_chipinfo.a's ameba_rom_patch.o, which also carries dozens of + * unrelated functions and cannot be linked in alone, so mirror its logic: a + * select code 0xa written to [31:28] of LSYS REG_LSYS_SCAN_CTRL (0x274) + * exposes the cut in [19:16] on readback; the register is then restored. + * The result is cached, as in the original. IPC_SEMTake()/IPC_SEMFree() + * (OTP reads) pick their semaphore register layout from this value. + */ + +uint32_t SYSCFG_RLVersion(void) +{ + static uint8_t cut = 0xff; + + if (cut == 0xff) + { + volatile uint32_t *reg = (volatile uint32_t *)0x42008274u; + uint32_t base = *reg & ~0xf0000000u; + uint32_t val; + + *reg = base | 0xa0000000u; + val = *reg; + *reg = base; + + cut = (val >> 16) & 0xf; + } + + return cut; +} + /**************************************************************************** * Name: rtl8730e_flash_init_para * diff --git a/boards/arm/rtl8730e/rtl8730e_evb/configs/adc/defconfig b/boards/arm/rtl8730e/rtl8730e_evb/configs/adc/defconfig new file mode 100644 index 00000000000..6fa0ab80ecd --- /dev/null +++ b/boards/arm/rtl8730e/rtl8730e_evb/configs/adc/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_ADC=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_ADC=y +CONFIG_EXAMPLES_ADC_NSAMPLES=1 +CONFIG_EXAMPLES_ADC_SWTRIG=y +CONFIG_EXAMPLES_HELLO=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_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 cd0e93042c0..88090db7424 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_AMEBA_UART) $(CONFIG_AMEBA_I2C) $(CONFIG_AMEBA_SPI) $(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER) $(CONFIG_AMEBA_WDG) $(CONFIG_RTL8730E_WIFI) $(CONFIG_RTL8730E_FLASH_FS)),) +ifneq ($(filter y,$(CONFIG_AMEBA_GPIO) $(CONFIG_AMEBA_UART) $(CONFIG_AMEBA_I2C) $(CONFIG_AMEBA_SPI) $(CONFIG_AMEBA_PWM) $(CONFIG_AMEBA_TIMER) $(CONFIG_AMEBA_WDG) $(CONFIG_AMEBA_ADC) $(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 4eaf77767f5..1bdd8a58a35 100644 --- a/boards/arm/rtl8730e/rtl8730e_evb/src/CMakeLists.txt +++ b/boards/arm/rtl8730e/rtl8730e_evb/src/CMakeLists.txt @@ -63,6 +63,12 @@ if(CONFIG_AMEBA_WDG) PRIVATE ${NUTTX_DIR}/arch/arm/src/common/ameba) endif() +if(CONFIG_AMEBA_ADC) + list(APPEND SRCS rtl8730e_adc.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 b6b8cc8cc54..619b895ea93 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)$(CONFIG_AMEBA_UART)$(CONFIG_AMEBA_I2C)$(CONFIG_AMEBA_SPI)$(CONFIG_AMEBA_PWM)$(CONFIG_AMEBA_TIMER)$(CONFIG_AMEBA_WDG),) +ifneq ($(CONFIG_RTL8730E_FLASH_FS)$(CONFIG_AMEBA_GPIO)$(CONFIG_AMEBA_UART)$(CONFIG_AMEBA_I2C)$(CONFIG_AMEBA_SPI)$(CONFIG_AMEBA_PWM)$(CONFIG_AMEBA_TIMER)$(CONFIG_AMEBA_WDG)$(CONFIG_AMEBA_ADC),) CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)arm$(DELIM)src$(DELIM)common$(DELIM)ameba endif @@ -66,4 +66,8 @@ ifeq ($(CONFIG_AMEBA_WDG),y) CSRCS += rtl8730e_wdg.c endif +ifeq ($(CONFIG_AMEBA_ADC),y) +CSRCS += rtl8730e_adc.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_adc.c similarity index 51% copy from boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h copy to boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_adc.c index 28de502f7cc..960b166431c 100644 --- a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h +++ b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_adc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h + * boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_adc.c * * SPDX-License-Identifier: Apache-2.0 * @@ -20,70 +20,76 @@ * ****************************************************************************/ -#ifndef __BOARDS_ARM_RTL8730E_RTL8730E_EVB_SRC_RTL8730E_EVB_H -#define __BOARDS_ARM_RTL8730E_RTL8730E_EVB_SRC_RTL8730E_EVB_H - /**************************************************************************** * Included Files ****************************************************************************/ #include <nuttx/config.h> -#include <stdint.h> +#include <sys/param.h> +#include <syslog.h> +#include <errno.h> -/**************************************************************************** - * Public Types - ****************************************************************************/ +#include "ameba_gpio.h" +#include "ameba_adc.h" +#include "rtl8730e_evb.h" /**************************************************************************** - * Public Data + * Private Data ****************************************************************************/ -#ifndef __ASSEMBLY__ +/* Channels sampled on /dev/adc0 and the analog pad each is wired to. The + * external channels CH0..CH5 are bound to the fixed pads PA0..PA5 (the chip + * pin-mux table names them TOUCHn_ADCn). PA0 and PA1 are not bonded out on + * the RTL8730EAM/EAH packages, so this board lists CH2..CH5 only; the same + * four are present on every package. + * + * PA3/PA4 are also I2C1 pads and PA4/PA5 are UART1 or PWM pads, so a config + * registering those too must drop the clashing channel here. The pads are + * shared with the cap-touch controller and the DMIC, which this port does + * not use. + */ + +static const uint8_t g_adc_channels[] = +{ + 2, /* ADC_CH2 */ + 3, /* ADC_CH3 */ + 4, /* ADC_CH4 */ + 5, /* ADC_CH5 */ +}; + +static const uint8_t g_adc_pins[] = +{ + AMEBA_PA(2), /* CH2 -> PA2 */ + AMEBA_PA(3), /* CH3 -> PA3 */ + AMEBA_PA(4), /* CH4 -> PA4 */ + AMEBA_PA(5), /* CH5 -> PA5 */ +}; /**************************************************************************** - * Public Functions Definitions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: rtl8730e_bringup + * Name: rtl8730e_adc_initialize * * Description: - * Bring up board features + * Register the board's ADC channels at /dev/adc0. * ****************************************************************************/ -#if defined(CONFIG_BOARDCTL) || defined(CONFIG_BOARD_LATE_INITIALIZE) -int rtl8730e_bringup(void); -#endif - -#ifdef CONFIG_AMEBA_GPIO -int rtl8730e_gpio_initialize(void); -#endif - -#ifdef CONFIG_AMEBA_UART -int rtl8730e_uart_initialize(void); -#endif - -#ifdef CONFIG_AMEBA_I2C -int rtl8730e_i2c_initialize(void); -#endif - -#ifdef CONFIG_AMEBA_SPI -int rtl8730e_spi_initialize(void); -#endif - -#ifdef CONFIG_AMEBA_PWM -int rtl8730e_pwm_initialize(void); -#endif - -#ifdef CONFIG_AMEBA_TIMER -int rtl8730e_timer_initialize(void); -#endif - -#ifdef CONFIG_AMEBA_WDG -int rtl8730e_wdg_initialize(void); -#endif - -#endif /* __ASSEMBLY__ */ -#endif /* __BOARDS_ARM_RTL8730E_RTL8730E_EVB_SRC_RTL8730E_EVB_H */ +int rtl8730e_adc_initialize(void) +{ + int ret; + + ret = ameba_adc_register("/dev/adc0", g_adc_channels, g_adc_pins, + nitems(g_adc_channels)); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: ameba_adc_register(/dev/adc0) failed: %d\n", ret); + return ret; + } + + return OK; +} diff --git a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c index 49d9dac6d74..72e0fa0805a 100644 --- a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c +++ b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_bringup.c @@ -315,6 +315,17 @@ int rtl8730e_bringup(void) } #endif +#ifdef CONFIG_AMEBA_ADC + /* Register the board's ADC channels at /dev/adc0. */ + + ret = rtl8730e_adc_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to initialize ADC: %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 28de502f7cc..a6b84bf8839 100644 --- a/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h +++ b/boards/arm/rtl8730e/rtl8730e_evb/src/rtl8730e_evb.h @@ -85,5 +85,9 @@ int rtl8730e_timer_initialize(void); int rtl8730e_wdg_initialize(void); #endif +#ifdef CONFIG_AMEBA_ADC +int rtl8730e_adc_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_ARM_RTL8730E_RTL8730E_EVB_SRC_RTL8730E_EVB_H */
