Port hub support to LPC31 from SAMA5; Updated Olimex-LPC-H3131 for hub support and refresh configurations
This commit is contained in:
parent
d88d10830e
commit
eabbb6ede1
@ -2951,7 +2951,7 @@ static void lpc17_asynch_completion(struct lpc17_usbhost_s *priv,
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lcp17_asynch
|
||||
* Name: lpc17_asynch
|
||||
*
|
||||
* Description:
|
||||
* Process a request to handle a transfer descriptor. This method will
|
||||
|
@ -60,6 +60,7 @@ config LPC31_SPI
|
||||
config LPC31_USBOTG
|
||||
bool "USB OTG"
|
||||
default n
|
||||
select USBHOST_HAVE_ASYNCH
|
||||
|
||||
config LPC31_MCI
|
||||
bool "MCI"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* arch/arm/src/lpc31xx/lpc31_ehci.c
|
||||
*
|
||||
* Copyright (C) 2013-2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2013-2015 Gregory Nutt. All rights reserved.
|
||||
* Authors: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -53,6 +53,7 @@
|
||||
#include <nuttx/usb/usb.h>
|
||||
#include <nuttx/usb/usbhost.h>
|
||||
#include <nuttx/usb/ehci.h>
|
||||
#include <nuttx/usb/usbhost_devaddr.h>
|
||||
#include <nuttx/usb/usbhost_trace.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
@ -178,6 +179,11 @@
|
||||
# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS)
|
||||
#endif
|
||||
|
||||
/* Port numbers */
|
||||
|
||||
#define RHPNDX(rh) ((rh)->hport.hport.port)
|
||||
#define RHPORT(rh) (RHPNDX(rh)+1)
|
||||
|
||||
/*******************************************************************************
|
||||
* Private Types
|
||||
*******************************************************************************/
|
||||
@ -257,12 +263,11 @@ struct lpc31_rhport_s
|
||||
|
||||
volatile bool connected; /* Connected to device */
|
||||
volatile bool lowspeed; /* Low speed device attached */
|
||||
uint8_t rhpndx; /* Root hub port index */
|
||||
struct lpc31_epinfo_s ep0; /* EP0 endpoint info */
|
||||
struct lpc31_epinfo_s ep0; /* EP0 endpoint info */
|
||||
|
||||
/* The bound device class driver */
|
||||
/* This is the hub port description understood by class drivers */
|
||||
|
||||
struct usbhost_class_s *class;
|
||||
struct usbhost_roothubport_s hport;
|
||||
};
|
||||
|
||||
/* This structure retains the overall state of the USB host controller */
|
||||
@ -270,6 +275,7 @@ struct lpc31_rhport_s
|
||||
struct lpc31_ehci_s
|
||||
{
|
||||
volatile bool pscwait; /* TRUE: Thread is waiting for port status change event */
|
||||
|
||||
sem_t exclsem; /* Support mutually exclusive access */
|
||||
sem_t pscsem; /* Semaphore to wait for port status change events */
|
||||
|
||||
@ -278,6 +284,12 @@ struct lpc31_ehci_s
|
||||
struct lpc31_list_s *qtdfree; /* List of free Queue Element Transfer Descriptor (qTD) */
|
||||
struct work_s work; /* Supports interrupt bottom half */
|
||||
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
/* Used to pass external hub port events */
|
||||
|
||||
volatile struct usbhost_hubport_s *hport;
|
||||
#endif
|
||||
|
||||
/* Root hub ports */
|
||||
|
||||
struct lpc31_rhport_s rhport[LPC31_EHCI_NRHPORT];
|
||||
@ -291,20 +303,20 @@ enum usbhost_trace1codes_e
|
||||
__TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */
|
||||
|
||||
EHCI_TRACE1_SYSTEMERROR, /* EHCI ERROR: System error */
|
||||
EHCI_TRACE1_QTDFOREACH_FAILED, /* EHCI ERROR: sam_qtd_foreach failed */
|
||||
EHCI_TRACE1_QTDFOREACH_FAILED, /* EHCI ERROR: lpc31_qtd_foreach failed */
|
||||
EHCI_TRACE1_QHALLOC_FAILED, /* EHCI ERROR: Failed to allocate a QH */
|
||||
EHCI_TRACE1_BUFTOOBIG, /* EHCI ERROR: Buffer too big */
|
||||
EHCI_TRACE1_REQQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate request qTD */
|
||||
EHCI_TRACE1_ADDBPL_FAILED, /* EHCI ERROR: sam_qtd_addbpl failed */
|
||||
EHCI_TRACE1_ADDBPL_FAILED, /* EHCI ERROR: lpc31_qtd_addbpl failed */
|
||||
EHCI_TRACE1_DATAQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate data buffer qTD */
|
||||
EHCI_TRACE1_DEVDISCONNECTED, /* EHCI ERROR: Device disconnected */
|
||||
EHCI_TRACE1_QHCREATE_FAILED, /* EHCI ERROR: sam_qh_create failed */
|
||||
EHCI_TRACE1_QTDSETUP_FAILED, /* EHCI ERROR: sam_qtd_setupphase failed */
|
||||
EHCI_TRACE1_QHCREATE_FAILED, /* EHCI ERROR: lpc31_qh_create failed */
|
||||
EHCI_TRACE1_QTDSETUP_FAILED, /* EHCI ERROR: lpc31_qtd_setupphase failed */
|
||||
|
||||
EHCI_TRACE1_QTDDATA_FAILED, /* EHCI ERROR: sam_qtd_dataphase failed */
|
||||
EHCI_TRACE1_QTDSTATUS_FAILED, /* EHCI ERROR: sam_qtd_statusphase failed */
|
||||
EHCI_TRACE1_QTDDATA_FAILED, /* EHCI ERROR: lpc31_qtd_dataphase failed */
|
||||
EHCI_TRACE1_QTDSTATUS_FAILED, /* EHCI ERROR: lpc31_qtd_statusphase failed */
|
||||
EHCI_TRACE1_TRANSFER_FAILED, /* EHCI ERROR: Transfer failed */
|
||||
EHCI_TRACE1_QHFOREACH_FAILED, /* EHCI ERROR: sam_qh_foreach failed: */
|
||||
EHCI_TRACE1_QHFOREACH_FAILED, /* EHCI ERROR: lpc31_qh_foreach failed: */
|
||||
EHCI_TRACE1_SYSERR_INTR, /* EHCI: Host System Error Interrup */
|
||||
EHCI_TRACE1_USBERR_INTR, /* EHCI: USB Error Interrupt (USBERRINT) Interrupt */
|
||||
EHCI_TRACE1_EPALLOC_FAILED, /* EHCI ERROR: Failed to allocate EP info structure */
|
||||
@ -314,7 +326,7 @@ enum usbhost_trace1codes_e
|
||||
|
||||
EHCI_TRACE1_QTDPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the qTD pool */
|
||||
EHCI_TRACE1_PERFLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the periodic frame list */
|
||||
EHCI_TRACE1_RESET_FAILED, /* EHCI ERROR: sam_reset failed */
|
||||
EHCI_TRACE1_RESET_FAILED, /* EHCI ERROR: lpc31_reset failed */
|
||||
EHCI_TRACE1_RUN_FAILED, /* EHCI ERROR: EHCI Failed to run */
|
||||
EHCI_TRACE1_IRQATTACH_FAILED, /* EHCI ERROR: Failed to attach IRQ */
|
||||
|
||||
@ -485,13 +497,14 @@ static int lpc31_ehci_interrupt(int irq, FAR void *context);
|
||||
/* USB Host Controller Operations **********************************************/
|
||||
|
||||
static int lpc31_wait(FAR struct usbhost_connection_s *conn,
|
||||
FAR const bool *connected);
|
||||
static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx);
|
||||
FAR struct usbhost_hubport_s **hport);
|
||||
static int lpc31_rh_enumerate(FAR struct usbhost_connection_s *conn,
|
||||
FAR struct usbhost_hubport_s *hport);
|
||||
static int lpc31_enumerate(FAR struct usbhost_connection_s *conn,
|
||||
FAR struct usbhost_hubport_s *hport);
|
||||
|
||||
static int lpc31_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
||||
uint16_t maxpacketsize);
|
||||
static int lpc31_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||
FAR struct usbhost_devinfo_s *devinfo);
|
||||
static int lpc31_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize);
|
||||
static int lpc31_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
||||
static int lpc31_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
||||
@ -501,12 +514,22 @@ static int lpc31_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
|
||||
static int lpc31_ioalloc(FAR struct usbhost_driver_s *drvr,
|
||||
FAR uint8_t **buffer, size_t buflen);
|
||||
static int lpc31_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
|
||||
static int lpc31_ctrlin(FAR struct usbhost_driver_s *drvr,
|
||||
static int lpc31_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
FAR const struct usb_ctrlreq_s *req, FAR uint8_t *buffer);
|
||||
static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr,
|
||||
static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
FAR const struct usb_ctrlreq_s *req, FAR const uint8_t *buffer);
|
||||
static int lpc31_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
||||
FAR uint8_t *buffer, size_t buflen);
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
static int lpc31_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
||||
FAR uint8_t *buffer, size_t buflen, usbhost_asynch_t callback,
|
||||
FAR void *arg);
|
||||
static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
||||
#endif
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
static int lpc31_connect(FAR struct usbhost_driver_s *drvr,
|
||||
FAR struct usbhost_hubport_s *hport, bool connected);
|
||||
#endif
|
||||
static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr);
|
||||
|
||||
/* Initialization **************************************************************/
|
||||
@ -581,20 +604,20 @@ static struct lpc31_qtd_s *g_qtdpool;
|
||||
static const struct lpc31_ehci_trace_s g_trace1[TRACE1_NSTRINGS] =
|
||||
{
|
||||
TRENTRY(EHCI_TRACE1_SYSTEMERROR, TR_FMT1, "EHCI ERROR: System error: %06x\n"),
|
||||
TRENTRY(EHCI_TRACE1_QTDFOREACH_FAILED, TR_FMT1, "EHCI ERROR: sam_qtd_foreach failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_QTDFOREACH_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_foreach failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_QHALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate a QH\n"),
|
||||
TRENTRY(EHCI_TRACE1_BUFTOOBIG, TR_FMT1, "EHCI ERROR: Buffer too big. Remaining %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_REQQTDALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate request qTD"),
|
||||
TRENTRY(EHCI_TRACE1_ADDBPL_FAILED, TR_FMT1, "EHCI ERROR: sam_qtd_addbpl failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_ADDBPL_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_addbpl failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_DATAQTDALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate data buffer qTD, 0"),
|
||||
TRENTRY(EHCI_TRACE1_DEVDISCONNECTED, TR_FMT1, "EHCI ERROR: Device disconnected %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_QHCREATE_FAILED, TR_FMT1, "EHCI ERROR: sam_qh_create failed\n"),
|
||||
TRENTRY(EHCI_TRACE1_QTDSETUP_FAILED, TR_FMT1, "EHCI ERROR: sam_qtd_setupphase failed\n"),
|
||||
TRENTRY(EHCI_TRACE1_QHCREATE_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qh_create failed\n"),
|
||||
TRENTRY(EHCI_TRACE1_QTDSETUP_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_setupphase failed\n"),
|
||||
|
||||
TRENTRY(EHCI_TRACE1_QTDDATA_FAILED, TR_FMT1, "EHCI ERROR: sam_qtd_dataphase failed\n"),
|
||||
TRENTRY(EHCI_TRACE1_QTDSTATUS_FAILED, TR_FMT1, "EHCI ERROR: sam_qtd_statusphase failed\n"),
|
||||
TRENTRY(EHCI_TRACE1_QTDDATA_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_dataphase failed\n"),
|
||||
TRENTRY(EHCI_TRACE1_QTDSTATUS_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qtd_statusphase failed\n"),
|
||||
TRENTRY(EHCI_TRACE1_TRANSFER_FAILED, TR_FMT1, "EHCI ERROR: Transfer failed %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_QHFOREACH_FAILED, TR_FMT1, "EHCI ERROR: sam_qh_foreach failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_QHFOREACH_FAILED, TR_FMT1, "EHCI ERROR: lpc31_qh_foreach failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_SYSERR_INTR, TR_FMT1, "EHCI: Host System Error Interrupt\n"),
|
||||
TRENTRY(EHCI_TRACE1_USBERR_INTR, TR_FMT1, "EHCI: USB Error Interrupt (USBERRINT) Interrupt: %06x\n"),
|
||||
TRENTRY(EHCI_TRACE1_EPALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate EP info structure\n"),
|
||||
@ -604,7 +627,7 @@ static const struct lpc31_ehci_trace_s g_trace1[TRACE1_NSTRINGS] =
|
||||
|
||||
TRENTRY(EHCI_TRACE1_QTDPOOLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the qTD pool\n"),
|
||||
TRENTRY(EHCI_TRACE1_PERFLALLOC_FAILED, TR_FMT1, "EHCI ERROR: Failed to allocate the periodic frame list\n"),
|
||||
TRENTRY(EHCI_TRACE1_RESET_FAILED, TR_FMT1, "EHCI ERROR: sam_reset failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_RESET_FAILED, TR_FMT1, "EHCI ERROR: lpc31_reset failed: %d\n"),
|
||||
TRENTRY(EHCI_TRACE1_RUN_FAILED, TR_FMT1, "EHCI ERROR: EHCI Failed to run: USBSTS=%06x\n"),
|
||||
TRENTRY(EHCI_TRACE1_IRQATTACH_FAILED, TR_FMT1, "EHCI ERROR: Failed to attach IRQ%d\n"),
|
||||
|
||||
@ -1607,6 +1630,7 @@ static struct lpc31_qh_s *lpc31_qh_create(struct lpc31_rhport_s *rhport,
|
||||
struct lpc31_epinfo_s *epinfo)
|
||||
{
|
||||
struct lpc31_qh_s *qh;
|
||||
uint32_t rhpndx;
|
||||
uint32_t regval;
|
||||
|
||||
/* Allocate a new queue head structure */
|
||||
@ -1636,9 +1660,9 @@ static struct lpc31_qh_s *lpc31_qh_create(struct lpc31_rhport_s *rhport,
|
||||
* RL NAK count reloaded 8
|
||||
*/
|
||||
|
||||
regval = ((uint32_t)epinfo->devaddr << QH_EPCHAR_DEVADDR_SHIFT) |
|
||||
((uint32_t)epinfo->epno << QH_EPCHAR_ENDPT_SHIFT) |
|
||||
((uint32_t)epinfo->speed << QH_EPCHAR_EPS_SHIFT) |
|
||||
regval = ((uint32_t)epinfo->devaddr << QH_EPCHAR_DEVADDR_SHIFT) |
|
||||
((uint32_t)epinfo->epno << QH_EPCHAR_ENDPT_SHIFT) |
|
||||
((uint32_t)EHCI_SPEED(epinfo->speed) << QH_EPCHAR_EPS_SHIFT) |
|
||||
QH_EPCHAR_DTC |
|
||||
((uint32_t)epinfo->maxpacket << QH_EPCHAR_MAXPKT_SHIFT) |
|
||||
((uint32_t)8 << QH_EPCHAR_RL_SHIFT);
|
||||
@ -1649,7 +1673,7 @@ static struct lpc31_qh_s *lpc31_qh_create(struct lpc31_rhport_s *rhport,
|
||||
* Otherwise it should always set this bit to a zero."
|
||||
*/
|
||||
|
||||
if (epinfo->speed != EHCI_HIGH_SPEED &&
|
||||
if (epinfo->speed != USB_SPEED_HIGH &&
|
||||
epinfo->xfrtype == USB_EP_ATTR_XFER_CONTROL)
|
||||
{
|
||||
regval |= QH_EPCHAR_C;
|
||||
@ -1673,9 +1697,10 @@ static struct lpc31_qh_s *lpc31_qh_create(struct lpc31_rhport_s *rhport,
|
||||
* and HUB device address to be included here.
|
||||
*/
|
||||
|
||||
regval = ((uint32_t)0 << QH_EPCAPS_HUBADDR_SHIFT) |
|
||||
((uint32_t)(rhport->rhpndx + 1) << QH_EPCAPS_PORT_SHIFT) |
|
||||
((uint32_t)1 << QH_EPCAPS_MULT_SHIFT);
|
||||
rhpndx = RHPNDX(rhport);
|
||||
regval = ((uint32_t)0 << QH_EPCAPS_HUBADDR_SHIFT) |
|
||||
((uint32_t)(rhpndx + 1) << QH_EPCAPS_PORT_SHIFT) |
|
||||
((uint32_t)1 << QH_EPCAPS_MULT_SHIFT);
|
||||
|
||||
#ifndef CONFIG_USBHOST_INT_DISABLE
|
||||
if (epinfo->xfrtype == USB_EP_ATTR_XFER_INT)
|
||||
@ -2015,7 +2040,7 @@ static ssize_t lpc31_async_transfer(struct lpc31_rhport_s *rhport,
|
||||
usbhost_vtrace2(EHCI_VTRACE2_ASYNCXFR, epinfo->epno, buflen);
|
||||
#else
|
||||
uvdbg("RHport%d EP%d: buffer=%p, buflen=%d, req=%p\n",
|
||||
rhport->rhpndx+1, epinfo->epno, buffer, buflen, req);
|
||||
RHPORT(rhport), epinfo->epno, buffer, buflen, req);
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(rhport && epinfo);
|
||||
@ -2374,7 +2399,7 @@ static ssize_t lpc31_intr_transfer(struct lpc31_rhport_s *rhport,
|
||||
usbhost_vtrace2(EHCI_VTRACE2_INTRXFR, epinfo->epno, buflen);
|
||||
#else
|
||||
uvdbg("RHport%d EP%d: buffer=%p, buflen=%d\n",
|
||||
rhport->rhpndx+1, epinfo->epno, buffer, buflen);
|
||||
RHPORT(rhport), epinfo->epno, buffer, buflen);
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(rhport && epinfo && buffer && buflen > 0);
|
||||
@ -2791,6 +2816,7 @@ static inline void lpc31_ioc_bottomhalf(void)
|
||||
static inline void lpc31_portsc_bottomhalf(void)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport;
|
||||
struct usbhost_hubport_s *hport;
|
||||
uint32_t portsc;
|
||||
int rhpndx;
|
||||
|
||||
@ -2853,12 +2879,13 @@ static inline void lpc31_portsc_bottomhalf(void)
|
||||
|
||||
/* Are we bound to a class instance? */
|
||||
|
||||
if (rhport->class)
|
||||
hport = &rhport->hport.hport;
|
||||
if (hport->devclass)
|
||||
{
|
||||
/* Yes.. Disconnect the class */
|
||||
|
||||
CLASS_DISCONNECTED(rhport->class);
|
||||
rhport->class = NULL;
|
||||
CLASS_DISCONNECTED(hport->devclass);
|
||||
hport->devclass = NULL;
|
||||
}
|
||||
|
||||
/* Notify any waiters for the Root Hub Status change
|
||||
@ -3126,23 +3153,20 @@ static int lpc31_ehci_interrupt(int irq, FAR void *context)
|
||||
* Name: lpc31_wait
|
||||
*
|
||||
* Description:
|
||||
* Wait for a device to be connected or disconnected to/from a root hub port.
|
||||
* Wait for a device to be connected or disconnected to/from a hub port.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The USB host connection instance obtained as a parameter from the call to
|
||||
* the USB driver initialization logic.
|
||||
* connected - A pointer to an array of 3 boolean values corresponding to
|
||||
* root hubs 1, 2, and 3. For each boolean value: TRUE: Wait for a device
|
||||
* to be connected on the root hub; FALSE: wait for device to be
|
||||
* disconnected from the root hub.
|
||||
* hport - The location to return the hub port descriptor that detected the
|
||||
* connection related event.
|
||||
*
|
||||
* Returned Values:
|
||||
* And index [0, 1, or 2} corresponding to the root hub port number {1, 2,
|
||||
* or 3} is returned when a device is connected or disconnected. This
|
||||
* function will not return until either (1) a device is connected or
|
||||
* disconnected to/from any root hub port or until (2) some failure occurs.
|
||||
* On a failure, a negated errno value is returned indicating the nature of
|
||||
* the failure
|
||||
* Zero (OK) is returned on success when a device in connected or
|
||||
* disconnected. This function will not return until either (1) a device is
|
||||
* connected or disconnect to/from any hub port or until (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.
|
||||
@ -3151,7 +3175,7 @@ static int lpc31_ehci_interrupt(int irq, FAR void *context)
|
||||
*******************************************************************************/
|
||||
|
||||
static int lpc31_wait(FAR struct usbhost_connection_s *conn,
|
||||
FAR const bool *connected)
|
||||
FAR struct usbhost_hubport_s **hport)
|
||||
{
|
||||
irqstate_t flags;
|
||||
int rhpndx;
|
||||
@ -3167,21 +3191,49 @@ static int lpc31_wait(FAR struct usbhost_connection_s *conn,
|
||||
|
||||
for (rhpndx = 0; rhpndx < LPC31_EHCI_NRHPORT; rhpndx++)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport;
|
||||
struct usbhost_hubport_s *connport;
|
||||
|
||||
/* Has the connection state changed on the RH port? */
|
||||
|
||||
if (g_ehci.rhport[rhpndx].connected != connected[rhpndx])
|
||||
rhport = &g_ehci.rhport[rhpndx];
|
||||
connport = &rhport->hport.hport;
|
||||
if (rhport->connected != connport->connected)
|
||||
{
|
||||
/* Yes.. Return the RH port number to inform the caller which
|
||||
/* Yes.. Return the RH port to inform the caller which
|
||||
* port has the connection change.
|
||||
*/
|
||||
|
||||
*hport = connport;
|
||||
irqrestore(flags);
|
||||
|
||||
usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP,
|
||||
rhpndx + 1, g_ehci.rhport[rhpndx].connected);
|
||||
return rhpndx;
|
||||
rhpndx + 1, rhport->conected);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
/* Is a device connected to an external hub? */
|
||||
|
||||
if (g_ehci.hport)
|
||||
{
|
||||
volatile struct usbhost_hubport_s *connport;
|
||||
|
||||
/* Yes.. return the external hub port */
|
||||
|
||||
connport = g_ehci.hport;
|
||||
g_ehci.hport = NULL;
|
||||
|
||||
*hport = (struct usbhost_hubport_s *)connport;
|
||||
irqrestore(flags);
|
||||
|
||||
usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP,
|
||||
connport->port + 1, connport->connected);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* No changes on any port. Wait for a connection/disconnection event
|
||||
* and check again
|
||||
*/
|
||||
@ -3200,32 +3252,35 @@ static int lpc31_wait(FAR struct usbhost_connection_s *conn,
|
||||
* 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
|
||||
* to get a class instance, and finally (5) call the connect() method
|
||||
* of the struct usbhost_class_s interface. After that, the class is in
|
||||
* charge of the sequence of operations.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The USB host connection instance obtained as a parameter from the call to
|
||||
* the USB driver initialization logic.
|
||||
* rphndx - Root hub port index. 0-(n-1) corresponds to root hub port 1-n.
|
||||
* conn - The USB host connection instance obtained as a parameter from
|
||||
* the call to the USB driver initialization logic.
|
||||
* hport - The descriptor of the hub port that has the newly connected
|
||||
* device.
|
||||
*
|
||||
* Returned Values:
|
||||
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||
* returned indicating the nature of the failure
|
||||
*
|
||||
* Assumptions:
|
||||
* - Only a single class bound to a single device is supported.
|
||||
* - Called from a single thread so no mutual exclusion is required.
|
||||
* - Never called from an interrupt handler.
|
||||
* This function will *not* be called from an interrupt handler.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
static int lpc31_rh_enumerate(FAR struct usbhost_connection_s *conn,
|
||||
FAR struct usbhost_hubport_s *hport)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport;
|
||||
volatile uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
int ret;
|
||||
int rhpndx;
|
||||
|
||||
DEBUGASSERT(conn != NULL && hport != NULL);
|
||||
rhpndx = hport->port;
|
||||
|
||||
DEBUGASSERT(rhpndx >= 0 && rhpndx < LPC31_EHCI_NRHPORT);
|
||||
rhport = &g_ehci.rhport[rhpndx];
|
||||
@ -3299,7 +3354,7 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
* repeat."
|
||||
*/
|
||||
|
||||
rhport->ep0.speed = EHCI_LOW_SPEED;
|
||||
rhport->ep0.speed = USB_SPEED_LOW;
|
||||
|
||||
#if 0 /* The LPC31xx does not support a companion host controller */
|
||||
regval |= EHCI_PORTSC_OWNER;
|
||||
@ -3315,7 +3370,7 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
{
|
||||
/* Assume full-speed for now */
|
||||
|
||||
rhport->ep0.speed = EHCI_FULL_SPEED;
|
||||
rhport->ep0.speed = USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/* Put the root hub port in reset.
|
||||
@ -3340,7 +3395,7 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
* write a zero to the Port Enable bit."
|
||||
*/
|
||||
|
||||
regaddr = &HCOR->portsc[rhport->rhpndx];
|
||||
regaddr = &HCOR->portsc[RHPNDX(rhport)];
|
||||
regval = lpc31_getreg(regaddr);
|
||||
regval &= ~EHCI_PORTSC_PE;
|
||||
regval |= EHCI_PORTSC_RESET;
|
||||
@ -3412,7 +3467,7 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
{
|
||||
/* High speed device */
|
||||
|
||||
rhport->ep0.speed = EHCI_HIGH_SPEED;
|
||||
rhport->ep0.speed = USB_SPEED_HIGH;
|
||||
}
|
||||
else if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_FS)
|
||||
{
|
||||
@ -3453,16 +3508,35 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
DEBUGASSERT((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_LS)
|
||||
}
|
||||
|
||||
/* Let the common usbhost_enumerate do all of the real work. Note that the
|
||||
* FunctionAddress (USB address) is set to the root hub port number + 1
|
||||
* for now.
|
||||
*
|
||||
* REVISIT: Hub support will require better device address assignment.
|
||||
* See include/nuttx/usb/usbhost_devaddr.h.
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int lpc31_enumerate(FAR struct usbhost_connection_s *conn,
|
||||
FAR struct usbhost_hubport_s *hport)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* If this is a connection on the root hub, then we need to go to
|
||||
* little more effort to get the device speed. If it is a connection
|
||||
* on an external hub, then we already have that information.
|
||||
*/
|
||||
|
||||
usbhost_vtrace2(EHCI_VTRACE2_CLASSENUM, rhpndx+1, rhpndx+1);
|
||||
ret = usbhost_enumerate(&g_ehci.rhport[rhpndx].drvr, rhpndx+1, &rhport->class);
|
||||
DEBUGASSERT(hport);
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
if (ROOTHUB(hport))
|
||||
#endif
|
||||
{
|
||||
ret = lpc31_rh_enumerate(conn, hport);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Then let the common usbhost_enumerate do the real enumeration. */
|
||||
|
||||
usbhost_vtrace1(EHCI_VTRACE2_CLASSENUM, hport->port);
|
||||
ret = usbhost_enumerate(hport, &hport->devclass);
|
||||
if (ret < 0)
|
||||
{
|
||||
usbhost_trace2(EHCI_TRACE2_CLASSENUM_FAILED, rhpndx+1, -ret);
|
||||
@ -3485,6 +3559,7 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
* funcaddr - The USB address of the function containing the endpoint that EP0
|
||||
* controls. A funcaddr of zero will be received if no address is yet assigned
|
||||
* to the device.
|
||||
* speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH
|
||||
* maxpacketsize - The maximum number of bytes that can be sent to or
|
||||
* received from the endpoint in a single data packet
|
||||
*
|
||||
@ -3497,17 +3572,12 @@ static int lpc31_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx)
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static int lpc31_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
||||
uint16_t maxpacketsize)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr;
|
||||
struct lpc31_epinfo_s *epinfo;
|
||||
static int lpc31_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize)
|
||||
{
|
||||
struct lpc31_epinfo_s *epinfo = (struct lpc31_epinfo_s *)ep0;
|
||||
|
||||
DEBUGASSERT(rhport &&
|
||||
funcaddr >= 0 && funcaddr <= LPC31_EHCI_NRHPORT &&
|
||||
maxpacketsize < 2048);
|
||||
|
||||
epinfo = &rhport->ep0;
|
||||
DEBUGASSERT(drvr != NULL && epinfo != NULL && maxpacketsize < 2048);
|
||||
|
||||
/* We must have exclusive access to the EHCI data structures. */
|
||||
|
||||
@ -3522,55 +3592,6 @@ static int lpc31_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
|
||||
return OK;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: lpc31_getdevinfo
|
||||
*
|
||||
* Description:
|
||||
* Get information about the connected device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
* the class create() method.
|
||||
* devinfo - A pointer to memory provided by the caller in which to return the
|
||||
* device information.
|
||||
*
|
||||
* Returned Values:
|
||||
* On success, zero (OK) is returned. 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static int lpc31_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||
FAR struct usbhost_devinfo_s *devinfo)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr;
|
||||
struct lpc31_epinfo_s *epinfo;
|
||||
|
||||
DEBUGASSERT(drvr && devinfo);
|
||||
epinfo = &rhport->ep0;
|
||||
|
||||
switch (epinfo->speed)
|
||||
{
|
||||
case EHCI_LOW_SPEED:
|
||||
devinfo->speed = DEVINFO_SPEED_LOW;
|
||||
break;
|
||||
|
||||
case EHCI_FULL_SPEED:
|
||||
devinfo->speed = DEVINFO_SPEED_FULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
case EHCI_HIGH_SPEED:
|
||||
devinfo->speed = DEVINFO_SPEED_HIGH;
|
||||
break;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: lpc31_epalloc
|
||||
*
|
||||
@ -3582,7 +3603,7 @@ static int lpc31_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||
* the class create() method.
|
||||
* epdesc - Describes the endpoint to be allocated.
|
||||
* ep - A memory location provided by the caller in which to receive the
|
||||
* allocated endpoint desciptor.
|
||||
* allocated endpoint descriptor.
|
||||
*
|
||||
* Returned Values:
|
||||
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||
@ -3596,14 +3617,15 @@ static int lpc31_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||
static int lpc31_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr;
|
||||
struct lpc31_epinfo_s *epinfo;
|
||||
struct usbhost_hubport_s *hport;
|
||||
|
||||
/* Sanity check. NOTE that this method should only be called if a device is
|
||||
* connected (because we need a valid low speed indication).
|
||||
*/
|
||||
|
||||
DEBUGASSERT(drvr && epdesc && ep);
|
||||
DEBUGASSERT(drvr != 0 && epdesc != NULL && epdesc->hport != NULL && ep != NULL);
|
||||
hport = epdesc->hport;
|
||||
|
||||
/* Terse output only if we are tracing */
|
||||
|
||||
@ -3611,7 +3633,7 @@ static int lpc31_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||
usbhost_vtrace2(EHCI_VTRACE2_EPALLOC, epdesc->addr, epdesc->xfrtype);
|
||||
#else
|
||||
uvdbg("EP%d DIR=%s FA=%08x TYPE=%d Interval=%d MaxPacket=%d\n",
|
||||
epdesc->addr, epdesc->in ? "IN" : "OUT", epdesc->funcaddr,
|
||||
epdesc->addr, epdesc->in ? "IN" : "OUT", hport->funcaddr,
|
||||
epdesc->xfrtype, epdesc->interval, epdesc->mxpacketsize);
|
||||
#endif
|
||||
|
||||
@ -3632,13 +3654,13 @@ static int lpc31_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||
|
||||
epinfo->epno = epdesc->addr;
|
||||
epinfo->dirin = epdesc->in;
|
||||
epinfo->devaddr = epdesc->funcaddr;
|
||||
epinfo->devaddr = hport->funcaddr;
|
||||
#ifndef CONFIG_USBHOST_INT_DISABLE
|
||||
epinfo->interval = epdesc->interval;
|
||||
#endif
|
||||
epinfo->maxpacket = epdesc->mxpacketsize;
|
||||
epinfo->xfrtype = epdesc->xfrtype;
|
||||
epinfo->speed = rhport->ep0.speed;
|
||||
epinfo->speed = hport->speed;
|
||||
sem_init(&epinfo->iocsem, 0, 0);
|
||||
|
||||
/* Success.. return an opaque reference to the endpoint information structure
|
||||
@ -3844,9 +3866,9 @@ static int lpc31_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer)
|
||||
*
|
||||
* Description:
|
||||
* Process a IN or OUT request on the control endpoint. These methods
|
||||
* will enqueue the request and wait for it to complete. Only one transfer may
|
||||
* be queued; Neither these methods nor the transfer() method can be called
|
||||
* again until the control transfer functions returns.
|
||||
* will enqueue the request and wait for it to complete. Only one transfer
|
||||
* may be queued; Neither these methods nor the transfer() method can be
|
||||
* called again until the control transfer functions returns.
|
||||
*
|
||||
* These are blocking methods; these functions will not return until the
|
||||
* control transfer has completed.
|
||||
@ -3854,12 +3876,13 @@ static int lpc31_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer)
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
* the class create() method.
|
||||
* ep0 - The control endpoint to send/receive the control request.
|
||||
* req - Describes the request to be sent. This request must lie in memory
|
||||
* created by DRVR_ALLOC.
|
||||
* buffer - A buffer used for sending the request and for returning any
|
||||
* responses. This buffer must be large enough to hold the length value
|
||||
* in the request description. buffer must have been allocated using
|
||||
* DRVR_ALLOC
|
||||
* DRVR_ALLOC.
|
||||
*
|
||||
* NOTE: On an IN transaction, req and buffer may refer to the same allocated
|
||||
* memory.
|
||||
@ -3869,31 +3892,31 @@ static int lpc31_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer)
|
||||
* returned indicating the nature of the failure
|
||||
*
|
||||
* Assumptions:
|
||||
* - Only a single class bound to a single device is supported.
|
||||
* - Called from a single thread so no mutual exclusion is required.
|
||||
* - Never called from an interrupt handler.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
static int lpc31_ctrlin(FAR struct usbhost_driver_s *drvr,
|
||||
FAR const struct usb_ctrlreq_s *req,
|
||||
FAR uint8_t *buffer)
|
||||
static int lpc31_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
FAR const struct usb_ctrlreq_s *req,
|
||||
FAR uint8_t *buffer)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport = (struct lpc31_rhport_s *)drvr;
|
||||
struct lpc31_epinfo_s *ep0info = (struct lpc31_epinfo_s *)ep0;
|
||||
uint16_t len;
|
||||
ssize_t nbytes;
|
||||
|
||||
DEBUGASSERT(rhport && req);
|
||||
DEBUGASSERT(rhport != NULL && ep0info != NULL && req != NULL);
|
||||
|
||||
len = lpc31_read16(req->len);
|
||||
|
||||
/* Terse output only if we are tracing */
|
||||
|
||||
#ifdef CONFIG_USBHOST_TRACE
|
||||
usbhost_vtrace2(EHCI_VTRACE2_CTRLINOUT, rhport->rhpndx + 1, req->req);
|
||||
usbhost_vtrace2(EHCI_VTRACE2_CTRLINOUT, RHPORT(rhport), req->req);
|
||||
#else
|
||||
uvdbg("RHPort%d type: %02x req: %02x value: %02x%02x index: %02x%02x len: %04x\n",
|
||||
rhport->rhpndx + 1, req->type, req->req, req->value[1], req->value[0],
|
||||
RHPORT(rhport), req->type, req->req, req->value[1], req->value[0],
|
||||
req->index[1], req->index[0], len);
|
||||
#endif
|
||||
|
||||
@ -3903,20 +3926,20 @@ static int lpc31_ctrlin(FAR struct usbhost_driver_s *drvr,
|
||||
|
||||
/* Now perform the transfer */
|
||||
|
||||
nbytes = lpc31_async_transfer(rhport, &rhport->ep0, req, buffer, len);
|
||||
nbytes = lpc31_async_transfer(rhport, ep0info, req, buffer, len);
|
||||
lpc31_givesem(&g_ehci.exclsem);
|
||||
return nbytes >=0 ? OK : (int)nbytes;
|
||||
}
|
||||
|
||||
static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr,
|
||||
FAR const struct usb_ctrlreq_s *req,
|
||||
FAR const uint8_t *buffer)
|
||||
static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
FAR const struct usb_ctrlreq_s *req,
|
||||
FAR const uint8_t *buffer)
|
||||
{
|
||||
/* lpc31_ctrlin can handle both directions. We just need to work around the
|
||||
* differences in the function signatures.
|
||||
*/
|
||||
|
||||
return lpc31_ctrlin(drvr, req, (uint8_t *)buffer);
|
||||
return lpc31_ctrlin(drvr, ep0, req, (uint8_t *)buffer);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -3924,8 +3947,9 @@ static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr,
|
||||
*
|
||||
* Description:
|
||||
* Process a request to handle a transfer descriptor. This method will
|
||||
* enqueue the transfer request and return immediately. Only one transfer may be
|
||||
* queued;.
|
||||
* enqueue the transfer request, blocking until the transfer completes. Only
|
||||
* one transfer may be queued; Neither this method nor the ctrlin or
|
||||
* ctrlout methods can be called again until this function returns.
|
||||
*
|
||||
* This is a blocking method; this functions will not return until the
|
||||
* transfer has completed.
|
||||
@ -3950,7 +3974,6 @@ static int lpc31_ctrlout(FAR struct usbhost_driver_s *drvr,
|
||||
* EPIPE - Overrun errors
|
||||
*
|
||||
* Assumptions:
|
||||
* - Only a single class bound to a single device is supported.
|
||||
* - Called from a single thread so no mutual exclusion is required.
|
||||
* - Never called from an interrupt handler.
|
||||
*
|
||||
@ -3998,6 +4021,127 @@ static int lpc31_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
||||
return nbytes >=0 ? OK : (int)nbytes;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc31_asynch
|
||||
*
|
||||
* Description:
|
||||
* Process a request to handle a transfer descriptor. This method will
|
||||
* enqueue the transfer request and return immediately. When the transfer
|
||||
* completes, the the callback will be invoked with the provided transfer.
|
||||
* This method is useful for receiving interrupt transfers which may come
|
||||
* infrequently.
|
||||
*
|
||||
* Only one transfer may be queued; Neither this method nor the ctrlin or
|
||||
* ctrlout methods can be called again until the transfer completes.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
* the class create() method.
|
||||
* ep - The IN or OUT endpoint descriptor for the device endpoint on which to
|
||||
* perform the transfer.
|
||||
* buffer - A buffer containing the data to be sent (OUT endpoint) or received
|
||||
* (IN endpoint). buffer must have been allocated using DRVR_ALLOC
|
||||
* buflen - The length of the data to be sent or received.
|
||||
* callback - This function will be called when the transfer completes.
|
||||
* arg - The arbitrary parameter that will be passed to the callback function
|
||||
* when the transfer completes.
|
||||
*
|
||||
* Returned Values:
|
||||
* On success, zero (OK) is returned. 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
static int lpc31_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
||||
FAR uint8_t *buffer, size_t buflen,
|
||||
usbhost_asynch_t callback, FAR void *arg)
|
||||
{
|
||||
# error Not implemented
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_USBHOST_ASYNCH */
|
||||
|
||||
/************************************************************************************
|
||||
* Name: lpc31_cancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel a pending asynchronous transfer on an endpoint.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
* the class create() method.
|
||||
* ep - The IN or OUT endpoint descriptor for the device endpoint on which an
|
||||
* asynchronous transfer should be transferred.
|
||||
*
|
||||
* Returned Values:
|
||||
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||
* returned indicating the nature of the failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
static int lpc31_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep)
|
||||
{
|
||||
# error Not implemented
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_USBHOST_ASYNCH */
|
||||
|
||||
/************************************************************************************
|
||||
* Name: lpc31_connect
|
||||
*
|
||||
* Description:
|
||||
* New connections may be detected by an attached hub. This method is the
|
||||
* mechanism that is used by the hub class to introduce a new connection
|
||||
* and port description to the system.
|
||||
*
|
||||
* Input Parameters:
|
||||
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||
* the class create() method.
|
||||
* hport - The descriptor of the hub port that detected the connection
|
||||
* related event
|
||||
* connected - True: device connected; false: device disconnected
|
||||
*
|
||||
* Returned Values:
|
||||
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||
* returned indicating the nature of the failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
static int lpc31_connect(FAR struct usbhost_driver_s *drvr,
|
||||
FAR struct usbhost_hubport_s *hport,
|
||||
bool connected)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Set the connected/disconnected flag */
|
||||
|
||||
hport->connected = connected;
|
||||
ullvdbg("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO");
|
||||
|
||||
/* Report the connection event */
|
||||
|
||||
flags = irqsave();
|
||||
DEBUGASSERT(g_ehci.hport == NULL); /* REVISIT */
|
||||
|
||||
g_ehci.hport = hport;
|
||||
if (g_ehci.pscwait)
|
||||
{
|
||||
g_ehci.pscwait = false;
|
||||
lpc31_givesem(&g_ehci.pscsem);
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lpc31_disconnect
|
||||
*
|
||||
@ -4029,7 +4173,7 @@ static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr)
|
||||
/* Unbind the class */
|
||||
/* REVISIT: Is there more that needs to be done? */
|
||||
|
||||
rhport->class = NULL;
|
||||
rhport->hport.hport.devclass = NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -4041,7 +4185,7 @@ static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr)
|
||||
* Description:
|
||||
* Set the HCRESET bit in the USBCMD register to reset the EHCI hardware.
|
||||
*
|
||||
* Table 2-9. USBCMD – USB Command Register Bit Definitions
|
||||
* Table 2-9. USBCMD - USB Command Register Bit Definitions
|
||||
*
|
||||
* "Host Controller Reset (HCRESET) ... This control bit is used by software
|
||||
* to reset the host controller. The effects of this on Root Hub registers
|
||||
@ -4073,7 +4217,7 @@ static void lpc31_disconnect(FAR struct usbhost_driver_s *drvr)
|
||||
* on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* - Called during the initializaation of the EHCI.
|
||||
* - Called during the initialization of the EHCI.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
@ -4179,6 +4323,7 @@ static int lpc31_reset(void)
|
||||
|
||||
FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller)
|
||||
{
|
||||
FAR struct usbhost_hubport_s *hport;
|
||||
uint32_t regval;
|
||||
#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE)
|
||||
uint16_t regval16;
|
||||
@ -4225,12 +4370,10 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller)
|
||||
for (i = 0; i < LPC31_EHCI_NRHPORT; i++)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport = &g_ehci.rhport[i];
|
||||
rhport->rhpndx = i;
|
||||
|
||||
/* Initialize the device operations */
|
||||
|
||||
rhport->drvr.ep0configure = lpc31_ep0configure;
|
||||
rhport->drvr.getdevinfo = lpc31_getdevinfo;
|
||||
rhport->drvr.epalloc = lpc31_epalloc;
|
||||
rhport->drvr.epfree = lpc31_epfree;
|
||||
rhport->drvr.alloc = lpc31_alloc;
|
||||
@ -4240,14 +4383,36 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller)
|
||||
rhport->drvr.ctrlin = lpc31_ctrlin;
|
||||
rhport->drvr.ctrlout = lpc31_ctrlout;
|
||||
rhport->drvr.transfer = lpc31_transfer;
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
rhport->drvr.asynch = lpc31_asynch;
|
||||
rhport->drvr.cancel = lpc31_cancel;
|
||||
#endif
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
rhport->drvr.connect = lpc31_connect;
|
||||
#endif
|
||||
rhport->drvr.disconnect = lpc31_disconnect;
|
||||
|
||||
/* Initialize EP0 */
|
||||
|
||||
rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL;
|
||||
rhport->ep0.speed = EHCI_FULL_SPEED;
|
||||
rhport->ep0.speed = USB_SPEED_FULL;
|
||||
rhport->ep0.maxpacket = 8;
|
||||
sem_init(&rhport->ep0.iocsem, 0, 0);
|
||||
|
||||
/* Initialize the public port representation */
|
||||
|
||||
hport = &rhport->hport.hport;
|
||||
hport->drvr = &rhport->drvr;
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
hport->parent = NULL;
|
||||
#endif
|
||||
hport->ep0 = &rhport->ep0;
|
||||
hport->port = i;
|
||||
hport->speed = USB_SPEED_FULL;
|
||||
|
||||
/* Initialize function address generation logic */
|
||||
|
||||
usbhost_devaddr_initialize(&rhport->hport);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LPC31_EHCI_PREALLOCATE
|
||||
@ -4380,18 +4545,18 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller)
|
||||
/* "In order to initialize the host controller, software should perform the
|
||||
* following steps:
|
||||
*
|
||||
* • "Program the CTRLDSSEGMENT register with 4-Gigabyte segment where all
|
||||
* - "Program the CTRLDSSEGMENT register with 4-Gigabyte segment where all
|
||||
* of the interface data structures are allocated. [64-bit mode]
|
||||
* • "Write the appropriate value to the USBINTR register to enable the
|
||||
* - "Write the appropriate value to the USBINTR register to enable the
|
||||
* appropriate interrupts.
|
||||
* • "Write the base address of the Periodic Frame List to the PERIODICLIST
|
||||
* - "Write the base address of the Periodic Frame List to the PERIODICLIST
|
||||
* BASE register. If there are no work items in the periodic schedule,
|
||||
* all elements of the Periodic Frame List should have their T-Bits set
|
||||
* to a one.
|
||||
* • "Write the USBCMD register to set the desired interrupt threshold,
|
||||
* - "Write the USBCMD register to set the desired interrupt threshold,
|
||||
* frame list size (if applicable) and turn the host controller ON via
|
||||
* setting the Run/Stop bit.
|
||||
* • Write a 1 to CONFIGFLAG register to route all ports to the EHCI controller
|
||||
* - Write a 1 to CONFIGFLAG register to route all ports to the EHCI controller
|
||||
* ...
|
||||
*
|
||||
* "At this point, the host controller is up and running and the port registers
|
||||
|
@ -257,7 +257,7 @@ struct sam_ehci_s
|
||||
volatile struct usbhost_hubport_s *hport;
|
||||
#endif
|
||||
|
||||
/* Root hub ports */
|
||||
/* Root hub ports */
|
||||
|
||||
struct sam_rhport_s rhport[SAM_EHCI_NRHPORT];
|
||||
};
|
||||
@ -392,23 +392,20 @@ static int sam_ioalloc(FAR struct usbhost_driver_s *drvr,
|
||||
FAR uint8_t **buffer, size_t buflen);
|
||||
static int sam_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
|
||||
static int sam_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
FAR const struct usb_ctrlreq_s *req,
|
||||
FAR uint8_t *buffer);
|
||||
FAR const struct usb_ctrlreq_s *req, FAR uint8_t *buffer);
|
||||
static int sam_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0,
|
||||
FAR const struct usb_ctrlreq_s *req,
|
||||
FAR const uint8_t *buffer);
|
||||
FAR const struct usb_ctrlreq_s *req, FAR const uint8_t *buffer);
|
||||
static int sam_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
||||
FAR uint8_t *buffer, size_t buflen);
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
static int sam_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
||||
FAR uint8_t *buffer, size_t buflen,
|
||||
usbhost_asynch_t callback, FAR void *arg);
|
||||
FAR uint8_t *buffer, size_t buflen, usbhost_asynch_t callback,
|
||||
FAR void *arg);
|
||||
static int sam_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
||||
#endif
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
static int sam_connect(FAR struct usbhost_driver_s *drvr,
|
||||
FAR struct usbhost_hubport_s *hport,
|
||||
bool connected);
|
||||
FAR struct usbhost_hubport_s *hport, bool connected);
|
||||
#endif
|
||||
static void sam_disconnect(FAR struct usbhost_driver_s *drvr);
|
||||
|
||||
@ -2638,6 +2635,7 @@ static inline void sam_ioc_bottomhalf(void)
|
||||
static inline void sam_portsc_bottomhalf(void)
|
||||
{
|
||||
struct sam_rhport_s *rhport;
|
||||
struct usbhost_hubport_s *hport;
|
||||
uint32_t portsc;
|
||||
int rhpndx;
|
||||
|
||||
@ -2699,12 +2697,13 @@ static inline void sam_portsc_bottomhalf(void)
|
||||
|
||||
/* Are we bound to a class instance? */
|
||||
|
||||
if (rhport->hport.devclass)
|
||||
hport = &rhport->hport.hport;
|
||||
if (hport->devclass)
|
||||
{
|
||||
/* Yes.. Disconnect the class */
|
||||
|
||||
CLASS_DISCONNECTED(rhport->hport.devclass);
|
||||
rhport->hport.devclass = NULL;
|
||||
CLASS_DISCONNECTED(hport->devclass);
|
||||
hport->devclass = NULL;
|
||||
}
|
||||
|
||||
/* Notify any waiters for the Root Hub Status change
|
||||
@ -3036,20 +3035,25 @@ static int sam_wait(FAR struct usbhost_connection_s *conn,
|
||||
|
||||
for (rhpndx = 0; rhpndx < SAM_EHCI_NRHPORT; rhpndx++)
|
||||
{
|
||||
struct lpc31_rhport_s *rhport;
|
||||
struct usbhost_hubport_s *connport;
|
||||
|
||||
/* Has the connection state changed on the RH port? */
|
||||
|
||||
if (g_ehci.rhport[rhpndx].hport.connected != connected[rhpndx])
|
||||
rhport = &g_ehci.rhport[rhpndx];
|
||||
connport = &rhport->hport.hport;
|
||||
if (rhport->connected != connport->connected)
|
||||
{
|
||||
/* Yes.. Return the RH port to inform the caller which
|
||||
* port has the connection change.
|
||||
*/
|
||||
|
||||
*hport = &g_ehci.rhport[rhpndx].hport;
|
||||
connport->connected = rhport->connected;
|
||||
*hport = connport;
|
||||
irqrestore(flags);
|
||||
|
||||
usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP,
|
||||
rhpndx + 1,
|
||||
g_ehci.rhport[rhpndx].hport.connected);
|
||||
rhpndx + 1, rhport->conected);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
@ -3059,14 +3063,14 @@ static int sam_wait(FAR struct usbhost_connection_s *conn,
|
||||
|
||||
if (g_ehci.hport)
|
||||
{
|
||||
FAR volatile struct usbhost_hubport_s *connport;
|
||||
volatile struct usbhost_hubport_s *connport;
|
||||
|
||||
/* Yes.. return the external hub port */
|
||||
|
||||
connport = g_ehci.hport;
|
||||
g_ehci.hport = NULL;
|
||||
|
||||
*hport = connport;
|
||||
*hport = (struct usbhost_hubport_s *)connport;
|
||||
irqrestore(flags);
|
||||
|
||||
usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP,
|
||||
@ -3119,7 +3123,6 @@ static int sam_rh_enumerate(FAR struct usbhost_connection_s *conn,
|
||||
volatile uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
int rhpndx;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(conn != NULL && hport != NULL);
|
||||
rhpndx = hport->port;
|
||||
@ -3690,7 +3693,6 @@ static int sam_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer)
|
||||
* Name: sam_ctrlin and sam_ctrlout
|
||||
*
|
||||
* Description:
|
||||
* Description:
|
||||
* Process a IN or OUT request on the control endpoint. These methods
|
||||
* will enqueue the request and wait for it to complete. Only one transfer may be
|
||||
* queued; Neither these methods nor the transfer() method can be called again
|
||||
@ -3847,7 +3849,7 @@ static int sam_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep,
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: lcp17_asynch
|
||||
* Name: lpc17_asynch
|
||||
*
|
||||
* Description:
|
||||
* Process a request to handle a transfer descriptor. This method will
|
||||
@ -3998,7 +4000,7 @@ static void sam_disconnect(FAR struct usbhost_driver_s *drvr)
|
||||
/* Unbind the class */
|
||||
/* REVISIT: Is there more that needs to be done? */
|
||||
|
||||
rhport->hport.devclass = NULL;
|
||||
rhport->hport.hport.devclass = NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -4010,7 +4012,7 @@ static void sam_disconnect(FAR struct usbhost_driver_s *drvr)
|
||||
* Description:
|
||||
* Set the HCRESET bit in the USBCMD register to reset the EHCI hardware.
|
||||
*
|
||||
* Table 2-9. USBCMD – USB Command Register Bit Definitions
|
||||
* Table 2-9. USBCMD - USB Command Register Bit Definitions
|
||||
*
|
||||
* "Host Controller Reset (HCRESET) ... This control bit is used by software
|
||||
* to reset the host controller. The effects of this on Root Hub registers
|
||||
@ -4042,7 +4044,7 @@ static void sam_disconnect(FAR struct usbhost_driver_s *drvr)
|
||||
* on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* - Called during the initializaation of the EHCI.
|
||||
* - Called during the initialization of the EHCI.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
|
@ -648,7 +648,7 @@ Configurations
|
||||
RAMTest: Pattern test: 30000000 33554432 33333333 cccccccc
|
||||
RAMTest: Address-in-address test: 30000000 33554432
|
||||
|
||||
4. This configuration has been used to test USB host functionaly. USB
|
||||
4. This configuration has been used to test USB host functionality. USB
|
||||
host is *not* enabled by default. If you will to enable USB host
|
||||
support in the NSH configuration, please modify the NuttX
|
||||
configuration as follows:
|
||||
@ -657,7 +657,7 @@ Configurations
|
||||
|
||||
Drivers -> USB Host Driver Support
|
||||
CONFIG_USBHOST=y : General USB host support
|
||||
CONFIG_USBHOST_INT_DISABLE=y : Not needed (unless you use the keyboard)
|
||||
CONFIG_USBHOST_INT_DISABLE=n : Interrupt EPs need with hub, HID keyboard, and HID mouse
|
||||
CONFIG_USBHOST_ISOC_DISABLE=y : Not needed (or supported)
|
||||
|
||||
System Type -> Peripherals
|
||||
@ -667,11 +667,24 @@ Configurations
|
||||
CONFIG_LPC31_EHCI_BUFSIZE=128
|
||||
CONFIG_LPC31_EHCI_PREALLOCATE=y
|
||||
|
||||
Library Routines
|
||||
RTOS Features -> Work Queue Support
|
||||
CONFIG_SCHED_WORKQUEUE=y : Work queue support is needed
|
||||
CONFIG_SCHED_HPWORKSTACKSIZE=1536
|
||||
|
||||
b. USB Mass Storage Class. With this class enabled, you can support
|
||||
b. Hub Support.
|
||||
|
||||
Drivers -> USB Host Driver Support
|
||||
CONFIG_USBHOST_INT_DISABLE=n : Interrupt endpoint support needed
|
||||
CONFIG_USBHOST_HUB=y : Enable the hub class
|
||||
CONFIG_USBHOST_ASYNCH=y : Asynchonous I/O supported needed for hubs
|
||||
|
||||
System Type -> USB host configuration
|
||||
To be provided
|
||||
|
||||
Logic nesting becomes deeper with a hub and it may also be
|
||||
necessary to increase some stack sizes.
|
||||
|
||||
c. USB Mass Storage Class. With this class enabled, you can support
|
||||
connection of USB FLASH storage drives. Support for the USB
|
||||
mass storage class is enabled like this:
|
||||
|
||||
@ -718,7 +731,7 @@ Configurations
|
||||
|
||||
nsh> umount /mnt/flash
|
||||
|
||||
c. HID Keyboard support. The following support will enable support
|
||||
d. HID Keyboard support. The following support will enable support
|
||||
for certain keyboard devices (only the so-called "boot" keyboard
|
||||
class is supported):
|
||||
|
||||
|
@ -46,8 +46,9 @@ CONFIG_RAW_BINARY=y
|
||||
# Debug Options
|
||||
#
|
||||
# CONFIG_DEBUG is not set
|
||||
CONFIG_ARCH_HAVE_STACKCHECK=y
|
||||
# CONFIG_ARCH_HAVE_HEAPCHECK is not set
|
||||
CONFIG_ARCH_HAVE_STACKCHECK=y
|
||||
# CONFIG_STACK_COLORATION is not set
|
||||
# CONFIG_DEBUG_SYMBOLS is not set
|
||||
CONFIG_ARCH_HAVE_CUSTOMOPT=y
|
||||
# CONFIG_DEBUG_NOOPT is not set
|
||||
@ -76,6 +77,7 @@ CONFIG_ARCH="arm"
|
||||
# CONFIG_ARCH_CHIP_C5471 is not set
|
||||
# CONFIG_ARCH_CHIP_CALYPSO is not set
|
||||
# CONFIG_ARCH_CHIP_DM320 is not set
|
||||
# CONFIG_ARCH_CHIP_EFM32 is not set
|
||||
# CONFIG_ARCH_CHIP_IMX is not set
|
||||
# CONFIG_ARCH_CHIP_KINETIS is not set
|
||||
# CONFIG_ARCH_CHIP_KL is not set
|
||||
@ -90,6 +92,7 @@ CONFIG_ARCH_CHIP_LPC31XX=y
|
||||
# CONFIG_ARCH_CHIP_SAMA5 is not set
|
||||
# CONFIG_ARCH_CHIP_SAMD is not set
|
||||
# CONFIG_ARCH_CHIP_SAM34 is not set
|
||||
# CONFIG_ARCH_CHIP_SAMV7 is not set
|
||||
# CONFIG_ARCH_CHIP_STM32 is not set
|
||||
# CONFIG_ARCH_CHIP_STR71X is not set
|
||||
# CONFIG_ARCH_ARM7TDMI is not set
|
||||
@ -98,11 +101,13 @@ CONFIG_ARCH_ARM926EJS=y
|
||||
# CONFIG_ARCH_CORTEXM0 is not set
|
||||
# CONFIG_ARCH_CORTEXM3 is not set
|
||||
# CONFIG_ARCH_CORTEXM4 is not set
|
||||
# CONFIG_ARCH_CORTEXM7 is not set
|
||||
# CONFIG_ARCH_CORTEXA5 is not set
|
||||
# CONFIG_ARCH_CORTEXA8 is not set
|
||||
CONFIG_ARCH_FAMILY="arm"
|
||||
CONFIG_ARCH_CHIP="lpc31xx"
|
||||
# CONFIG_ARCH_HAVE_FPU is not set
|
||||
# CONFIG_ARCH_HAVE_DPFPU is not set
|
||||
CONFIG_ARCH_HAVE_LOWVECTORS=y
|
||||
CONFIG_ARCH_LOWVECTORS=y
|
||||
CONFIG_ARCH_ROMPGTABLE=y
|
||||
@ -225,6 +230,12 @@ CONFIG_NSH_MMCSDMINOR=0
|
||||
#
|
||||
# Board-Specific Options
|
||||
#
|
||||
CONFIG_LIB_BOARDCTL=y
|
||||
# CONFIG_BOARDCTL_TSCTEST is not set
|
||||
# CONFIG_BOARDCTL_ADCTEST is not set
|
||||
# CONFIG_BOARDCTL_PWMTEST is not set
|
||||
# CONFIG_BOARDCTL_GRAPHICS is not set
|
||||
# CONFIG_BOARDCTL_IOCTL is not set
|
||||
|
||||
#
|
||||
# RTOS Features
|
||||
@ -254,6 +265,9 @@ CONFIG_PREALLOC_TIMERS=4
|
||||
#
|
||||
# Tasks and Scheduling
|
||||
#
|
||||
# CONFIG_INIT_NONE is not set
|
||||
CONFIG_INIT_ENTRYPOINT=y
|
||||
# CONFIG_INIT_FILEPATH is not set
|
||||
CONFIG_USER_ENTRYPOINT="nsh_main"
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_TASK_NAME_SIZE=0
|
||||
@ -307,6 +321,13 @@ CONFIG_SIG_SIGCONDTIMEDOUT=16
|
||||
CONFIG_PREALLOC_MQ_MSGS=4
|
||||
CONFIG_MQ_MAXMSGSIZE=32
|
||||
|
||||
#
|
||||
# Work Queue Support
|
||||
#
|
||||
# CONFIG_SCHED_WORKQUEUE is not set
|
||||
# CONFIG_SCHED_HPWORK is not set
|
||||
# CONFIG_SCHED_LPWORK is not set
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
#
|
||||
@ -337,9 +358,13 @@ CONFIG_DEV_NULL=y
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_SPI is not set
|
||||
# CONFIG_I2S is not set
|
||||
|
||||
#
|
||||
# Timer Driver Support
|
||||
#
|
||||
# CONFIG_TIMER is not set
|
||||
# CONFIG_RTC is not set
|
||||
# CONFIG_WATCHDOG is not set
|
||||
# CONFIG_TIMER is not set
|
||||
# CONFIG_ANALOG is not set
|
||||
# CONFIG_AUDIO_DEVICES is not set
|
||||
# CONFIG_VIDEO_DEVICES is not set
|
||||
@ -348,6 +373,7 @@ CONFIG_DEV_NULL=y
|
||||
# CONFIG_LCD is not set
|
||||
# CONFIG_MMCSD is not set
|
||||
# CONFIG_MTD is not set
|
||||
# CONFIG_EEPROM is not set
|
||||
# CONFIG_PIPES is not set
|
||||
# CONFIG_PM is not set
|
||||
# CONFIG_POWER is not set
|
||||
@ -377,13 +403,18 @@ CONFIG_ARCH_HAVE_UART=y
|
||||
# CONFIG_ARCH_HAVE_USART6 is not set
|
||||
# CONFIG_ARCH_HAVE_USART7 is not set
|
||||
# CONFIG_ARCH_HAVE_USART8 is not set
|
||||
# CONFIG_ARCH_HAVE_OTHER_UART is not set
|
||||
|
||||
#
|
||||
# USART Configuration
|
||||
#
|
||||
CONFIG_MCU_SERIAL=y
|
||||
CONFIG_STANDARD_SERIAL=y
|
||||
# CONFIG_SERIAL_IFLOWCONTROL is not set
|
||||
# CONFIG_SERIAL_OFLOWCONTROL is not set
|
||||
# CONFIG_ARCH_HAVE_SERIAL_TERMIOS is not set
|
||||
CONFIG_UART_SERIAL_CONSOLE=y
|
||||
# CONFIG_OTHER_SERIAL_CONSOLE is not set
|
||||
# CONFIG_NO_SERIAL_CONSOLE is not set
|
||||
|
||||
#
|
||||
@ -397,8 +428,6 @@ CONFIG_UART_PARITY=0
|
||||
CONFIG_UART_2STOP=0
|
||||
# CONFIG_UART_IFLOWCONTROL is not set
|
||||
# CONFIG_UART_OFLOWCONTROL is not set
|
||||
# CONFIG_SERIAL_IFLOWCONTROL is not set
|
||||
# CONFIG_SERIAL_OFLOWCONTROL is not set
|
||||
# CONFIG_USBDEV is not set
|
||||
# CONFIG_USBHOST is not set
|
||||
# CONFIG_WIRELESS is not set
|
||||
@ -411,6 +440,7 @@ CONFIG_UART_2STOP=0
|
||||
# System Logging
|
||||
#
|
||||
# CONFIG_RAMLOG is not set
|
||||
# CONFIG_SYSLOG_CONSOLE is not set
|
||||
|
||||
#
|
||||
# Networking Support
|
||||
@ -436,6 +466,8 @@ CONFIG_UART_2STOP=0
|
||||
# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
|
||||
CONFIG_FS_READABLE=y
|
||||
CONFIG_FS_WRITABLE=y
|
||||
# CONFIG_FS_NAMED_SEMAPHORES is not set
|
||||
CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
|
||||
# CONFIG_FS_RAMMAP is not set
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_FAT_LCNAMES=y
|
||||
@ -451,8 +483,8 @@ CONFIG_FAT_MAXFNAME=32
|
||||
#
|
||||
# System Logging
|
||||
#
|
||||
|
||||
# CONFIG_SYSLOG is not set
|
||||
# CONFIG_SYSLOG_TIMESTAMP is not set
|
||||
|
||||
#
|
||||
# Graphics Support
|
||||
@ -474,7 +506,7 @@ CONFIG_MM_REGIONS=1
|
||||
# CONFIG_AUDIO is not set
|
||||
|
||||
#
|
||||
# Binary Formats
|
||||
# Binary Loader
|
||||
#
|
||||
# CONFIG_BINFMT_DISABLE is not set
|
||||
# CONFIG_BINFMT_EXEPATH is not set
|
||||
@ -498,6 +530,7 @@ CONFIG_LIB_HOMEDIR="/"
|
||||
# CONFIG_LIBM is not set
|
||||
# CONFIG_NOPRINTF_FIELDWIDTH is not set
|
||||
# CONFIG_LIBC_FLOATINGPOINT is not set
|
||||
# CONFIG_LIBC_IOCTL_VARIADIC is not set
|
||||
CONFIG_LIB_RAND_ORDER=1
|
||||
# CONFIG_EOL_IS_CR is not set
|
||||
# CONFIG_EOL_IS_LF is not set
|
||||
@ -508,8 +541,11 @@ CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024
|
||||
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=1536
|
||||
# CONFIG_LIBC_STRERROR is not set
|
||||
# CONFIG_LIBC_PERROR_STDOUT is not set
|
||||
CONFIG_LIBC_TMPDIR="/tmp"
|
||||
CONFIG_LIBC_MAX_TMPFILE=32
|
||||
CONFIG_ARCH_LOWPUTC=y
|
||||
# CONFIG_LIBC_LOCALTIME is not set
|
||||
# CONFIG_TIME_EXTENDED is not set
|
||||
CONFIG_LIB_SENDFILE_BUFSIZE=512
|
||||
# CONFIG_ARCH_ROMGETC is not set
|
||||
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
|
||||
@ -517,7 +553,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512
|
||||
#
|
||||
# Non-standard Library Support
|
||||
#
|
||||
# CONFIG_SCHED_WORKQUEUE is not set
|
||||
# CONFIG_LIB_KBDCODEC is not set
|
||||
# CONFIG_LIB_SLCDCODEC is not set
|
||||
|
||||
@ -569,10 +604,10 @@ CONFIG_EXAMPLES_NSH=y
|
||||
# CONFIG_EXAMPLES_OSTEST is not set
|
||||
# CONFIG_EXAMPLES_PIPE is not set
|
||||
# CONFIG_EXAMPLES_POLL is not set
|
||||
# CONFIG_EXAMPLES_PPPD is not set
|
||||
# CONFIG_EXAMPLES_POSIXSPAWN is not set
|
||||
# CONFIG_EXAMPLES_QENCODER is not set
|
||||
# CONFIG_EXAMPLES_RGMP is not set
|
||||
# CONFIG_EXAMPLES_ROMFS is not set
|
||||
# CONFIG_EXAMPLES_SENDMAIL is not set
|
||||
# CONFIG_EXAMPLES_SERIALBLASTER is not set
|
||||
# CONFIG_EXAMPLES_SERIALRX is not set
|
||||
@ -584,7 +619,6 @@ CONFIG_EXAMPLES_NSH=y
|
||||
# CONFIG_EXAMPLES_THTTPD is not set
|
||||
# CONFIG_EXAMPLES_TIFF is not set
|
||||
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
|
||||
# CONFIG_EXAMPLES_UDP is not set
|
||||
# CONFIG_EXAMPLES_WEBSERVER is not set
|
||||
# CONFIG_EXAMPLES_USBSERIAL is not set
|
||||
# CONFIG_EXAMPLES_USBTERM is not set
|
||||
@ -594,12 +628,15 @@ CONFIG_EXAMPLES_NSH=y
|
||||
# Graphics Support
|
||||
#
|
||||
# CONFIG_TIFF is not set
|
||||
# CONFIG_GRAPHICS_TRAVELER is not set
|
||||
|
||||
#
|
||||
# Interpreters
|
||||
#
|
||||
# CONFIG_INTERPRETERS_BAS is not set
|
||||
# CONFIG_INTERPRETERS_FICL is not set
|
||||
# CONFIG_INTERPRETERS_PCODE is not set
|
||||
# CONFIG_INTERPRETERS_MICROPYTHON is not set
|
||||
|
||||
#
|
||||
# Network Utilities
|
||||
@ -609,15 +646,11 @@ CONFIG_EXAMPLES_NSH=y
|
||||
# Networking Utilities
|
||||
#
|
||||
# CONFIG_NETUTILS_CODECS is not set
|
||||
# CONFIG_NETUTILS_DHCPD is not set
|
||||
# CONFIG_NETUTILS_FTPC is not set
|
||||
# CONFIG_NETUTILS_FTPD is not set
|
||||
# CONFIG_NETUTILS_JSON is not set
|
||||
# CONFIG_NETUTILS_SMTP is not set
|
||||
# CONFIG_NETUTILS_TFTPC is not set
|
||||
# CONFIG_NETUTILS_THTTPD is not set
|
||||
# CONFIG_NETUTILS_NETLIB is not set
|
||||
# CONFIG_NETUTILS_WEBCLIENT is not set
|
||||
# CONFIG_NETUTILS_PPPD is not set
|
||||
|
||||
#
|
||||
# FreeModBus
|
||||
@ -650,6 +683,7 @@ CONFIG_NSH_NESTDEPTH=3
|
||||
# CONFIG_NSH_DISABLE_CD is not set
|
||||
# CONFIG_NSH_DISABLE_CP is not set
|
||||
# CONFIG_NSH_DISABLE_CMP is not set
|
||||
CONFIG_NSH_DISABLE_DATE=y
|
||||
# CONFIG_NSH_DISABLE_DD is not set
|
||||
# CONFIG_NSH_DISABLE_DF is not set
|
||||
# CONFIG_NSH_DISABLE_DELROUTE is not set
|
||||
@ -671,6 +705,7 @@ CONFIG_NSH_NESTDEPTH=3
|
||||
# CONFIG_NSH_DISABLE_MKRD is not set
|
||||
# CONFIG_NSH_DISABLE_MH is not set
|
||||
# CONFIG_NSH_DISABLE_MOUNT is not set
|
||||
# CONFIG_NSH_DISABLE_MV is not set
|
||||
# CONFIG_NSH_DISABLE_MW is not set
|
||||
# CONFIG_NSH_DISABLE_PS is not set
|
||||
# CONFIG_NSH_DISABLE_PUT is not set
|
||||
@ -708,7 +743,6 @@ CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_CONSOLE=y
|
||||
# CONFIG_NSH_ALTCONDEV is not set
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_LIB_BOARDCTL=y
|
||||
|
||||
#
|
||||
# NxWidgets/NxWM
|
||||
@ -722,115 +756,19 @@ CONFIG_LIB_BOARDCTL=y
|
||||
#
|
||||
# System Libraries and NSH Add-Ons
|
||||
#
|
||||
|
||||
#
|
||||
# Custom Free Memory Command
|
||||
#
|
||||
# CONFIG_SYSTEM_FREE is not set
|
||||
|
||||
#
|
||||
# EMACS-like Command Line Editor
|
||||
#
|
||||
# CONFIG_SYSTEM_CLE is not set
|
||||
|
||||
#
|
||||
# FLASH Program Installation
|
||||
#
|
||||
# CONFIG_SYSTEM_CUTERM is not set
|
||||
# CONFIG_SYSTEM_INSTALL is not set
|
||||
|
||||
#
|
||||
# FLASH Erase-all Command
|
||||
#
|
||||
|
||||
#
|
||||
# Intel HEX to binary conversion
|
||||
#
|
||||
# CONFIG_SYSTEM_HEX2BIN is not set
|
||||
|
||||
#
|
||||
# I2C tool
|
||||
#
|
||||
|
||||
#
|
||||
# INI File Parser
|
||||
#
|
||||
# CONFIG_SYSTEM_INIFILE is not set
|
||||
|
||||
#
|
||||
# NxPlayer media player library / command Line
|
||||
#
|
||||
# CONFIG_SYSTEM_NXPLAYER is not set
|
||||
|
||||
#
|
||||
# RAM test
|
||||
#
|
||||
# CONFIG_SYSTEM_RAMTEST is not set
|
||||
|
||||
#
|
||||
# readline()
|
||||
#
|
||||
CONFIG_SYSTEM_READLINE=y
|
||||
CONFIG_READLINE_ECHO=y
|
||||
|
||||
#
|
||||
# P-Code Support
|
||||
#
|
||||
|
||||
#
|
||||
# PHY Tool
|
||||
#
|
||||
|
||||
#
|
||||
# Power Off
|
||||
#
|
||||
# CONFIG_SYSTEM_POWEROFF is not set
|
||||
|
||||
#
|
||||
# RAMTRON
|
||||
#
|
||||
# CONFIG_SYSTEM_RAMTRON is not set
|
||||
|
||||
#
|
||||
# SD Card
|
||||
#
|
||||
# CONFIG_SYSTEM_SDCARD is not set
|
||||
|
||||
#
|
||||
# Sudoku
|
||||
#
|
||||
# CONFIG_SYSTEM_SUDOKU is not set
|
||||
|
||||
#
|
||||
# Sysinfo
|
||||
#
|
||||
# CONFIG_SYSTEM_SYSINFO is not set
|
||||
|
||||
#
|
||||
# VI Work-Alike Editor
|
||||
#
|
||||
# CONFIG_SYSTEM_VI is not set
|
||||
|
||||
#
|
||||
# Stack Monitor
|
||||
#
|
||||
|
||||
#
|
||||
# USB CDC/ACM Device Commands
|
||||
#
|
||||
|
||||
#
|
||||
# USB Composite Device Commands
|
||||
#
|
||||
|
||||
#
|
||||
# USB Mass Storage Device Commands
|
||||
#
|
||||
|
||||
#
|
||||
# USB Monitor
|
||||
#
|
||||
|
||||
#
|
||||
# Zmodem Commands
|
||||
#
|
||||
# CONFIG_SYSTEM_ZMODEM is not set
|
||||
|
@ -51,6 +51,7 @@ fi
|
||||
# toolchain under windows. You will also have to edit this if you install
|
||||
# the CodeSourcery toolchain in any other location
|
||||
export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin"
|
||||
#export TOOLCHAIN_BIN="/cygdrive/c/Users/MyName/MentorGraphics/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
|
||||
|
||||
# This is the Cygwin path to the location where I build the buildroot
|
||||
# toolchain.
|
||||
|
@ -97,35 +97,23 @@ static xcpt_t g_ochandler;
|
||||
|
||||
static int ehci_waiter(int argc, char *argv[])
|
||||
{
|
||||
bool connected = false;
|
||||
int rhpndx;
|
||||
int ret;
|
||||
FAR struct usbhost_hubport_s *hport;
|
||||
|
||||
uvdbg("Waiter Running\n");
|
||||
uvdbg("ehci_waiter: Running\n");
|
||||
for (;;)
|
||||
{
|
||||
/* Wait for the device to change state */
|
||||
|
||||
rhpndx = CONN_WAIT(g_ehciconn, &connected);
|
||||
DEBUGASSERT(rhpndx >= 0 && rhpndx < 1);
|
||||
|
||||
connected = !connected;
|
||||
|
||||
uvdbg("RHport1 %s\n",
|
||||
connected ? "connected" : "disconnected");
|
||||
DEBUGVERIFY(CONN_WAIT(g_ehciconn, &hport));
|
||||
printf("ehci_waiter: %s\n", hport->connected ? "connected" : "disconnected");
|
||||
|
||||
/* Did we just become connected? */
|
||||
|
||||
if (connected)
|
||||
if (hport->connected)
|
||||
{
|
||||
/* Yes.. enumerate the newly connected device */
|
||||
|
||||
ret = CONN_ENUMERATE(g_ehciconn, rhpndx);
|
||||
if (ret < 0)
|
||||
{
|
||||
uvdbg("RHport1 CONN_ENUMERATE failed: %d\n", ret);
|
||||
connected = false;
|
||||
}
|
||||
(void)CONN_ENUMERATE(g_ehciconn, hport);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,11 +171,21 @@ int lpc31_usbhost_initialize(void)
|
||||
|
||||
/* First, register all of the class drivers needed to support the drivers
|
||||
* that we care about
|
||||
*
|
||||
* Register theUSB host Mass Storage Class:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
/* Initialize USB hub support */
|
||||
|
||||
ret = usbhost_hub_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: usbhost_hub_initialize failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_MSC
|
||||
/* Register theUSB host Mass Storage Class */
|
||||
|
||||
ret = usbhost_storageinit();
|
||||
if (ret != OK)
|
||||
{
|
||||
@ -195,9 +193,9 @@ int lpc31_usbhost_initialize(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_HIDKBD
|
||||
/* Register the USB host HID keyboard class driver */
|
||||
|
||||
#ifdef CONFIG_USBHOST_HIDKBD
|
||||
ret = usbhost_kbdinit();
|
||||
if (ret != OK)
|
||||
{
|
||||
|
@ -977,7 +977,7 @@ Configuration Sub-Directories
|
||||
crash seems seems to be due to a corrupt addess in the callback from
|
||||
the new asynchronous I/O. Should not be too hard to fix.
|
||||
|
||||
Also, the code does not enumerat the hub if it is connected at the
|
||||
Also, the code does not enumerate the hub if it is connected at the
|
||||
time of power up.
|
||||
|
||||
hidmouse:
|
||||
|
Loading…
Reference in New Issue
Block a user