Separate waiting for a device and enumerating a device
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3204 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
ed9719a040
commit
e8620ef2ca
@ -164,7 +164,5 @@ void up_initialize(void)
|
||||
/* Initialize USB -- device and/or host */
|
||||
|
||||
up_usbinitialize();
|
||||
up_usbhostinitialize();
|
||||
|
||||
up_ledon(LED_IRQSENABLED);
|
||||
}
|
||||
|
@ -275,12 +275,6 @@ extern void up_usbuninitialize(void);
|
||||
# define up_usbuninitialize()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST
|
||||
extern void up_usbhostinitialize(void);
|
||||
#else
|
||||
# define up_usbhostinitialize()
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __UP_INTERNAL_H */
|
||||
|
@ -250,6 +250,7 @@ static int lpc17_usbinterrupt(int irq, FAR void *context);
|
||||
|
||||
/* USB host controller operations **********************************************/
|
||||
|
||||
static int lpc17_wait(FAR struct usbhost_driver_s *drvr);
|
||||
static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr);
|
||||
static int lpc17_alloc(FAR struct usbhost_driver_s *drvr,
|
||||
FAR uint8_t **buffer, FAR size_t *maxlen);
|
||||
@ -284,6 +285,7 @@ static struct lpc17_usbhost_s g_usbhost =
|
||||
{
|
||||
.drvr =
|
||||
{
|
||||
.wait = lpc17_wait,
|
||||
.enumerate = lpc17_enumerate,
|
||||
.alloc = lpc17_alloc,
|
||||
.free = lpc17_free,
|
||||
@ -938,19 +940,56 @@ static int lpc17_usbinterrupt(int irq, FAR void *context)
|
||||
* USB Host Controller Operations
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_wait
|
||||
*
|
||||
* Description:
|
||||
* Wait for a device to be connected.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
* the class create() method.
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned when a device in connected. This function will not
|
||||
* return until either (1) a device is connected or (2) some failure occurs.
|
||||
* On a failure, a negated errno value is returned indicating the nature of
|
||||
* the failure
|
||||
*
|
||||
* Assumptions:
|
||||
* - Called from a single thread so no mutual exclusion is required.
|
||||
* - Never called from an interrupt handler.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
static int lpc17_wait(FAR struct usbhost_driver_s *drvr)
|
||||
{
|
||||
struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
|
||||
|
||||
/* Are we already connected? */
|
||||
|
||||
while (!priv->connected)
|
||||
{
|
||||
/* No, wait for the connection */
|
||||
|
||||
lpc17_takesem(&priv->rhssem);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc17_enumerate
|
||||
*
|
||||
* Description:
|
||||
* Enumerate the connected device. This function will enqueue the
|
||||
* enumeration process. As part of this enumeration process, the driver
|
||||
* will (1) get the device's configuration descriptor, (2) extract the class
|
||||
* ID info from the configuration descriptor, (3) call usbhost_findclass()
|
||||
* to find the class that supports this device, (4) call the create()
|
||||
* method on the struct usbhost_registry_s interface to get a class
|
||||
* instance, and finally (5) call the configdesc() method of the struct
|
||||
* usbhost_class_s interface. After that, the class is in charge of the
|
||||
* sequence of operations.
|
||||
* Enumerate the connected device. As part of this enumeration process,
|
||||
* the driver will (1) get the device's configuration descriptor, (2)
|
||||
* extract the class ID info from the configuration descriptor, (3) call
|
||||
* usbhost_findclass() to find the class that supports this device, (4)
|
||||
* call the create() method on the struct usbhost_registry_s interface
|
||||
* to get a class instance, and finally (5) call the configdesc() method
|
||||
* of the struct usbhost_class_s interface. After that, the class is in
|
||||
* charge of the sequence of operations.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
@ -975,7 +1014,17 @@ static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr)
|
||||
uint8_t *td;
|
||||
int ret;
|
||||
|
||||
ulldbg("Enumerate device\n");
|
||||
/* Are we connected to a device? The caller should have called the wait()
|
||||
* method first to be assured that a device is connected.
|
||||
*/
|
||||
|
||||
while (!priv->connected)
|
||||
{
|
||||
/* No, return an error */
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
ulldbg("Enumerate the device\n");
|
||||
|
||||
/* Allocate a TD buffer for use in this function */
|
||||
|
||||
@ -986,15 +1035,6 @@ static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr)
|
||||
}
|
||||
ctrlreq = (struct usb_ctrlreq_s *)td;
|
||||
|
||||
/* Are we already connected? */
|
||||
|
||||
while (!priv->connected)
|
||||
{
|
||||
/* No, wait for the connection */
|
||||
|
||||
lpc17_takesem(&priv->rhssem);
|
||||
}
|
||||
|
||||
/* USB 2.0 spec says at least 50ms delay before port reset */
|
||||
|
||||
up_mdelay(100);
|
||||
@ -1499,13 +1539,26 @@ static void lpc17_hccainit(volatile struct lpc17_hcca_s *hcca)
|
||||
* Description:
|
||||
* Initialize USB host device controller hardware.
|
||||
*
|
||||
* Input Parameters:
|
||||
* controller -- If the device supports more than USB host controller, then
|
||||
* this identifies which controller is being intialized. Normally, this
|
||||
* is just zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* And instance of the USB host interface. The controlling task should
|
||||
* use this interface to (1) call the wait() method to wait for a device
|
||||
* to be connected, and (2) call the enumerate() method to bind the device
|
||||
* to a class driver.
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called very early in the initialization sequence in order
|
||||
* - This function should called in the initialization sequence in order
|
||||
* to initialize the USB device functionality.
|
||||
* - Class drivers should be initialized prior to calling this function.
|
||||
* Otherwise, there is a race condition if the device is already connected.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
void up_usbhostinitialize(void)
|
||||
FAR struct usbhost_driver_s *up_usbhostinitialize(int controller)
|
||||
{
|
||||
struct lpc17_usbhost_s *priv = &g_usbhost;
|
||||
uint32_t regval;
|
||||
@ -1513,6 +1566,8 @@ void up_usbhostinitialize(void)
|
||||
irqstate_t flags;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(controller == 0);
|
||||
|
||||
/* Initialize the state data structure */
|
||||
|
||||
sem_init(&priv->rhssem, 0, 0);
|
||||
@ -1627,7 +1682,7 @@ void up_usbhostinitialize(void)
|
||||
if (irq_attach(LPC17_IRQ_USB, lpc17_usbinterrupt) != 0)
|
||||
{
|
||||
udbg("Failed to attach IRQ\n");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Enable USB interrupts at the SYCON controller */
|
||||
@ -1642,4 +1697,5 @@ void up_usbhostinitialize(void)
|
||||
|
||||
up_enable_irq(LPC17_IRQ_USB); /* enable USB interrupt */
|
||||
udbg("USB host Initialized\n");
|
||||
return &priv->drvr;
|
||||
}
|
||||
|
@ -140,19 +140,41 @@
|
||||
|
||||
#define CLASS_DISCONNECTED(class) ((class)->disconnected(class))
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: DRVR_WAIT
|
||||
*
|
||||
* Description:
|
||||
* Wait for a device to be connected.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
* the class create() method.
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned when a device in connected. This function will not
|
||||
* return until either (1) a device is connected or (2) some failure occurs.
|
||||
* On a failure, a negated errno value is returned indicating the nature of
|
||||
* the failure
|
||||
*
|
||||
* Assumptions:
|
||||
* This function will *not* be called from an interrupt handler.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#define DRVR_WAIT(drvr) ((drvr)->wait(drvr))
|
||||
|
||||
/************************************************************************************
|
||||
* Name: DRVR_ENUMERATE
|
||||
*
|
||||
* Description:
|
||||
* Enumerate the connected device. This function will enqueue the
|
||||
* enumeration process. As part of this enumeration process, the driver
|
||||
* will (1) get the device's configuration descriptor, (2) extract the class
|
||||
* ID info from the configuration descriptor, (3) call usbhost_findclass()
|
||||
* to find the class that supports this device, (4) call the create()
|
||||
* method on the struct usbhost_registry_s interface to get a class
|
||||
* instance, and finally (5) call the configdesc() method of the struct
|
||||
* usbhost_class_s interface. After that, the class is in charge of the
|
||||
* sequence of operations.
|
||||
* Enumerate the connected device. As part of this enumeration process,
|
||||
* the driver will (1) get the device's configuration descriptor, (2)
|
||||
* extract the class ID info from the configuration descriptor, (3) call
|
||||
* usbhost_findclass() to find the class that supports this device, (4)
|
||||
* call the create() method on the struct usbhost_registry_s interface
|
||||
* to get a class instance, and finally (5) call the configdesc() method
|
||||
* of the struct usbhost_class_s interface. After that, the class is in
|
||||
* charge of the sequence of operations.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
@ -389,15 +411,18 @@ struct usbhost_class_s
|
||||
struct usbhost_epdesc_s;
|
||||
struct usbhost_driver_s
|
||||
{
|
||||
/* Enumerate the connected device. This function will enqueue the
|
||||
* enumeration process. As part of this enumeration process, the driver
|
||||
* will (1) get the device's configuration descriptor, (2) extract the class
|
||||
* ID info from the configuration descriptor, (3) call usbhost_findclass()
|
||||
* to find the class that supports this device, (4) call the create()
|
||||
* method on the struct usbhost_registry_s interface to get a class
|
||||
* instance, and finally (5) call the configdesc() method of the struct
|
||||
* usbhost_class_s interface. After that, the class is in charge of the
|
||||
* sequence of operations.
|
||||
/* Wait for a device to connect. */
|
||||
|
||||
int (*wait)(FAR struct usbhost_driver_s *drvr);
|
||||
|
||||
/* Enumerate the connected device. As part of this enumeration process,
|
||||
* the driver will (1) get the device's configuration descriptor, (2)
|
||||
* extract the class ID info from the configuration descriptor, (3) call
|
||||
* usbhost_findclass() to find the class that supports this device, (4)
|
||||
* call the create() method on the struct usbhost_registry_s interface
|
||||
* to get a class instance, and finally (5) call the configdesc() method
|
||||
* of the struct usbhost_class_s interface. After that, the class is in
|
||||
* charge of the sequence of operations.
|
||||
*/
|
||||
|
||||
int (*enumerate)(FAR struct usbhost_driver_s *drvr);
|
||||
@ -539,6 +564,33 @@ EXTERN const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_i
|
||||
|
||||
EXTERN int usbhost_storageinit(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: up_usbhostinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize USB host device controller hardware.
|
||||
*
|
||||
* Input Parameters:
|
||||
* controller -- If the device supports more than USB host controller, then
|
||||
* this identifies which controller is being intialized. Normally, this
|
||||
* is just zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* And instance of the USB host interface. The controlling task should
|
||||
* use this interface to (1) call the wait() method to wait for a device
|
||||
* to be connected, and (2) call the enumerate() method to bind the device
|
||||
* to a class driver.
|
||||
*
|
||||
* Assumptions:
|
||||
* - This function should called in the initialization sequence in order
|
||||
* to initialize the USB device functionality.
|
||||
* - Class drivers should be initialized prior to calling this function.
|
||||
* Otherwise, there is a race condition if the device is already connected.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
EXTERN FAR struct usbhost_driver_s *usbhost_initialize(int controller);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user