summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-01-12 04:03:27 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-01-12 04:03:27 +0000
commit2894a818b0ddd256bd74232c8cd7f2bc226530c7 (patch)
treeb8ae1cb44879b7f9f95bcc0e7c2b40153f253e45 /nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
parentcd909fc9cfe7d728c3b6a3c91d5cf3a1a2eb88b6 (diff)
downloadpx4-nuttx-2894a818b0ddd256bd74232c8cd7f2bc226530c7.tar.gz
px4-nuttx-2894a818b0ddd256bd74232c8cd7f2bc226530c7.tar.bz2
px4-nuttx-2894a818b0ddd256bd74232c8cd7f2bc226530c7.zip
Add support for lowspeed devices
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3244 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c')
-rwxr-xr-xnuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
index 917ecd2e5..3968a7027 100755
--- a/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
@@ -156,6 +156,7 @@ struct lpc17_usbhost_s
volatile uint8_t tdstatus; /* TD control status bits from last Writeback Done Head event */
volatile bool connected; /* Connected to device */
+ volatile bool lowspeed; /* Low speed device attached. */
volatile bool rhswait; /* TRUE: Thread is waiting for Root Hub Status change */
volatile bool wdhwait; /* TRUE: Thread is waiting for WDH interrupt */
sem_t rhssem; /* Semaphore to wait Writeback Done Head event */
@@ -739,10 +740,12 @@ static int lpc17_usbinterrupt(int irq, FAR void *context)
else
{
- /* Check if we are now connected */
+ /* Check current connect status */
if ((rhportst1 & OHCI_RHPORTST_CCS) != 0)
{
+ /* Connected ... Did we just become connected? */
+
if (!priv->connected)
{
/* Yes.. connected. */
@@ -763,6 +766,13 @@ static int lpc17_usbinterrupt(int irq, FAR void *context)
{
ulldbg("Spurious status change (connected)\n");
}
+
+ /* The LSDA (Low speed device attached) bit is valid
+ * when CCS == 1.
+ */
+
+ priv->lowspeed = (rhportst1 & OHCI_RHPORTST_LSDA) != 0;
+ ullvdbg("Speed:%s\n", priv->lowspeed ? "LOW" : "FULL");
}
/* Check if we are now disconnected */
@@ -773,6 +783,7 @@ static int lpc17_usbinterrupt(int irq, FAR void *context)
ullvdbg("Disconnected\n");
priv->connected = false;
+ priv->lowspeed = false;
/* Are we bound to a class instance? */
@@ -1028,9 +1039,19 @@ static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr)
static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
uint16_t maxpacketsize)
{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
+
DEBUGASSERT(drvr && funcaddr < 128 && maxpacketsize < 2048);
+
EDCTRL->ctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT |
(uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT;
+
+ if (priv->lowspeed)
+ {
+ EDCTRL->ctrl |= ED_CONTROL_S;
+ }
+
+ uvdbg("EP0 CTRL:%08x\n", EDCTRL->ctrl);
return OK;
}
@@ -1059,10 +1080,15 @@ static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep)
{
+ struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
struct ohci_ed_s *ed;
int ret = -ENOMEM;
- DEBUGASSERT(epdesc && ep);
+ /* Sanity check. NOTE that this method should only be called if a device is
+ * connected (because we need a valid low speed indication).
+ */
+
+ DEBUGASSERT(priv && epdesc && ep && priv->connected);
/* Take the next ED from the beginning of the free list */
@@ -1091,6 +1117,14 @@ static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
ed->ctrl |= ED_CONTROL_D_OUT;
}
+ /* Check for a low-speed device */
+
+ if (priv->lowspeed)
+ {
+ ed->ctrl |= ED_CONTROL_S;
+ }
+ uvdbg("EP%d CTRL:%08x\n", epdesc->addr, ed->ctrl);
+
/* Return an opaque reference to the ED */
*ep = (usbhost_ep_t)ed;