summaryrefslogtreecommitdiffstats
path: root/nuttx/arch/arm/src/lpc214x
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-10-09 15:15:00 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-10-09 15:15:00 +0000
commite65ba356d053eb31f9d1ec1898ac1bb82c0ce712 (patch)
tree033c7ab96eb7b5ab7d0065a24998a63d6ab43a64 /nuttx/arch/arm/src/lpc214x
parentc63b2b4c43bfeaa6c9e58a3e17d0bc52d253e4ce (diff)
Last option in configure; ep address in ep struct
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@1011 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/arch/arm/src/lpc214x')
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c96
1 files changed, 71 insertions, 25 deletions
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c b/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
index 8edd83651a..0db5437a4b 100644
--- a/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
@@ -241,6 +241,9 @@
#define LPC214X_EPPHYIN(epphy) (((epphy)&1)!=0)
#define LPC214X_EPPHYOUT(epphy) (((epphy)&1)==0)
+#define LPC214X_EPPHYIN2LOG(epphy) (((ubyte)(epphy)>>1)|USB_DIR_IN)
+#define LPC214X_EPPHYOUT2LOG(epphy) (((ubyte)(epphy)>>1)|USB_DIR_OUT)
+
/* Each endpoint has somewhat different characteristics */
#define LPC214X_EPALLSET (0xffffffff) /* All endpoints */
@@ -304,7 +307,6 @@ struct lpc214x_ep_s
struct lpc214x_req_s *head; /* Request list for this endpoint */
struct lpc214x_req_s *tail;
ubyte epphy; /* Physical EP address */
- ubyte eplog; /* Configured logical EP address */
ubyte stalled:1; /* Endpoint is halted */
ubyte halted:1; /* Endpoint feature halted */
ubyte txnullpkt:1; /* Null packet needed at end of transfer */
@@ -433,7 +435,7 @@ static void lpc214x_dmadisable(ubyte epphy);
/* Endpoint operations *********************************************************/
static int lpc214x_epconfigure(FAR struct usbdev_ep_s *ep,
- const struct usb_epdesc_s *desc);
+ const struct usb_epdesc_s *desc, boolean last);
static int lpc214x_epdisable(FAR struct usbdev_ep_s *ep);
static FAR struct usbdev_req_s *lpc214x_epallocreq(FAR struct usbdev_ep_s *ep);
static void lpc214x_epfreereq(FAR struct usbdev_ep_s *ep,
@@ -1202,7 +1204,7 @@ static struct lpc214x_ep_s *lpc214x_epfindbyaddr(struct lpc214x_usbdev_s *priv,
/* Same logical endpoint number? (includes direction bit) */
- if (eplog == privep->eplog)
+ if (eplog == privep->ep.eplog)
{
/* Return endpoint found */
@@ -2447,19 +2449,24 @@ static void lpc214x_dmadisable(ubyte epphy)
* Description:
* Configure endpoint, making it usable
*
+ * Input Parameters:
+ * ep - the struct usbdev_ep_s instance obtained from allocep()
+ * desc - A struct usb_epdesc_s instance describing the endpoint
+ * last - TRUE if this this last endpoint to be configured. Some hardware
+ * needs to take special action when all of the endpoints have been
+ * configured.
+ *
*******************************************************************************/
static int lpc214x_epconfigure(FAR struct usbdev_ep_s *ep,
- FAR const struct usb_epdesc_s *desc)
+ FAR const struct usb_epdesc_s *desc,
+ boolean last)
{
FAR struct lpc214x_ep_s *privep = (FAR struct lpc214x_ep_s *)ep;
uint32 inten;
usbtrace(TRACE_EPCONFIGURE, privep->epphy);
-
- /* Save the logical EP number (so that we can map logical to physical later) */
-
- privep->eplog = desc->addr;
+ DEBUGASSERT(desc->addr == ep->eplog);
/* Realize the endpoint */
@@ -2477,10 +2484,19 @@ static int lpc214x_epconfigure(FAR struct usbdev_ep_s *ep,
#else
/* Enable Ep interrupt (R/W) */
- inten = lpc214x_getreg(LPC214X_USBDEV_EPINTEN);
- inten |= (1 << privep->epphy);
- lpc214x_putreg(inten, LPC214X_USBDEV_EPINTEN);
+ inten = lpc214x_getreg(LPC214X_USBDEV_EPINTEN);
+ inten |= (1 << privep->epphy);
+ lpc214x_putreg(inten, LPC214X_USBDEV_EPINTEN);
#endif
+
+ /* If all of the endpoints have been configured, then tell the USB controller
+ * to enabled normal activity on all realized endpoints.
+ */
+
+ if (last)
+ {
+ lpc214x_usbcmd(CMD_USB_DEV_CONFIG, 1);
+ }
return OK;
}
@@ -2776,35 +2792,52 @@ static int lpc214x_epstall(FAR struct usbdev_ep_s *ep, boolean resume)
* Allocate an endpoint matching the parameters.
*
* Input Parameters:
- * epphy - 7-bit physical endpoint number (without direction bit). Zero means
- * that any endpoint matching the other requirements will suffice.
+ * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means
+ * that any endpoint matching the other requirements will suffice. The
+ * assigned endpoint can be found in the eplog field.
* in - TRUE: IN (device-to-host) endpoint requested
* eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK,
* USB_EP_ATTR_XFER_INT}
*
*******************************************************************************/
-static FAR struct usbdev_ep_s *lcp214x_allocep(FAR struct usbdev_s *dev, ubyte epphy,
+static FAR struct usbdev_ep_s *lcp214x_allocep(FAR struct usbdev_s *dev, ubyte eplog,
boolean in, ubyte eptype)
{
FAR struct lpc214x_usbdev_s *priv = (FAR struct lpc214x_usbdev_s *)dev;
- uint32 epset = LPC214X_EPALLSET;
+ uint32 epset = LPC214X_EPALLSET & ~LPC214X_EPCTRLSET;
irqstate_t flags;
int epndx = 0;
- usbtrace(TRACE_DEVALLOCEP, (uint16)epphy);
+ usbtrace(TRACE_DEVALLOCEP, (uint16)eplog);
+
+ /* Ignore any direction bits in the logical address */
- /* epphy=0 means that any endpoint will do */
+ eplog = USB_EPNO(eplog);
- if (epphy > 0)
+ /* A logical address of 0 means that any endpoint will do */
+
+ if (eplog > 0)
{
- if (epphy >= LPC214X_NLOGENDPOINTS)
+ /* Otherwise, we will return the endpoint structure only for the requested
+ * 'logical' endpoint. All of the other checks will still be performed.
+ *
+ * First, verify that the logical endpoint is in the range supported by
+ * by the hardware.
+ */
+
+ if (eplog >= LPC214X_NLOGENDPOINTS)
{
- usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADEPNO), (uint16)epphy);
- return NULL;
+ usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_BADEPNO), (uint16)eplog);
+ return NULL;
}
- epset &= 3 << epphy;
+ /* Convert the logical address to a physical OUT endpoint address and
+ * remove all of the candidate endpoints from the bitset except for the
+ * the IN/OUT pair for this logical address.
+ */
+
+ epset &= 3 << (eplog << 1);
}
/* Get the subset matching the requested direction */
@@ -2857,9 +2890,9 @@ static FAR struct usbdev_ep_s *lcp214x_allocep(FAR struct usbdev_s *dev, ubyte e
uint32 bit = 1 << epndx;
if ((epset & bit) != 0)
{
- /* Mark the endpoint no longer available */
+ /* Mark the IN/OUT endpoint no longer available */
- priv->epavail &= ~bit;
+ priv->epavail &= ~(3 << (bit & ~1));
irqrestore(flags);
/* And return the pointer to the standard endpoint structure */
@@ -2872,7 +2905,7 @@ static FAR struct usbdev_ep_s *lcp214x_allocep(FAR struct usbdev_s *dev, ubyte e
irqrestore(flags);
}
- usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_NOEP), (uint16)epphy);
+ usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_NOEP), (uint16)eplog);
return NULL;
}
@@ -3050,7 +3083,20 @@ void up_usbinitialize(void)
*/
priv->eplist[i].ep.ops = &g_epops;
priv->eplist[i].dev = priv;
+
+ /* The index, i, is the physical endpoint address; Map this
+ * to a logical endpoint address usable by the class driver.
+ */
+
priv->eplist[i].epphy = i;
+ if (LPC214X_EPPHYIN(i))
+ {
+ priv->eplist[i].ep.eplog = LPC214X_EPPHYIN2LOG(i);
+ }
+ else
+ {
+ priv->eplist[i].ep.eplog = LPC214X_EPPHYOUT2LOG(i);
+ }
/* The maximum packet size may depend on the type of endpoint */