Fix endian-ness issue in SETUP
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2205 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
54d8372694
commit
026fdc7e41
@ -4,6 +4,10 @@
|
||||
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* References:
|
||||
* - RM0008 Reference manual, STMicro document ID 13902
|
||||
* - STM32F10xxx USB development kit, UM0424, STMicro
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -204,29 +208,35 @@
|
||||
#define STM32_TRACEINTID_CLEARFEATURE 0x0001
|
||||
#define STM32_TRACEINTID_DEVGETSTATUS 0x0002
|
||||
#define STM32_TRACEINTID_DISPATCH 0x0003
|
||||
#define STM32_TRACEINTID_EP0SETUPSETADDRESS 0x0004
|
||||
#define STM32_TRACEINTID_EPGETSTATUS 0x0005
|
||||
#define STM32_TRACEINTID_EPIN 0x0006
|
||||
#define STM32_TRACEINTID_EPINQEMPTY 0x0007
|
||||
#define STM32_TRACEINTID_EPOUT 0x0008
|
||||
#define STM32_TRACEINTID_EPOUTPENDING 0x0009
|
||||
#define STM32_TRACEINTID_EPOUTQEMPTY 0x000a
|
||||
#define STM32_TRACEINTID_ESOF 0x000b
|
||||
#define STM32_TRACEINTID_GETCONFIG 0x000c
|
||||
#define STM32_TRACEINTID_GETSETDESC 0x000d
|
||||
#define STM32_TRACEINTID_GETSETIF 0x000e
|
||||
#define STM32_TRACEINTID_GETSTATUS 0x000f
|
||||
#define STM32_TRACEINTID_HPINTERRUPT 0x0010
|
||||
#define STM32_TRACEINTID_IFGETSTATUS 0x0011
|
||||
#define STM32_TRACEINTID_LPCTR 0x0012
|
||||
#define STM32_TRACEINTID_LPINTERRUPT 0x0013
|
||||
#define STM32_TRACEINTID_NOSTDREQ 0x0014
|
||||
#define STM32_TRACEINTID_RESET 0x0015
|
||||
#define STM32_TRACEINTID_SETCONFIG 0x0016
|
||||
#define STM32_TRACEINTID_SETFEATURE 0x0017
|
||||
#define STM32_TRACEINTID_SUSP 0x0018
|
||||
#define STM32_TRACEINTID_SYNCHFRAME 0x0019
|
||||
#define STM32_TRACEINTID_WKUP 0x001a
|
||||
#define STM32_TRACEINTID_EP0IN 0x0004
|
||||
#define STM32_TRACEINTID_EP0INDONE 0x0005
|
||||
#define STM32_TRACEINTID_EP0OUTDONE 0x0006
|
||||
#define STM32_TRACEINTID_EP0SETUPDONE 0x0007
|
||||
#define STM32_TRACEINTID_EP0SETUPSETADDRESS 0x0008
|
||||
#define STM32_TRACEINTID_EPGETSTATUS 0x0009
|
||||
#define STM32_TRACEINTID_EPIN 0x000a
|
||||
#define STM32_TRACEINTID_EPINDONE 0x000b
|
||||
#define STM32_TRACEINTID_EPINQEMPTY 0x000c
|
||||
#define STM32_TRACEINTID_EPOUT 0x000d
|
||||
#define STM32_TRACEINTID_EPOUTDONE 0x000e
|
||||
#define STM32_TRACEINTID_EPOUTPENDING 0x000f
|
||||
#define STM32_TRACEINTID_EPOUTQEMPTY 0x0010
|
||||
#define STM32_TRACEINTID_ESOF 0x0011
|
||||
#define STM32_TRACEINTID_GETCONFIG 0x0012
|
||||
#define STM32_TRACEINTID_GETSETDESC 0x0013
|
||||
#define STM32_TRACEINTID_GETSETIF 0x0014
|
||||
#define STM32_TRACEINTID_GETSTATUS 0x0015
|
||||
#define STM32_TRACEINTID_HPINTERRUPT 0x0016
|
||||
#define STM32_TRACEINTID_IFGETSTATUS 0x0017
|
||||
#define STM32_TRACEINTID_LPCTR 0x0018
|
||||
#define STM32_TRACEINTID_LPINTERRUPT 0x0019
|
||||
#define STM32_TRACEINTID_NOSTDREQ 0x001a
|
||||
#define STM32_TRACEINTID_RESET 0x001b
|
||||
#define STM32_TRACEINTID_SETCONFIG 0x001c
|
||||
#define STM32_TRACEINTID_SETFEATURE 0x001d
|
||||
#define STM32_TRACEINTID_SUSP 0x001e
|
||||
#define STM32_TRACEINTID_SYNCHFRAME 0x001f
|
||||
#define STM32_TRACEINTID_WKUP 0x0020
|
||||
|
||||
/* Ever-present MIN and MAX macros */
|
||||
|
||||
@ -238,6 +248,16 @@
|
||||
# define MAX(a,b) (a > b ? a : b)
|
||||
#endif
|
||||
|
||||
/* Byte ordering in host-based values */
|
||||
|
||||
#ifdef CONFIG_ENDIAN_BIG
|
||||
# define LSB 1
|
||||
# define MSB 0
|
||||
#else
|
||||
# define LSB 0
|
||||
# define MSB 1
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Definitions
|
||||
****************************************************************************/
|
||||
@ -1495,8 +1515,8 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), priv->ctrl.type);
|
||||
if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 ||
|
||||
index.b[0] != 0 || value.w != 0)
|
||||
if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 ||
|
||||
index.b[MSB] != 0 || value.w != 0)
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0);
|
||||
priv->devstate = DEVSTATE_STALLED;
|
||||
@ -1507,7 +1527,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
{
|
||||
case USB_REQ_RECIPIENT_ENDPOINT:
|
||||
{
|
||||
epno = USB_EPNO(index.b[1]);
|
||||
epno = USB_EPNO(index.b[LSB]);
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), epno);
|
||||
if (epno >= STM32_NENDPOINTS)
|
||||
{
|
||||
@ -1520,7 +1540,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
response.w = 0; /* Not stalled */
|
||||
nbytes = 2; /* Response size: 2 bytes */
|
||||
|
||||
if (USB_ISEPIN(index.b[1]))
|
||||
if (USB_ISEPIN(index.b[LSB]))
|
||||
{
|
||||
/* IN endpoint */
|
||||
|
||||
@ -1528,7 +1548,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
{
|
||||
/* IN Endpoint stalled */
|
||||
|
||||
response.b[0] = 1; /* Stalled */
|
||||
response.b[LSB] = 1; /* Stalled */
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1537,9 +1557,9 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
|
||||
if (stm32_eprxstalled(epno))
|
||||
{
|
||||
/*OUT Endpoint stalled */
|
||||
/* OUT Endpoint stalled */
|
||||
|
||||
response.b[0] |= 1; /* Stalled */
|
||||
response.b[LSB] = 1; /* Stalled */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1554,10 +1574,10 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
|
||||
/* Features: Remote Wakeup=YES; selfpowered=? */
|
||||
|
||||
response.w = 0;
|
||||
response.b[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) |
|
||||
(1 << USB_FEATURE_REMOTEWAKEUP);
|
||||
nbytes = 2; /* Response size: 2 bytes */
|
||||
response.w = 0;
|
||||
response.b[LSB] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) |
|
||||
(1 << USB_FEATURE_REMOTEWAKEUP);
|
||||
nbytes = 2; /* Response size: 2 bytes */
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1615,8 +1635,8 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
{
|
||||
/* Endpoint recipient */
|
||||
|
||||
epno = USB_EPNO(index.b[1]);
|
||||
if (epno < STM32_NENDPOINTS && index.b[0] == 0 &&
|
||||
epno = USB_EPNO(index.b[LSB]);
|
||||
if (epno < STM32_NENDPOINTS && index.b[MSB] == 0 &&
|
||||
value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0)
|
||||
{
|
||||
privep = &priv->eplist[epno];
|
||||
@ -1666,8 +1686,8 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
{
|
||||
/* Handler recipient=endpoint */
|
||||
|
||||
epno = USB_EPNO(index.b[1]);
|
||||
if (epno < STM32_NENDPOINTS && index.b[0] == 0 &&
|
||||
epno = USB_EPNO(index.b[LSB]);
|
||||
if (epno < STM32_NENDPOINTS && index.b[MSB] == 0 &&
|
||||
value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0)
|
||||
{
|
||||
privep = &priv->eplist[epno];
|
||||
@ -1693,11 +1713,15 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0SETUPSETADDRESS), value.w);
|
||||
if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_DEVICE ||
|
||||
index.w != 0 || len.w != 0 || value.b[1] > 127 || value.b[0] != 0)
|
||||
index.w != 0 || len.w != 0 || value.w > 127)
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0);
|
||||
priv->devstate = DEVSTATE_STALLED;
|
||||
}
|
||||
|
||||
/* Note that setting of the device address will be deferred until the
|
||||
* EP0IN complete interrupt
|
||||
*/
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1920,7 +1944,7 @@ static void stm32_ep0in(struct stm32_usbdev_s *priv)
|
||||
{
|
||||
union wb_u value;
|
||||
value.w = GETUINT16(priv->ctrl.value);
|
||||
stm32_setdevaddr(priv, value.b[1]);
|
||||
stm32_setdevaddr(priv, value.b[LSB]);
|
||||
}
|
||||
|
||||
devstate = DEVSTATE_STALLED;
|
||||
@ -1997,17 +2021,19 @@ static void stm32_lptransfer(struct stm32_usbdev_s *priv)
|
||||
|
||||
while (((istr = stm32_getreg(STM32_USB_ISTR)) & USB_ISTR_CTR) != 0)
|
||||
{
|
||||
stm32_putreg((uint16)~USB_ISTR_CTR, STM32_USB_ISTR); /* clear CTR flag */
|
||||
stm32_putreg((uint16)~USB_ISTR_CTR, STM32_USB_ISTR);
|
||||
|
||||
/* Extract highest priority endpoint number */
|
||||
|
||||
epno = (ubyte)(istr & USB_ISTR_EPID_MASK);
|
||||
privep = &priv->eplist[epno];
|
||||
|
||||
/* Handle EP0 completion events */
|
||||
|
||||
if (epno == 0)
|
||||
{
|
||||
/* Decode and service control endpoint interrupt */
|
||||
|
||||
|
||||
/* Save RX & TX status */
|
||||
|
||||
priv->rxstatus = stm32_geteprxstatus(EP0);
|
||||
@ -2018,61 +2044,72 @@ static void stm32_lptransfer(struct stm32_usbdev_s *priv)
|
||||
stm32_seteprxstatus(EP0, USB_EPR_STATRX_NAK);
|
||||
stm32_seteptxstatus(EP0, USB_EPR_STATTX_NAK);
|
||||
|
||||
/* DIR bit = origin of the interrupt */
|
||||
/* Check the direction bit to determine if this the completion of an
|
||||
* EP packet sent to or received from the host PC.
|
||||
*/
|
||||
|
||||
if ((istr & USB_ISTR_DIR) == 0)
|
||||
{
|
||||
/* DIR = 0 => IN int */
|
||||
/* DIR = 0 implies that (USB_EPR_CTR_TX = 1) always */
|
||||
/* EP0 IN: device-to-host (DIR=0) */
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0IN), istr);
|
||||
stm32_clrepctrtx(EP0);
|
||||
stm32_ep0in(priv);
|
||||
|
||||
/* Set Tx & Rx status */
|
||||
/* Set TX and RX status */
|
||||
|
||||
stm32_seteprxstatus(EP0, priv->rxstatus);
|
||||
stm32_seteptxstatus(EP0, priv->txstatus);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DIR = 1 */
|
||||
/* DIR = 1 & CTR_RX => SETUP or OUT int */
|
||||
/* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
|
||||
/* EP0 OUT: host-to-device (DIR=1) */
|
||||
|
||||
epval = stm32_getreg(STM32_USB_EPR(EP0));
|
||||
if ((epval & USB_EPR_CTR_TX) != 0)
|
||||
{
|
||||
/* CTR_TX is set when an IN transaction successfully
|
||||
* completes on an endpoint
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0INDONE), epval);
|
||||
stm32_clrepctrtx(EP0);
|
||||
stm32_ep0in(priv);
|
||||
|
||||
/* Set Tx & Rx status */
|
||||
/* Set TX and RX status */
|
||||
|
||||
stm32_seteprxstatus(EP0, priv->rxstatus);
|
||||
stm32_seteptxstatus(EP0, priv->txstatus);
|
||||
return;
|
||||
}
|
||||
else if ((epval & USB_EPR_SETUP) != 0)
|
||||
{
|
||||
stm32_clrepctrrx(EP0); /* SETUP bit kept frozen while CTR_RX=1 */
|
||||
/* SETUP is set by the hardware when the last completed
|
||||
* transaction was a control endpoint SETUP
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0SETUPDONE), epval);
|
||||
stm32_clrepctrrx(EP0);
|
||||
stm32_ep0setup(priv);
|
||||
|
||||
/* Set Tx & Rx status */
|
||||
/* Set TX and RX status */
|
||||
|
||||
stm32_seteprxstatus(EP0, priv->rxstatus);
|
||||
stm32_seteptxstatus(EP0, priv->txstatus);
|
||||
return;
|
||||
}
|
||||
else if ((epval & USB_EPR_CTR_RX) != 0)
|
||||
{
|
||||
/* Set by the hardware when an OUT/SETUP transaction successfully
|
||||
* completed on this endpoint.
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EP0OUTDONE), epval);
|
||||
stm32_clrepctrrx(EP0);
|
||||
stm32_ep0out(priv, privep);
|
||||
|
||||
/* Set Tx & Rx status */
|
||||
/* Set TX and RX status */
|
||||
|
||||
stm32_seteprxstatus(EP0, priv->rxstatus);
|
||||
stm32_seteptxstatus(EP0, priv->txstatus);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2084,16 +2121,18 @@ static void stm32_lptransfer(struct stm32_usbdev_s *priv)
|
||||
epval = stm32_getreg(STM32_USB_EPR(epno));
|
||||
if ((epval & USB_EPR_CTR_RX) != 0)
|
||||
{
|
||||
/* OUT: host-to-device */
|
||||
/* OUT: host-to-device
|
||||
* CTR_RX is set by the hardware when an OUT/SETUP transaction
|
||||
* successfully completed on this endpoint.
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUTDONE), epval);
|
||||
|
||||
/* Clear interrupt status */
|
||||
|
||||
stm32_clrepctrrx(epno);
|
||||
|
||||
/* Handle read requests */
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT), (uint16)epno);
|
||||
|
||||
/* Read host data into the current read request */
|
||||
/* Handle read requests: Read host data into the current read request */
|
||||
|
||||
if (!stm32_rqempty(privep))
|
||||
{
|
||||
@ -2108,14 +2147,19 @@ static void stm32_lptransfer(struct stm32_usbdev_s *priv)
|
||||
|
||||
if ((epval & USB_EPR_CTR_TX) != 0)
|
||||
{
|
||||
/* IN: device-to-host */
|
||||
/* IN: device-to-host
|
||||
* CTR_TX is set when an IN transaction successfully completes on
|
||||
* an endpoint
|
||||
*/
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPINDONE), epval);
|
||||
|
||||
/* Clear interrupt status */
|
||||
|
||||
stm32_clrepctrtx(epno);
|
||||
|
||||
/* Handle write requests */
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN), (uint16)epno);
|
||||
privep->txbusy = 0;
|
||||
stm32_wrrequest(priv, privep);
|
||||
}
|
||||
@ -2291,7 +2335,7 @@ static int stm32_lpinterrupt(int irq, void *context)
|
||||
{
|
||||
/* Low priority endpoint correct transfer interrupt */
|
||||
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_LPCTR), 0);
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_LPCTR), istr);
|
||||
stm32_lptransfer(priv);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user