diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index adc0041f980827a1b4ab516e58e0e4259711b54f..e04000f7860d68bbfbf011329c967301b6c41a56 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -3219,12 +3219,6 @@ 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_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index 1d3877ed01c3b0f507ac33cd8dd81ff95e62e47c..e4d905a0707d8a1595b623d4bc60f890f17d7f74 100755 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -82,10 +82,12 @@ # error "No IO buffers allocated" #endif -/* Frame Interval */ +/* Frame Interval / Periodic Start */ #define FI (12000-1) /* 12000 bits per frame (-1) */ -#define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI) +#define FSMPS ((6 * (FI - 210)) / 7) +#define DEFAULT_FMINTERVAL ((FSMPS << OHCI_FMINT_FSMPS_SHIFT) | FI) +#define DEFAULT_PERSTART ((9 * FI) / 10) /* CLKCTRL enable bits */ @@ -279,7 +281,7 @@ static struct lpc17_usbhost_s g_usbhost = { .drvr = { - .wait = lpc17_wait, + .wait = lpc17_wait, .enumerate = lpc17_enumerate, .ep0configure = lpc17_ep0configure, .alloc = lpc17_alloc, @@ -676,6 +678,7 @@ static int lpc17_ctrltd(struct lpc17_usbhost_s *priv, uint32_t dirpid, } else { + uvdbg("Bad TD completion status: %d\n", priv->tdstatus); return -EIO; } } @@ -735,13 +738,15 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) { if (!priv->connected) { + /* Yes.. connected. */ + ullvdbg("Connected\n"); priv->tdstatus = 0; + + /* Notify any waiters */ + priv->connected = true; -#ifdef CONFIG_USBHOST_HAVERHSC - DEBUGASSERT(priv->rhssem.semcount <= 0); lpc17_givesem(&priv->rhssem); -#endif } else { @@ -756,7 +761,6 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) /* Yes.. disable interrupts and disconnect the device */ ullvdbg("Disconnected\n"); - lpc17_putreg(0, LPC17_USBHOST_INTEN); priv->connected = false; /* Are we bound to a class instance? */ @@ -768,7 +772,8 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) CLASS_DISCONNECTED(priv->class); } - DEBUGASSERT(priv->rhssem.semcount <= 0); + /* Notify any waiters */ + lpc17_givesem(&priv->rhssem); } else @@ -846,7 +851,6 @@ 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) @@ -855,19 +859,7 @@ 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; } @@ -907,21 +899,19 @@ 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 */ udbg("Not connected\n"); - return -ENODEV; + return -ENODEV; } -#endif /* USB 2.0 spec says at least 50ms delay before port reset */ up_mdelay(100); - /* Put the RH port in reset */ + /* Put RH port 1 in reset (the LPC176x supports only a single downstream port) */ lpc17_putreg(OHCI_RHPORTST_PRS, LPC17_USBHOST_RHPORTST1); @@ -929,7 +919,7 @@ static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr) while ((lpc17_getreg(LPC17_USBHOST_RHPORTST1) & OHCI_RHPORTST_PRS) != 0); - /* Release the RH port from reset and wait a bit */ + /* Release RH port 1 from reset and wait a bit */ lpc17_putreg(OHCI_RHPORTST_PRSC, LPC17_USBHOST_RHPORTST1); up_mdelay(200); @@ -1091,6 +1081,11 @@ static int lpc17_ctrlin(FAR struct usbhost_driver_s *drvr, uint16_t len; int ret; + DEBUGASSERT(drvr && req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + len = lpc17_getle16(req->len); ret = lpc17_ctrltd(priv, GTD_STATUS_DP_SETUP, (uint8_t*)req, USB_SIZEOF_CTRLREQ); if (ret == OK) @@ -1116,6 +1111,11 @@ static int lpc17_ctrlout(FAR struct usbhost_driver_s *drvr, uint16_t len; int ret; + DEBUGASSERT(drvr && req); + uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + len = lpc17_getle16(req->len); ret = lpc17_ctrltd(priv, GTD_STATUS_DP_SETUP, (uint8_t*)req, USB_SIZEOF_CTRLREQ); if (ret == OK) @@ -1429,7 +1429,7 @@ FAR struct usbhost_driver_s *usbhost_initialize(int controller) * 10: reserved * 11: U1=host, U2=device * - * We need only select U1=host (Bit 0=1); + * We need only select U1=host (Bit 0=1, Bit 1 is not used on LPC176x); * NOTE: The PORTSEL clock needs to be enabled when accessing OTGSTCTRL */ @@ -1504,9 +1504,12 @@ FAR struct usbhost_driver_s *usbhost_initialize(int controller) lpc17_putreg(OHCI_CMDST_HCR, LPC17_USBHOST_CMDST); - /* Write Fm interval and largest data packet counter */ + /* Write Fm interval (FI), largest data packet counter (FSMPS), and + * periodic start. + */ lpc17_putreg(DEFAULT_FMINTERVAL, LPC17_USBHOST_FMINT); + lpc17_putreg(DEFAULT_PERSTART, LPC17_USBHOST_PERSTART); /* Put HC in operational state */ @@ -1515,9 +1518,9 @@ FAR struct usbhost_driver_s *usbhost_initialize(int controller) regval |= OHCI_CTRL_HCFS_OPER; lpc17_putreg(regval, LPC17_USBHOST_CTRL); - /* Set global power */ + /* Set global power in HcRhStatus */ - lpc17_putreg(OHCI_RHSTATUS_LPS, LPC17_USBHOST_RHSTATUS); + lpc17_putreg(OHCI_RHSTATUS_SGP, LPC17_USBHOST_RHSTATUS); /* Set HCCA base address */ diff --git a/configs/README.txt b/configs/README.txt index 6b5bcc49f1f60bf13e195621a3dedf21ee1df24c..e2b725c908756e24986b9a900351745bd41d2cbf 100644 --- a/configs/README.txt +++ b/configs/README.txt @@ -706,12 +706,6 @@ 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 8082b6e974b7938816cfe92e5778d9c909f229d4..d65516e185b9f1d40b6b36982d0afb70a5780764 100755 --- a/configs/nucleus2g/src/up_nsh.c +++ b/configs/nucleus2g/src/up_nsh.c @@ -172,7 +172,6 @@ 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); @@ -189,39 +188,6 @@ 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 */ diff --git a/configs/olimex-lpc1766stk/src/up_nsh.c b/configs/olimex-lpc1766stk/src/up_nsh.c index 3a3bd4d975cb46aa4abce6b037548f8df48ceac0..0d59dc4fa103261d526e449fa175770399e6ac55 100755 --- a/configs/olimex-lpc1766stk/src/up_nsh.c +++ b/configs/olimex-lpc1766stk/src/up_nsh.c @@ -165,7 +165,6 @@ 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); @@ -182,39 +181,6 @@ 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 */ diff --git a/include/nuttx/usb/ohci.h b/include/nuttx/usb/ohci.h index cb96bc2c3475287872464f4c59421091eb48056b..f24e97811d6410da70086e37807bf60dfb9525a6 100755 --- a/include/nuttx/usb/ohci.h +++ b/include/nuttx/usb/ohci.h @@ -226,26 +226,19 @@ /* HcRhStatus: Root hub status (7.4.3) */ -#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status */ +#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status (read)*/ +#define OHCI_RHSTATUS_CGP (1 << 0) /* Bit 0: Clear global power (write)*/ #define OHCI_RHSTATUS_OCI (1 << 1) /* Bit 1: Over current indicator */ /* Bits 2-14: Reserved */ #define OHCI_RHSTATUS_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */ -#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change */ +#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change (read) */ +#define OHCI_RHSTATUS_SGP (1 << 16) /* Bit 16: Set global power (write) */ #define OHCI_RHSTATUS_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */ /* Bits 18-30: Reserved */ #define OHCI_RHSTATUS_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */ /* HcRhPortStatus: Root hub port status (7.4.4) */ -#define OHCI_RHPORTST_LPS (1 << 0) /* Bit 0: Local power status */ -#define OHCI_RHPORTST_OCI (1 << 1) /* Bit 1: Over current indicator */ - /* Bits 2-14: Reserved */ -#define OHCI_RHPORTST_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */ -#define OHCI_RHPORTST_LPSC (1 << 16) /* Bit 16: Local power status change */ -#define OHCI_RHPORTST_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */ - /* Bits 18-30: Reserved */ -#define OHCI_RHPORTST_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */ - #define OHCI_RHPORTST_CCS (1 << 0) /* Bit 0: Current connect status */ #define OHCI_RHPORTST_PES (1 << 1) /* Bit 1: Port enable status*/ #define OHCI_RHPORTST_PSS (1 << 2) /* Bit 2: Port suspend status */ diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h index b1c211cc44e6b10c2d38ff3449a20abdfbce72e9..18753e1b8a255866a880499ccea8ef0bed77b308 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 (see CONFIG_USBHOST_HAVERHSC). */ + /* Wait for a device to connect or disconnect. */ int (*wait)(FAR struct usbhost_driver_s *drvr, bool connected);