diff --git a/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst b/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst index f21730c4027..b10833d2c7d 100644 --- a/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst +++ b/Documentation/platforms/risc-v/gd32vw55x/boards/gd32vw553k-start/index.rst @@ -300,6 +300,33 @@ on ``/mnt/sd``, so no manual ``mount`` is needed:: GD32 on NuttX nsh> ls -l /mnt/sd +adc +--- + +NSH plus the ADC driver, registered as ``/dev/adc0`` and read by the ``adc`` +example. Channel 8 (ADC_IN8) is routed to **PB0** on the J1 header, so an +analog voltage applied there is sampled. + +The ADC converts on demand rather than continuously, so the example is built +with ``CONFIG_EXAMPLES_ADC_SWTRIG``: it issues a software trigger and then +reads a group of samples. It is bounded to 20 groups +(``CONFIG_EXAMPLES_ADC_NSAMPLES``) so it returns to the prompt:: + + nsh> adc + adc_main: g_adcstate.count: 20 + adc_main: Hardware initialized. Opening the ADC device: /dev/adc0 + Sample: + 1: channel: 8 value: 2108 + Sample: + 1: channel: 8 value: 2115 + Sample: + 1: channel: 8 value: 2112 + ... + +The reported ``value`` is the 12-bit conversion (0..4095) spanning 0..3.3 V; a +1.65 V input (half of the reference) reads about 2048, and tying PB0 to GND or +3.3 V drives it to the rails. + littlefs -------- diff --git a/arch/risc-v/src/gd32vw55x/gd32vw55x_adc.c b/arch/risc-v/src/gd32vw55x/gd32vw55x_adc.c index df37f294c9d..94be2eb395a 100644 --- a/arch/risc-v/src/gd32vw55x/gd32vw55x_adc.c +++ b/arch/risc-v/src/gd32vw55x/gd32vw55x_adc.c @@ -419,6 +419,15 @@ static int adc_setup(struct adc_dev_s *dev) return ret; } + /* Re-enable the ADC clock. adc_shutdown() gates it on close, and the + * one-shot adc_reset() that first turned it on only runs at registration; + * without this a second open would drive a clock-gated peripheral and its + * conversions would never complete. Clock gating preserves the register + * configuration set up by adc_reset(), so nothing has to be re-programmed. + */ + + modifyreg32(GD32VW55X_RCU_APB2EN, 0, RCU_APB2EN_ADCEN); + /* Make sure that the interrupts are disabled and power up the ADC */ modifyreg32(GD32VW55X_ADC_CTL0, diff --git a/boards/risc-v/gd32vw55x/gd32vw553k-start/configs/adc/defconfig b/boards/risc-v/gd32vw55x/gd32vw553k-start/configs/adc/defconfig new file mode 100644 index 00000000000..1e703838fe8 --- /dev/null +++ b/boards/risc-v/gd32vw55x/gd32vw553k-start/configs/adc/defconfig @@ -0,0 +1,55 @@ +# +# 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_ARCH_LEDS is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="gd32vw553k-start" +CONFIG_ARCH_BOARD_GD32VW553K_START=y +CONFIG_ARCH_CHIP="gd32vw55x" +CONFIG_ARCH_CHIP_GD32VW553KM=y +CONFIG_ARCH_CHIP_GD32VW55X=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=16000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_ADC=y +CONFIG_EXAMPLES_ADC_NSAMPLES=20 +CONFIG_EXAMPLES_ADC_SWTRIG=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_FS_PROCFS=y +CONFIG_GD32VW55X_ADC=y +CONFIG_GD32VW55X_UART2=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=64 +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_RAM_SIZE=294400 +CONFIG_RAM_START=0x20000200 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=13 +CONFIG_START_MONTH=7 +CONFIG_START_YEAR=2026 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=12 +CONFIG_UART2_RXBUFSIZE=128 +CONFIG_UART2_SERIAL_CONSOLE=y +CONFIG_UART2_TXBUFSIZE=128 diff --git a/boards/risc-v/gd32vw55x/gd32vw553k-start/include/board.h b/boards/risc-v/gd32vw55x/gd32vw553k-start/include/board.h index 9f0be66d09c..1e7b41f9bf8 100644 --- a/boards/risc-v/gd32vw55x/gd32vw553k-start/include/board.h +++ b/boards/risc-v/gd32vw55x/gd32vw553k-start/include/board.h @@ -115,6 +115,18 @@ GPIO_CFG_AF_1 | GPIO_CFG_PORT_A | GPIO_CFG_PIN_0) #endif +/* ADC. Route ADC channel 8 (ADC_IN8) to PB0 on the J1 header (datasheet + * Table 2-5) so an analog signal can be applied there. When SPI is enabled + * PB0 is instead claimed by the I2C0 fallback (see above), so the analog pin + * is only routed when SPI is off. The board bringup samples this channel + * when the macro is defined. + */ + +#if defined(CONFIG_GD32VW55X_ADC) && !defined(CONFIG_GD32VW55X_SPI) +# define GPIO_ADC_IN8 (GPIO_CFG_MODE_ANALOG | GPIO_CFG_PUPD_NONE | \ + GPIO_CFG_PORT_B | GPIO_CFG_PIN_0) +#endif + /* LEDs *********************************************************************/ /* The GD32VW553K-START has three LEDs on GPIOC, driven push-pull and diff --git a/boards/risc-v/gd32vw55x/gd32vw553k-start/src/gd32_bringup.c b/boards/risc-v/gd32vw55x/gd32vw553k-start/src/gd32_bringup.c index 6426b0028cf..e644af7e2a9 100644 --- a/boards/risc-v/gd32vw55x/gd32vw553k-start/src/gd32_bringup.c +++ b/boards/risc-v/gd32vw55x/gd32vw553k-start/src/gd32_bringup.c @@ -103,7 +103,11 @@ int gd32_bringup(void) #ifdef CONFIG_GD32VW55X_ADC static const uint8_t chanlist[1] = { - 0 +#ifdef GPIO_ADC_IN8 + 8 /* ADC_IN8 (PB0) on J1, routed by the adc example */ +#else + 0 /* ADC_IN0 (PA0); no analog pin routed, registers the device only */ +#endif }; struct adc_dev_s *adc;