summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-12 11:59:10 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-12 11:59:10 -0600
commitd5cee29af56c68dceeb8e26f6f4081c9d3c66988 (patch)
tree2edea2eb0800f1fd1307767e570454789fd561d6
parent2a817aaf19030b551a0153ff45de9bb759c418ad (diff)
downloadnuttx-d5cee29af56c68dceeb8e26f6f4081c9d3c66988.tar.gz
nuttx-d5cee29af56c68dceeb8e26f6f4081c9d3c66988.tar.bz2
nuttx-d5cee29af56c68dceeb8e26f6f4081c9d3c66988.zip
SAMA5: Add logic to control VBUS power for OHCI
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/arch/arm/src/sama5/sam_ohci.c18
-rw-r--r--nuttx/arch/arm/src/sama5/sam_usbhost.h (renamed from nuttx/arch/arm/src/sama5/sam_ohci.h)71
-rw-r--r--nuttx/configs/sama5d3x-ek/README.txt57
-rw-r--r--nuttx/configs/sama5d3x-ek/src/sam_nsh.c32
-rw-r--r--nuttx/configs/sama5d3x-ek/src/sam_usb.c254
-rw-r--r--nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h82
7 files changed, 453 insertions, 65 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 4cf104efc..6ee8926fe 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5366,3 +5366,7 @@
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).
+ * arch/arm/src/sama5/sam_ohci.c and sam_usbhost.h (was sam_ohci.h), and
+ configs/sama5d3x-ek/src/sam_usb.c, and sama5d3x-ek.h: Add controls
+ to enable VBUS power in OHCI host most (2013-8-12).
+
diff --git a/nuttx/arch/arm/src/sama5/sam_ohci.c b/nuttx/arch/arm/src/sama5/sam_ohci.c
index 040163a9c..40ff3dea0 100644
--- a/nuttx/arch/arm/src/sama5/sam_ohci.c
+++ b/nuttx/arch/arm/src/sama5/sam_ohci.c
@@ -63,7 +63,7 @@
#include "chip.h"
#include "sam_periphclks.h"
-#include "sam_ohci.h"
+#include "sam_usbhost.h"
#include "chip/sam_pmc.h"
#include "chip/sam_sfr.h"
#include "chip/sam_ohci.h"
@@ -333,7 +333,7 @@ static int sam_ctrltd(struct sam_ohci_s *priv, uint32_t dirpid,
/* Interrupt handling **********************************************************/
-static int sam_usbinterrupt(int irq, FAR void *context);
+static int sam_ohci_interrupt(int irq, FAR void *context);
/* USB host controller operations **********************************************/
@@ -1326,14 +1326,14 @@ static int sam_ctrltd(struct sam_ohci_s *priv, uint32_t dirpid, uint8_t *buffer,
}
/*******************************************************************************
- * Name: sam_usbinterrupt
+ * Name: sam_ohci_interrupt
*
* Description:
* USB interrupt handler
*
*******************************************************************************/
-static int sam_usbinterrupt(int irq, FAR void *context)
+static int sam_ohci_interrupt(int irq, FAR void *context)
{
struct sam_ohci_s *priv = &g_usbhost;
uint32_t intst;
@@ -2409,7 +2409,7 @@ static inline void sam_ep0init(struct sam_ohci_s *priv)
* Initialize USB OHCI host controller hardware.
*
* Input Parameters:
- * controller -- If the device supports more than USB host controller, then
+ * controller -- If the device supports more than one OHCI interface, then
* this identifies which controller is being intialized. Normally, this
* is just zero.
*
@@ -2572,7 +2572,7 @@ FAR struct usbhost_driver_s *sam_ohci_initialize(int controller)
/* Attach USB host controller interrupt handler */
- if (irq_attach(SAM_IRQ_UHPHS, sam_usbinterrupt) != 0)
+ if (irq_attach(SAM_IRQ_UHPHS, sam_ohci_interrupt) != 0)
{
udbg("Failed to attach IRQ\n");
return NULL;
@@ -2586,6 +2586,12 @@ FAR struct usbhost_driver_s *sam_ohci_initialize(int controller)
regval = sam_getreg(SAM_USBHOST_RHPORTST1);
priv->connected = ((regval & OHCI_RHPORTST_CCS) != 0);
+ /* Drive Vbus +5V (the smoke test). Should be done elsewhere in OTG
+ * mode.
+ */
+
+ sam_usbhost_vbusdrive(SAM_OHCI_IFACE, true);
+
/* Enable interrupts at the interrupt controller */
up_enable_irq(SAM_IRQ_UHPHS); /* enable USB interrupt */
diff --git a/nuttx/arch/arm/src/sama5/sam_ohci.h b/nuttx/arch/arm/src/sama5/sam_usbhost.h
index fc7713576..c64664daf 100644
--- a/nuttx/arch/arm/src/sama5/sam_ohci.h
+++ b/nuttx/arch/arm/src/sama5/sam_usbhost.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/lpc17xx/lpc17_usbhost.h
+ * arch/arm/src/sama5/sam_usbhost.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_LPC17XX_LPC17_USBHOST_H
-#define __ARCH_ARM_SRC_LPC17XX_LPC17_USBHOST_H
+#ifndef __ARCH_ARM_SRC_SAMA5_SAM_USBHOST_H
+#define __ARCH_ARM_SRC_SAMA5_SAM_USBHOST_H
/************************************************************************************
* Included Files
@@ -42,9 +42,17 @@
#include <nuttx/config.h>
+#ifdef CONFIG_USBHOST
+
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
+/* This is the interface argument for call outs to board-specific functions which
+ * need to know which USB host interface is being used.
+ */
+
+#define SAM_EHCI_IFACE 0
+#define SAM_OHCI_IFACE 1
/************************************************************************************
* Public Types
@@ -80,7 +88,7 @@ extern "C"
* Initialize USB OHCI host controller hardware.
*
* Input Parameters:
- * controller -- If the device supports more than USB host controller, then
+ * controller -- If the device supports more than one USB OHCI interface, then
* this identifies which controller is being intialized. Normally, this
* is just zero.
*
@@ -98,15 +106,66 @@ extern "C"
*
*******************************************************************************/
-#ifdef CONFIG_USBHOST
+#ifdef CONFIG_SAMA5_OHCI
struct usbhost_driver_s;
FAR struct usbhost_driver_s *sam_ohci_initialize(int controller);
#endif
+/*******************************************************************************
+ * Name: sam_ehci_initialize
+ *
+ * Description:
+ * Initialize USB EHCI host controller hardware.
+ *
+ * Input Parameters:
+ * controller -- If the device supports more than one EHCI interface, then
+ * this identifies which controller is being intialized. Normally, this
+ * is just zero.
+ *
+ * Returned Value:
+ * And instance of the USB host interface. The controlling task should
+ * use this interface to (1) call the wait() method to wait for a device
+ * to be connected, and (2) call the enumerate() method to bind the device
+ * to a class driver.
+ *
+ * Assumptions:
+ * - This function should called in the initialization sequence in order
+ * to initialize the USB device functionality.
+ * - Class drivers should be initialized prior to calling this function.
+ * Otherwise, there is a race condition if the device is already connected.
+ *
+ *******************************************************************************/
+
+#ifdef CONFIG_SAMA5_EHCI
+struct usbhost_driver_s;
+FAR struct usbhost_driver_s *sam_ehci_initialize(int controller);
+#endif
+
+/***********************************************************************************
+ * Name: sam_usbhost_vbusdrive
+ *
+ * Description:
+ * Enable/disable driving of VBUS 5V output. This function must be provided by
+ * each platform that implements the OHCI or EHCI host interface
+ *
+ * Input Parameters:
+ * iface - Selects USB host interface:
+ * 0 = EHCI
+ * 1 = OHCI
+ * enable - true: enable VBUS power; false: disable VBUS power
+ *
+ * Returned Value:
+ * None
+ *
+ ***********************************************************************************/
+
+void sam_usbhost_vbusdrive(int iface, bool enable);
+
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
-#endif /* __ARCH_ARM_SRC_LPC17XX_LPC17_USBHOST_H */
+#endif /* CONFIG_USBHOST */
+#endif /* __ARCH_ARM_SRC_SAMA5_SAM_USBHOST_H */
diff --git a/nuttx/configs/sama5d3x-ek/README.txt b/nuttx/configs/sama5d3x-ek/README.txt
index 5998bcc04..04b42212e 100644
--- a/nuttx/configs/sama5d3x-ek/README.txt
+++ b/nuttx/configs/sama5d3x-ek/README.txt
@@ -75,6 +75,7 @@ Contents
- Serial Consoles
- Serial FLASH
- HSMCI Card Slots
+ - USB Ports
- SAMA5D3x-EK Configuration Options
- Configurations
@@ -564,6 +565,59 @@ HSMCI Card Slots
PB24 MCI1_CK
PB19 MCI1_CDA
+USB Ports
+=========
+
+ The SAMA5D3 series-MB features three USB communication ports:
+
+ * Port A Host High Speed (EHCI) and Full Speed (OHCI) multiplexed with
+ USB Device High Speed Micro AB connector, J20
+
+ * Port B Host High Speed (EHCI) and Full Speed (OHCI) standard type A
+ connector, J19 upper port
+
+ * Port C Host Full Speed (OHCI) only standard type A connector, J19
+ lower port
+
+ All three USB host ports are equipped with 500 mA high-side power switch
+ for self-powered and buspowered applications. The USB device port feature
+ VBUS inserts detection function.
+
+ Port A
+ ------
+
+ PIO Signal Name Function
+ ---- ----------- -------------------------------------------------------
+ PD29 VBUS_SENSE VBus detection
+ PD25 EN5V_USBA VBus power enable (via MN15 AIC1526 Dual USB High-Side
+ Power Switch. The other channel of the switch is for
+ the LCD)
+
+ Port B
+ ------
+
+ PIO Signal Name Function
+ ---- ----------- -------------------------------------------------------
+ PD26 EN5V_USBB VBus power enable (via MN14 AIC1526 Dual USB High-Side
+ Power Switch). To the A1 pin of J19 Dual USB A
+ connector
+
+ Port C
+ ------
+
+ PIO Signal Name Function
+ ---- ----------- -------------------------------------------------------
+ PD27 EN5V_USBC VBus power enable (via MN14 AIC1526 Dual USB High-Side
+ Power Switch). To the B1 pin of J19 Dual USB A
+ connector
+
+ Both Ports B and C
+ ------------------
+
+ PIO Signal Name Function
+ ---- ----------- -------------------------------------------------------
+ PD28 OVCUR_USB Combined overrcurrent indication from port A and B
+
SAMA5D3x-EK Configuration Options
=================================
@@ -1131,6 +1185,9 @@ Configurations
Library Routines
CONFIG_SCHED_WORKQUEUE : Worker thread support is required
+ Application Configuration -> NSH Library
+ CONFIG_NSH_ARCHINIT=y : NSH board-initialization
+
STATUS:
2013-7-19: This configuration (as do the others) run at 396MHz.
The SAMA5D3 can run at 536MHz. I still need to figure out the
diff --git a/nuttx/configs/sama5d3x-ek/src/sam_nsh.c b/nuttx/configs/sama5d3x-ek/src/sam_nsh.c
index 1b7ecea4e..648a015a6 100644
--- a/nuttx/configs/sama5d3x-ek/src/sam_nsh.c
+++ b/nuttx/configs/sama5d3x-ek/src/sam_nsh.c
@@ -88,6 +88,22 @@
# define AT25_MINOR CONFIG_NSH_MMCSDMINOR
#endif
+/* Debug ********************************************************************/
+
+#ifdef CONFIG_CPP_HAVE_VARARGS
+# ifdef CONFIG_DEBUG
+# define message(...) syslog(__VA_ARGS__)
+# else
+# define message(...) printf(__VA_ARGS__)
+# endif
+#else
+# ifdef CONFIG_DEBUG
+# define message syslog
+# else
+# define message printf
+# endif
+#endif
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -102,7 +118,7 @@
int nsh_archinitialize(void)
{
-#if defined(HAVE_AT25_MTD) || defined(HAVE_HSMCI_MTD)
+#if defined(HAVE_AT25_MTD) || defined(HAVE_HSMCI_MTD) || defined(HAVE_USBHOST)
int ret;
#endif
@@ -112,7 +128,7 @@ int nsh_archinitialize(void)
ret = sam_at25_initialize(AT25_MINOR);
if (ret < 0)
{
- dbg("ERROR: sam_at25_initialize failed: %d\n", ret);
+ message("ERROR: sam_at25_initialize failed: %d\n", ret);
return ret;
}
#endif
@@ -122,8 +138,8 @@ int nsh_archinitialize(void)
ret = sam_hsmci_initialize(HSMCI0_SLOTNO, HSMCI0_MINOR);
if (ret < 0)
{
- dbg("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n",
- HSMCI0_SLOTNO, HSMCI0_MINOR, ret);
+ message("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n",
+ HSMCI0_SLOTNO, HSMCI0_MINOR, ret);
return ret;
}
#endif
@@ -132,14 +148,14 @@ int nsh_archinitialize(void)
ret = sam_hsmci_initialize(HSMCI1_SLOTNO, HSMCI1_MINOR);
if (ret < 0)
{
- dbg("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n",
- HSMCI1_SLOTNO, HSMCI1_MINOR, ret);
+ message("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)
+#ifdef HAVE_USBHOST
/* Initialize USB host operation. sam_usbhost_initialize() starts a thread
* will monitor for USB connection and disconnection events.
*/
@@ -147,7 +163,7 @@ int nsh_archinitialize(void)
ret = sam_usbhost_initialize();
if (ret != OK)
{
- dbg("ERROR: Failed to initialize USB host: %d\n", ret);
+ message("ERROR: Failed to initialize USB host: %d\n", ret);
return ret;
}
#endif
diff --git a/nuttx/configs/sama5d3x-ek/src/sam_usb.c b/nuttx/configs/sama5d3x-ek/src/sam_usb.c
index 98f989b75..3b009bb41 100644
--- a/nuttx/configs/sama5d3x-ek/src/sam_usb.c
+++ b/nuttx/configs/sama5d3x-ek/src/sam_usb.c
@@ -1,5 +1,5 @@
/************************************************************************************
- * configs/sama5d3x-ek/src/up_usbdev.c
+ * configs/sama5d3x-ek/src/up_usb.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -52,7 +52,8 @@
#include <nuttx/usb/usbdev_trace.h>
#include "up_arch.h"
-#include "sam_ohci.h"
+#include "sam_pio.h"
+#include "sam_usbhost.h"
#include "sama5d3x-ek.h"
#if defined(CONFIG_SAMA5_UHPHS) || defined(CONFIG_SAMA5_UDPHS)
@@ -72,9 +73,13 @@
/************************************************************************************
* Private Data
************************************************************************************/
+/* Retained device driver handles */
-#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI)
-static struct usbhost_driver_s *g_drvr;
+#ifdef CONFIG_SAMA5_OHCI
+static struct usbhost_driver_s *g_ohci;
+#endif
+#ifdef CONFIG_SAMA5_EHCI
+static struct usbhost_driver_s *g_ehci;
#endif
/************************************************************************************
@@ -85,12 +90,12 @@ static struct usbhost_driver_s *g_drvr;
* Name: usbhost_waiter
*
* Description:
- * Wait for USB devices to be connected.
+ * Wait for USB devices to be connected to either the OHCI or EHCI hub.
*
************************************************************************************/
-#ifdef CONFIG_USBHOST
-static int usbhost_waiter(int argc, char *argv[])
+#if HAVE_USBHOST
+static int usbhost_waiter(struct usbhost_driver_s *dev)
{
bool connected = false;
@@ -99,7 +104,7 @@ static int usbhost_waiter(int argc, char *argv[])
{
/* Wait for the device to change state */
- DEBUGVERIFY(DRVR_WAIT(g_drvr, connected) == OK);
+ DEBUGVERIFY(DRVR_WAIT(dev, connected) == OK);
connected = !connected;
uvdbg("%s\n", connected ? "connected" : "disconnected");
@@ -110,7 +115,7 @@ static int usbhost_waiter(int argc, char *argv[])
{
/* Yes.. enumerate the newly connected device */
- (void)DRVR_ENUMERATE(g_drvr);
+ (void)DRVR_ENUMERATE(dev);
}
}
@@ -121,6 +126,36 @@ static int usbhost_waiter(int argc, char *argv[])
#endif
/************************************************************************************
+ * Name: ohci_waiter
+ *
+ * Description:
+ * Wait for USB devices to be connected to the OHCI hub.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_SAMA5_OHCI
+static int ohci_waiter(int argc, char *argv[])
+{
+ return usbhost_waiter(g_ohci);
+}
+#endif
+
+/************************************************************************************
+ * Name: ehci_waiter
+ *
+ * Description:
+ * Wait for USB devices to be connected to the EHCI hub.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_SAMA5_EHCI
+static int ehci_waiter(int argc, char *argv[])
+{
+ return usbhost_waiter(g_ehci);
+}
+#endif
+
+/************************************************************************************
* Public Functions
************************************************************************************/
@@ -129,15 +164,93 @@ static int usbhost_waiter(int argc, char *argv[])
*
* Description:
* Called from sam_usbinitialize very early in inialization to setup USB-related
- * GPIO pins for the STM32F4Discovery board.
+ * GPIO pins for the SAMA5D3x-EK board.
+ *
+ * USB Ports
+ * The SAMA5D3 series-MB features three USB communication ports:
+ *
+ * 1. Port A Host High Speed (EHCI) and Full Speed (OHCI) multiplexed with
+ * USB Device High Speed Micro AB connector, J20
+ *
+ * 2. Port B Host High Speed (EHCI) and Full Speed (OHCI) standard type A
+ * connector, J19 upper port
+ *
+ * 3. Port C Host Full Speed (OHCI) only standard type A connector, J19
+ * lower port
+ *
+ * All three USB host ports are equipped with 500 mA high-side power switch
+ * for self-powered and buspowered applications. The USB device port feature
+ * VBUS inserts detection function.
+ *
+ * Port A
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD29 VBUS_SENSE VBus detection
+ * PD25 EN5V_USBA VBus power enable (via MN15 AIC1526 Dual USB High-Side
+ * Power Switch. The other channel of the switch is for
+ * the LCD)
+ *
+ * Port B
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD26 EN5V_USBB VBus power enable (via MN14 AIC1526 Dual USB High-Side
+ * Power Switch). To the A1 pin of J19 Dual USB A
+ * connector
+ *
+ * Port C
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD27 EN5V_USBC VBus power enable (via MN14 AIC1526 Dual USB High-Side
+ * Power Switch). To the B1 pin of J19 Dual USB A
+ * connector
+ *
+ * Both Ports B and C
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD28 OVCUR_USB Combined overrcurrent indication from port A and B
+ *
+ * That offers a lot of flexibility. However, here we enable the ports only
+ * as follows:
+ *
+ * Port A -- USB device
+ * Port B -- EHCI host
+ * Port C -- OHCI host
*
************************************************************************************/
void weak_function sam_usbinitialize(void)
{
- /* Configure pull-ups */
+#if 0
+ /* Configure Port A to support the USB device function */
+
+ sam_configpio(PIO_USBA_VBUS_SENSE); /* VBUS sense */
+
+ /* TODO: Configure an interrupt on VBUS sense */
+#endif
+
+#ifdef CONFIG_SAMA5_OHCI
+ /* Configure Port C to support the USB OHCI function */
+
+ sam_configpio(PIO_USBC_VBUS_ENABLE); /* VBUS enable, initially OFF */
+
+#endif
- /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent PIOs */
+#ifdef CONFIG_SAMA5_EHCI
+ /* Configure Port B to support the USB OHCI function */
+
+ sam_configpio(PIO_USBB_VBUS_ENABLE); /* VBUS enable, initially OFF */
+
+#endif
+
+#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI)
+ /* Configure Port B/C VBUS overrcurrent detection */
+
+ sam_configpio(PIO_USBBC_VBUS_OVERCURRENT); /* VBUS overcurrent */
+#endif
}
/***********************************************************************************
@@ -150,7 +263,7 @@ void weak_function sam_usbinitialize(void)
*
***********************************************************************************/
-#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI)
+#if HAVE_USBHOST
int sam_usbhost_initialize(void)
{
int pid;
@@ -160,30 +273,55 @@ int sam_usbhost_initialize(void)
* that we care about:
*/
- uvdbg("Register class drivers\n");
ret = usbhost_storageinit();
if (ret != OK)
{
- udbg("Failed to register the mass storage class\n");
+ udbg("ERROR: Failed to register the mass storage class: %d\n", ret);
+ }
+
+#ifdef CONFIG_SAMA5_OHCI
+ /* Get an instance of the USB OHCI interface */
+
+ g_ohci = sam_ohci_initialize(0);
+ if (!g_ohci)
+ {
+ udbg("ERROR: sam_ohci_initialize failed\n");
+ return -ENODEV;
}
- /* Then get an instance of the USB host interface */
+ /* Start a thread to handle device connection. */
- uvdbg("Initialize USB host\n");
- g_drvr = sam_ohci_initialize(0);
- if (g_drvr)
+ pid = TASK_CREATE("usbhost", CONFIG_USBHOST_DEFPRIO, CONFIG_USBHOST_STACKSIZE,
+ (main_t)ohci_waiter, (FAR char * const *)NULL);
+ if (pid < 0)
{
- /* Start a thread to handle device connection. */
+ udbg("ERROR: Failed to create ohci_waiter task: %d\n", ret);
+ return -ENODEV;
+ }
+#endif
- uvdbg("Start usbhost_waiter\n");
+#ifdef CONFIG_SAMA5_EHCI
+ /* Get an instance of the USB EHCI interface */
- pid = TASK_CREATE("usbhost", CONFIG_USBHOST_DEFPRIO,
- CONFIG_USBHOST_STACKSIZE,
- (main_t)usbhost_waiter, (FAR char * const *)NULL);
- return pid < 0 ? -ENOEXEC : OK;
+ g_ehci = sam_ehci_initialize(0);
+ if (!g_ehci)
+ {
+ udbg("ERROR: sam_ehci_initialize failed\n");
+ return -ENODEV;
}
- return -ENODEV;
+ /* Start a thread to handle device connection. */
+
+ pid = TASK_CREATE("usbhost", CONFIG_USBHOST_DEFPRIO, CONFIG_USBHOST_STACKSIZE,
+ (main_t)ehci_waiter, (FAR char * const *)NULL);
+ if (pid < 0)
+ {
+ udbg("ERROR: Failed to create ehci_waiter task: %d\n", ret);
+ return -ENODEV;
+ }
+#endif
+
+ return OK;
}
#endif
@@ -191,21 +329,13 @@ int sam_usbhost_initialize(void)
* 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."
+ * Enable/disable driving of VBUS 5V output. This function must be provided by
+ * each platform that implements the OHCI or EHCI host interface
*
* Input Parameters:
- * iface - For future growth to handle multiple USB host interface. Should be zero.
+ * iface - Selects USB host interface:
+ * 0 = EHCI (Port B)
+ * 1 = OHCI (Port C)
* enable - true: enable VBUS power; false: disable VBUS power
*
* Returned Value:
@@ -213,18 +343,49 @@ int sam_usbhost_initialize(void)
*
***********************************************************************************/
-#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI)
+#if HAVE_USBHOST
void sam_usbhost_vbusdrive(int iface, bool enable)
{
- DEBUGASSERT(iface == 0);
-
+ pio_pinset_t pinset;
+
+ /* Pick the PIO associated with the OHCI or EHCI interface */
+
+#ifdef CONFIG_SAMA5_OHCI
+ if (iface == SAM_OHCI_IFACE)
+ {
+ uvdbg("OHCI: iface %d enable %d\n", iface, enable);
+ pinset = PIO_USBC_VBUS_ENABLE;
+ }
+ else
+#endif
+
+#ifdef CONFIG_SAMA5_EHCI
+ if (iface == SAM_EHCI_IFACE)
+ {
+ uvdbg("EHCI: iface %d enable %d\n", iface, enable);
+ pinset = PIO_USBB_VBUS_ENABLE;
+ }
+ else
+#endif
+
+ {
+ udbg("ERROR: Unsupported iface %d\n", iface);
+ return;
+ }
+
+ /* Then enable or disable VBUS power */
+
if (enable)
{
/* Enable the Power Switch by driving the enable pin low */
+
+ sam_piowrite(pinset, false);
}
else
- {
+ {
/* Disable the Power Switch by driving the enable pin high */
+
+ sam_piowrite(pinset, false);
}
}
#endif
@@ -244,9 +405,14 @@ void sam_usbhost_vbusdrive(int iface, bool enable)
*
************************************************************************************/
-#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI)
+#if HAVE_USBHOST
xcpt_t sam_setup_overcurrent(xcpt_t handler)
{
+ /* Since this is a common signal, we will need to come up with some way to inform
+ * both EHCI and OHCI drivers when this error occurs.
+ */
+
+# warning Missing logic
return NULL;
}
#endif
diff --git a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
index 76bd78808..0cf87b2e4 100644
--- a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
+++ b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
@@ -57,6 +57,7 @@
#define HAVE_HSMCI_MTD 1
#define HAVE_AT25_MTD 1
+#define HAVE_USBHOST 1
/* HSMCI */
/* Can't support MMC/SD if the card interface(s) are not enable */
@@ -141,6 +142,10 @@
# undef CONFIG_SAMA5_EHCI
#endif
+#if !defined(CONFIG_SAMA5_OHCI) && !defined(CONFIG_SAMA5_EHCI)
+# undef HAVE_USBHOST
+#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
@@ -225,6 +230,81 @@
PIO_INT_BOTHEDGES | PIO_PORT_PIOD | PIO_PIN18)
#define IRQ_MCI1_CD SAM_IRQ_PD18
+/* USB Ports ************************************************************************/
+/* The SAMA5D3 series-MB features three USB communication ports:
+ *
+ * 1. Port A Host High Speed (EHCI) and Full Speed (OHCI) multiplexed with
+ * USB Device High Speed Micro AB connector, J20
+ *
+ * 2. Port B Host High Speed (EHCI) and Full Speed (OHCI) standard type A
+ * connector, J19 upper port
+ *
+ * 3. Port C Host Full Speed (OHCI) only standard type A connector, J19
+ * lower port
+ *
+ * All three USB host ports are equipped with 500 mA high-side power switch
+ * for self-powered and buspowered applications. The USB device port feature
+ * VBUS inserts detection function.
+ *
+ * Port A
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD29 VBUS_SENSE VBus detection
+ * PD25 EN5V_USBA VBus power enable (via MN15 AIC1526 Dual USB High-Side
+ * Power Switch. The other channel of the switch is for
+ * the LCD)
+ */
+
+#define PIO_USBA_VBUS_SENSE \
+ (PIO_INPUT | PIO_CFG_PULLUP | PIO_CFG_DEGLITCH | \
+ PIO_INT_BOTHEDGES | PIO_PORT_PIOD | PIO_PIN29)
+#define IRQ_USBA_VBUS_SENSE \
+ SAM_IRQ_PD29
+
+#define PIO_USBA_VBUS_ENABLE \
+ (PIO_OUTPUT | PIO_CFG_DEFAULT | PIO_OUTPUT_CLEAR | \
+ PIO_PORT_PIOD | PIO_PIN25)
+
+/* Port B
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD26 EN5V_USBB VBus power enable (via MN14 AIC1526 Dual USB High-Side
+ * Power Switch). To the A1 pin of J19 Dual USB A
+ * connector
+ */
+
+#define PIO_USBB_VBUS_ENABLE \
+ (PIO_OUTPUT | PIO_CFG_DEFAULT | PIO_OUTPUT_CLEAR | \
+ PIO_PORT_PIOD | PIO_PIN26)
+
+/* Port C
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD27 EN5V_USBC VBus power enable (via MN14 AIC1526 Dual USB High-Side
+ * Power Switch). To the B1 pin of J19 Dual USB A
+ * connector
+ */
+
+#define PIO_USBC_VBUS_ENABLE \
+ (PIO_OUTPUT | PIO_CFG_DEFAULT | PIO_OUTPUT_CLEAR | \
+ PIO_PORT_PIOD | PIO_PIN27)
+
+/* Both Ports B and C
+ *
+ * PIO Signal Name Function
+ * ---- ----------- -------------------------------------------------------
+ * PD28 OVCUR_USB Combined overrcurrent indication from port A and B
+ */
+
+#define PIO_USBBC_VBUS_OVERCURRENT \
+ (PIO_INPUT | PIO_CFG_PULLUP | PIO_CFG_DEGLITCH | \
+ PIO_INT_BOTHEDGES | PIO_PORT_PIOD | PIO_PIN28)
+#define IRQ_USBBC_VBUS_OVERCURRENT \
+ SAM_IRQ_PD28
+
/* SPI Chip Selects *****************************************************************/
/* Both the Ronetix and Embest versions of the SAMAD3x CPU modules include an
* Atmel AT25DF321A, 32-megabit, 2.7-volt SPI serial flash. The SPI
@@ -379,7 +459,7 @@ void weak_function sam_usbinitialize(void);
*
****************************************************************************************************/
-#if defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI)
+#ifdef HAVE_USBHOST
int sam_usbhost_initialize(void);
#endif