From 2a817aaf19030b551a0153ff45de9bb759c418ad Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 11 Aug 2013 17:52:36 -0600 Subject: SAMA5: Add support for initialization of the USB host and mass storage class --- nuttx/ChangeLog | 2 + nuttx/configs/sama5d3x-ek/src/Makefile | 8 + nuttx/configs/sama5d3x-ek/src/sam_boot.c | 13 ++ nuttx/configs/sama5d3x-ek/src/sam_nsh.c | 23 ++- nuttx/configs/sama5d3x-ek/src/sam_usb.c | 272 ++++++++++++++++++++++++++++ nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h | 61 +++++++ 6 files changed, 374 insertions(+), 5 deletions(-) create mode 100644 nuttx/configs/sama5d3x-ek/src/sam_usb.c diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 45262a4d4..4cf104efc 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -5364,3 +5364,5 @@ * drivers/usbhost/usbhost_hidkbd.c and usbhost_storage.c: Correct some compilation errors when pre-allocated class structures are used. Also eliminate some warnings about uninitialized variables (2013-8-11). + * configs/sama5d3x-ek/src/sam_usb.c and related files: Add support for + initialization of the USB host and mass storage class device (2013-8-11). diff --git a/nuttx/configs/sama5d3x-ek/src/Makefile b/nuttx/configs/sama5d3x-ek/src/Makefile index 420568701..a673b5a8a 100644 --- a/nuttx/configs/sama5d3x-ek/src/Makefile +++ b/nuttx/configs/sama5d3x-ek/src/Makefile @@ -78,6 +78,14 @@ CSRCS += sam_hsmci.c endif endif +ifeq ($(CONFIG_SAMA5_UHPHS),y) +CSRCS += sam_usb.c +else +ifeq ($(CONFIG_SAMA5_UDPHS),y) +CSRCS += sam_usb.c +endif +endif + ifeq ($(CONFIG_NSH_ARCHINIT),y) CSRCS += sam_nsh.c endif diff --git a/nuttx/configs/sama5d3x-ek/src/sam_boot.c b/nuttx/configs/sama5d3x-ek/src/sam_boot.c index 4d4cb27e6..fda4c8354 100644 --- a/nuttx/configs/sama5d3x-ek/src/sam_boot.c +++ b/nuttx/configs/sama5d3x-ek/src/sam_boot.c @@ -90,6 +90,19 @@ void sam_boardinitialize(void) #endif + /* Initialize USB if the 1) the HS host or device controller is in the + * configuration and 2) the weak function sam_usbinitialize() has been brought + * into the build. Presumeably either CONFIG_USBDEV or CONFIG_USBHOST is also + * selected. + */ + +#if defined(CONFIG_SAMA5_UHPHS) || defined(CONFIG_SAMA5_UDPHS) + if (sam_usbinitialize) + { + sam_usbinitialize(); + } +#endif + #ifdef CONFIG_ARCH_LEDS /* Configure on-board LEDs if LED support has been selected. */ diff --git a/nuttx/configs/sama5d3x-ek/src/sam_nsh.c b/nuttx/configs/sama5d3x-ek/src/sam_nsh.c index b84418a6a..1b7ecea4e 100644 --- a/nuttx/configs/sama5d3x-ek/src/sam_nsh.c +++ b/nuttx/configs/sama5d3x-ek/src/sam_nsh.c @@ -112,7 +112,7 @@ int nsh_archinitialize(void) ret = sam_at25_initialize(AT25_MINOR); if (ret < 0) { - fdbg("ERROR: sam_at25_initialize failed: %d\n", ret); + dbg("ERROR: sam_at25_initialize failed: %d\n", ret); return ret; } #endif @@ -122,8 +122,8 @@ int nsh_archinitialize(void) ret = sam_hsmci_initialize(HSMCI0_SLOTNO, HSMCI0_MINOR); if (ret < 0) { - fdbg("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n", - HSMCI0_SLOTNO, HSMCI0_MINOR, ret); + dbg("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n", + HSMCI0_SLOTNO, HSMCI0_MINOR, ret); return ret; } #endif @@ -132,12 +132,25 @@ int nsh_archinitialize(void) ret = sam_hsmci_initialize(HSMCI1_SLOTNO, HSMCI1_MINOR); if (ret < 0) { - fdbg("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n", - HSMCI1_SLOTNO, HSMCI1_MINOR, ret); + dbg("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n", + HSMCI1_SLOTNO, HSMCI1_MINOR, ret); return ret; } #endif #endif +#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) + /* Initialize USB host operation. sam_usbhost_initialize() starts a thread + * will monitor for USB connection and disconnection events. + */ + + ret = sam_usbhost_initialize(); + if (ret != OK) + { + dbg("ERROR: Failed to initialize USB host: %d\n", ret); + return ret; + } +#endif + return OK; } diff --git a/nuttx/configs/sama5d3x-ek/src/sam_usb.c b/nuttx/configs/sama5d3x-ek/src/sam_usb.c new file mode 100644 index 000000000..98f989b75 --- /dev/null +++ b/nuttx/configs/sama5d3x-ek/src/sam_usb.c @@ -0,0 +1,272 @@ +/************************************************************************************ + * configs/sama5d3x-ek/src/up_usbdev.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "sam_ohci.h" +#include "sama5d3x-ek.h" + +#if defined(CONFIG_SAMA5_UHPHS) || defined(CONFIG_SAMA5_UDPHS) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#ifndef CONFIG_USBHOST_DEFPRIO +# define CONFIG_USBHOST_DEFPRIO 50 +#endif + +#ifndef CONFIG_USBHOST_STACKSIZE +# define CONFIG_USBHOST_STACKSIZE 1024 +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) +static struct usbhost_driver_s *g_drvr; +#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[]) +{ + bool connected = false; + + uvdbg("Running\n"); + for (;;) + { + /* Wait for the device to change state */ + + DEBUGVERIFY(DRVR_WAIT(g_drvr, connected) == OK); + + connected = !connected; + uvdbg("%s\n", connected ? "connected" : "disconnected"); + + /* Did we just become connected? */ + + if (connected) + { + /* Yes.. enumerate the newly connected device */ + + (void)DRVR_ENUMERATE(g_drvr); + } + } + + /* Keep the compiler from complaining */ + + return 0; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_usbinitialize + * + * Description: + * Called from sam_usbinitialize very early in inialization to setup USB-related + * GPIO pins for the STM32F4Discovery board. + * + ************************************************************************************/ + +void weak_function sam_usbinitialize(void) +{ + /* Configure pull-ups */ + + /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent PIOs */ +} + +/*********************************************************************************** + * Name: sam_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_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) +int sam_usbhost_initialize(void) +{ + int pid; + int ret; + + /* First, register all of the class drivers needed to support the drivers + * that we care about: + */ + + uvdbg("Register class drivers\n"); + ret = usbhost_storageinit(); + if (ret != OK) + { + udbg("Failed to register the mass storage class\n"); + } + + /* Then get an instance of the USB host interface */ + + uvdbg("Initialize USB host\n"); + g_drvr = sam_ohci_initialize(0); + if (g_drvr) + { + /* Start a thread to handle device connection. */ + + uvdbg("Start usbhost_waiter\n"); + + pid = TASK_CREATE("usbhost", CONFIG_USBHOST_DEFPRIO, + CONFIG_USBHOST_STACKSIZE, + (main_t)usbhost_waiter, (FAR char * const *)NULL); + return pid < 0 ? -ENOEXEC : OK; + } + + return -ENODEV; +} +#endif + +/*********************************************************************************** + * Name: sam_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 + * + ***********************************************************************************/ + +#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) +void sam_usbhost_vbusdrive(int iface, bool enable) +{ + DEBUGASSERT(iface == 0); + + if (enable) + { + /* Enable the Power Switch by driving the enable pin low */ + } + else + { + /* Disable the Power Switch by driving the enable pin high */ + } +} +#endif + +/************************************************************************************ + * Name: sam_setup_overcurrent + * + * Description: + * Setup to receive an interrupt-level callback if an overcurrent condition is + * detected. + * + * Input paramter: + * handler - New overcurrent interrupt handler + * + * Returned value: + * Old overcurrent interrupt handler + * + ************************************************************************************/ + +#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) +xcpt_t sam_setup_overcurrent(xcpt_t handler) +{ + return NULL; +} +#endif + +/************************************************************************************ + * Name: sam_usbsuspend + * + * Description: + * Board logic must provide the sam_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 sam_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + ulldbg("resume: %d\n", resume); +} +#endif + +#endif /* CONFIG_SAMA5_UHPHS || CONFIG_SAMA5_UDPHS*/ diff --git a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h index c568001f7..76bd78808 100644 --- a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h +++ b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h @@ -58,6 +58,7 @@ #define HAVE_HSMCI_MTD 1 #define HAVE_AT25_MTD 1 +/* HSMCI */ /* Can't support MMC/SD if the card interface(s) are not enable */ #if !defined(CONFIG_SAMA5_HSMCI0) && !defined(CONFIG_SAMA5_HSMCI1) @@ -78,6 +79,7 @@ # undef HAVE_HSMCI_MTD #endif +/* AT25 Serial FLASH */ /* Can't support the AT25 device if it SPI0 or AT25 support are not enabled */ #if !defined(CONFIG_SAMA5_SPI0) || !defined(CONFIG_MTD_AT25) @@ -106,6 +108,39 @@ # undef CONFIG_SAMA5_AT25_NXFFS #endif +/* USB Host / USB Device */ +/* Either CONFIG_SAMA5_UHPHS or CONFIG_SAMA5_UDPHS must be defined, or there is + * no USB of any kind. + */ + +#if !defined(CONFIG_SAMA5_UHPHS) +# undef CONFIG_SAMA5_OHCI +# undef CONFIG_SAMA5_EHCI +#endif + +#if !defined(CONFIG_SAMA5_UDPHS) +#endif + +/* CONFIG_USBDEV and CONFIG_USBHOST must also be defined */ + +#if defined(CONFIG_USBDEV) +#else +#endif + +#if defined(CONFIG_USBHOST) +# if !defined(CONFIG_SAMA5_OHCI) && !defined(CONFIG_SAMA5_EHCI) +# warning CONFIG_USBHOST is defined, but neither CONFIG_SAMA5_OHCI nor CONFIG_SAMA5_EHCI are defined +# endif +#else +# undef CONFIG_SAMA5_OHCI +# undef CONFIG_SAMA5_EHCI +#endif + +#if defined(CONFIG_SAMA5_OHCI) && defined(CONFIG_SAMA5_EHCI) +# warning Both CONFIG_SAMA5_OHCI and CONFIG_SAMA5_EHCI are defined +# undef CONFIG_SAMA5_EHCI +#endif + /* LEDs *****************************************************************************/ /* There are two LEDs on the SAMA5D3 series-CM board that can be controlled * by software. A blue LED is controlled via PIO pins. A red LED normally @@ -322,6 +357,32 @@ bool sam_cardinserted(int slotno); bool sam_writeprotected(int slotno); #endif +/************************************************************************************ + * Name: sam_usbinitialize + * + * Description: + * Called from sam_usbinitialize very early in inialization to setup USB-related + * GPIO pins for the STM32F4Discovery board. + * + ************************************************************************************/ + +#if defined(CONFIG_SAMA5_UHPHS) || defined(CONFIG_SAMA5_UDPHS) +void weak_function sam_usbinitialize(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_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) +int sam_usbhost_initialize(void); +#endif + /************************************************************************************ * Name: up_ledinit ************************************************************************************/ -- cgit v1.2.3