9
0
Fork 0

More descriptor stuff

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3197 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2010-12-19 17:49:53 +00:00
parent d63e0474c3
commit f3c523924d
5 changed files with 115 additions and 21 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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.