Make space for int/isoc endpoint support

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3254 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-01-16 14:02:42 +00:00
parent dc81d843a3
commit 258009c392
11 changed files with 333 additions and 61 deletions

View File

@ -12,7 +12,7 @@
<h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i>
</font></big></h1>
<p>Last Updated: January 9, 2011</p>
<p>Last Updated: January 16, 2011</p>
</td>
</tr>
</table>
@ -3612,6 +3612,15 @@ build
<li>
<code>CONFIG_USBHOST_NPREALLOC</code>: Number of pre-allocated class instances
</li>
<li>
<code>CONFIG_USBHOST_BULK_DISABLE</code>: On some architectures, selecting this setting will reduce driver size by disabling bulk endpoint support
</li>
<li>
<code>CONFIG_USBHOST_INT_DISABLE</code>: On some architectures, selecting this setting will reduce driver size by disabling interrupt endpoint support
</li>
<li>
<code>CONFIG_USBHOST_ISOC_DISABLE</code>: On some architectures, selecting this setting will reduce driver size by disabling isochronous endpoint support
</li>
</ul>
<h2>Graphics related configuration settings</h3>

View File

@ -174,9 +174,9 @@ struct lpc17_ed_s
/* Software specific fields */
uint8_t xfrtype; /* Transfer type. See SB_EP_ATTR_XFER_* in usb.h */
uint8_t period; /* Periodic EP polling frequency 1, 2, 4, 6, 16, or 32 */
volatile uint8_t tdstatus; /* TD control status bits from last Writeback Done Head event */
volatile bool wdhwait; /* TRUE: Thread is waiting for WDH interrupt */
uint8_t pad;
sem_t wdhsem; /* Semaphore used to wait for Writeback Done Head event */
/* Unused bytes follow, depending on the size of sem_t */
};
@ -233,7 +233,7 @@ static void lpc17_takesem(sem_t *sem);
static inline uint16_t lpc17_getle16(const uint8_t *val);
static void lpc17_putle16(uint8_t *dest, uint16_t val);
/* Descriptor helper functions *************************************************/
/* OHCI memory pool helper functions *******************************************/
static inline void lpc17_edfree(struct lpc17_ed_s *ed);
static struct lpc17_gtd_s *lpc17_tdalloc(void);
@ -244,6 +244,24 @@ static void lpc17_tbfree(uint8_t *buffer);
static uint8_t *lpc17_ioalloc(void);
static void lpc17_iofree(uint8_t *buffer);
#endif
/* ED list helper functions ****************************************************/
static inline int lpc17_addbulked(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed);
static inline int lpc17_rembulked(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed);
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed);
static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed);
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed);
static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed);
/* Descriptor helper functions *************************************************/
static int lpc17_enqueuetd(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed, uint32_t dirpid,
uint32_t toggle, volatile uint8_t *buffer,
@ -659,6 +677,173 @@ static void lpc17_iofree(uint8_t *buffer)
}
#endif
/*******************************************************************************
* Name: lpc17_addbulked
*
* Description:
* Helper function to add an ED to the bulk list.
*
*******************************************************************************/
static inline int lpc17_addbulked(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed)
{
#ifndef CONFIG_USBHOST_BULK_DISABLE
uint32_t regval;
/* Add the new bulk ED to the head of the bulk list */
ed->hw.nexted = lpc17_getreg(LPC17_USBHOST_BULKHEADED);
lpc17_putreg((uint32_t)ed, LPC17_USBHOST_BULKHEADED);
/* BulkListEnable. This bit is set to enable the processing of the
* Bulk list. Note: once enabled, it remains. We really should
* never modify the bulk list while BLE is set.
*/
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
regval |= OHCI_CTRL_BLE;
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
return OK;
#else
return -ENOSYS;
#endif
}
/*******************************************************************************
* Name: lpc17_rembulked
*
* Description:
* Helper function remove an ED from the bulk list.
*
*******************************************************************************/
static inline int lpc17_rembulked(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed)
{
#ifndef CONFIG_USBHOST_BULK_DISABLE
struct lpc17_ed_s *curr = NULL;
struct lpc17_ed_s *prev = NULL;
uint32_t regval;
/* Find the ED in the bulk list. NOTE: We really should never be mucking
* with the bulk list while BLE is set.
*/
for (curr = (struct lpc17_ed_s *)lpc17_getreg(LPC17_USBHOST_BULKHEADED),
prev = NULL;
curr && curr != ed;
prev = curr, curr = (struct lpc17_ed_s *)curr->hw.nexted);
/* Hmmm.. It would be a bug if we do not find the ED in the bulk list. */
DEBUGASSERT(curr != NULL);
/* Remove the ED from the bulk list */
if (curr != NULL)
{
/* Is this ED the first on in the bulk list? */
if (prev == NULL)
{
/* Yes... set the head of the bulk list to skip over this ED */
lpc17_putreg(ed->hw.nexted, LPC17_USBHOST_BULKHEADED);
/* If the bulk list is now empty, then disable it */
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
regval &= ~OHCI_CTRL_BLE;
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
}
else
{
/* No.. set the forward link of the previous ED in the list
* skip over this ED.
*/
prev->hw.nexted = ed->hw.nexted;
}
}
return OK;
#else
return -ENOSYS;
#endif
}
/*******************************************************************************
* Name: lpc17_addinted
*
* Description:
* Helper function to add an ED to the HCCA interrupt table.
*
*******************************************************************************/
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed)
{
#ifndef CONFIG_USBHOST_INT_DISABLE
# warning "Interrupt endpoints not yet supported"
#else
return -ENOSYS;
#endif
}
/*******************************************************************************
* Name: lpc17_addbulked
*
* Description:
* Helper function to remove an ED from the HCCA interrupt table.
*
*******************************************************************************/
static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed)
{
#ifndef CONFIG_USBHOST_INT_DISABLE
# warning "Interrupt endpoints not yet supported"
#else
return -ENOSYS;
#endif
}
/*******************************************************************************
* Name: lpc17_addbulked
*
* Description:
* Helper functions to add an ED to the periodic table.
*
*******************************************************************************/
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed)
{
#ifndef CONFIG_USBHOST_ISOC_DISABLE
# warning "Isochronous endpoints not yet supported"
#endif
return -ENOSYS;
}
/*******************************************************************************
* Name: lpc17_addbulked
*
* Description:
* Helper functions to remove an ED from the periodic table.
*
*******************************************************************************/
static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv,
struct lpc17_ed_s *ed)
{
#ifndef CONFIG_USBHOST_ISOC_DISABLE
# warning "Isochronous endpoints not yet supported"
#endif
return -ENOSYS;
}
/*******************************************************************************
* Name: lpc17_enqueuetd
*
@ -1224,7 +1409,6 @@ static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
{
struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
struct lpc17_ed_s *ed;
uint32_t regval;
int ret = -ENOMEM;
/* Sanity check. NOTE that this method should only be called if a device is
@ -1293,32 +1477,49 @@ static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
sem_init(&ed->wdhsem, 0, 0);
/* Now add the endpoint descriptor to the appropriate list */
#warning "Missing logic for other endpoint types"
/* Link the common tail TD to the ED's TD list */
ed->hw.headp = (uint32_t)TDTAIL;
ed->hw.tailp = (uint32_t)TDTAIL;
/* Add the new bulk ED to the head of the bulk list */
/* Now add the endpoint descriptor to the appropriate list */
ed->hw.nexted = lpc17_getreg(LPC17_USBHOST_BULKHEADED);
lpc17_putreg((uint32_t)ed, LPC17_USBHOST_BULKHEADED);
switch (ed->xfrtype)
{
case USB_EP_ATTR_XFER_BULK:
ret = lpc17_addbulked(priv, ed);
break;
/* BulkListEnable. This bit is set to enable the processing of the Bulk
* list. Note: once enabled, it remains. We really should never modify
* the bulk list while BLE is set.
*/
case USB_EP_ATTR_XFER_INT:
ret = lpc17_addinted(priv, ed);
break;
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
regval |= OHCI_CTRL_BLE;
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
case USB_EP_ATTR_XFER_ISOC:
ret = lpc17_addisoced(priv, ed);
break;
/* Return an opaque reference to the ED */
case USB_EP_ATTR_XFER_CONTROL:
default:
ret = -EINVAL;
break;
}
*ep = (usbhost_ep_t)ed;
ret = OK;
/* Was the ED successfully added? */
if (ret != OK)
{
/* No.. destroy it and report the error */
udbg("ERROR: Failed to queue ED for transfer type: %d\n", ed->xfrtype);
sem_destroy(&ed->wdhsem);
lpc17_edfree(ed);
}
else
{
/* Yes.. return an opaque reference to the ED */
*ep = (usbhost_ep_t)ed;
}
}
lpc17_givesem(&priv->exclsem);
@ -1349,9 +1550,7 @@ static int lpc17_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
{
struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep;
struct lpc17_ed_s *curr = NULL;
struct lpc17_ed_s *prev = NULL;
uint32_t regval;
int ret;
/* There should not be any pending, real TDs linked to this ED */
@ -1363,45 +1562,26 @@ static int lpc17_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
lpc17_takesem(&priv->exclsem);
/* Find the ED in the bulk list. NOTE: We really should never be mucking
* with the bulk list while BLE is set.
*/
/* Remove the ED to the correct list depending on the trasfer type */
for (curr = (struct lpc17_ed_s *)lpc17_getreg(LPC17_USBHOST_BULKHEADED),
prev = NULL;
curr && curr != ed;
prev = curr, curr = (struct lpc17_ed_s *)curr->hw.nexted);
/* Hmmm.. It would be a bug if we do not find the ED in the bulk list. */
DEBUGASSERT(curr != NULL);
/* Remove the ED from the bulk list */
if (curr != NULL)
switch (ed->xfrtype)
{
/* Is this ED the first on in the bulk list? */
case USB_EP_ATTR_XFER_BULK:
ret = lpc17_rembulked(priv, ed);
break;
if (prev == NULL)
{
/* Yes... set the head of the bulk list to skip over this ED */
case USB_EP_ATTR_XFER_INT:
ret = lpc17_reminted(priv, ed);
break;
lpc17_putreg(ed->hw.nexted, LPC17_USBHOST_BULKHEADED);
case USB_EP_ATTR_XFER_ISOC:
ret = lpc17_remisoced(priv, ed);
break;
/* If the bulk list is now empty, then disable it */
regval = lpc17_getreg(LPC17_USBHOST_CTRL);
regval &= ~OHCI_CTRL_BLE;
lpc17_putreg(regval, LPC17_USBHOST_CTRL);
}
else
{
/* No.. set the forward link of the previous ED in the list
* skip over this ED.
*/
prev->hw.nexted = ed->hw.nexted;
}
case USB_EP_ATTR_XFER_CONTROL:
default:
ret = -EINVAL;
break;
}
/* Destroy the semaphore */
@ -1412,7 +1592,7 @@ static int lpc17_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
lpc17_edfree(ed);
lpc17_givesem(&priv->exclsem);
return OK;
return ret;
}
/*******************************************************************************

View File

@ -708,6 +708,15 @@ defconfig -- This is a configuration file similar to the Linux
Enables USB host support
CONFIG_USBHOST_NPREALLOC
Number of pre-allocated class instances
CONFIG_USBHOST_BULK_DISABLE
On some architectures, selecting this setting will reduce driver size
by disabling bulk endpoint support
CONFIG_USBHOST_INT_DISABLE
On some architectures, selecting this setting will reduce driver size
by disabling interrupt endpoint support
CONFIG_USBHOST_ISOC_DISABLE
On some architectures, selecting this setting will reduce driver size
by disabling isochronous endpoint support
USB serial device class driver
CONFIG_USBSER

View File

@ -326,6 +326,7 @@ CONFIG_APP_DIR=examples/nsh
CONFIG_DEBUG=n
CONFIG_DEBUG_VERBOSE=n
CONFIG_DEBUG_SYMBOLS=n
CONFIG_DEBUG_USB=n
CONFIG_MM_REGIONS=2
CONFIG_ARCH_LOWPUTC=y
CONFIG_RR_INTERVAL=200
@ -593,9 +594,21 @@ CONFIG_USBDEV_TRACE_NRECORDS=128
# Enables USB host support
# CONFIG_USBHOST_NPREALLOC
# Number of pre-allocated class instances
# CONFIG_USBHOST_BULK_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling bulk endpoint support
# CONFIG_USBHOST_INT_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling interrupt endpoint support
# CONFIG_USBHOST_ISOC_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling isochronous endpoint support
#
CONFIG_USBHOST=n
CONFIG_USBHOST_NPREALLOC=0
CONFIG_USBHOST_BULK_DISABLE=n
CONFIG_USBHOST_INT_DISABLE=y
CONFIG_USBHOST_ISOC_DISABLE=y
#
# LPC17xx USB Device Configuration

View File

@ -330,6 +330,7 @@ CONFIG_APP_DIR=examples/hidkbd
CONFIG_DEBUG=n
CONFIG_DEBUG_VERBOSE=n
CONFIG_DEBUG_SYMBOLS=n
CONFIG_DEBUG_USB=n
CONFIG_MM_REGIONS=2
CONFIG_ARCH_LOWPUTC=y
CONFIG_RR_INTERVAL=200
@ -599,9 +600,21 @@ CONFIG_USBDEV_TRACE_NRECORDS=128
# Enables USB host support
# CONFIG_USBHOST_NPREALLOC
# Number of pre-allocated class instances
# CONFIG_USBHOST_BULK_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling bulk endpoint support
# CONFIG_USBHOST_INT_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling interrupt endpoint support
# CONFIG_USBHOST_ISOC_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling isochronous endpoint support
#
CONFIG_USBHOST=y
CONFIG_USBHOST_NPREALLOC=0
CONFIG_USBHOST_BULK_DISABLE=y
CONFIG_USBHOST_INT_DISABLE=n
CONFIG_USBHOST_ISOC_DISABLE=y
#
# LPC17xx USB Device Configuration

View File

@ -330,6 +330,7 @@ CONFIG_APP_DIR=examples/nsh
CONFIG_DEBUG=n
CONFIG_DEBUG_VERBOSE=n
CONFIG_DEBUG_SYMBOLS=n
CONFIG_DEBUG_USB=n
CONFIG_MM_REGIONS=2
CONFIG_ARCH_LOWPUTC=y
CONFIG_RR_INTERVAL=200
@ -599,9 +600,21 @@ CONFIG_USBDEV_TRACE_NRECORDS=128
# Enables USB host support
# CONFIG_USBHOST_NPREALLOC
# Number of pre-allocated class instances
# CONFIG_USBHOST_BULK_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling bulk endpoint support
# CONFIG_USBHOST_INT_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling interrupt endpoint support
# CONFIG_USBHOST_ISOC_DISABLE
# On some architectures, selecting this setting will reduce driver size
# by disabling isochronous endpoint support
#
CONFIG_USBHOST=n
CONFIG_USBHOST_NPREALLOC=0
CONFIG_USBHOST_BULK_DISABLE=n
CONFIG_USBHOST_INT_DISABLE=y
CONFIG_USBHOST_ISOC_DISABLE=y
#
# LPC17xx USB Device Configuration

View File

@ -59,6 +59,10 @@
#include <nuttx/usb/usbhost.h>
#include <nuttx/usb/hid.h>
/* Don't compile if prerequisites are not met */
#if defined(CONFIG_USBHOST) && !defined(CONFIG_USBHOST_INT_DISABLE) && CONFIG_NFILE_DESCRIPTORS > 0
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -654,6 +658,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
epoutdesc.in = false;
epoutdesc.funcaddr = funcaddr;
epoutdesc.xfrtype = USB_EP_ATTR_XFER_INT;
epoutdesc.interval = epdesc->interval;
epoutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Interrupt OUT EP addr:%d mxpacketsize:%d\n",
epoutdesc.addr, epoutdesc.mxpacketsize);
@ -680,6 +685,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
epindesc.in = 1;
epindesc.funcaddr = funcaddr;
epindesc.xfrtype = USB_EP_ATTR_XFER_INT;
epindesc.interval = epdesc->interval;
epindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Interrupt IN EP addr:%d mxpacketsize:%d\n",
epindesc.addr, epindesc.mxpacketsize);
@ -1280,3 +1286,6 @@ int usbhost_kbdinit(void)
return usbhost_registerclass(&g_skeleton);
}
#endif /* CONFIG_USBHOST)&& !CONFIG_USBHOST_INT_DISABLE && CONFIG_NFILE_DESCRIPTORS */

View File

@ -503,6 +503,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
boutdesc.in = false;
boutdesc.funcaddr = funcaddr;
boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
boutdesc.interval = epdesc->interval;
boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
boutdesc.addr, boutdesc.mxpacketsize);
@ -529,6 +530,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
bindesc.in = 1;
bindesc.funcaddr = funcaddr;
bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
bindesc.interval = epdesc->interval;
bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n",
bindesc.addr, bindesc.mxpacketsize);

View File

@ -56,7 +56,10 @@
#include <nuttx/usb/usbhost.h>
#include <nuttx/usb/storage.h>
#if defined(CONFIG_USBHOST) && !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
/* Don't compile if prerequisites are not met */
#if defined(CONFIG_USBHOST) && !defined(CONFIG_USBHOST_BULK_DISABLE) && \
!defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
/****************************************************************************
* Pre-processor Definitions
@ -1039,6 +1042,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
boutdesc.in = false;
boutdesc.funcaddr = funcaddr;
boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
boutdesc.interval = epdesc->interval;
boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
boutdesc.addr, boutdesc.mxpacketsize);
@ -1065,6 +1069,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
bindesc.in = 1;
bindesc.funcaddr = funcaddr;
bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
bindesc.interval = epdesc->interval;
bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n",
bindesc.addr, bindesc.mxpacketsize);
@ -2199,4 +2204,4 @@ int usbhost_storageinit(void)
return usbhost_registerclass(&g_storage);
}
#endif /* CONFIG_USBHOST && !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 */
#endif /* CONFIG_USBHOST && !CONFIG_USBHOST_BULK_DISABLE && !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 */

View File

@ -48,6 +48,23 @@
/****************************************************************************
* Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Sanity checking */
#ifndef CONFIG_USBHOST
# error "CONFIG_USBHOST is not defined"
#endif
#ifdef CONFIG_USBHOST_INT_DISABLE
# error "Interrupt endpoints are disabled (CONFIG_USBHOST_INT_DISABLE)"
#endif
#ifndef CONFIG_NFILE_DESCRIPTORS
# error "CONFIG_NFILE_DESCRIPTORS > 0 needed"
#endif
/* Provide some default values for other configuration settings */
#ifndef CONFIG_EXAMPLES_HIDKBD_DEFPRIO
# define CONFIG_EXAMPLES_HIDKBD_DEFPRIO 50

View File

@ -488,7 +488,8 @@ struct usbhost_class_s
};
/* This structure describes one endpoint. It is used as an input to the
* allocep() method.
* allocep() method. Most of this information comes from the endpoint
* descriptor.
*/
struct usbhost_epdesc_s
@ -497,6 +498,7 @@ struct usbhost_epdesc_s
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 */
uint8_t interval; /* Polling interval */
uint16_t mxpacketsize; /* Max packetsize */
};