From 868a0f7bac083d8684771d508ba5caafe3f68a1d Mon Sep 17 00:00:00 2001 From: patacongo 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.