Add USB serial driver

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@984 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2008-10-06 23:12:09 +00:00
parent 80db9814b7
commit 7996949c97
13 changed files with 1946 additions and 60 deletions

View File

@ -485,6 +485,9 @@
* Add an option to set aside a separate stack for interrupt handling (ARM only). * Add an option to set aside a separate stack for interrupt handling (ARM only).
This is useful when memory is constrained, there are multiple tasks, and This is useful when memory is constrained, there are multiple tasks, and
the interrupt stack requirement is high (as when USB is enabled). the interrupt stack requirement is high (as when USB is enabled).
* Basic LPC214x USB device side driver basically functional (but probably still buggy)
* Initial USB serial class device side driver check in (not well tested at initial checkin)
* Add LPC214x USB serial configuration; Add examples/usbserial test (still a work in progress)

View File

@ -1075,6 +1075,9 @@ nuttx-0.3.16 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
* Add an option to set aside a separate stack for interrupt handling (ARM only). * Add an option to set aside a separate stack for interrupt handling (ARM only).
This is useful when memory is constrained, there are multiple tasks, and This is useful when memory is constrained, there are multiple tasks, and
the interrupt stack requirement is high (as when USB is enabled). the interrupt stack requirement is high (as when USB is enabled).
* Basic LPC214x USB device side driver basically functional (but probably still buggy)
* Initial USB serial class device side driver check in (not well tested at initial checkin)
* Add LPC214x USB serial configuration; Add examples/usbserial test (still a work in progress)
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>

View File

@ -1014,11 +1014,21 @@ static int lpc214x_wrrequest(struct lpc214x_ep_s *privep)
uvdbg("len=%d xfrd=%d nullpkt=%d\n", uvdbg("len=%d xfrd=%d nullpkt=%d\n",
privreq->req.len, privreq->req.xfrd, privep->txnullpkt); privreq->req.len, privreq->req.xfrd, privep->txnullpkt);
/* Ignore any attempt to send a zero length packet */ /* Ignore any attempt to send a zero length packet on anything but EP0IN */
if (privreq->req.len == 0) if (privreq->req.len == 0)
{ {
usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EPINNULLPACKET), 0); if (privep->epphy == LPC214X_EP0_IN)
{
lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0);
}
else
{
usbtrace(TRACE_DEVERROR(LPC214X_TRACEERR_EPINNULLPACKET), 0);
}
/* In any event, the request is complete */
lpc214x_reqcomplete(privep, OK); lpc214x_reqcomplete(privep, OK);
return OK; return OK;
} }
@ -1390,6 +1400,8 @@ static void lpc214x_dispatchrequest(struct lpc214x_usbdev_s *priv,
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DISPATCH), 0); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DISPATCH), 0);
if (priv && priv->driver) if (priv && priv->driver)
{ {
/* Forward to the control request to the class driver implementation */
ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl); ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl);
if (ret < 0) if (ret < 0)
{ {
@ -1414,7 +1426,9 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
struct lpc214x_ep_s *ep0 = &priv->eplist[LPC214X_EP0_OUT]; struct lpc214x_ep_s *ep0 = &priv->eplist[LPC214X_EP0_OUT];
struct lpc214x_req_s *privreq = lpc214x_rqpeek(ep0); struct lpc214x_req_s *privreq = lpc214x_rqpeek(ep0);
struct usb_ctrlreq_s ctrl; struct usb_ctrlreq_s ctrl;
uint16 value;
uint16 index; uint16 index;
uint16 len;
ubyte epphy; ubyte epphy;
ubyte response[2]; ubyte response[2];
int ret; int ret;
@ -1454,9 +1468,14 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
return; return;
} }
/* And extract the little-endian 16-bit values to host order */
value = GETUINT16(ctrl.value);
index = GETUINT16(ctrl.index);
len = GETUINT16(ctrl.len);
uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
ctrl.type, ctrl.req, ctrl.type, ctrl.req, value, index, len);
GETUINT16(ctrl.value), GETUINT16(ctrl.index), GETUINT16(ctrl.len));
/* Dispatch any non-standard requests */ /* Dispatch any non-standard requests */
@ -1481,8 +1500,8 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
*/ */
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETSTATUS), 0); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETSTATUS), 0);
if (!priv->paddrset || GETUINT16(ctrl.len) != 2 || if (!priv->paddrset || len != 2 ||
(ctrl.type & USB_REQ_DIR_IN) == 0 || GETUINT16(ctrl.value) != 0) (ctrl.type & USB_REQ_DIR_IN) == 0 || value != 0)
{ {
priv->stalled = 1; priv->stalled = 1;
} }
@ -1493,7 +1512,7 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
case USB_REQ_RECIPIENT_ENDPOINT: case USB_REQ_RECIPIENT_ENDPOINT:
{ {
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPGETSTATUS), 0); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EPGETSTATUS), 0);
epphy = USB_EPNO(GETUINT16(ctrl.index)) << 1; epphy = USB_EPNO(index) << 1;
if (epphy < LPC214X_NPHYSENDPOINTS) if (epphy < LPC214X_NPHYSENDPOINTS)
{ {
if ((lpc214x_usbcmd(CMD_USB_EP_SELECT|epphy, 0) & CMD_USB_EPSELECT_ST) != 0) if ((lpc214x_usbcmd(CMD_USB_EP_SELECT|epphy, 0) & CMD_USB_EPSELECT_ST) != 0)
@ -1518,7 +1537,6 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
case USB_REQ_RECIPIENT_DEVICE: case USB_REQ_RECIPIENT_DEVICE:
{ {
index = GETUINT16(ctrl.index);
if (index == 0) if (index == 0)
{ {
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DEVGETSTATUS), 0); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_DEVGETSTATUS), 0);
@ -1573,10 +1591,10 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
{ {
lpc214x_dispatchrequest(priv, &ctrl); lpc214x_dispatchrequest(priv, &ctrl);
} }
else if (priv->paddrset && GETUINT16(ctrl.value) == USB_FEATURE_ENDPOINTHALT && else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT &&
GETUINT16(ctrl.index) < LPC214X_NLOGENDPOINTS && GETUINT16(ctrl.len) == 0) index < LPC214X_NLOGENDPOINTS && len == 0)
{ {
ubyte epphys = LPC214X_EP_LOG2PHY(GETUINT16(ctrl.index)); ubyte epphys = LPC214X_EP_LOG2PHY(index);
priv->eplist[epphys].halted = 0; priv->eplist[epphys].halted = 0;
lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0); lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0);
priv->ep0state = LPC214X_EP0STATUSIN; priv->ep0state = LPC214X_EP0STATUSIN;
@ -1599,18 +1617,18 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SETFEATURE), 0); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SETFEATURE), 0);
if (((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) && if (((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) &&
GETUINT16(ctrl.value) == USB_FEATURE_TESTMODE) value == USB_FEATURE_TESTMODE)
{ {
uvdbg("test mode: %d\n", GETUINT16(ctrl.index)); uvdbg("test mode: %d\n", index);
} }
else if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT) else if ((ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_ENDPOINT)
{ {
lpc214x_dispatchrequest(priv, &ctrl); lpc214x_dispatchrequest(priv, &ctrl);
} }
else if (priv->paddrset && GETUINT16(ctrl.value) == USB_FEATURE_ENDPOINTHALT && else if (priv->paddrset != 0 && value == USB_FEATURE_ENDPOINTHALT &&
GETUINT16(ctrl.index) < LPC214X_NLOGENDPOINTS && GETUINT16(ctrl.len) == 0) index < LPC214X_NLOGENDPOINTS && len == 0)
{ {
ubyte epphys = LPC214X_EP_LOG2PHY(GETUINT16(ctrl.index)); ubyte epphys = LPC214X_EP_LOG2PHY(index);
priv->eplist[epphys].halted = 1; priv->eplist[epphys].halted = 1;
lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0); lpc214x_epwrite(LPC214X_EP0_IN, NULL, 0);
priv->ep0state = LPC214X_EP0STATUSIN; priv->ep0state = LPC214X_EP0STATUSIN;
@ -1631,10 +1649,9 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
* len: 0; data = none * len: 0; data = none
*/ */
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EP0SETUPSETADDRESS), GETUINT16(ctrl.value)); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_EP0SETUPSETADDRESS), value);
if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
GETUINT16(ctrl.index) == 0 && GETUINT16(ctrl.len) == 0 && index == 0 && len == 0 && value < 128)
GETUINT16(ctrl.value) < 128)
{ {
/* Save the address. We cannot actually change to the next address until /* Save the address. We cannot actually change to the next address until
* the completion of the status phase. * the completion of the status phase.
@ -1699,8 +1716,7 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
{ {
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETCONFIG), 0); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_GETCONFIG), 0);
if (priv->paddrset && (ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && if (priv->paddrset && (ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
GETUINT16(ctrl.value) == 0 && GETUINT16(ctrl.index) == 0 && value == 0 && index == 0 && len == 1)
GETUINT16(ctrl.len) == 1)
{ {
lpc214x_dispatchrequest(priv, &ctrl); lpc214x_dispatchrequest(priv, &ctrl);
} }
@ -1721,7 +1737,7 @@ static inline void lpc214x_ep0setup(struct lpc214x_usbdev_s *priv)
{ {
usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SETCONFIG), 0); usbtrace(TRACE_INTDECODE(LPC214X_TRACEINTID_SETCONFIG), 0);
if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && if ((ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
GETUINT16(ctrl.index) == 0 && GETUINT16(ctrl.len) == 0) index == 0 && len == 0)
{ {
lpc214x_dispatchrequest(priv, &ctrl); lpc214x_dispatchrequest(priv, &ctrl);
} }

View File

@ -398,8 +398,8 @@ CONFIG_USBSER_EPOUT=1
CONFIG_USBSER_EPIN=2 CONFIG_USBSER_EPIN=2
CONFIG_USBSER_NWRREQS=4 CONFIG_USBSER_NWRREQS=4
CONFIG_USBSER_NRDREQS=4 CONFIG_USBSER_NRDREQS=4
CONFIG_USBSER_VENDORID=0x0525 CONFIG_USBSER_VENDORID=0x067b
CONFIG_USBSER_PRODUCTID=0xa4a6 CONFIG_USBSER_PRODUCTID=0x2303
CONFIG_USBSER_VENDORSTR="Nuttx" CONFIG_USBSER_VENDORSTR="Nuttx"
CONFIG_USBSER_PRODUCTSTR="USBdev Serial" CONFIG_USBSER_PRODUCTSTR="USBdev Serial"
CONFIG_USBSER_RXBUFSIZE=512 CONFIG_USBSER_RXBUFSIZE=512

View File

@ -398,8 +398,8 @@ CONFIG_USBSER_EPOUT=1
CONFIG_USBSER_EPIN=2 CONFIG_USBSER_EPIN=2
CONFIG_USBSER_NWRREQS=4 CONFIG_USBSER_NWRREQS=4
CONFIG_USBSER_NRDREQS=4 CONFIG_USBSER_NRDREQS=4
CONFIG_USBSER_VENDORID=0x0525 CONFIG_USBSER_VENDORID=0x067b
CONFIG_USBSER_PRODUCTID=0xa4a6 CONFIG_USBSER_PRODUCTID=0x2303
CONFIG_USBSER_VENDORSTR="Nuttx" CONFIG_USBSER_VENDORSTR="Nuttx"
CONFIG_USBSER_PRODUCTSTR="USBdev Serial" CONFIG_USBSER_PRODUCTSTR="USBdev Serial"
CONFIG_USBSER_RXBUFSIZE=512 CONFIG_USBSER_RXBUFSIZE=512

View File

@ -375,8 +375,8 @@ CONFIG_USBSER_EPOUT=1
CONFIG_USBSER_EPIN=2 CONFIG_USBSER_EPIN=2
CONFIG_USBSER_NWRREQS=4 CONFIG_USBSER_NWRREQS=4
CONFIG_USBSER_NRDREQS=4 CONFIG_USBSER_NRDREQS=4
CONFIG_USBSER_VENDORID=0x0525 CONFIG_USBSER_VENDORID=0x067b
CONFIG_USBSER_PRODUCTID=0xa4a6 CONFIG_USBSER_PRODUCTID=0x2303
CONFIG_USBSER_VENDORSTR="Nuttx" CONFIG_USBSER_VENDORSTR="Nuttx"
CONFIG_USBSER_PRODUCTSTR="USBdev Serial" CONFIG_USBSER_PRODUCTSTR="USBdev Serial"
CONFIG_USBSER_RXBUFSIZE=512 CONFIG_USBSER_RXBUFSIZE=512

View File

@ -383,8 +383,8 @@ CONFIG_USBSER_EPOUT=1
CONFIG_USBSER_EPIN=2 CONFIG_USBSER_EPIN=2
CONFIG_USBSER_NWRREQS=4 CONFIG_USBSER_NWRREQS=4
CONFIG_USBSER_NRDREQS=4 CONFIG_USBSER_NRDREQS=4
CONFIG_USBSER_VENDORID=0x0525 CONFIG_USBSER_VENDORID=0x067b
CONFIG_USBSER_PRODUCTID=0xa4a6 CONFIG_USBSER_PRODUCTID=0x2303
CONFIG_USBSER_VENDORSTR="Nuttx" CONFIG_USBSER_VENDORSTR="Nuttx"
CONFIG_USBSER_PRODUCTSTR="USBdev Serial" CONFIG_USBSER_PRODUCTSTR="USBdev Serial"
CONFIG_USBSER_RXBUFSIZE=512 CONFIG_USBSER_RXBUFSIZE=512

View File

@ -375,8 +375,8 @@ CONFIG_USBSER_EPOUT=1
CONFIG_USBSER_EPIN=2 CONFIG_USBSER_EPIN=2
CONFIG_USBSER_NWRREQS=4 CONFIG_USBSER_NWRREQS=4
CONFIG_USBSER_NRDREQS=4 CONFIG_USBSER_NRDREQS=4
CONFIG_USBSER_VENDORID=0x0525 CONFIG_USBSER_VENDORID=0x067b
CONFIG_USBSER_PRODUCTID=0xa4a6 CONFIG_USBSER_PRODUCTID=0x2303
CONFIG_USBSER_VENDORSTR="Nuttx" CONFIG_USBSER_VENDORSTR="Nuttx"
CONFIG_USBSER_PRODUCTSTR="USBdev Serial" CONFIG_USBSER_PRODUCTSTR="USBdev Serial"
CONFIG_USBSER_RXBUFSIZE=512 CONFIG_USBSER_RXBUFSIZE=512

View File

@ -375,8 +375,8 @@ CONFIG_USBSER_EPOUT=1
CONFIG_USBSER_EPIN=2 CONFIG_USBSER_EPIN=2
CONFIG_USBSER_NWRREQS=4 CONFIG_USBSER_NWRREQS=4
CONFIG_USBSER_NRDREQS=4 CONFIG_USBSER_NRDREQS=4
CONFIG_USBSER_VENDORID=0x0525 CONFIG_USBSER_VENDORID=0x067b
CONFIG_USBSER_PRODUCTID=0xa4a6 CONFIG_USBSER_PRODUCTID=0x2303
CONFIG_USBSER_VENDORSTR="Nuttx" CONFIG_USBSER_VENDORSTR="Nuttx"
CONFIG_USBSER_PRODUCTSTR="USBdev Serial" CONFIG_USBSER_PRODUCTSTR="USBdev Serial"
CONFIG_USBSER_RXBUFSIZE=512 CONFIG_USBSER_RXBUFSIZE=512

View File

@ -375,8 +375,8 @@ CONFIG_USBSER_EPOUT=1
CONFIG_USBSER_EPIN=2 CONFIG_USBSER_EPIN=2
CONFIG_USBSER_NWRREQS=4 CONFIG_USBSER_NWRREQS=4
CONFIG_USBSER_NRDREQS=4 CONFIG_USBSER_NRDREQS=4
CONFIG_USBSER_VENDORID=0x0525 CONFIG_USBSER_VENDORID=0x067b
CONFIG_USBSER_PRODUCTID=0xa4a6 CONFIG_USBSER_PRODUCTID=0x2303
CONFIG_USBSER_VENDORSTR="Nuttx" CONFIG_USBSER_VENDORSTR="Nuttx"
CONFIG_USBSER_PRODUCTSTR="USBdev Serial" CONFIG_USBSER_PRODUCTSTR="USBdev Serial"
CONFIG_USBSER_RXBUFSIZE=512 CONFIG_USBSER_RXBUFSIZE=512

View File

@ -37,6 +37,6 @@ USBDEV_ASRCS =
USBDEV_CSRCS = USBDEV_CSRCS =
ifeq ($(CONFIG_USBDEV),y) ifeq ($(CONFIG_USBDEV),y)
USBDEV_CSRCS += usbdev_trace.c USBDEV_CSRCS += usbdev_serial.c usbdev_trace.c
endif endif

File diff suppressed because it is too large Load Diff

View File

@ -136,29 +136,33 @@
/* Values of the class error ID used by the USB serial driver */ /* Values of the class error ID used by the USB serial driver */
#define USBSER_TRACEERR_ALLOCCTRLREQ 0x0001 #define USBSER_TRACEERR_ALLOCCTRLREQ 0x0001
#define USBSER_TRACEERR_ALREADYCLOSED 0x0002 #define USBSER_TRACEERR_ALREADYCLOSED 0x0002
#define USBSER_TRACEERR_CONSOLEREGISTER 0x0003 #define USBSER_TRACEERR_CONSOLEREGISTER 0x0003
#define USBSER_TRACEERR_DEVREGISTER 0x0004 #define USBSER_TRACEERR_DEVREGISTER 0x0004
#define USBSER_TRACEERR_EPRESPQ 0x0005 #define USBSER_TRACEERR_EPRESPQ 0x0005
#define USBSER_TRACEERR_GETUNKNOWNDESC 0x0006 #define USBSER_TRACEERR_GETUNKNOWNDESC 0x0006
#define USBSER_TRACEERR_INALLOCEPFAIL 0x0007 #define USBSER_TRACEERR_INALLOCEPFAIL 0x0007
#define USBSER_TRACEERR_INCONFIGEPFAIL 0x0008 #define USBSER_TRACEERR_INCONFIGEPFAIL 0x0008
#define USBSER_TRACEERR_INVALIDARG 0x0009 #define USBSER_TRACEERR_INVALIDARG 0x0009
#define USBSER_TRACEERR_EP0NOTBOUND 0x000a #define USBSER_TRACEERR_EP0NOTBOUND 0x000a
#define USBSER_TRACEERR_OUTALLOCEPFAIL 0x000b #define USBSER_TRACEERR_OUTALLOCEPFAIL 0x000b
#define USBSER_TRACEERR_OUTCONFIGEPFAIL 0x000c #define USBSER_TRACEERR_OUTCONFIGEPFAIL 0x000c
#define USBSER_TRACEERR_RDALLOCREQ 0x000d #define USBSER_TRACEERR_RDALLOCREQ 0x000d
#define USBSER_TRACEERR_RDSHUTDOWN 0x000e #define USBSER_TRACEERR_RDSHUTDOWN 0x000e
#define USBSER_TRACEERR_RDSUBMIT 0x000f #define USBSER_TRACEERR_RDSUBMIT 0x000f
#define USBSER_TRACEERR_RDUNEXPECTED 0x0010 #define USBSER_TRACEERR_RDUNEXPECTED 0x0010
#define USBSER_TRACEERR_REQRESULT 0x0011 #define USBSER_TRACEERR_REQRESULT 0x0011
#define USBSER_TRACEERR_SETUPNOTCONNECTED 0x0012 #define USBSER_TRACEERR_SETUPNOTCONNECTED 0x0012
#define USBSER_TRACEERR_SUBMITFAIL 0x0013 #define USBSER_TRACEERR_SUBMITFAIL 0x0013
#define USBSER_TRACEERR_UARTREGISTER 0x0014 #define USBSER_TRACEERR_UARTREGISTER 0x0014
#define USBSER_TRACEERR_WRALLOCREQ 0x0015 #define USBSER_TRACEERR_UNSUPPORTEDCTRLREQ 0x0015
#define USBSER_TRACEERR_WRSHUTDOWN 0x0016 #define USBSER_TRACEERR_UNSUPPORTEDRWREQ 0x0016
#define USBSER_TRACEERR_WRUNEXPECTED 0x0017 #define USBSER_TRACEERR_UNSUPPORTEDSTDREQ 0x0017
#define USBSER_TRACEERR_UNSUPPORTEDTYPE 0x0018
#define USBSER_TRACEERR_WRALLOCREQ 0x0019
#define USBSER_TRACEERR_WRSHUTDOWN 0x001a
#define USBSER_TRACEERR_WRUNEXPECTED 0x001b
/**************************************************************************** /****************************************************************************
* Public Types * Public Types