summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xnuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h23
-rwxr-xr-xnuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c131
-rw-r--r--nuttx/drivers/usbhost/usbhost_hidkbd.c4
-rw-r--r--nuttx/drivers/usbhost/usbhost_skeleton.c4
-rw-r--r--nuttx/drivers/usbhost/usbhost_storage.c4
-rw-r--r--nuttx/include/nuttx/usb/usbhost.h1
6 files changed, 85 insertions, 82 deletions
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h b/nuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h
index 0e9f81ecb..9cc76b2b4 100755
--- a/nuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_ohciram.h
@@ -112,10 +112,17 @@
#define LPC17_HCCA_SIZE 256
-/* Fixed endpoint and transfer descriptor sizes */
+/* Fixed transfer descriptor size */
#define LPC17_TD_SIZE 16
-#define LPC17_ED_SIZE 16
+
+/* Fixed endpoint descriptor size. The actual size required by the hardware is only
+ * 16 bytes, however, we set aside an additional 16 bytes for for internal use by
+ * the OHCI host driver. 16-bytes is set aside because the EDs must still be
+ * aligned to 16-byte boundaries.
+ */
+
+#define LPC17_ED_SIZE 32
/* Configurable number of user endpoint descriptors (EDs). This number excludes
* the control endpoint that is always allocated.
@@ -177,7 +184,7 @@
* CONFIG_USBHOST_IOBUFSIZE 512
*
* Sizes of things
- * LPC17_EDFREE_SIZE 48
+ * LPC17_EDFREE_SIZE 96 (including EP0)
* LPC17_TDFREE_SIZE 256
* LPC17_IOFREE_SIZE 512
*
@@ -192,12 +199,12 @@
* LPC17_TDHEAD_ADDR 0x2000bc00
* LPC17_TDTAIL_ADDR 0x2000bc10
* LPC17_EDCTRL_ADDR 0x2000bc20
- * LPC17_EDFREE_BASE 0x2000bc30
- * LPC17_TDFREE_BASE 0x2000bc50
- * LPC17_IOFREE_BASE 0x2000bd50
- * LPC17_IOBUFFERS (0x2000c000 - 0x2000bd50) / 512 = 688/512 = 1
+ * LPC17_EDFREE_BASE 0x2000bc40
+ * LPC17_TDFREE_BASE 0x2000bc80
+ * LPC17_IOFREE_BASE 0x2000bd80
+ * LPC17_IOBUFFERS (0x2000c000 - 0x2000bd80) / 512 = 640/512 = 1
*
- * Wasted memory: 688-512 = 176 bytes
+ * Wasted memory: 640-512 = 128 bytes
*/
#define LPC17_HCCA_BASE (LPC17_OHCIRAM_BASE)
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
index 3968a7027..fa99f097e 100755
--- a/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c
@@ -121,9 +121,9 @@
#define HCCA ((volatile struct ohci_hcca_s *)LPC17_HCCA_BASE)
#define TDHEAD ((volatile struct ohci_gtd_s *)LPC17_TDHEAD_ADDR)
#define TDTAIL ((volatile struct ohci_gtd_s *)LPC17_TDTAIL_ADDR)
-#define EDCTRL ((volatile struct ohci_ed_s *)LPC17_EDCTRL_ADDR)
+#define EDCTRL ((volatile struct lpc17_ed_s *)LPC17_EDCTRL_ADDR)
-#define EDFREE ((struct ohci_ed_s *)LPC17_EDFREE_BASE)
+#define EDFREE ((struct lpc17_ed_s *)LPC17_EDFREE_BASE)
#define TDFREE ((uint8_t *)LPC17_TDFREE_BASE)
#define IOFREE ((uint8_t *)LPC17_IOFREE_BASE)
@@ -156,25 +156,43 @@ 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 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 */
sem_t wdhsem; /* Semaphore used to wait for Writeback Done Head event */
};
+/* The OCHI expects the size of an endpoint descriptor to be 16 bytes.
+ * However, the size allocated for an endpoint descriptor is 32 bytes in
+ * lpc17_ohciram.h. This extra 16-bytes is used by the OHCI host driver in
+ * order to maintain additional endpoint-specific data.
+ */
+
+struct lpc17_ed_s
+{
+ /* Hardware specific fields */
+
+ struct ohci_ed_s hw;
+
+ /* Software specific fields */
+
+ uint8_t xfrtype; /* Transfer type. See SB_EP_ATTR_XFER_* in usb.h */
+ uint8_t pad[15];
+};
+
/* The following are used to manage lists of free EDs and TD buffers*/
struct lpc17_edlist_s
{
- struct lpc17_edlist_s *flink; /* Link to next ED in the list */
- uint32_t pad[3]; /* To make the same size as struct ohci_ed_s */
+ struct lpc17_edlist_s *flink; /* Link to next ED in the list */
+ uint32_t pad[7]; /* To make the same size as struct lpc17_ed_s */
};
struct lpc17_buflist_s
{
- struct lpc17_buflist_s *flink; /* Link to next buffer in the list */
- /* Variable length buffer data follows */
+ struct lpc17_buflist_s *flink; /* Link to next buffer in the list */
+ /* Variable length buffer data follows */
};
/*******************************************************************************
@@ -243,12 +261,6 @@ static int lpc17_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
FAR uint8_t *buffer, size_t buflen);
static void lpc17_disconnect(FAR struct usbhost_driver_s *drvr);
-/* Initializaion ***************************************************************/
-
-static void lpc17_tdinit(volatile struct ohci_gtd_s *td);
-static void lpc17_edinit(volatile struct ohci_ed_s *ed);
-static void lpc17_hccainit(volatile struct ohci_hcca_s *hcca);
-
/*******************************************************************************
* Private Data
*******************************************************************************/
@@ -650,7 +662,7 @@ static int lpc17_ctrltd(struct lpc17_usbhost_s *priv, uint32_t dirpid,
/* Then enqueue the transfer */
priv->tdstatus = TD_CC_NOERROR;
- lpc17_enqueuetd(EDCTRL, dirpid, toggle, buffer, buflen);
+ lpc17_enqueuetd(&EDCTRL->hw, dirpid, toggle, buffer, buflen);
/* Set the head of the control list to the EP0 EDCTRL (this would have to
* change if we want more than on control EP queued at a time).
@@ -1043,15 +1055,21 @@ static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
DEBUGASSERT(drvr && funcaddr < 128 && maxpacketsize < 2048);
- EDCTRL->ctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT |
- (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT;
+ /* Set the EP0 ED control word */
+
+ EDCTRL->hw.ctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT |
+ (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT;
if (priv->lowspeed)
{
- EDCTRL->ctrl |= ED_CONTROL_S;
+ EDCTRL->hw.ctrl |= ED_CONTROL_S;
}
- uvdbg("EP0 CTRL:%08x\n", EDCTRL->ctrl);
+ /* Set the transfer type to control */
+
+ EDCTRL->xfrtype = USB_EP_ATTR_XFER_CONTROL;
+
+ uvdbg("EP0 CTRL:%08x\n", EDCTRL->hw.ctrl);
return OK;
}
@@ -1081,7 +1099,7 @@ 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;
+ struct lpc17_ed_s *ed;
int ret = -ENOMEM;
/* Sanity check. NOTE that this method should only be called if a device is
@@ -1092,7 +1110,7 @@ static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
/* Take the next ED from the beginning of the free list */
- ed = (struct ohci_ed_s *)g_edfree;
+ ed = (struct lpc17_ed_s *)g_edfree;
if (ed)
{
/* Remove the ED from the freelist */
@@ -1101,29 +1119,33 @@ static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
/* Configure the endpoint descriptor. */
- lpc17_edinit(ed);
- ed->ctrl = (uint32_t)(epdesc->funcaddr) << ED_CONTROL_FA_SHIFT |
- (uint32_t)(epdesc->addr) << ED_CONTROL_EN_SHIFT |
- (uint32_t)(epdesc->mxpacketsize) << ED_CONTROL_MPS_SHIFT;
+ memset((void*)ed, 0, sizeof(struct lpc17_ed_s));
+ ed->hw.ctrl = (uint32_t)(epdesc->funcaddr) << ED_CONTROL_FA_SHIFT |
+ (uint32_t)(epdesc->addr) << ED_CONTROL_EN_SHIFT |
+ (uint32_t)(epdesc->mxpacketsize) << ED_CONTROL_MPS_SHIFT;
/* Get the direction of the endpoint */
if (epdesc->in != 0)
{
- ed->ctrl |= ED_CONTROL_D_IN;
+ ed->hw.ctrl |= ED_CONTROL_D_IN;
}
else
{
- ed->ctrl |= ED_CONTROL_D_OUT;
+ ed->hw.ctrl |= ED_CONTROL_D_OUT;
}
/* Check for a low-speed device */
if (priv->lowspeed)
{
- ed->ctrl |= ED_CONTROL_S;
+ ed->hw.ctrl |= ED_CONTROL_S;
}
- uvdbg("EP%d CTRL:%08x\n", epdesc->addr, ed->ctrl);
+ uvdbg("EP%d CTRL:%08x\n", epdesc->addr, ed->hw.ctrl);
+
+ /* Set the transfer type */
+
+ ed->xfrtype = epdesc->xfrtype;
/* Return an opaque reference to the ED */
@@ -1371,7 +1393,7 @@ static int lpc17_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
FAR uint8_t *buffer, size_t buflen)
{
struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
- struct ohci_ed_s *ed = (struct ohci_ed_s *)ep;
+ struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep;
uint32_t dirpid;
uint32_t regval;
#if LPC17_IOBUFFERS > 0
@@ -1382,12 +1404,12 @@ static int lpc17_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
DEBUGASSERT(priv && ed && buffer && buflen > 0);
- in = (ed->ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN;
+ in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN;
uvdbg("EP%d %s toggle:%d maxpacket:%d buflen:%d\n",
- (ed->ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT,
+ (ed->hw.ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT,
in ? "IN" : "OUT",
- (ed->headp & ED_HEADP_C) != 0 ? 1 : 0,
- (ed->ctrl & ED_CONTROL_MPS_MASK) >> ED_CONTROL_MPS_SHIFT,
+ (ed->hw.headp & ED_HEADP_C) != 0 ? 1 : 0,
+ (ed->hw.ctrl & ED_CONTROL_MPS_MASK) >> ED_CONTROL_MPS_SHIFT,
buflen);
/* Allocate an IO buffer if the user buffer does not lie in AHB SRAM */
@@ -1455,7 +1477,7 @@ static int lpc17_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
/* Then enqueue the transfer */
priv->tdstatus = TD_CC_NOERROR;
- lpc17_enqueuetd(ed, dirpid, GTD_STATUS_T_TOGGLE, buffer, buflen);
+ lpc17_enqueuetd(&ed->hw, dirpid, GTD_STATUS_T_TOGGLE, buffer, buflen);
/* Set the head of the bulk list to the EP descriptor (this would have to
* change if we want more than on bulk EP queued at a time).
@@ -1554,39 +1576,6 @@ static void lpc17_disconnect(FAR struct usbhost_driver_s *drvr)
}
/*******************************************************************************
- * Initialization
- *******************************************************************************/
-
-static void lpc17_tdinit(volatile struct ohci_gtd_s *td)
-{
- td->ctrl = 0;
- td->cbp = 0;
- td->nexttd = 0;
- td->be = 0;
-}
-
-static void lpc17_edinit(volatile struct ohci_ed_s *ed)
-{
- ed->ctrl = 0;
- ed->tailp = 0;
- ed->headp = 0;
- ed->nexted = 0;
-}
-
-static void lpc17_hccainit(volatile struct ohci_hcca_s *hcca)
-{
- int i;
-
- for (i = 0; i < 32; i++)
- {
- hcca->inttbl[i] = 0;
- }
-
- hcca->fmno = 0;
- hcca->donehead = 0;
-}
-
-/*******************************************************************************
* Public Functions
*******************************************************************************/
@@ -1689,10 +1678,10 @@ FAR struct usbhost_driver_s *usbhost_initialize(int controller)
/* Initialize all the TDs, EDs and HCCA to 0 */
- lpc17_hccainit(HCCA);
- lpc17_tdinit(TDHEAD);
- lpc17_tdinit(TDTAIL);
- lpc17_edinit(EDCTRL);
+ memset((void*)HCCA, 0, sizeof(struct ohci_hcca_s));
+ memset((void*)TDHEAD, 0, sizeof(struct ohci_gtd_s));
+ memset((void*)TDTAIL, 0, sizeof(struct ohci_gtd_s));
+ memset((void*)EDCTRL, 0, sizeof(struct lpc17_ed_s));
/* Initialize user-configurable EDs */
diff --git a/nuttx/drivers/usbhost/usbhost_hidkbd.c b/nuttx/drivers/usbhost/usbhost_hidkbd.c
index c8e5b32ac..782069c9f 100644
--- a/nuttx/drivers/usbhost/usbhost_hidkbd.c
+++ b/nuttx/drivers/usbhost/usbhost_hidkbd.c
@@ -653,6 +653,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
epoutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
epoutdesc.in = false;
epoutdesc.funcaddr = funcaddr;
+ epoutdesc.xfrtype = USB_EP_ATTR_XFER_INT;
epoutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Interrupt OUT EP addr:%d mxpacketsize:%d\n",
epoutdesc.addr, epoutdesc.mxpacketsize);
@@ -675,9 +676,10 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
/* Save the interrupt IN endpoint information */
- epindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
+ epindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
epindesc.in = 1;
epindesc.funcaddr = funcaddr;
+ epindesc.xfrtype = USB_EP_ATTR_XFER_INT;
epindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Interrupt IN EP addr:%d mxpacketsize:%d\n",
epindesc.addr, epindesc.mxpacketsize);
diff --git a/nuttx/drivers/usbhost/usbhost_skeleton.c b/nuttx/drivers/usbhost/usbhost_skeleton.c
index 28cf4b996..d04954f02 100644
--- a/nuttx/drivers/usbhost/usbhost_skeleton.c
+++ b/nuttx/drivers/usbhost/usbhost_skeleton.c
@@ -502,6 +502,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
boutdesc.in = false;
boutdesc.funcaddr = funcaddr;
+ boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
boutdesc.addr, boutdesc.mxpacketsize);
@@ -524,9 +525,10 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
/* Save the bulk IN endpoint information */
- bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
+ bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
bindesc.in = 1;
bindesc.funcaddr = funcaddr;
+ bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n",
bindesc.addr, bindesc.mxpacketsize);
diff --git a/nuttx/drivers/usbhost/usbhost_storage.c b/nuttx/drivers/usbhost/usbhost_storage.c
index 2cfc61500..286a26885 100644
--- a/nuttx/drivers/usbhost/usbhost_storage.c
+++ b/nuttx/drivers/usbhost/usbhost_storage.c
@@ -1038,6 +1038,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
boutdesc.in = false;
boutdesc.funcaddr = funcaddr;
+ boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
boutdesc.addr, boutdesc.mxpacketsize);
@@ -1060,9 +1061,10 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
/* Save the bulk IN endpoint information */
- bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
+ bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
bindesc.in = 1;
bindesc.funcaddr = funcaddr;
+ bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n",
bindesc.addr, bindesc.mxpacketsize);
diff --git a/nuttx/include/nuttx/usb/usbhost.h b/nuttx/include/nuttx/usb/usbhost.h
index e69f1814a..6e2bff3e0 100644
--- a/nuttx/include/nuttx/usb/usbhost.h
+++ b/nuttx/include/nuttx/usb/usbhost.h
@@ -496,6 +496,7 @@ struct usbhost_epdesc_s
uint8_t addr; /* Endpoint address */
bool in; /* Direction: true->IN */
uint8_t funcaddr; /* USB address of function containing endpoint */
+ uint8_t xfrtype; /* Transfer type. See SB_EP_ATTR_XFER_* in usb.h */
uint16_t mxpacketsize; /* Max packetsize */
};