Merged in webbbn/nuttx/add_usb_conf_to_stm32f411disco (pull request #314)

Adds USB host support to stm32f411-disco board.

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
Brian Webb 2017-04-13 12:21:29 +00:00 committed by Gregory Nutt
commit 6b7e4d7877
6 changed files with 574 additions and 16 deletions

View File

@ -5,4 +5,15 @@
if ARCH_BOARD_STM32F411E_DISCO
config STM32F411DISCO_USBHOST_STACKSIZE
int "USB host waiter stack size"
default 1024
depends on USBHOST
config STM32F411DISCO_USBHOST_PRIO
int "USB host waiter task priority"
default 100
depends on USBHOST
endif

View File

@ -36,10 +36,14 @@
-include $(TOPDIR)/Make.defs
ASRCS =
CSRCS = stm32_boot.c
CSRCS = stm32_boot.c stm32_bringup.c
ifeq ($(CONFIG_NSH_LIBRARY),y)
CSRCS += stm32_appinit.c
endif
ifeq ($(CONFIG_STM32_OTGFS),y)
CSRCS += stm32_usb.c
endif
include $(TOPDIR)/configs/Board.mk

View File

@ -80,10 +80,9 @@ void stm32_boardinitialize(void)
stm32_spidev_initialize();
#endif
#if defined(CONFIG_USBDEV) && defined(CONFIG_STM32_USB)
/* Initialize USB is 1) USBDEV is selected, 2) the USB controller is not
* disabled, and 3) the weak function stm32_usbinitialize() has been brought
* into the build.
#ifdef CONFIG_STM32_OTGFS
/* Initialize USB if the 1) OTG FS controller is in the configuration and 2)
* disabled. Presumably either CONFIG_USBDEV or CONFIG_USBHOST is also selected.
*/
stm32_usbinitialize();
@ -106,14 +105,8 @@ void stm32_boardinitialize(void)
#ifdef CONFIG_BOARD_INITIALIZE
void board_initialize(void)
{
#if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_LIB_BOARDCTL)
/* Perform NSH initialization here instead of from the NSH. This
* alternative NSH initialization is necessary when NSH is ran in user-space
* but the initialization function must run in kernel space.
*/
board_app_initialize(0);
#endif
/* Perform board-specific initialization */
(void)stm32_bringup();
}
#endif

View File

@ -0,0 +1,123 @@
/****************************************************************************
* config/stm32f4discovery/src/stm32_bringup.c
*
* Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <sys/mount.h>
#include <stdbool.h>
#include <stdio.h>
#include <debug.h>
#include <errno.h>
#ifdef CONFIG_USBMONITOR
# include <nuttx/usb/usbmonitor.h>
#endif
#include <nuttx/binfmt/elf.h>
#include "stm32.h"
#ifdef CONFIG_STM32_OTGFS
# include "stm32_usbhost.h"
#endif
#include "stm32f411e-disco.h"
/* Conditional logic in stm32f4discover.h will determine if certain features
* are supported. Tests for these features need to be made after including
* stm32f4discovery.h.
*/
#ifdef HAVE_RTC_DRIVER
# include <nuttx/timers/rtc.h>
# include "stm32_rtc.h"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_bringup
*
* Description:
* Perform architecture-specific initialization
*
* CONFIG_BOARD_INITIALIZE=y :
* Called from board_initialize().
*
* CONFIG_BOARD_INITIALIZE=n && CONFIG_LIB_BOARDCTL=y :
* Called from the NSH library
*
****************************************************************************/
int stm32_bringup(void)
{
int ret = OK;
#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)
{
uerr("ERROR: Failed to initialize USB host: %d\n", ret);
return ret;
}
#endif
#ifdef CONFIG_FS_PROCFS
/* Mount the procfs file system */
ret = mount(NULL, STM32_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
if (ret < 0)
{
serr("ERROR: Failed to mount procfs at %s: %d\n",
STM32_PROCFS_MOUNTPOINT, ret);
}
#endif
return ret;
}

View File

@ -0,0 +1,352 @@
/************************************************************************************
* configs/stm32f411e-disco/src/stm32_usb.c
*
* Copyright (C) 2012-2013, 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Copyright (C) 2017 Brian Webb. All rights reserved.
* Author: Brian Webb <webbbn@gmail.com>
*
* 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 <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <sched.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/usb/usbdev.h>
#include <nuttx/usb/usbhost.h>
#include <nuttx/usb/usbdev_trace.h>
#include "up_arch.h"
#include "stm32.h"
#include "stm32_otgfs.h"
#include "stm32f411e-disco.h"
#ifdef CONFIG_STM32_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_STM32F411DISCO_USBHOST_PRIO
# define CONFIG_STM32F411DISCO_USBHOST_PRIO 100
#endif
#ifndef CONFIG_STM32F411DISCO_USBHOST_STACKSIZE
# define CONFIG_STM32F411DISCO_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 */
(void)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 STM32F411 Discovery 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_STM32_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 pid;
#if defined(CONFIG_USBHOST_HUB) || defined(CONFIG_USBHOST_MSC) || \
defined(CONFIG_USBHOST_HIDKBD) || defined(CONFIG_USBHOST_HIDMOUSE) || \
defined(CONFIG_USBHOST_XBOXCONTROLLER)
int ret;
#endif
/* 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
#ifdef CONFIG_USBHOST_XBOXCONTROLLER
/* Initialize the HID mouse class */
ret = usbhost_xboxcontroller_init();
if (ret != OK)
{
uerr("ERROR: Failed to register the XBox Controller 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");
pid = task_create("usbhost", CONFIG_STM32F411DISCO_USBHOST_PRIO,
CONFIG_STM32F411DISCO_USBHOST_STACKSIZE,
(main_t)usbhost_waiter, (FAR char * const *)NULL);
return pid < 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);
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 Parameter:
* 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(FAR struct usbdev_s *dev, bool resume)
{
uinfo("resume: %d\n", resume);
}
#endif
#endif /* CONFIG_STM32_OTGFS */

View File

@ -85,6 +85,48 @@
#define GPIO_SPI1_SCK_OFF (GPIO_INPUT | GPIO_PULLDOWN | \
GPIO_PORTA | GPIO_PIN5)
/* Assume that we have everything */
#define HAVE_USBDEV 1
#define HAVE_USBHOST 1
#define HAVE_USBMONITOR 1
#define HAVE_SDIO 1
#define HAVE_RTC_DRIVER 1
#define HAVE_ELF 1
#define HAVE_NETMONITOR 1
/* USB OTG FS
*
* PA9 OTG_FS_VBUS VBUS sensing (also connected to the green LED)
* PC0 OTG_FS_PowerSwitchOn
* PD5 OTG_FS_Overcurrent
*/
#define GPIO_OTGFS_VBUS (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|\
GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9)
#define GPIO_OTGFS_PWRON (GPIO_OUTPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|\
GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN0)
#ifdef CONFIG_USBHOST
# define GPIO_OTGFS_OVER (GPIO_INPUT|GPIO_EXTI|GPIO_FLOAT|\
GPIO_SPEED_100MHz|GPIO_PUSHPULL|\
GPIO_PORTD|GPIO_PIN5)
#else
# define GPIO_OTGFS_OVER (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|\
GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN5)
#endif
/* procfs File System */
#ifdef CONFIG_FS_PROCFS
# ifdef CONFIG_NSH_PROC_MOUNTPOINT
# define STM32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT
# else
# define STM32_PROCFS_MOUNTPOINT "/proc"
# endif
#endif
/************************************************************************************
* Public Data
************************************************************************************/
@ -112,14 +154,47 @@ extern struct spi_dev_s *g_spi2;
void stm32_spidev_initialize(void);
/************************************************************************************
/****************************************************************************
* Name: stm32_usbinitialize
*
* Description:
* Called to setup USB-related GPIO pins.
* Called from stm32_usbinitialize very early in initialization to setup
* USB-related GPIO pins for the STM32F4Discovery board.
*
************************************************************************************/
****************************************************************************/
#ifdef CONFIG_STM32_OTGFS
void stm32_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_STM32_OTGFS) && defined(CONFIG_USBHOST)
int stm32_usbhost_initialize(void);
#endif
/****************************************************************************
* Name: stm32_bringup
*
* Description:
* Perform architecture-specific initialization
*
* CONFIG_BOARD_INITIALIZE=y :
* Called from board_initialize().
*
* CONFIG_BOARD_INITIALIZE=y && CONFIG_LIB_BOARDCTL=y :
* Called from the NSH library
*
****************************************************************************/
int stm32_bringup(void);
#endif /* __CONFIGS_STM32F411E_DISCO_SRC_STM32F411E_DISCO_H */