From 4a04c221474470bc7a408870702e078e138d4862 Mon Sep 17 00:00:00 2001 From: Roberto Bucher Date: Sat, 10 Feb 2024 13:24:55 +0100 Subject: [PATCH] STM32-H745 files for pysimCoder --- arch/arm/src/stm32h7/stm32_adc.c | 2 +- .../nucleo-h745zi/configs/pysim_cm7/defconfig | 134 +++++++ .../arm/stm32h7/nucleo-h745zi/include/board.h | 43 +++ boards/arm/stm32h7/nucleo-h745zi/src/Makefile | 24 ++ .../stm32h7/nucleo-h745zi/src/nucleo-h745zi.h | 89 ++++- .../arm/stm32h7/nucleo-h745zi/src/stm32_adc.c | 222 ++++++++++++ .../stm32h7/nucleo-h745zi/src/stm32_bringup.c | 115 ++++++ .../stm32h7/nucleo-h745zi/src/stm32_gpio.c | 331 ++++++++++++++++++ .../arm/stm32h7/nucleo-h745zi/src/stm32_pwm.c | 112 ++++++ .../nucleo-h745zi/src/stm32_qencoder.c | 65 ++++ .../arm/stm32h7/nucleo-h745zi/src/stm32_usb.c | 320 +++++++++++++++++ 11 files changed, 1453 insertions(+), 4 deletions(-) create mode 100644 boards/arm/stm32h7/nucleo-h745zi/configs/pysim_cm7/defconfig create mode 100644 boards/arm/stm32h7/nucleo-h745zi/src/stm32_adc.c create mode 100644 boards/arm/stm32h7/nucleo-h745zi/src/stm32_gpio.c create mode 100644 boards/arm/stm32h7/nucleo-h745zi/src/stm32_pwm.c create mode 100644 boards/arm/stm32h7/nucleo-h745zi/src/stm32_qencoder.c create mode 100644 boards/arm/stm32h7/nucleo-h745zi/src/stm32_usb.c diff --git a/arch/arm/src/stm32h7/stm32_adc.c b/arch/arm/src/stm32h7/stm32_adc.c index 10ad1b9c1d..ce1104f1c4 100644 --- a/arch/arm/src/stm32h7/stm32_adc.c +++ b/arch/arm/src/stm32h7/stm32_adc.c @@ -1584,7 +1584,7 @@ static void adc_setupclock(struct stm32_dev_s *priv) uint32_t max_clock = 36000000; uint32_t src_clock; uint32_t adc_clock; - uint32_t setbits; + uint32_t setbits = 0; /* The maximum clock is different for rev Y devices and rev V devices. * rev V can support an ADC clock of up to 50MHz. rev Y only supports diff --git a/boards/arm/stm32h7/nucleo-h745zi/configs/pysim_cm7/defconfig b/boards/arm/stm32h7/nucleo-h745zi/configs/pysim_cm7/defconfig new file mode 100644 index 0000000000..46c4ecce81 --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h745zi/configs/pysim_cm7/defconfig @@ -0,0 +1,134 @@ +# +# 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_STM32H7_USE_LEGACY_PINMAP is not set +CONFIG_ADC=y +CONFIG_ANALOG=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="nucleo-h745zi" +CONFIG_ARCH_BOARD_NUCLEO_H745ZI=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H745ZI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=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_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_POSIX_SPAWN_DEFAULT_STACKSIZE=2048 +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_CLEANUP_STACKSIZE=1 +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_HSI48=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_SYSTEM_TELNETD_SESSION_STACKSIZE=2048 +CONFIG_SYSTEM_TELNETD_STACKSIZE=2048 +CONFIG_TASK_NAME_SIZE=0 +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-h745zi/include/board.h b/boards/arm/stm32h7/nucleo-h745zi/include/board.h index 5c75966617..a6228b86d7 100644 --- a/boards/arm/stm32h7/nucleo-h745zi/include/board.h +++ b/boards/arm/stm32h7/nucleo-h745zi/include/board.h @@ -281,6 +281,12 @@ /* Ethernet definitions *****************************************************/ +#define GPIO_ETH_MDC (GPIO_ETH_MDC_0|GPIO_SPEED_100MHz) +#define GPIO_ETH_MDIO (GPIO_ETH_MDIO_0|GPIO_SPEED_100MHz) +#define GPIO_ETH_RMII_CRS_DV (GPIO_ETH_RMII_CRS_DV_0|GPIO_SPEED_100MHz) +#define GPIO_ETH_RMII_REF_CLK (GPIO_ETH_RMII_REF_CLK_0|GPIO_SPEED_100MHz) +#define GPIO_ETH_RMII_RXD0 (GPIO_ETH_RMII_RXD0_0|GPIO_SPEED_100MHz) +#define GPIO_ETH_RMII_RXD1 (GPIO_ETH_RMII_RXD1_0|GPIO_SPEED_100MHz) #define GPIO_ETH_RMII_TXD0 GPIO_ETH_RMII_TXD0_2 /* PG13 */ #define GPIO_ETH_RMII_TXD1 GPIO_ETH_RMII_TXD1_1 /* PB 13 */ #define GPIO_ETH_RMII_TX_EN GPIO_ETH_RMII_TX_EN_2 @@ -352,6 +358,14 @@ /* Alternate function pin selections ****************************************/ +/* ADC */ + +#define GPIO_ADC12_INP5 GPIO_ADC12_INP5_0 /* PB1 */ +#define GPIO_ADC123_INP10 GPIO_ADC123_INP10_0 /* PC0 */ +#define GPIO_ADC123_INP12 GPIO_ADC123_INP12_0 /* PC2 */ +#define GPIO_ADC12_INP13 GPIO_ADC12_INP13_0 /* PC3 */ +#define GPIO_ADC12_INP15 GPIO_ADC12_INP15_0 /* PA3 */ + /* USART1 (Arduino Serial Shield) */ #define GPIO_USART1_RX (GPIO_USART1_RX_3) /* PB7 */ @@ -365,6 +379,35 @@ #define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_0 #define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_1 +/* TIM1 */ + +#define GPIO_TIM1_CH1OUT (GPIO_TIM1_CH1OUT_2|GPIO_SPEED_50MHz) /* PE9 - D6 */ +#define GPIO_TIM1_CH1NOUT (GPIO_TIM1_CH1NOUT_3|GPIO_SPEED_50MHz) /* PE8 - D42 */ +#define GPIO_TIM1_CH2OUT (GPIO_TIM1_CH2OUT_2|GPIO_SPEED_50MHz) /* PE11 - D5 */ +#define GPIO_TIM1_CH2NOUT (GPIO_TIM1_CH2NOUT_3|GPIO_SPEED_50MHz) /* PE10 - D40 */ + +#define GPIO_TIM1_CH1IN (GPIO_TIM1_CH1IN_2|GPIO_SPEED_50MHz) /* PE9 */ +#define GPIO_TIM1_CH2IN (GPIO_TIM1_CH2IN_2|GPIO_SPEED_50MHz) /* PE11 */ + +/* TIM3 */ + +#define GPIO_TIM3_CH1OUT (GPIO_TIM3_CH1OUT_2|GPIO_SPEED_50MHz) /* PB4 */ +#define GPIO_TIM3_CH2OUT (GPIO_TIM3_CH2OUT_2|GPIO_SPEED_50MHz) /* PB5 */ + +#define GPIO_TIM3_CH1IN (GPIO_TIM3_CH1IN_2|GPIO_SPEED_50MHz) /* PA4 */ +#define GPIO_TIM3_CH2IN (GPIO_TIM3_CH2IN_2|GPIO_SPEED_50MHz) /* PB5 */ + +/* TIM4 */ + +#define GPIO_TIM4_CH1IN (GPIO_TIM4_CH1IN_2|GPIO_SPEED_50MHz) /* PD12 */ +#define GPIO_TIM4_CH2IN (GPIO_TIM4_CH2IN_2|GPIO_SPEED_50MHz) /* PD13 */ + +/* OTG */ + +#define GPIO_OTGFS_DM (GPIO_OTGFS_DM_0|GPIO_SPEED_100MHz) /* PA11 */ +#define GPIO_OTGFS_DP (GPIO_OTGFS_DP_0|GPIO_SPEED_100MHz) /* PA12 */ +#define GPIO_OTGFS_ID (GPIO_OTGFS_ID_0|GPIO_SPEED_100MHz) /* PA10 */ + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/boards/arm/stm32h7/nucleo-h745zi/src/Makefile b/boards/arm/stm32h7/nucleo-h745zi/src/Makefile index d7694432ab..561bc5d1b3 100644 --- a/boards/arm/stm32h7/nucleo-h745zi/src/Makefile +++ b/boards/arm/stm32h7/nucleo-h745zi/src/Makefile @@ -22,14 +22,38 @@ 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 CSRCS += stm32_userleds.c endif +ifeq ($(CONFIG_STM32H7_OTGFS),y) +CSRCS += stm32_usb.c +endif + 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 + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/stm32h7/nucleo-h745zi/src/nucleo-h745zi.h b/boards/arm/stm32h7/nucleo-h745zi/src/nucleo-h745zi.h index 618a8f649b..6fb4d72bad 100644 --- a/boards/arm/stm32h7/nucleo-h745zi/src/nucleo-h745zi.h +++ b/boards/arm/stm32h7/nucleo-h745zi/src/nucleo-h745zi.h @@ -167,15 +167,28 @@ /* GPIO pins used by the GPIO Subsystem */ -#define BOARD_NGPIOIN 1 /* Amount of GPIO Input pins */ -#define BOARD_NGPIOOUT 1 /* Amount of GPIO Output pins */ +#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_PIN2) +#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_PIN5) /* X-NUCLEO IKS01A2 */ @@ -211,7 +224,11 @@ /* PWM */ +#if defined(CONFIG_STM32H7_TIM1_PWM) #define NUCLEOH745ZI_PWMTIMER 1 +#else +#define NUCLEOH745ZI_PWMTIMER 3 +#endif /**************************************************************************** * Public Function Prototypes @@ -234,4 +251,70 @@ int stm32_bringup(void); +#ifdef CONFIG_STM32H7_OTGFS +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(int adcno); +#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 + * + * Description: + * Called at application startup time to initialize the USB host + * functionality. This function will start a thread that will monitor for + * device connection/disconnection events. + * + ****************************************************************************/ + +#if defined(CONFIG_STM32H7_OTGFS) && defined(CONFIG_USBHOST) +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 + +/**************************************************************************** + * Name: stm32_qencoder_initialize + * + * Description: + * Initialize and register a qencoder + * + ****************************************************************************/ + +#ifdef CONFIG_SENSORS_QENCODER +int stm32_qencoder_initialize(const char *devpath, int timer); +#endif + #endif /* __BOARDS_ARM_STM32H7_NUCLEO_H745ZI_SRC_NUCLEO_H745ZI_H */ diff --git a/boards/arm/stm32h7/nucleo-h745zi/src/stm32_adc.c b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_adc.c new file mode 100644 index 0000000000..e5c80f4073 --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_adc.c @@ -0,0 +1,222 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h745zi/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 + +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_adc.h" +#include "nucleo-h745zi.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(int adcno) +{ +#if defined(CONFIG_STM32H7_ADC1) || defined(CONFIG_STM32H7_ADC3) + static bool initialized = false; + struct adc_dev_s *adc; + int ret; + int i; + char devname[10]; + + /* Check if we have already initialized */ + + if (!initialized) + { + snprintf(devname, 1, "/dev/adc%d", adcno); + +#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-h745zi/src/stm32_bringup.c b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_bringup.c index e5a4cfed25..65b816f5d7 100644 --- a/boards/arm/stm32h7/nucleo-h745zi/src/stm32_bringup.c +++ b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_bringup.c @@ -110,5 +110,120 @@ int stm32_bringup(void) # endif #endif + #ifdef HAVE_USBHOST + /* Initialize USB host operation. stm32_usbhost_initialize() + * starts a thread will monitor for USB connection and + * disconnection events. + */ + + ret = stm32_usbhost_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, + "ERROR: Failed to initialize USB host: %d\n", + ret); + } +#endif + +#ifdef HAVE_USBMONITOR + /* Start the USB Monitor */ + + ret = usbmonitor_start(); + if (ret != OK) + { + syslog(LOG_ERR, + "ERROR: Failed to start USB monitor: %d\n", + ret); + } +#endif + +#ifdef CONFIG_ADC + /* Initialize ADC and register the ADC driver. */ + + int adcno = 0; + +#ifdef CONFIG_STM32H7_ADC1 + adcno = 0; +#endif + +#ifdef CONFIG_STM32H7_ADC3 + adcno = 2; +#endif + + ret = stm32_adc_setup(adcno); + 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 + stm32_fdcansockinitialize(0); +# endif + +# ifdef CONFIG_STM32H7_FDCAN2 + 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-h745zi/src/stm32_gpio.c b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_gpio.c new file mode 100644 index 0000000000..2de003357c --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_gpio.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h745zi/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-h745zi.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-h745zi/src/stm32_pwm.c b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_pwm.c new file mode 100644 index 0000000000..b4228394d3 --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_pwm.c @@ -0,0 +1,112 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h745zi/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-h745zi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* 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(NUCLEOH745ZI_PWMTIMER); + if (pwm == NULL) + { + 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-h745zi/src/stm32_qencoder.c b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_qencoder.c new file mode 100644 index 0000000000..a9c146a47c --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_qencoder.c @@ -0,0 +1,65 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h745zi/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-h745zi.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; + + /* 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; +} diff --git a/boards/arm/stm32h7/nucleo-h745zi/src/stm32_usb.c b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_usb.c new file mode 100644 index 0000000000..d209e4a09f --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h745zi/src/stm32_usb.c @@ -0,0 +1,320 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h745zi/src/stm32_usb.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 +#include +#include +#include + +#include "arm_internal.h" +#include "chip.h" +#include "stm32_gpio.h" +#include "stm32_otg.h" +#include "nucleo-h745zi.h" + +#ifdef CONFIG_STM32H7_OTGFS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_USBDEV) || defined(CONFIG_USBHOST) +# define HAVE_USB 1 +#else +# warning "CONFIG_STM32_OTGFS is enabled but neither CONFIG_USBDEV nor CONFIG_USBHOST" +# undef HAVE_USB +#endif + +#ifndef CONFIG_USBHOST_DEFPRIO +# define CONFIG_USBHOST_DEFPRIO 100 +#endif + +#ifndef CONFIG_USBHOST_STACKSIZE +# define CONFIG_USBHOST_STACKSIZE 2048 +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +static struct usbhost_connection_s *g_usbconn; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usbhost_waiter + * + * Description: + * Wait for USB devices to be connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +static int usbhost_waiter(int argc, char *argv[]) +{ + struct usbhost_hubport_s *hport; + + uinfo("Running\n"); + for (; ; ) + { + /* Wait for the device to change state */ + + DEBUGVERIFY(CONN_WAIT(g_usbconn, &hport)); + uinfo("%s\n", hport->connected ? "connected" : "disconnected"); + + /* Did we just become connected? */ + + if (hport->connected) + { + /* Yes.. enumerate the newly connected device */ + + CONN_ENUMERATE(g_usbconn, hport); + } + } + + /* Keep the compiler from complaining */ + + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_usbinitialize + * + * Description: + * Called from stm32_usbinitialize very early in inialization to setup + * USB-related GPIO pins for the nucleo-144 board. + * + ****************************************************************************/ + +void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up. + * No GPIO configuration is required + */ + + /* Configure the OTG FS VBUS sensing GPIO, + * Power On, and Overcurrent GPIOs + */ + +#ifdef CONFIG_STM32H7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); + stm32_configgpio(GPIO_OTGFS_PWRON); + stm32_configgpio(GPIO_OTGFS_OVER); +#endif +} + +/**************************************************************************** + * Name: stm32_usbhost_initialize + * + * Description: + * Called at application startup time to initialize the USB host + * functionality. + * This function will start a thread that will monitor for device + * connection/disconnection events. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +int stm32_usbhost_initialize(void) +{ + int ret; + + /* First, register all of the class drivers needed to support the drivers + * that we care about: + */ + + uinfo("Register class drivers\n"); + +#ifdef CONFIG_USBHOST_HUB + /* Initialize USB hub class support */ + + ret = usbhost_hub_initialize(); + if (ret < 0) + { + uerr("ERROR: usbhost_hub_initialize failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_MSC + /* Register the USB mass storage class class */ + + ret = usbhost_msc_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the mass storage class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_CDCACM + /* Register the CDC/ACM serial class */ + + ret = usbhost_cdcacm_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the CDC/ACM serial class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_HIDKBD + /* Initialize the HID keyboard class */ + + ret = usbhost_kbdinit(); + if (ret != OK) + { + uerr("ERROR: Failed to register the HID keyboard class\n"); + } +#endif + +#ifdef CONFIG_USBHOST_HIDMOUSE + /* Initialize the HID mouse class */ + + ret = usbhost_mouse_init(); + if (ret != OK) + { + uerr("ERROR: Failed to register the HID mouse class\n"); + } +#endif + + /* Then get an instance of the USB host interface */ + + uinfo("Initialize USB host\n"); + g_usbconn = stm32_otgfshost_initialize(0); + if (g_usbconn) + { + /* Start a thread to handle device connection. */ + + uinfo("Start usbhost_waiter\n"); + + ret = kthread_create("usbhost", CONFIG_USBHOST_DEFPRIO, + CONFIG_USBHOST_STACKSIZE, + usbhost_waiter, NULL); + return ret < 0 ? -ENOEXEC : OK; + } + + return -ENODEV; +} +#endif + +/**************************************************************************** + * Name: stm32_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be + * provided be each platform that implements the STM32 OTG FS host + * interface + * + * "On-chip 5 V VBUS generation is not supported. For this reason, a + * charge pump or, if 5 V are available on the application board, a + * basic power switch, must be added externally to drive the 5 V VBUS + * line. The external charge pump can be driven by any GPIO output. + * When the application decides to power on VBUS using the chosen GPIO, + * it must also set the port power bit in the host port control and status + * register (PPWR bit in OTG_FS_HPRT). + * + * "The application uses this field to control power to this port, and + * the core clears this bit on an overcurrent condition." + * + * Input Parameters: + * iface - For future growth to handle multiple USB host interface. + * Should be zero. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +void stm32_usbhost_vbusdrive(int iface, bool enable) +{ + DEBUGASSERT(iface == 0); + + /* Set the Power Switch by driving the active low enable pin */ + + stm32_gpiowrite(GPIO_OTGFS_PWRON, !enable); +} +#endif + +/**************************************************************************** + * Name: stm32_setup_overcurrent + * + * Description: + * Setup to receive an interrupt-level callback if an overcurrent + * condition is detected. + * + * Input Parameters: + * handler - New overcurrent interrupt handler + * arg - The argument provided for the interrupt handler + * + * Returned Value: + * Zero (OK) is returned on success. Otherwise, a negated errno value + * is returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +int stm32_setup_overcurrent(xcpt_t handler, void *arg) +{ + return stm32_gpiosetevent(GPIO_OTGFS_OVER, true, true, true, handler, arg); +} +#endif + +/**************************************************************************** + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV + * driver is used. This function is called whenever the USB enters or + * leaves suspend mode. This is an opportunity for the board logic to + * shutdown clocks, power, etc. while the USB is suspended. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV +void stm32_usbsuspend(struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} +#endif + +#endif /* CONFIG_STM32_OTGFS */