From 793f37c0079036d2962191aa71ee9959bb01ca15 Mon Sep 17 00:00:00 2001 From: Roberto Bucher Date: Thu, 27 Oct 2022 11:08:39 +0200 Subject: [PATCH] Files for pysimCoder on nucleo-h743zi2 --- arch/arm/src/stm32h7/stm32_adc.c | 14 +- arch/arm/src/stm32h7/stm32_qencoder.c | 3 +- .../nucleo-h743zi2/configs/pysim/defconfig | 132 +++++++ .../stm32h7/nucleo-h743zi2/include/board.h | 13 +- .../arm/stm32h7/nucleo-h743zi2/src/Makefile | 16 + .../nucleo-h743zi2/src/nucleo-h743zi2.h | 73 ++++ .../stm32h7/nucleo-h743zi2/src/stm32_adc.c | 219 ++++++++++++ .../nucleo-h743zi2/src/stm32_bringup.c | 66 ++++ .../stm32h7/nucleo-h743zi2/src/stm32_gpio.c | 331 ++++++++++++++++++ .../stm32h7/nucleo-h743zi2/src/stm32_pwm.c | 114 ++++++ .../nucleo-h743zi2/src/stm32_qencoder.c | 65 ++++ 11 files changed, 1036 insertions(+), 10 deletions(-) create mode 100644 boards/arm/stm32h7/nucleo-h743zi2/configs/pysim/defconfig create mode 100644 boards/arm/stm32h7/nucleo-h743zi2/src/stm32_adc.c create mode 100644 boards/arm/stm32h7/nucleo-h743zi2/src/stm32_gpio.c create mode 100644 boards/arm/stm32h7/nucleo-h743zi2/src/stm32_pwm.c create mode 100644 boards/arm/stm32h7/nucleo-h743zi2/src/stm32_qencoder.c diff --git a/arch/arm/src/stm32h7/stm32_adc.c b/arch/arm/src/stm32h7/stm32_adc.c index dde66edf03..f98c8018e2 100644 --- a/arch/arm/src/stm32h7/stm32_adc.c +++ b/arch/arm/src/stm32h7/stm32_adc.c @@ -767,7 +767,7 @@ static int adc_timinit(struct stm32_dev_s *priv) * position. */ - ainfo("Initializing timers extsel = 0x%08x\n", priv->extsel); + ainfo("Initializing timers extsel = 0x%08" PRIx32 "\n", priv->extsel); adc_modifyreg(priv, STM32_ADC_CFGR_OFFSET, ADC_CFGR_EXTEN_MASK | ADC_CFGR_EXTSEL_MASK, @@ -1478,17 +1478,19 @@ static int adc_setup(struct adc_dev_s *dev) leave_critical_section(flags); - ainfo("ISR: 0x%08x CR: 0x%08x CFGR: 0x%08x CFGR2: 0x%08x\n", + ainfo("ISR: 0x%08" PRIx32 " CR: 0x%08" PRIx32 " \ + CFGR: 0x%08" PRIx32 " CFGR2: 0x%08" PRIx32 "\n", adc_getreg(priv, STM32_ADC_ISR_OFFSET), adc_getreg(priv, STM32_ADC_CR_OFFSET), adc_getreg(priv, STM32_ADC_CFGR_OFFSET), adc_getreg(priv, STM32_ADC_CFGR2_OFFSET)); - ainfo("SQR1: 0x%08x SQR2: 0x%08x SQR3: 0x%08x SQR4: 0x%08x\n", + ainfo("SQR1: 0x%08" PRIx32 " SQR2: 0x%08" PRIx32 " \ + SQR3: 0x%08" PRIx32 " SQR4: 0x%08" PRIx32 "\n", adc_getreg(priv, STM32_ADC_SQR1_OFFSET), adc_getreg(priv, STM32_ADC_SQR2_OFFSET), adc_getreg(priv, STM32_ADC_SQR3_OFFSET), adc_getreg(priv, STM32_ADC_SQR4_OFFSET)); - ainfo("CCR: 0x%08x\n", adc_getregm(priv, STM32_ADC_CCR_OFFSET)); + ainfo("CCR: 0x%08" PRIx32 "\n", adc_getregm(priv, STM32_ADC_CCR_OFFSET)); /* Enable the ADC interrupt */ @@ -1854,8 +1856,8 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) value = adc_getreg(priv, STM32_ADC_DR_OFFSET); value &= ADC_DR_MASK; - awarn("WARNING: Analog Watchdog, Value (0x%03x) out of range!\n", - value); + awarn("WARNING: Analog Watchdog, Value (0x%03" PRIx32 ") \ + out of range!\n", value); /* Stop ADC conversions to avoid continuous interrupts */ diff --git a/arch/arm/src/stm32h7/stm32_qencoder.c b/arch/arm/src/stm32h7/stm32_qencoder.c index 24bbe3fe61..f9fd0d2375 100644 --- a/arch/arm/src/stm32h7/stm32_qencoder.c +++ b/arch/arm/src/stm32h7/stm32_qencoder.c @@ -987,7 +987,8 @@ static int stm32_shutdown(struct qe_lowerhalf_s *lower) putreg32(regval, regaddr); leave_critical_section(flags); - sninfo("regaddr: %08x resetbit: %08x\n", regaddr, resetbit); + sninfo("regaddr: %08" PRIx32 " resetbit: %08" PRIx32 "\n", \ + regaddr, resetbit); stm32_dumpregs(priv, "After stop"); /* Disable clocking to the timer */ diff --git a/boards/arm/stm32h7/nucleo-h743zi2/configs/pysim/defconfig b/boards/arm/stm32h7/nucleo-h743zi2/configs/pysim/defconfig new file mode 100644 index 0000000000..5f3e340b8f --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h743zi2/configs/pysim/defconfig @@ -0,0 +1,132 @@ +# +# 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_STANDARD_SERIAL is not set +CONFIG_ADC=y +CONFIG_ANALOG=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="nucleo-h743zi2" +CONFIG_ARCH_BOARD_NUCLEO_H743ZI2=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743ZI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_RAMVECTORS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_TASK_STACKSIZE=4096 +CONFIG_DEV_GPIO=y +CONFIG_DHCPC_RENEW_STACKSIZE=2048 +CONFIG_ETH0_PHY_LAN8742A=y +CONFIG_FAT_LCNAMES=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=2048 +CONFIG_INTELHEX_BINARY=y +CONFIG_IOEXPANDER=y +CONFIG_LIBC_EXECFUNCS=y +CONFIG_LIBC_STRERROR=y +CONFIG_LIBM=y +CONFIG_MM_REGIONS=4 +CONFIG_NET=y +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETINIT_DHCPC=y +CONFIG_NETINIT_DRIPADDR=0xc0a8b201 +CONFIG_NETUTILS_DISCOVER=y +CONFIG_NETUTILS_TELNETD=y +CONFIG_NETUTILS_WEBCLIENT=y +CONFIG_NET_ARP_IPIN=y +CONFIG_NET_ARP_SEND=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1500 +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_IGMP=y +CONFIG_NET_LOOPBACK=y +CONFIG_NET_ROUTE=y +CONFIG_NET_STATISTICS=y +CONFIG_NET_TCP=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_CHECKSUMS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_FILE_APPS=y +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_NSH_TELNETD_CLIENTSTACKSIZE=2048 +CONFIG_NSH_TELNETD_DAEMONSTACKSIZE=2048 +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_CLEANUP=y +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_PTHREAD_STACK_DEFAULT=2048 +CONFIG_PTHREAD_STACK_MIN=1024 +CONFIG_PWM=y +CONFIG_PWM_MULTICHAN=y +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=10 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKSTACKSIZE=2048 +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKSTACKSIZE=2048 +CONFIG_SCHED_WAITPID=y +CONFIG_SENSORS=y +CONFIG_SENSORS_QENCODER=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SPI=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32H7_ADC1=y +CONFIG_STM32H7_ADC1_SAMPLE_FREQUENCY=5000 +CONFIG_STM32H7_ADC1_TIMTRIG=1 +CONFIG_STM32H7_DMA1=y +CONFIG_STM32H7_ETHMAC=y +CONFIG_STM32H7_OTGFS=y +CONFIG_STM32H7_PHYSR=31 +CONFIG_STM32H7_PHYSR_100FD=0x0018 +CONFIG_STM32H7_PHYSR_100HD=0x0008 +CONFIG_STM32H7_PHYSR_10FD=0x0014 +CONFIG_STM32H7_PHYSR_10HD=0x0004 +CONFIG_STM32H7_PHYSR_ALTCONFIG=y +CONFIG_STM32H7_PHYSR_ALTMODE=0x001c +CONFIG_STM32H7_PWM_MULTICHAN=y +CONFIG_STM32H7_TIM1=y +CONFIG_STM32H7_TIM1_QE=y +CONFIG_STM32H7_TIM2=y +CONFIG_STM32H7_TIM2_ADC=y +CONFIG_STM32H7_TIM3=y +CONFIG_STM32H7_TIM3_CH1OUT=y +CONFIG_STM32H7_TIM3_CH2OUT=y +CONFIG_STM32H7_TIM3_CHANNEL1=y +CONFIG_STM32H7_TIM3_CHANNEL2=y +CONFIG_STM32H7_TIM3_PWM=y +CONFIG_STM32H7_USART3=y +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_PING=y +CONFIG_SYSTEM_PING_STACKSIZE=2048 +CONFIG_TASK_NAME_SIZE=0 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 +CONFIG_USART3_SERIAL_CONSOLE=y +CONFIG_USBHOST=y +CONFIG_USBHOST_MSC=y +CONFIG_USBHOST_MSC_NOTIFIER=y +CONFIG_USEC_PER_TICK=1000 diff --git a/boards/arm/stm32h7/nucleo-h743zi2/include/board.h b/boards/arm/stm32h7/nucleo-h743zi2/include/board.h index a4def19fcc..8fc362cdff 100644 --- a/boards/arm/stm32h7/nucleo-h743zi2/include/board.h +++ b/boards/arm/stm32h7/nucleo-h743zi2/include/board.h @@ -389,9 +389,16 @@ #define GPIO_TIM1_CH1NOUT GPIO_TIM1_CH1NOUT_3 /* PE8 - D42 */ #define GPIO_TIM1_CH2OUT GPIO_TIM1_CH2OUT_2 /* PE11 - D5 */ #define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2NOUT_3 /* PE10 - D40 */ -#define GPIO_TIM1_CH3OUT GPIO_TIM1_CH3OUT_2 /* PE13 - D3 */ -#define GPIO_TIM1_CH3NOUT GPIO_TIM1_CH3NOUT_3 /* PE12 - D39 */ -#define GPIO_TIM1_CH4OUT GPIO_TIM1_CH4OUT_2 /* PE14 - D38 */ + +/* TIM3 */ + +#define GPIO_TIM3_CH1IN GPIO_TIM3_CH1IN_2 /* PA4 */ +#define GPIO_TIM3_CH2IN GPIO_TIM3_CH2IN_2 /* PB5 */ + +/* TIM4 */ + +#define GPIO_TIM4_CH1IN GPIO_TIM4_CH1IN_2 /* PD12 */ +#define GPIO_TIM4_CH2IN GPIO_TIM4_CH2IN_2 /* PD13 */ /* FDCAN1 */ diff --git a/boards/arm/stm32h7/nucleo-h743zi2/src/Makefile b/boards/arm/stm32h7/nucleo-h743zi2/src/Makefile index 222e9f41c8..34f044927a 100644 --- a/boards/arm/stm32h7/nucleo-h743zi2/src/Makefile +++ b/boards/arm/stm32h7/nucleo-h743zi2/src/Makefile @@ -22,6 +22,10 @@ include $(TOPDIR)/Make.defs CSRCS = stm32_boot.c stm32_bringup.c +ifeq ($(CONFIG_ADC),y) +CSRCS += stm32_adc.c +endif + ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += stm32_autoleds.c else @@ -36,6 +40,18 @@ ifeq ($(CONFIG_BOARDCTL),y) CSRCS += stm32_appinitialize.c endif +ifeq ($(CONFIG_DEV_GPIO),y) +CSRCS += stm32_gpio.c +endif + +ifeq ($(CONFIG_PWM),y) +CSRCS += stm32_pwm.c +endif + +ifeq ($(CONFIG_SENSORS_QENCODER),y) +CSRCS += stm32_qencoder.c +endif + ifeq ($(CONFIG_BOARDCTL_RESET),y) CSRCS += stm32_reset.c endif diff --git a/boards/arm/stm32h7/nucleo-h743zi2/src/nucleo-h743zi2.h b/boards/arm/stm32h7/nucleo-h743zi2/src/nucleo-h743zi2.h index a93dbb745b..4e399f1f8a 100644 --- a/boards/arm/stm32h7/nucleo-h743zi2/src/nucleo-h743zi2.h +++ b/boards/arm/stm32h7/nucleo-h743zi2/src/nucleo-h743zi2.h @@ -101,6 +101,39 @@ GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN7) #endif +/* GPIO pins used by the GPIO Subsystem */ + +#define BOARD_NGPIOIN 4 /* Amount of GPIO Input pins */ +#define BOARD_NGPIOOUT 8 /* Amount of GPIO Output pins */ +#define BOARD_NGPIOINT 1 /* Amount of GPIO Input w/ Interruption pins */ + +/* Example, used free Ports on the board */ + +#define GPIO_IN1 (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTE | GPIO_PIN7) +#define GPIO_IN2 (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTE | GPIO_PIN12) +#define GPIO_IN3 (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTE | GPIO_PIN14) +#define GPIO_IN4 (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTE | GPIO_PIN15) + +#define GPIO_OUT1 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTE | GPIO_PIN4) +#define GPIO_OUT2 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTE | GPIO_PIN5) +#define GPIO_OUT3 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTE | GPIO_PIN6) +#define GPIO_OUT4 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTA| GPIO_PIN5) +#define GPIO_OUT5 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTF | GPIO_PIN3) +#define GPIO_INT1 (GPIO_INPUT | GPIO_FLOAT | GPIO_PORTE | GPIO_PIN3) + +/* PWM */ + +#if defined(CONFIG_STM32H7_TIM1_PWM) +# define NUCLEOH743ZI2_PWMTIMER 1 +#else +# define NUCLEOH743ZI2_PWMTIMER 3 +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -134,6 +167,30 @@ int stm32_bringup(void); void weak_function stm32_usbinitialize(void); #endif +/**************************************************************************** + * Name: stm32_adc_setup + * + * Description: + * Initialize ADC and register the ADC driver. + * + ****************************************************************************/ + +#ifdef CONFIG_ADC +int stm32_adc_setup(void); +#endif + +/**************************************************************************** + * Name: stm32_gpio_initialize + * + * Description: + * Initialize GPIO-Driver. + * + ****************************************************************************/ + +#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF) +int stm32_gpio_initialize(void); +#endif + /**************************************************************************** * Name: stm32_usbhost_initialize * @@ -148,4 +205,20 @@ void weak_function stm32_usbinitialize(void); int stm32_usbhost_initialize(void); #endif +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +#ifdef CONFIG_PWM +int stm32_pwm_setup(void); +#endif + +#ifdef CONFIG_SENSORS_QENCODER +int stm32_qencoder_initialize(const char *devpath, int timer); +#endif + #endif /* __BOARDS_ARM_STM32H7_NUCLEO_H743ZI2_SRC_NUCLEO_H743ZI2_H */ diff --git a/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_adc.c b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_adc.c new file mode 100644 index 0000000000..df3a2452d0 --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_adc.c @@ -0,0 +1,219 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h743zi2/src/stm32_adc.c + * + * 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 +#include +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_adc.h" +#include "nucleo-h743zi2.h" + +#ifdef CONFIG_ADC + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Up to 3 ADC interfaces are supported */ + +#if defined(CONFIG_STM32H7_ADC1) || defined(CONFIG_STM32H7_ADC2) || \ + defined(CONFIG_STM32H7_ADC3) +#ifndef CONFIG_STM32H7_ADC1 +# warning "Channel information only available for ADC1" +#endif + +/* The number of ADC channels in the conversion list */ + +#define ADC1_NCHANNELS 5 +#define ADC3_NCHANNELS 1 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_STM32H7_ADC1 +/* Identifying number of each ADC channel: Variable Resistor. + * + * ADC1: {5, 10, 12, 13, 15}; + */ + +static const uint8_t g_adc1_chanlist[ADC1_NCHANNELS] = +{ + 5, 10, 12, 13, 15 +}; + +/* Configurations of pins used by each ADC channels + * + * ADC1: + * {GPIO_ADC12_INP5, GPIO_ADC123_INP10, GPIO_ADC123_INP12, GPIO_ADC12_INP13, + * GPIO_ADC12_INP15}; + */ + +static const uint32_t g_adc1_pinlist[ADC1_NCHANNELS] = +{ + GPIO_ADC12_INP5, + GPIO_ADC123_INP10, + GPIO_ADC123_INP12, + GPIO_ADC12_INP13, + GPIO_ADC12_INP15 +}; +#endif + +#ifdef CONFIG_STM32H7_ADC3 +/* Identifying number of each ADC channel: Variable Resistor. + * + * ADC3: {6,}; + */ + +static const uint8_t g_adc3_chanlist[ADC1_NCHANNELS] = +{ + 6 +}; + +/* Configurations of pins used by each ADC channels + * + * + * ADC3: {GPIO_ADC3_INP6} + */ + +static const uint32_t g_adc3_pinlist[ADC3_NCHANNELS] = +{ + GPIO_ADC3_INP6 +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_adc_setup + * + * Description: + * Initialize ADC and register the ADC driver. + * + ****************************************************************************/ + +int stm32_adc_setup(void) +{ +#if defined(CONFIG_STM32H7_ADC1) || defined(CONFIG_STM32H7_ADC3) + static bool initialized = false; + struct adc_dev_s *adc; + int ret; + int i; + char devname[] = "/dev/adc0"; + + /* Check if we have already initialized */ + + if (!initialized) + { +#endif +#if defined(CONFIG_STM32H7_ADC1) + /* Configure the pins as analog inputs for the selected channels */ + + for (i = 0; i < ADC1_NCHANNELS; i++) + { + if (g_adc1_pinlist[i] != 0) + { + stm32_configgpio(g_adc1_pinlist[i]); + } + } + + /* Call stm32_adcinitialize() to get an instance of the ADC interface */ + + adc = stm32h7_adc_initialize(1, g_adc1_chanlist, ADC1_NCHANNELS); + if (adc == NULL) + { + aerr("ERROR: Failed to get ADC1 interface\n"); + return -ENODEV; + } + + /* Register the ADC driver at "/dev/adc0" */ + + ret = adc_register(devname, adc); + if (ret < 0) + { + aerr("ERROR: adc_register(%s) failed: %d\n", devname, ret); + return ret; + } + + devname[8]++; +#endif +#if defined(CONFIG_STM32H7_ADC3) + /* Configure the pins as analog inputs for the selected channels */ + + for (i = 0; i < ADC3_NCHANNELS; i++) + { + if (g_adc3_pinlist[i] != 0) + { + stm32_configgpio(g_adc3_pinlist[i]); + } + } + + /* Call stm32_adcinitialize() to get an instance of the ADC interface */ + + adc = stm32h7_adc_initialize(3, g_adc3_chanlist, ADC3_NCHANNELS); + if (adc == NULL) + { + aerr("ERROR: Failed to get ADC3 interface\n"); + return -ENODEV; + } + + /* Register the ADC driver at "/dev/adc0 or 1" */ + + ret = adc_register(devname, adc); + if (ret < 0) + { + aerr("ERROR: adc_register(%s) failed: %d\n", devname, ret); + return ret; + } +#endif + +#if defined(CONFIG_STM32H7_ADC1) || defined(CONFIG_STM32H7_ADC3) + /* Now we are initialized */ + + initialized = true; + } + + return OK; +#else + return -ENOSYS; +#endif +} + +#endif /* CONFIG_STM32H7_ADC1 || CONFIG_STM32H7_ADC2 || CONFIG_STM32H7_ADC3 */ +#endif /* CONFIG_ADC */ diff --git a/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_bringup.c b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_bringup.c index 0821f6d189..4834598c52 100644 --- a/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_bringup.c +++ b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_bringup.c @@ -178,6 +178,27 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_ADC + /* Initialize ADC and register the ADC driver. */ + + ret = stm32_adc_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_adc_setup failed: %d\n", ret); + } +#endif /* CONFIG_ADC */ + +#ifdef CONFIG_DEV_GPIO + /* Register the GPIO driver */ + + ret = stm32_gpio_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret); + return ret; + } +#endif + #ifdef CONFIG_NETDEV_LATEINIT # ifdef CONFIG_STM32H7_FDCAN1 @@ -188,6 +209,51 @@ int stm32_bringup(void) stm32_fdcansockinitialize(1); # endif +#endif + +#ifdef CONFIG_SENSORS_QENCODER +#ifdef CONFIG_STM32H7_TIM1_QE + ret = stm32_qencoder_initialize("/dev/qe0", 1); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to register the qencoder: %d\n", + ret); + return ret; + } +#endif + +#ifdef CONFIG_STM32H7_TIM3_QE + ret = stm32_qencoder_initialize("/dev/qe2", 3); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to register the qencoder: %d\n", + ret); + return ret; + } +#endif + +#ifdef CONFIG_STM32H7_TIM4_QE + ret = stm32_qencoder_initialize("/dev/qe3", 4); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to register the qencoder: %d\n", + ret); + return ret; + } +#endif +#endif + +#ifdef CONFIG_PWM + /* Initialize PWM and register the PWM device. */ + + ret = stm32_pwm_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_pwm_setup() failed: %d\n", ret); + } #endif return OK; diff --git a/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_gpio.c b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_gpio.c new file mode 100644 index 0000000000..8b2d4dbd81 --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_gpio.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h743zi2/src/stm32_gpio.c + * + * 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 + +#include +#include +#include + +#include + +#include "chip.h" +#include "stm32_gpio.h" +#include "nucleo-h743zi2.h" + +#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32gpio_dev_s +{ + struct gpio_dev_s gpio; + uint8_t id; +}; + +struct stm32gpint_dev_s +{ + struct stm32gpio_dev_s stm32gpio; + pin_interrupt_t callback; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int gpin_read(struct gpio_dev_s *dev, bool *value); +static int gpout_read(struct gpio_dev_s *dev, bool *value); +static int gpout_write(struct gpio_dev_s *dev, bool value); +static int gpint_read(struct gpio_dev_s *dev, bool *value); +static int gpint_attach(struct gpio_dev_s *dev, + pin_interrupt_t callback); +static int gpint_enable(struct gpio_dev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct gpio_operations_s gpin_ops = +{ + .go_read = gpin_read, + .go_write = NULL, + .go_attach = NULL, + .go_enable = NULL, +}; + +static const struct gpio_operations_s gpout_ops = +{ + .go_read = gpout_read, + .go_write = gpout_write, + .go_attach = NULL, + .go_enable = NULL, +}; + +static const struct gpio_operations_s gpint_ops = +{ + .go_read = gpint_read, + .go_write = NULL, + .go_attach = gpint_attach, + .go_enable = gpint_enable, +}; + +#if BOARD_NGPIOIN > 0 +/* This array maps the GPIO pins used as INPUT */ + +static const uint32_t g_gpioinputs[BOARD_NGPIOIN] = +{ + GPIO_IN1, + GPIO_IN2, + GPIO_IN3, + GPIO_IN4, +}; + +static struct stm32gpio_dev_s g_gpin[BOARD_NGPIOIN]; +#endif + +#if BOARD_NGPIOOUT +/* This array maps the GPIO pins used as OUTPUT */ + +static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = +{ + GPIO_LD1, + GPIO_LD2, + GPIO_LD3, + GPIO_OUT1, + GPIO_OUT2, + GPIO_OUT3, + GPIO_OUT4, + GPIO_OUT5, +}; + +static struct stm32gpio_dev_s g_gpout[BOARD_NGPIOOUT]; +#endif + +#if BOARD_NGPIOINT > 0 +/* This array maps the GPIO pins used as INTERRUPT INPUTS */ + +static const uint32_t g_gpiointinputs[BOARD_NGPIOINT] = +{ + GPIO_INT1, +}; + +static struct stm32gpint_dev_s g_gpint[BOARD_NGPIOINT]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int stm32gpio_interrupt(int irq, void *context, void *arg) +{ + struct stm32gpint_dev_s *stm32gpint = + (struct stm32gpint_dev_s *)arg; + + DEBUGASSERT(stm32gpint != NULL && stm32gpint->callback != NULL); + gpioinfo("Interrupt! callback=%p\n", stm32gpint->callback); + + stm32gpint->callback(&stm32gpint->stm32gpio.gpio, + stm32gpint->stm32gpio.id); + return OK; +} + +static int gpin_read(struct gpio_dev_s *dev, bool *value) +{ + struct stm32gpio_dev_s *stm32gpio = + (struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL && value != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOIN); + gpioinfo("Reading...\n"); + + *value = stm32_gpioread(g_gpioinputs[stm32gpio->id]); + return OK; +} + +static int gpout_read(struct gpio_dev_s *dev, bool *value) +{ + struct stm32gpio_dev_s *stm32gpio = + (struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL && value != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOOUT); + gpioinfo("Reading...\n"); + + *value = stm32_gpioread(g_gpiooutputs[stm32gpio->id]); + return OK; +} + +static int gpout_write(struct gpio_dev_s *dev, bool value) +{ + struct stm32gpio_dev_s *stm32gpio = + (struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOOUT); + gpioinfo("Writing %d\n", (int)value); + + stm32_gpiowrite(g_gpiooutputs[stm32gpio->id], value); + return OK; +} + +static int gpint_read(struct gpio_dev_s *dev, bool *value) +{ + struct stm32gpint_dev_s *stm32gpint = + (struct stm32gpint_dev_s *)dev; + + DEBUGASSERT(stm32gpint != NULL && value != NULL); + DEBUGASSERT(stm32gpint->stm32gpio.id < BOARD_NGPIOINT); + gpioinfo("Reading int pin...\n"); + + *value = stm32_gpioread(g_gpiointinputs[stm32gpint->stm32gpio.id]); + return OK; +} + +static int gpint_attach(struct gpio_dev_s *dev, + pin_interrupt_t callback) +{ + struct stm32gpint_dev_s *stm32gpint = + (struct stm32gpint_dev_s *)dev; + + gpioinfo("Attaching the callback\n"); + + /* Make sure the interrupt is disabled */ + + stm32_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], false, + false, false, NULL, NULL); + + gpioinfo("Attach %p\n", callback); + stm32gpint->callback = callback; + return OK; +} + +static int gpint_enable(struct gpio_dev_s *dev, bool enable) +{ + struct stm32gpint_dev_s *stm32gpint = + (struct stm32gpint_dev_s *)dev; + + if (enable) + { + if (stm32gpint->callback != NULL) + { + gpioinfo("Enabling the interrupt\n"); + + /* Configure the interrupt for rising edge */ + + stm32_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], + true, false, false, stm32gpio_interrupt, + &g_gpint[stm32gpint->stm32gpio.id]); + } + } + else + { + gpioinfo("Disable the interrupt\n"); + stm32_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], + false, false, false, NULL, NULL); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_gpio_initialize + * + * Description: + * Initialize GPIO drivers for use with /apps/examples/gpio + * + ****************************************************************************/ + +int stm32_gpio_initialize(void) +{ + int i; + int pincount = 0; + +#if BOARD_NGPIOIN > 0 + for (i = 0; i < BOARD_NGPIOIN; i++) + { + /* Setup and register the GPIO pin */ + + g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN; + g_gpin[i].gpio.gp_ops = &gpin_ops; + g_gpin[i].id = i; + gpio_pin_register(&g_gpin[i].gpio, pincount); + + /* Configure the pin that will be used as input */ + + stm32_configgpio(g_gpioinputs[i]); + + pincount++; + } +#endif + +#if BOARD_NGPIOOUT > 0 + for (i = 0; i < BOARD_NGPIOOUT; i++) + { + /* Setup and register the GPIO pin */ + + g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN; + g_gpout[i].gpio.gp_ops = &gpout_ops; + g_gpout[i].id = i; + gpio_pin_register(&g_gpout[i].gpio, pincount); + + /* Configure the pin that will be used as output */ + + stm32_gpiowrite(g_gpiooutputs[i], 0); + stm32_configgpio(g_gpiooutputs[i]); + + pincount++; + } +#endif + +#if BOARD_NGPIOINT > 0 + for (i = 0; i < BOARD_NGPIOINT; i++) + { + /* Setup and register the GPIO pin */ + + g_gpint[i].stm32gpio.gpio.gp_pintype = GPIO_INTERRUPT_PIN; + g_gpint[i].stm32gpio.gpio.gp_ops = &gpint_ops; + g_gpint[i].stm32gpio.id = i; + gpio_pin_register(&g_gpint[i].stm32gpio.gpio, pincount); + + /* Configure the pin that will be used as interrupt input */ + + stm32_configgpio(g_gpiointinputs[i]); + + pincount++; + } +#endif + + return 0; +} +#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */ diff --git a/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_pwm.c b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_pwm.c new file mode 100644 index 0000000000..44aeaa543b --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_pwm.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h743zi2/src/stm32_pwm.c + * + * 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 + +#include +#include + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_pwm.h" +#include "nucleo-h743zi2.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OK 0 + +/* Configuration ************************************************************/ + +#define HAVE_PWM 1 + +#ifndef CONFIG_PWM +# undef HAVE_PWM +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +int stm32_pwm_setup(void) +{ +#ifdef HAVE_PWM + static bool initialized = false; + struct pwm_lowerhalf_s *pwm; + int ret; + + /* Have we already initialized? */ + + if (!initialized) + { + /* Get an instance of the PWM interface */ + + pwm = stm32_pwminitialize(NUCLEOH743ZI2_PWMTIMER); + if (!pwm) + { + tmrerr("ERROR: Failed to get the STM32 PWM lower half\n"); + return -ENODEV; + } + + /* Register the PWM driver at "/dev/pwm0" */ + + #if defined(CONFIG_STM32H7_TIM1_PWM) + ret = pwm_register("/dev/pwm0", pwm); + if (ret < 0) + { + tmrerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } +#endif + +#if defined(CONFIG_STM32H7_TIM3_PWM) + ret = pwm_register("/dev/pwm2", pwm); + if (ret < 0) + { + tmrerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } +#endif + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +#else + return -ENODEV; +#endif +} diff --git a/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_qencoder.c b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_qencoder.c new file mode 100644 index 0000000000..5c8182ae70 --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h743zi2/src/stm32_qencoder.c @@ -0,0 +1,65 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h743zi2/src/stm32_qencoder.c + * + * 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 +#include + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_qencoder.h" +#include "nucleo-h743zi2.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: qe_devinit + * + * Description: + * All STM32H7 architectures must provide the following interface to work + * with examples/qencoder. + * + ****************************************************************************/ + +int stm32_qencoder_initialize(const char *devpath, int timer) +{ + int ret = 0; + + /* Initialize a quadrature encoder interface. */ + + sninfo("Initializing the quadrature encoder using TIM%d\n", timer); + ret = stm32_qeinitialize(devpath, timer); + if (ret < 0) + { + snerr("ERROR: stm32_qeinitialize failed: %d\n", ret); + } + + return ret; +}