diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index cdc4db1d3b93e3a1b09c756077b509d390f4cf7a..adc0041f980827a1b4ab516e58e0e4259711b54f 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -12,7 +12,7 @@ <h1><big><font color="#3c34ec"> <i>NuttX RTOS Porting Guide</i> </font></big></h1> - <p>Last Updated: December 22, 2010</p> + <p>Last Updated: December 29, 2010</p> </td> </tr> </table> @@ -3219,6 +3219,12 @@ build <li> <code>CONFIG_USBHOST</code>: Enables USB host support </li> + <li> + <code>CONFIG_USBHOST_HAVERHSC</code>: + Define if the hardware is able to detect a root hub status change when a device is inserted. + If <code>CONFIG_USBHOST_HAVERHSC</code> is not set, then it is assumed that the hardware cannot detect the presence of a USB device + and that the application must periodically attempt to enumerate the device. + </li> <li> <code>CONFIG_USBHOST_NPREALLOC</code>: Number of pre-allocated class instances </li> diff --git a/arch/arm/src/lpc17xx/lpc17_internal.h b/arch/arm/src/lpc17xx/lpc17_internal.h index 2c684767c87199d9290cd62d29a83e34988f2065..f2b15bbd3501baab14a5f12a80e5207367e4f3d4 100755 --- a/arch/arm/src/lpc17xx/lpc17_internal.h +++ b/arch/arm/src/lpc17xx/lpc17_internal.h @@ -274,7 +274,7 @@ #define GPIO_PWM1p3_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) #define GPIO_SSP0_SSEL_2 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN21) #define GPIO_MCPWM_MCOB0 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) -#define GPIO_USB_PWRD (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) +#define GPIO_USB_PWRD (GPIO_ALT2 | GPIO_PULLDN | GPIO_PORT1 | GPIO_PIN22) #define GPIO_MAT1p0 (GPIO_ALT3 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN22) #define GPIO_MCPWM_MCI1 (GPIO_ALT1 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) #define GPIO_PWM1p4_1 (GPIO_ALT2 | GPIO_PULLUP | GPIO_PORT1 | GPIO_PIN23) diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index 5d1ae17275c05937a427b722a341d38281278de2..1d3877ed01c3b0f507ac33cd8dd81ff95e62e47c 100755 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -55,13 +55,14 @@ #include <nuttx/usb/usbhost.h> #include <arch/irq.h> -#include <arch/board/board.h> + +#include "lpc17_internal.h" /* Includes default GPIO settings */ +#include <arch/board/board.h> /* May redefine GPIO settings */ #include "chip.h" #include "up_arch.h" #include "up_internal.h" -#include "lpc17_internal.h" #include "lpc17_usb.h" #include "lpc17_syscon.h" #include "lpc17_ohciram.h" @@ -700,7 +701,7 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) intstatus = lpc17_getreg(LPC17_USBHOST_INTST); intenable = lpc17_getreg(LPC17_USBHOST_INTEN); - ullvdbg("INST: %08x INTEN:\n", intstatus, intenable); + ullvdbg("INST: %08x INTEN: %08x\n", intstatus, intenable); intstatus &= intenable; if (intstatus != 0) @@ -715,7 +716,7 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) if ((rhportst1 & OHCI_RHPORTST_CSC) != 0) { uint32_t rhstatus = lpc17_getreg(LPC17_USBHOST_RHSTATUS); - ullvdbg("Connect Status Change, RHSTATUS: %08x\n", rhportst1); + ullvdbg("Connect Status Change, RHSTATUS: %08x\n", rhstatus); /* If DRWE is set, Connect Status Change indicates a remote wake-up event */ @@ -735,10 +736,12 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) if (!priv->connected) { ullvdbg("Connected\n"); - DEBUGASSERT(priv->rhssem.semcount <= 0); priv->tdstatus = 0; priv->connected = true; +#ifdef CONFIG_USBHOST_HAVERHSC + DEBUGASSERT(priv->rhssem.semcount <= 0); lpc17_givesem(&priv->rhssem); +#endif } else { @@ -764,6 +767,8 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) CLASS_DISCONNECTED(priv->class); } + + DEBUGASSERT(priv->rhssem.semcount <= 0); lpc17_givesem(&priv->rhssem); } else @@ -841,6 +846,7 @@ static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected) { struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; +#ifdef CONFIG_USBHOST_HAVERHSC /* Are we already connected? */ while (priv->connected == connected) @@ -849,7 +855,19 @@ static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected) lpc17_takesem(&priv->rhssem); } +#else + if (!connected) + { + /* Are we already connected? */ + while (priv->connected) + { + /* Yes... wait for the disconnection */ + + lpc17_takesem(&priv->rhssem); + } + } +#endif return OK; } @@ -889,6 +907,7 @@ static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr) * method first to be assured that a device is connected. */ +#ifdef CONFIG_USBHOST_HAVERHSC while (!priv->connected) { /* No, return an error */ @@ -896,6 +915,7 @@ static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr) udbg("Not connected\n"); return -ENODEV; } +#endif /* USB 2.0 spec says at least 50ms delay before port reset */ diff --git a/configs/README.txt b/configs/README.txt index e2b725c908756e24986b9a900351745bd41d2cbf..6b5bcc49f1f60bf13e195621a3dedf21ee1df24c 100644 --- a/configs/README.txt +++ b/configs/README.txt @@ -706,6 +706,12 @@ defconfig -- This is a configuration file similar to the Linux USB host controller driver CONFIG_USBHOST Enables USB host support + CONFIG_USBHOST_HAVERHSC + Define if the hardware is able to detect a root hub status change + when a device is inserted. If CONFIG_USBHOST_HAVERHSC is not set, + then it is assumed that the hardware cannot detect the presence + of a USB device and that the application must periodically attempt + to enumerate the device. CONFIG_USBHOST_NPREALLOC Number of pre-allocated class instances diff --git a/configs/nucleus2g/src/up_nsh.c b/configs/nucleus2g/src/up_nsh.c index 301057be0c1ade50c3a7142298114136412a643f..8082b6e974b7938816cfe92e5778d9c909f229d4 100755 --- a/configs/nucleus2g/src/up_nsh.c +++ b/configs/nucleus2g/src/up_nsh.c @@ -41,6 +41,7 @@ #include <nuttx/config.h> #include <stdio.h> +#include <unistd.h> #include <debug.h> #include <errno.h> @@ -171,6 +172,7 @@ static int nsh_waiter(int argc, char *argv[]) message("nsh_waiter: Running\n"); for (;;) { +#ifdef CONFIG_USBHOST_HAVERHSC /* Wait for the device to change state */ ret = DRVR_WAIT(g_drvr, connected); @@ -187,6 +189,39 @@ static int nsh_waiter(int argc, char *argv[]) (void)DRVR_ENUMERATE(g_drvr); } +#else + /* Is the device connected? */ + + if (connected) + { + /* Yes.. wait for the disconnect event */ + + ret = DRVR_WAIT(g_drvr, false); + DEBUGASSERT(ret == OK); + + connected = false; + message("nsh_waiter: Not connected\n"); + } + else + { + /* Wait a bit */ + + sleep(2); + + /* Try to enumerate the device */ + + uvdbg("nsh_usbhostinitialize: Enumerate device\n"); + ret = DRVR_ENUMERATE(g_drvr); + if (ret != OK) + { + uvdbg("nsh_usbhostinitialize: Enumeration failed: %d\n", ret); + } + else + { + message("nsh_usbhostinitialize: Connected\n"); + } + } +#endif } /* Keep the compiler from complaining */ @@ -210,6 +245,7 @@ static int nsh_usbhostinitialize(void) /* First, get an instance of the USB host interface */ + message("nsh_usbhostinitialize: Initialize USB host\n"); g_drvr = usbhost_initialize(0); if (g_drvr) { diff --git a/configs/olimex-lpc1766stk/include/board.h b/configs/olimex-lpc1766stk/include/board.h index 6d6212644ba2cc3cd5eeecd13381fa6a5bddd3c4..275714da0cf19e8388e08e4949d389583fe769be 100755 --- a/configs/olimex-lpc1766stk/include/board.h +++ b/configs/olimex-lpc1766stk/include/board.h @@ -225,6 +225,29 @@ * P2[9]/USB_CONNECT/RXD2 64 USBD_CONNECT */ +#ifdef GPIO_USB_PPWR /* We can only redefine this if they have been defined */ + +/* The Olimex LPC1766-STK has 10K pull-ups on PPWR and OVRCR and a 100k + * pull-down on PWRD so we should make sure that the outputs float. + */ + +# undef GPIO_USB_PPWR +# define GPIO_USB_PPWR (GPIO_ALT2 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN19) +# undef GPIO_USB_OVRCR +# define GPIO_USB_OVRCR (GPIO_ALT2 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN27) +# undef GPIO_USB_PWRD +# define GPIO_USB_PWRD (GPIO_ALT2 | GPIO_FLOAT | GPIO_PORT1 | GPIO_PIN22) + +/* In host mode (only) there are also 15K pull-downs on D+ and D- */ + +# ifdef CONFIG_USBHOST +# undef GPIO_USB_DP +# define GPIO_USB_DP (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT0 | GPIO_PIN29) +# undef GPIO_USB_DM +# define GPIO_USB_DM (GPIO_ALT1 | GPIO_FLOAT | GPIO_PORT0 | GPIO_PIN30) +# endif +#endif + /* Ethernet GPIO PIN SIGNAL NAME * -------------------------------- ---- -------------- * P1[0]/ENET_TXD0 95 E_TXD0 diff --git a/configs/olimex-lpc1766stk/src/up_nsh.c b/configs/olimex-lpc1766stk/src/up_nsh.c index 62b470400a5049d9879da71cb19102a4427d678a..3a3bd4d975cb46aa4abce6b037548f8df48ceac0 100755 --- a/configs/olimex-lpc1766stk/src/up_nsh.c +++ b/configs/olimex-lpc1766stk/src/up_nsh.c @@ -41,6 +41,7 @@ #include <nuttx/config.h> #include <stdio.h> +#include <unistd.h> #include <debug.h> #include <errno.h> @@ -164,6 +165,7 @@ static int nsh_waiter(int argc, char *argv[]) message("nsh_waiter: Running\n"); for (;;) { +#ifdef CONFIG_USBHOST_HAVERHSC /* Wait for the device to change state */ ret = DRVR_WAIT(g_drvr, connected); @@ -180,6 +182,39 @@ static int nsh_waiter(int argc, char *argv[]) (void)DRVR_ENUMERATE(g_drvr); } +#else + /* Is the device connected? */ + + if (connected) + { + /* Yes.. wait for the disconnect event */ + + ret = DRVR_WAIT(g_drvr, false); + DEBUGASSERT(ret == OK); + + connected = false; + message("nsh_waiter: Not connected\n"); + } + else + { + /* Wait a bit */ + + sleep(2); + + /* Try to enumerate the device */ + + uvdbg("nsh_usbhostinitialize: Enumerate device\n"); + ret = DRVR_ENUMERATE(g_drvr); + if (ret != OK) + { + uvdbg("nsh_usbhostinitialize: Enumeration failed: %d\n", ret); + } + else + { + message("nsh_usbhostinitialize: Connected\n"); + } + } +#endif } /* Keep the compiler from complaining */ @@ -263,6 +298,7 @@ static int nsh_usbhostinitialize(void) /* First, get an instance of the USB host interface */ + message("nsh_usbhostinitialize: Initialize USB host\n"); g_drvr = usbhost_initialize(0); if (g_drvr) { diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h index 18753e1b8a255866a880499ccea8ef0bed77b308..b1c211cc44e6b10c2d38ff3449a20abdfbce72e9 100644 --- a/include/nuttx/usb/usbhost.h +++ b/include/nuttx/usb/usbhost.h @@ -444,7 +444,7 @@ struct usbhost_class_s struct usbhost_epdesc_s; struct usbhost_driver_s { - /* Wait for a device to connect or disconnect. */ + /* Wait for a device to connect or disconnect (see CONFIG_USBHOST_HAVERHSC). */ int (*wait)(FAR struct usbhost_driver_s *drvr, bool connected);