From 868a0f7bac083d8684771d508ba5caafe3f68a1d Mon Sep 17 00:00:00 2001
From: patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>
Date: Sun, 19 Dec 2010 17:49:53 +0000
Subject: [PATCH] More descriptor stuff

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3197 42af7a65-404d-4744-a932-0658087f49c3
---
 arch/arm/src/lpc17xx/lpc17_ohciram.h | 10 +--
 arch/arm/src/lpc17xx/lpc17_usbhost.c | 94 +++++++++++++++++++++++-----
 drivers/usbhost/usbhost_storage.c    |  2 +-
 include/nuttx/usb/ohci.h             | 28 +++++++++
 include/nuttx/usb/usbhost.h          |  2 +-
 5 files changed, 115 insertions(+), 21 deletions(-)

diff --git a/arch/arm/src/lpc17xx/lpc17_ohciram.h b/arch/arm/src/lpc17xx/lpc17_ohciram.h
index 453c55d7a1..431a8d8d32 100755
--- a/arch/arm/src/lpc17xx/lpc17_ohciram.h
+++ b/arch/arm/src/lpc17xx/lpc17_ohciram.h
@@ -127,7 +127,7 @@
 
 /* Derived size of user endpoint descriptor (ED) memory. */
 
-#define LPC17_FREEED_SIZE (CONFIG_USBHOST_NEDS * LPC17_ED_SIZE)
+#define LPC17_EDFREE_SIZE (CONFIG_USBHOST_NEDS * LPC17_ED_SIZE)
 
 /* Configurable number of descriptor buffer (TDBUFFER) */
 
@@ -170,7 +170,7 @@
  *
  *  Sizes of things
  *    CONFIG_USBHOST_NEDS         2
- *    LPC17_FREEED_SIZE           48
+ *    LPC17_EDFREE_SIZE           48
  *    LPC17_TDBUFFER_SIZE         128
  *    LPC17_TDBUFFER_SIZE         512
  *
@@ -185,7 +185,7 @@
  *    LPC17_TDHEAD_ADDR           0x2000bd00
  *    LPC17_TDTAIL_ADDR           0x2000bd10
  *    LPC17_EDCTRL_ADDR           0x2000bd20
- *    LPC17_FREEED_BASE           0x2000bd30
+ *    LPC17_EDFREE_BASE           0x2000bd30
  *    LPC17_TDBUFFER_BASE         0x2000bd50
  *    LPC17_IOBUFFER_BASE         0x2000bdd0
  *    LPC17_IOBUFFERS            (0x2000c000 + 0x2000bdd0) / 512 = 560/512 = 1
@@ -197,8 +197,8 @@
 #define LPC17_TDHEAD_ADDR   (LPC17_OHCIRAM_BASE + LPC17_HCCA_SIZE)
 #define LPC17_TDTAIL_ADDR   (LPC17_TDHEAD_ADDR + LPC17_TD_SIZE)
 #define LPC17_EDCTRL_ADDR   (LPC17_TDTAIL_ADDR + LPC17_TD_SIZE)
-#define LPC17_FREEED_BASE   (LPC17_EDCTRL_ADDR + LPC17_ED_SIZE)
-#define LPC17_TDBUFFER_BASE (LPC17_FREEED_BASE + LPC17_FREEED_SIZE)
+#define LPC17_EDFREE_BASE   (LPC17_EDCTRL_ADDR + LPC17_ED_SIZE)
+#define LPC17_TDBUFFER_BASE (LPC17_EDFREE_BASE + LPC17_EDFREE_SIZE)
 #define LPC17_IOBUFFER_BASE (LPC17_TDBUFFER_BASE + LPC17_TDBUFFER_SIZE)
 
 /* Finally, use the remainder of the allocated OHCI for IO buffers */
diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c
index 1f6552a4af..c415794b47 100755
--- a/arch/arm/src/lpc17xx/lpc17_usbhost.c
+++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c
@@ -101,10 +101,16 @@
 #define TDHEAD      ((volatile struct lpc17_hctd_s *)LPC17_TDHEAD_ADDR)
 #define TDTAIL      ((volatile struct lpc17_hctd_s *)LPC17_TDTAIL_ADDR)
 #define EDCTRL      ((volatile struct lpc17_hced_s *)LPC17_EDCTRL_ADDR)
-#define FREEEDS     ((volatile struct lpc17_hced_s *)LPC17_FREEED_BASE)
 
+#define EDFREE      ((struct lpc17_hced_s *)LPC17_EDFREE_BASE)
 #define TDBuffer    ((volatile uint8_t *)(LPC17_TDBUFFER_BASE)
 
+/* Descriptors *****************************************************************/
+
+/* TD delay interrupt value */
+
+#define TD_DELAY(n) (uint32_t)((n) << GTD_STATUS_DI_SHIFT)
+
 /* Debug ***********************************************************************/
 
 /* Trace error codes */
@@ -166,10 +172,10 @@ struct lpc17_hced_s
 
 /* The following is used manage a list of free EDs */
 
-struct lpc17_edmem_s
+struct lpc17_edlist_s
 {
-  struct lpc17_edmem_s *flink;         /* Link to next ED in the list */
-  uint32_t              pad[3];        /* To make the same size as struct lpc17_hced_s */
+  struct lpc17_edlist_s *flink;        /* Link to next ED in the list */
+  uint32_t               pad[3];       /* To make the same size as struct lpc17_hced_s */
 };
 
 /*******************************************************************************
@@ -188,6 +194,14 @@ static void lpc17_putreg(uint32_t val, uint32_t addr);
 # define lpc17_putreg(val,addr) putreg32(val,addr)
 #endif
 
+/* Descriptor helper functions *************************************************/
+
+static struct lpc17_hced_s *lpc17_edalloc(struct lpc17_usbhost_s *priv);
+static void lpc17_edfree(struct lpc17_usbhost_s *priv, struct lpc17_hced_s *ed);
+static void lpc17_enqueuetd(volatile struct lpc17_hced_s *ed, uint32_t dirpid,
+                            uint32_t toggle, volatile uint8_t *buffer,
+                            size_t buflen);
+
 /* Interrupt handling **********************************************************/
 
 static int lpc17_usbinterrupt(int irq, FAR void *context);
@@ -236,7 +250,7 @@ static struct lpc17_usbhost_s g_usbhost =
 
 /* This is a free list of EDs */
 
-static struct lpc17_edmem_s *g_freeeds;
+static struct lpc17_edlist_s *g_edfree;
 
 /*******************************************************************************
  * Public Data
@@ -368,6 +382,64 @@ static void lpc17_putreg(uint32_t val, uint32_t addr)
 }
 #endif
 
+/*******************************************************************************
+ * Name: lpc17_edalloc
+ *
+ * Description:
+ *   Allocate an ED from the free list
+ *
+ *******************************************************************************/
+
+static struct lpc17_hced_s *lpc17_edalloc(struct lpc17_usbhost_s *priv)
+{
+  struct lpc17_hced_s *ret = (struct lpc17_hced_s *)g_edfree;
+  if (ret)
+    {
+      g_edfree = ((struct lpc17_edlist_s*)ret)->flink;
+    }
+  return ret;
+}
+
+/*******************************************************************************
+ * Name: lpc17_edfree
+ *
+ * Description:
+ *   Return an ED to the free list
+ *
+ *******************************************************************************/
+
+static void lpc17_edfree(struct lpc17_usbhost_s *priv, struct lpc17_hced_s *ed)
+{
+  struct lpc17_edlist_s *edfree = (struct lpc17_edlist_s *)ed;
+  edfree->flink                 = g_edfree;
+  g_edfree                      = edfree;
+}
+
+/*******************************************************************************
+ * Name: lpc17_enqueuetd
+ *
+ * Description:
+ *   Enqueue a transfer descriptor
+ *
+ *******************************************************************************/
+
+static void lpc17_enqueuetd(volatile struct lpc17_hced_s *ed, uint32_t dirpid,
+                            uint32_t toggle, volatile uint8_t *buffer, size_t buflen)
+{
+  TDHEAD->ctrl    = (GTD_STATUS_R | dirpid | TD_DELAY(0) | toggle | GTD_STATUS_CC_MASK);
+  TDTAIL->ctrl    = 0;
+  TDHEAD->currptr = (uint32_t)buffer;
+  TDTAIL->currptr = 0;
+  TDHEAD->next    = (uint32_t)TDTAIL;
+  TDTAIL->next    = 0;
+  TDHEAD->bufend  = (uint32_t)(buffer + (buflen - 1));
+  TDTAIL->bufend  = 0;
+
+  ed->headtd      = (uint32_t)TDHEAD | ((ed->headtd) & 0x00000002);
+  ed->tailtd      = (uint32_t)TDTAIL;
+  ed->next        = 0;
+}
+
 /*******************************************************************************
  * Name: lpc17_usbinterrupt
  *
@@ -691,19 +763,13 @@ void up_usbhostinitialize(void)
   lpc17_tdinit(TDTAIL);
   lpc17_edinit(EDCTRL);
 
+  /* Initialize user-configurable EDs */
+
   for (i = 0; i < CONFIG_USBHOST_NEDS; i++)
     {
-      struct lpc17_edmem_s *freeed;
-
-      /* Initialize the ED */
-
-      lpc17_edinit(&FREEEDS[i]);
-
       /* Put the ED in a free list */
 
-      freeed        = (struct lpc17_edmem_s *)&FREEEDS[i];
-      freeed->flink = g_freeeds;
-      g_freeeds     = freeed;
+      lpc17_edfree(priv, &EDFREE[i]);
     }
 
   /* Wait 50MS then perform hardware reset */
diff --git a/drivers/usbhost/usbhost_storage.c b/drivers/usbhost/usbhost_storage.c
index e161b24c8c..2193caf1f0 100644
--- a/drivers/usbhost/usbhost_storage.c
+++ b/drivers/usbhost/usbhost_storage.c
@@ -1850,7 +1850,7 @@ static ssize_t usbhost_write(FAR struct inode *inode, const unsigned char *buffe
               /* Send the user data */
 #warning "For lpc17xx, I think this buffer needs to lie in BANK1"
               result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
-                                     buffer, priv->blocksize * nsectors);
+                                     (uint8_t*)buffer, priv->blocksize * nsectors);
               if (result == OK)
                 {
                   /* Wait for the data in operation to complete */
diff --git a/include/nuttx/usb/ohci.h b/include/nuttx/usb/ohci.h
index d23e1aa673..d8d1d5cdfa 100755
--- a/include/nuttx/usb/ohci.h
+++ b/include/nuttx/usb/ohci.h
@@ -263,6 +263,34 @@
                                               /* Bits 21-31: Reserved */
 
 /* Transfer Descriptors *****************************************************/
+/* Endpoint Descriptor Offsets (4.2.1) */
+
+#define ED_CONTROL_OFFSET          (0x00)     /* TD status bits */
+#define ED_TAILP_OFFSET            (0x04)     /* Current Buffer Pointer (CBP) */
+#define ED_HEADP_OFFSET            (0x08)     /* Next TD (NextTD) */
+#define ED_NEXTED_OFFSET           (0x0c)     /* Buffer End (BE) */
+
+/* Endpoint Descriptor Bit Definitions (4.2.2) */
+
+#define ED_CONTROL_FA_SHIFT        (0)        /* Bits 0-6: Function Address */
+#define ED_CONTROL_FA_MASK         (0x7f << ED_CONTROL_FA_SHIFT)
+#define ED_CONTROL_EN_SHIFT        (7)        /* Bits 7-10: Endpoint number */
+#define ED_CONTROL_EN_MASK         (15 << ED_CONTROL_EN_SHIFT)
+#define ED_CONTROL_D_SHIFT         (11)       /* Bits 11-12: Direction */
+#define ED_CONTROL_D_MASK          (3 << ED_CONTROL_D_SHIFT)
+#  define ED_CONTROL_D_TD1         (0 << ED_CONTROL_D_SHIFT) /* Get direction from TD */
+#  define ED_CONTROL_D_OUT         (1 << ED_CONTROL_D_SHIFT) /* OUT */
+#  define ED_CONTROL_D_IN          (2 << ED_CONTROL_D_SHIFT) /* IN */
+#  define ED_CONTROL_D_TD2         (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */
+#define ED_CONTROL_S               (1 << 13)  /* Bit 13: Speed (low) */
+#define ED_CONTROL_K               (1 << 14)  /* Bit 14: Skip */
+#define ED_CONTROL_F               (1 << 15)  /* Bit 15: Format (isochronous) */
+#define ED_CONTROL_MPS_SHIFT       (16)       /* Bits 16-26: Maximum packet size */
+#define ED_CONTROL_MPS_MASK        (0x7ff << ED_CONTROL_MPS_SHIFT)
+
+#define ED_TAILP_H                 (1 << 0)  /* Bit 0: Halted */
+#define ED_TAILP_C                 (1 << 1)  /* Bit 1: Toggle carry */
+
 /* General Transfer Descriptor Offsets (4.3.1) */
 
 #define GTD_STATUS_OFFSET          (0x00)     /* TD status bits */
diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h
index 821d127d21..d197b12e44 100644
--- a/include/nuttx/usb/usbhost.h
+++ b/include/nuttx/usb/usbhost.h
@@ -466,7 +466,7 @@ struct usbhost_driver_s
    */
 
   int (*transfer)(FAR struct usbhost_driver_s *drvr,
-                  FAR struct usbhost_epdesc_s *ed,
+                  FAR struct usbhost_epdesc_s *ep,
                   FAR uint8_t *buffer, size_t buflen);
 
   /* Called by the class when an error occurs and driver has been disconnected.
-- 
GitLab