From 0dafa5f92118a1e080287d4cf4241e37fc08afd1 Mon Sep 17 00:00:00 2001 From: okayserh Date: Fri, 2 Dec 2022 22:32:35 +0100 Subject: [PATCH] Added initial USB support for stm32f746g discovery. --- arch/arm/src/stm32f7/Kconfig | 15 + arch/arm/src/stm32f7/Make.defs | 8 + arch/arm/src/stm32f7/stm32_otgdev.c | 1 + arch/arm/src/stm32f7/stm32_otghost.c | 26 +- arch/arm/src/stm32f7/stm32_usbhost.c | 171 +++++++++ arch/arm/src/stm32f7/stm32_usbhost.h | 80 +++++ arch/arm/src/stm32h7/stm32_otghost.c | 4 +- .../arm/stm32f7/stm32f746g-disco/src/Makefile | 6 + .../stm32f7/stm32f746g-disco/src/stm32_boot.c | 7 + .../stm32f746g-disco/src/stm32_bringup.c | 13 + .../stm32f7/stm32f746g-disco/src/stm32_usb.c | 335 ++++++++++++++++++ .../stm32f746g-disco/src/stm32f746g-disco.h | 39 ++ 12 files changed, 688 insertions(+), 17 deletions(-) create mode 100644 arch/arm/src/stm32f7/stm32_usbhost.c create mode 100644 boards/arm/stm32f7/stm32f746g-disco/src/stm32_usb.c diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index 2a2d7e90cc..74b732b701 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1469,6 +1469,21 @@ config STM32F7_QUADSPI bool "QuadSPI" default n +config STM32F7_USBDEV_REGDEBUG + bool "OTG USBDEV REGDEBUG" + default n + depends on USBDEV + +config STM32F7_USBHOST_REGDEBUG + bool "OTG USBHOST REGDEBUG" + default n + depends on USBHOST + +config STM32F7_USBHOST_PKTDUMP + bool "OTG USBHOST PKTDUMP" + default n + depends on USBHOST + config STM32F7_RTC bool "RTC" default n diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs index d102354001..11f893bef3 100644 --- a/arch/arm/src/stm32f7/Make.defs +++ b/arch/arm/src/stm32f7/Make.defs @@ -109,6 +109,14 @@ ifeq ($(CONFIG_USBHOST),y) CHIP_CSRCS += stm32_otghost.c endif +ifeq ($(CONFIG_USBHOST_TRACE),y) +CHIP_CSRCS += stm32_usbhost.c +else +ifeq ($(CONFIG_DEBUG_USB),y) +CHIP_CSRCS += stm32_usbhost.c +endif +endif + ifeq ($(CONFIG_STM32F7_TIM),y) CHIP_CSRCS += stm32_tim.c stm32_tim_lowerhalf.c endif diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c index 54ea27aa30..154e993162 100644 --- a/arch/arm/src/stm32f7/stm32_otgdev.c +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -46,6 +46,7 @@ #include "chip.h" #include "stm32_gpio.h" #include "stm32_otg.h" +#include "stm32_rcc.h" #include "arm_internal.h" #if defined(CONFIG_USBDEV) && (defined(CONFIG_STM32F7_OTGFS) || \ diff --git a/arch/arm/src/stm32f7/stm32_otghost.c b/arch/arm/src/stm32f7/stm32_otghost.c index 80cdd70c58..fe8195140d 100644 --- a/arch/arm/src/stm32f7/stm32_otghost.c +++ b/arch/arm/src/stm32f7/stm32_otghost.c @@ -52,6 +52,8 @@ #include /* May redefine GPIO settings */ #include "arm_internal.h" +#include "hardware/stm32_pwr.h" +#include "stm32_gpio.h" #include "stm32_otg.h" #include "stm32_usbhost.h" @@ -67,9 +69,9 @@ * * Pre-requisites * - * CONFIG_USBHOST - Enable general USB host support - * CONFIG_STM32F7_OTGFS - Enable the STM32 USB OTG FS block - * CONFIG_STM32F7_SYSCFG - Needed + * CONFIG_USBHOST - Enable general USB host support + * CONFIG_STM32F7_OTGFS - Enable the STM32 USB OTG FS block + * CONFIG_STM32F7_SYSCFG_IOCOMPENSATION - Needed * * Options: * @@ -90,8 +92,8 @@ /* Pre-requisites (partial) */ -#ifndef CONFIG_STM32F7_SYSCFG -# error "CONFIG_STM32F7_SYSCFG is required" +#ifndef CONFIG_STM32F7_SYSCFG_IOCOMPENSATION +# error "CONFIG_STM32F7_SYSCFG_IOCOMPENSATION is required" #endif /* Default RxFIFO size */ @@ -502,7 +504,7 @@ static struct usbhost_connection_s g_usbconn = #ifdef CONFIG_STM32F7_USBHOST_REGDEBUG static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite) { - llerr("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); + uinfo("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); } #endif @@ -552,7 +554,7 @@ static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) { /* No.. More than one. */ - llerr("[repeats %d more times]\n", count); + uinfo("[repeats %d more times]\n", count); } } @@ -5306,17 +5308,11 @@ static inline int stm32_hw_initialize(struct stm32_usbhost_s *priv) /* Deactivate the power down */ - regval = (OTG_GCCFG_PWRDWN | OTG_GCCFG_VBUSASEN | OTG_GCCFG_VBUSBSEN); -#ifndef CONFIG_USBDEV_VBUSSENSING - regval |= OTG_GCCFG_NOVBUSSENS; -#endif -#ifdef CONFIG_STM32F7_OTG_SOFOUTPUT - regval |= OTG_GCCFG_SOFOUTEN; -#endif + regval = (OTG_GCCFG_PWRDWN | OTG_GCCFG_VBDEN); stm32_putreg(STM32_OTG_GCCFG, regval); up_mdelay(20); - /* Initialize OTG features: In order to support OTP, the HNPCAP and SRPCAP + /* Initialize OTG features: In order to support OTG, the HNPCAP and SRPCAP * bits would need to be set in the GUSBCFG register about here. */ diff --git a/arch/arm/src/stm32f7/stm32_usbhost.c b/arch/arm/src/stm32f7/stm32_usbhost.c new file mode 100644 index 0000000000..fbc6ab76ee --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_usbhost.c @@ -0,0 +1,171 @@ +/******************************************************************************************************************** + * arch/arm/src/stm32f7/stm32_usbhost.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 "stm32_usbhost.h" + +#ifdef HAVE_USBHOST_TRACE + +/******************************************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************************************/ + +#define TR_FMT1 false +#define TR_FMT2 true + +#define TRENTRY(id,fmt1,string) {string} + +/******************************************************************************************************************** + * Private Types + ********************************************************************************************************************/ + +struct stm32_usbhost_trace_s +{ + const char *string; +}; + +/******************************************************************************************************************** + * Private Data + ********************************************************************************************************************/ + +static const struct stm32_usbhost_trace_s g_trace1[TRACE1_NSTRINGS] = +{ +#ifdef HAVE_USBHOST_TRACE + + TRENTRY(OTG_TRACE1_DEVDISCONN, TR_FMT1, "OTG ERROR: Host Port %d. Device disconnected\n"), + TRENTRY(OTG_TRACE1_IRQATTACH, TR_FMT1, "OTG ERROR: Failed to attach IRQ\n"), + TRENTRY(OTG_TRACE1_TRNSFRFAILED, TR_FMT1, "OTG ERROR: Transfer Failed. ret=%d\n"), + TRENTRY(OTG_TRACE1_SENDSETUP, TR_FMT1, "OTG ERROR: ctrl_sendsetup() failed with: %d\n"), + TRENTRY(OTG_TRACE1_SENDDATA, TR_FMT1, "OTG ERROR: ctrl_senddata() failed with: %d\n"), + TRENTRY(OTG_TRACE1_RECVDATA, TR_FMT1, "OTG ERROR: ctrl_recvdata() failed with: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(OTG_VTRACE1_CONNECTED, TR_FMT1, "OTG Host Port %d connected.\n"), + TRENTRY(OTG_VTRACE1_DISCONNECTED, TR_FMT1, "OTG Host Port %d disconnected.\n"), + TRENTRY(OTG_VTRACE1_GINT, TR_FMT1, "OTG Handling Interrupt. Entry Point.\n"), + TRENTRY(OTG_VTRACE1_GINT_SOF, TR_FMT1, "OTG Handle the start of frame interrupt.\n"), + TRENTRY(OTG_VTRACE1_GINT_RXFLVL, TR_FMT1, "OTG Handle the RxFIFO non-empty interrupt.\n"), + TRENTRY(OTG_VTRACE1_GINT_NPTXFE, TR_FMT1, "OTG Handle the non-periodic TxFIFO empty interrupt.\n"), + TRENTRY(OTG_VTRACE1_GINT_PTXFE, TR_FMT1, "OTG Handle the periodic TxFIFO empty interrupt.\n"), + TRENTRY(OTG_VTRACE1_GINT_HC, TR_FMT1, "OTG Handle the host channels interrupt.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT, TR_FMT1, "OTG Handle the host port interrupt.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT_POCCHNG, TR_FMT1, "OTG HPRT: Port Over-Current Change.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT_PCDET, TR_FMT1, "OTG HPRT: Port Connect Detect.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT_PENCHNG, TR_FMT1, "OTG HPRT: Port Enable Changed.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT_LSDEV, TR_FMT1, "OTG HPRT: Low Speed Device Connected.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT_FSDEV, TR_FMT1, "OTG HPRT: Full Speed Device Connected.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT_LSFSSW, TR_FMT1, "OTG HPRT: Host Switch: LS -> FS.\n"), + TRENTRY(OTG_VTRACE1_GINT_HPRT_FSLSSW, TR_FMT1, "OTG HPRT: Host Switch: FS -> LS.\n"), + TRENTRY(OTG_VTRACE1_GINT_DISC, TR_FMT1, "OTG Handle the disconnect detected interrupt.\n"), + TRENTRY(OTG_VTRACE1_GINT_IPXFR, TR_FMT1, "OTG Handle the incomplete periodic transfer.\n"), + +# endif +#endif +}; + +static const struct stm32_usbhost_trace_s g_trace2[TRACE2_NSTRINGS] = +{ +#ifdef HAVE_USBHOST_TRACE + + TRENTRY(OTG_TRACE2_CLIP, TR_FMT2, "OTG CLIP: chidx: %d buflen: %d\n"), + +# ifdef HAVE_USBHOST_TRACE_VERBOSE + + TRENTRY(OTG_VTRACE2_CHANWAKEUP_IN, TR_FMT2, "OTG EP%d(IN) wake up with result: %d\n"), + TRENTRY(OTG_VTRACE2_CHANWAKEUP_OUT, TR_FMT2, "OTG EP%d(OUT) wake up with result: %d\n"), + TRENTRY(OTG_VTRACE2_CTRLIN, TR_FMT2, "OTG CTRL_IN type: %02x req: %02x\n"), + TRENTRY(OTG_VTRACE2_CTRLOUT, TR_FMT2, "OTG CTRL_OUT type: %02x req: %02x\n"), + TRENTRY(OTG_VTRACE2_INTRIN, TR_FMT2, "OTG INTR_IN chidx: %02x len: %02x\n"), + TRENTRY(OTG_VTRACE2_INTROUT, TR_FMT2, "OTG INTR_OUT chidx: %02x len: %02x\n"), + TRENTRY(OTG_VTRACE2_BULKIN, TR_FMT2, "OTG BULK_IN chidx: %02x len: %02x\n"), + TRENTRY(OTG_VTRACE2_BULKOUT, TR_FMT2, "OTG BULK_OUT chidx: %02x len: %02x\n"), + TRENTRY(OTG_VTRACE2_ISOCIN, TR_FMT2, "OTG ISOC_IN chidx: %02x len: %04d\n"), + TRENTRY(OTG_VTRACE2_ISOCOUT, TR_FMT2, "OTG ISOC_OUT chidx: %02x req: %02x\n"), + TRENTRY(OTG_VTRACE2_STARTTRANSFER, TR_FMT2, "OTG Transfer chidx: %d buflen: %d\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_CTRL_IN, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,IN ,CTRL)\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_CTRL_OUT, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,OUT,CTRL)\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_INTR_IN, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,IN ,INTR)\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_INTR_OUT, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,OUT,INTR)\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_BULK_IN, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,IN ,BULK)\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_BULK_OUT, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,OUT,BULK)\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_ISOC_IN, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,IN ,ISOC)\n"), + TRENTRY(OTG_VTRACE2_CHANCONF_ISOC_OUT, TR_FMT2, "OTG Channel configured. chidx: %d: (EP%d,OUT,ISOC)\n"), + TRENTRY(OTG_VTRACE2_CHANHALT, TR_FMT2, "OTG Channel halted. chidx: %d, reason: %d\n"), + +# endif +#endif +}; + +/******************************************************************************************************************** + * Private Function Prototypes + ********************************************************************************************************************/ + +/******************************************************************************************************************** + * Public Functions + ********************************************************************************************************************/ + +/******************************************************************************************************************** + * Name: usbhost_trformat1 and usbhost_trformat2 + * + * Description: + * This interface must be provided by platform specific logic that knows + * the HCDs encoding of USB trace data. + * + * Given an 9-bit index, return a format string suitable for use with, say, + * printf. The returned format is expected to handle two unsigned integer + * values. + * + ********************************************************************************************************************/ + +const char *usbhost_trformat1(uint16_t id) +{ + int ndx = TRACE1_INDEX(id); + + if (ndx < TRACE1_NSTRINGS) + { + return g_trace1[ndx].string; + } + + return NULL; +} + +const char *usbhost_trformat2(uint16_t id) +{ + int ndx = TRACE2_INDEX(id); + + if (ndx < TRACE2_NSTRINGS) + { + return g_trace2[ndx].string; + } + + return NULL; +} + +#endif /* HAVE_USBHOST_TRACE */ diff --git a/arch/arm/src/stm32f7/stm32_usbhost.h b/arch/arm/src/stm32f7/stm32_usbhost.h index 847fe84e77..6f94c2e5af 100644 --- a/arch/arm/src/stm32f7/stm32_usbhost.h +++ b/arch/arm/src/stm32f7/stm32_usbhost.h @@ -51,11 +51,91 @@ ****************************************************************************/ #include +#include +#include +#include #include #if (defined(CONFIG_STM32F7_OTGFS) || defined(CONFIG_STM32F7_OTGFSHS)) && \ defined(CONFIG_USBHOST) +#ifdef HAVE_USBHOST_TRACE +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + + OTG_TRACE1_DEVDISCONN, /* OTG ERROR: Host Port Device disconnected */ + OTG_TRACE1_IRQATTACH, /* OTG ERROR: Failed to attach IRQ */ + OTG_TRACE1_TRNSFRFAILED, /* OTG ERROR: Host Port Transfer Failed */ + OTG_TRACE1_SENDSETUP, /* OTG ERROR: sendsetup() failed with: */ + OTG_TRACE1_SENDDATA, /* OTG ERROR: senddata() failed with: */ + OTG_TRACE1_RECVDATA, /* OTG ERROR: recvdata() failed with: */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + + OTG_VTRACE1_CONNECTED, /* OTG Host Port connected */ + OTG_VTRACE1_DISCONNECTED, /* OTG Host Port disconnected */ + OTG_VTRACE1_GINT, /* OTG Handling Interrupt. Entry Point */ + OTG_VTRACE1_GINT_SOF, /* OTG Handle the start of frame interrupt */ + OTG_VTRACE1_GINT_RXFLVL, /* OTG Handle the RxFIFO non-empty interrupt */ + OTG_VTRACE1_GINT_NPTXFE, /* OTG Handle the non-periodic TxFIFO empty interrupt */ + OTG_VTRACE1_GINT_PTXFE, /* OTG Handle the periodic TxFIFO empty interrupt */ + OTG_VTRACE1_GINT_HC, /* OTG Handle the host channels interrupt */ + OTG_VTRACE1_GINT_HPRT, /* OTG Handle the host port interrupt */ + OTG_VTRACE1_GINT_HPRT_POCCHNG, /* OTG HPRT: Port Over-Current Change */ + OTG_VTRACE1_GINT_HPRT_PCDET, /* OTG HPRT: Port Connect Detect */ + OTG_VTRACE1_GINT_HPRT_PENCHNG, /* OTG HPRT: Port Enable Changed */ + OTG_VTRACE1_GINT_HPRT_LSDEV, /* OTG HPRT: Low Speed Device Connected */ + OTG_VTRACE1_GINT_HPRT_FSDEV, /* OTG HPRT: Full Speed Device Connected */ + OTG_VTRACE1_GINT_HPRT_LSFSSW, /* OTG HPRT: Host Switch: LS -> FS */ + OTG_VTRACE1_GINT_HPRT_FSLSSW, /* OTG HPRT: Host Switch: FS -> LS */ + OTG_VTRACE1_GINT_DISC, /* OTG Handle the disconnect detected interrupt */ + OTG_VTRACE1_GINT_IPXFR, /* OTG Handle the incomplete periodic transfer */ + +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + + OTG_TRACE2_CLIP, /* OTG CLIP: chidx: buflen: */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + + OTG_VTRACE2_CHANWAKEUP_IN, /* OTG IN Channel wake up with result */ + OTG_VTRACE2_CHANWAKEUP_OUT, /* OTG OUT Channel wake up with result */ + OTG_VTRACE2_CTRLIN, /* OTG CTRLIN */ + OTG_VTRACE2_CTRLOUT, /* OTG CTRLOUT */ + OTG_VTRACE2_INTRIN, /* OTG INTRIN */ + OTG_VTRACE2_INTROUT, /* OTG INTROUT */ + OTG_VTRACE2_BULKIN, /* OTG BULKIN */ + OTG_VTRACE2_BULKOUT, /* OTG BULKOUT */ + OTG_VTRACE2_ISOCIN, /* OTG ISOCIN */ + OTG_VTRACE2_ISOCOUT, /* OTG ISOCOUT */ + OTG_VTRACE2_STARTTRANSFER, /* OTG EP buflen */ + OTG_VTRACE2_CHANCONF_CTRL_IN, + OTG_VTRACE2_CHANCONF_CTRL_OUT, + OTG_VTRACE2_CHANCONF_INTR_IN, + OTG_VTRACE2_CHANCONF_INTR_OUT, + OTG_VTRACE2_CHANCONF_BULK_IN, + OTG_VTRACE2_CHANCONF_BULK_OUT, + OTG_VTRACE2_CHANCONF_ISOC_IN, + OTG_VTRACE2_CHANCONF_ISOC_OUT, + OTG_VTRACE2_CHANHALT, /* Channel halted. chidx: , reason: */ + +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS + 1) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) + +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/arch/arm/src/stm32h7/stm32_otghost.c b/arch/arm/src/stm32h7/stm32_otghost.c index c3be17f89f..c52fe71881 100644 --- a/arch/arm/src/stm32h7/stm32_otghost.c +++ b/arch/arm/src/stm32h7/stm32_otghost.c @@ -504,7 +504,7 @@ static struct usbhost_connection_s g_usbconn = #ifdef CONFIG_STM32H7_USBHOST_REGDEBUG static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite) { - llerr("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); + uinfo("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); } #endif @@ -554,7 +554,7 @@ static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) { /* No.. More than one. */ - llerr("[repeats %d more times]\n", count); + uinfo("[repeats %d more times]\n", count); } } diff --git a/boards/arm/stm32f7/stm32f746g-disco/src/Makefile b/boards/arm/stm32f7/stm32f746g-disco/src/Makefile index 142e3d9729..202884f6b4 100644 --- a/boards/arm/stm32f7/stm32f746g-disco/src/Makefile +++ b/boards/arm/stm32f7/stm32f746g-disco/src/Makefile @@ -60,6 +60,12 @@ ifeq ($(CONFIG_MTD_N25QXXX),y) CSRCS += stm32_n25q.c endif +ifeq ($(CONFIG_STM32F7_OTGFS),y) +CSRCS += stm32_usb.c +else ifeq ($(CONFIG_STM32F7_OTGFSHS),y) +CSRCS += stm32_usb.c +endif + ifeq ($(CONFIG_STM32F7_SDMMC),y) CSRCS += stm32_sdmmc.c endif diff --git a/boards/arm/stm32f7/stm32f746g-disco/src/stm32_boot.c b/boards/arm/stm32f7/stm32f746g-disco/src/stm32_boot.c index 9b9a9d11ee..281fb3c6cf 100644 --- a/boards/arm/stm32f7/stm32f746g-disco/src/stm32_boot.c +++ b/boards/arm/stm32f7/stm32f746g-disco/src/stm32_boot.c @@ -30,6 +30,7 @@ #include #include "arm_internal.h" +#include "stm32_start.h" #include "stm32f746g-disco.h" /**************************************************************************** @@ -78,6 +79,12 @@ void stm32_boardinitialize(void) board_autoled_initialize(); #endif +#if defined(CONFIG_STM32F7_OTGFS) || defined(CONFIG_STM32F7_HOST) + /* Initialize USB */ + + stm32_usbinitialize(); +#endif + #ifdef CONFIG_STM32F7_FMC stm32_enablefmc(); #endif diff --git a/boards/arm/stm32f7/stm32f746g-disco/src/stm32_bringup.c b/boards/arm/stm32f7/stm32f746g-disco/src/stm32_bringup.c index c4857b1cc5..6cad661578 100644 --- a/boards/arm/stm32f7/stm32f746g-disco/src/stm32_bringup.c +++ b/boards/arm/stm32f7/stm32f746g-disco/src/stm32_bringup.c @@ -104,6 +104,19 @@ int stm32_bringup(void) } #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); + return ret; + } +#endif + #ifdef CONFIG_INPUT_FT5X06 /* Initialize the touchscreen */ diff --git a/boards/arm/stm32f7/stm32f746g-disco/src/stm32_usb.c b/boards/arm/stm32f7/stm32f746g-disco/src/stm32_usb.c new file mode 100644 index 0000000000..ca7652c4ba --- /dev/null +++ b/boards/arm/stm32f7/stm32f746g-disco/src/stm32_usb.c @@ -0,0 +1,335 @@ +/**************************************************************************** + * boards/arm/stm32f7/stm32f746g-disco/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 + +#include "arm_internal.h" +#include "stm32_otg.h" +#include "stm32_gpio.h" +#include "stm32f746g-disco.h" + +#ifdef CONFIG_STM32F7_OTGFS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_USBDEV) || defined(CONFIG_USBHOST) +# define HAVE_USB 1 +#else +# warning "CONFIG_STM32F7_OTGFS is enabled but neither CONFIG_USBDEV nor CONFIG_USBHOST" +# undef HAVE_USB +#endif + +#ifndef CONFIG_STM32F7F4DISCO_USBHOST_PRIO +# define CONFIG_STM32F7F4DISCO_USBHOST_PRIO 100 +#endif + +#ifndef CONFIG_STM32F7F4DISCO_USBHOST_STACKSIZE +# define CONFIG_STM32F7F4DISCO_USBHOST_STACKSIZE 1024 +#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 STM32F4Discovery 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_STM32F7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); + +#ifdef CONFIG_USBHOST + stm32_configgpio(GPIO_OTGFS_PWRON); + stm32_configgpio(GPIO_OTGFS_OVER); +#endif +#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_STM32F7F4DISCO_USBHOST_PRIO, + CONFIG_STM32F7F4DISCO_USBHOST_STACKSIZE, + (main_t)usbhost_waiter, (char * const *)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); + + syslog(LOG_INFO, "USB Drive %i %i", iface, (int)enable); + + if (enable) + { + /* Enable the Power Switch by driving the enable pin low */ + + stm32_gpiowrite(GPIO_OTGFS_PWRON, false); + } + else + { + /* Disable the Power Switch by driving the enable pin high */ + + stm32_gpiowrite(GPIO_OTGFS_PWRON, true); + } +} +#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_STM32F7_OTGFS */ diff --git a/boards/arm/stm32f7/stm32f746g-disco/src/stm32f746g-disco.h b/boards/arm/stm32f7/stm32f746g-disco/src/stm32f746g-disco.h index d69f3a3027..c03cb075b6 100644 --- a/boards/arm/stm32f7/stm32f746g-disco/src/stm32f746g-disco.h +++ b/boards/arm/stm32f7/stm32f746g-disco/src/stm32f746g-disco.h @@ -33,6 +33,45 @@ * Pre-processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ + +#define HAVE_USBDEV 1 +#define HAVE_USBHOST 1 +#define HAVE_USBMONITOR 1 + +/* Can't support USB host or device features if USB OTG FS is not enabled */ + +#ifndef CONFIG_STM32F7_OTGFS +# undef HAVE_USBDEV +# undef HAVE_USBHOST +#endif + +/* Can't support USB device if USB device is not enabled */ + +#ifndef CONFIG_USBDEV +# undef HAVE_USBDEV +#endif + +/* Can't support USB host is USB host is not enabled */ + +#ifndef CONFIG_USBHOST +# undef HAVE_USBHOST +#endif + +/* Check if we should enable the USB monitor before starting NSH */ + +#ifndef CONFIG_USBMONITOR +# undef HAVE_USBMONITOR +#endif + +#ifndef HAVE_USBDEV +# undef CONFIG_USBDEV_TRACE +#endif + +#if !defined(CONFIG_USBDEV_TRACE) && !defined(CONFIG_USBHOST_TRACE) +# undef HAVE_USBMONITOR +#endif + /* procfs File System */ #ifdef CONFIG_FS_PROCFS