Working for missing logic to get EP0 OUT DATA

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4594 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-04-12 14:47:29 +00:00
parent 0969329aa2
commit 333bd7254a
3 changed files with 86 additions and 12 deletions

16
TODO
View File

@ -521,6 +521,22 @@ o USB (drivers/usbdev, drivers/usbhost)
Status: Open
Priority: Low (Unless you need RTL8187 support).
Title: EP0 OUT CLASS DATA
Description: There is no mechanism in place to handle EP0 OUT data transfers.
There are two aspects to this problem, neither are easy to fix
(only because of the number of drivers that would be impacted):
1. The class drivers only send EP0 write requests and these are
only queued on EP0 IN by this drivers. There is never a read
request queued on EP0 OUT.
2. But EP0 OUT data could be buffered in a buffer in the driver
data structure. However, there is no method currently
defined in the USB device interface to obtain the EP0 data.
Status: Open
Priority: High for class drivers that need EP0 data. For example, the
CDC/ACM serial driver might need the line coding data (that
data is not used currenly, but it might be).
o Libraries (lib/)
^^^^^^^^^^^^^^^^

View File

@ -262,16 +262,16 @@ enum stm32_devstate_e
enum stm32_ep0state_e
{
EP0STATE_IDLE = 0, /* Idle State, leave on receiving a setup packet or
EP0STATE_IDLE = 0, /* Idle State, leave on receiving a SETUP packet or
* epsubmit:
* SET: In stm32_epin() and stm32_epout() when
* we revert from request processing to
* SETUP processing.
* TESTED: Never */
EP0STATE_SETUP, /* Setup Packet received by stm32_ep0out_setup():
EP0STATE_SETUP, /* SETUP packet beign processing in stm32_ep0out_setup():
* SET: When SETUP packet received in EP0 OUT
* TESTED: Never */
EP0STATE_SETUPRESPONSE, /* Short setup response write (without a USB request):
EP0STATE_SETUPRESPONSE, /* Short SETUP response write (without a USB request):
* SET: When SETUP response is sent by
* stm32_ep0in_setupresponse()
* TESTED: Never */
@ -418,6 +418,7 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep,
FAR uint8_t *dest, uint16_t len);
static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len);
static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv,
FAR struct stm32_ep_s *privep);
static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt);
@ -427,7 +428,8 @@ static void stm32_epout_request(FAR struct stm32_usbdev_s *priv,
/* General request handling */
static void stm32_ep_flush(FAR struct stm32_ep_s *privep);
static void stm32_req_complete(FAR struct stm32_ep_s *privep, int16_t result);
static void stm32_req_complete(FAR struct stm32_ep_s *privep,
int16_t result);
static void stm32_req_cancel(FAR struct stm32_ep_s *privep,
int16_t status);
@ -1163,7 +1165,7 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
* Name: stm32_rxfifo_read
*
* Description:
* Read packet from the EP0 RxFIFO.
* Read packet from the RxFIFO into a read request.
*
*******************************************************************************/
@ -1200,6 +1202,35 @@ static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep,
}
}
/*******************************************************************************
* Name: stm32_rxfifo_discard
*
* Description:
* Discard packet data from the RxFIFO.
*
*******************************************************************************/
static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len)
{
if (len > 0)
{
uint32_t regaddr;
int i;
/* Get the address of the endpoint FIFO */
regaddr = STM32_OTGFS_DFIFO_DEP(privep->epphy);
/* Read 32-bits at time */
for (i = 0; i < len; i += 4)
{
volatile uint32_t data = stm32_getreg(regaddr);
(void)data;
}
}
}
/*******************************************************************************
* Name: stm32_epout_complete
*
@ -1255,7 +1286,7 @@ static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv,
* Description:
* This function is called from the RXFLVL interrupt handler when new incoming
* data is available in the endpoint's RxFIFO. This function will simply
* copy the incoming data into pending requests data buffer.
* copy the incoming data into pending request's data buffer.
*
*******************************************************************************/
@ -1266,19 +1297,37 @@ static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt)
int buflen;
int readlen;
/* Get a reference to the request at the head of the endpoint's request queue */
/* Get a reference to the request at the head of the endpoint's request
* queue.
*
* TODO: There is no mechanism in place to handle EP0 OUT data transfers.
* There are two aspects to this problem, neither are easy to fix (only
* because of the number of drivers that would be impacted):
*
* 1. The class drivers only send EP0 write requests and these are only
* queued on EP0 IN by this drivers. There is never a read request
* queued on EP0 OUT.
* 2. But EP0 OUT data could be buffered in a buffer in the driver data
* structure. However, there is no method currently defined in
* the USB device interface to obtain the EP0 data.
*/
privreq = stm32_rqpeek(privep);
DEBUGASSERT(privreq);
if (!privreq)
{
/* Incoming data is available in the RxFIFO, but there is no read setup
* to receive the receive the data. In this case, the endpoint should have
* been NAKing but apparently was not. The data is lost!
* to receive the receive the data. In this case, the endpoint should
* have been NAKing but apparently was not. The data is lost!
*
* NOTE: EP0 data may still be received in this case because it will
* not be NAKing.
*/
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy);
/* Discard the data in the RxFIFO */
stm32_rxfifo_discard(privep, bcnt);
privep->active = false;
return;
}
@ -1300,6 +1349,12 @@ static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt)
stm32_rxfifo_read(privep, dest, readlen);
/* If there were more bytes in the RxFIFO than could be held in the read
* request, then we will have to discard those.
*/
stm32_rxfifo_discard(privep, bcnt - readlen);
/* Update the number of bytes transferred */
privreq->req.xfrd += readlen;
@ -2298,7 +2353,7 @@ static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv)
stm32_putreg(OTGFS_DOEPINT_XFRC, STM32_OTGFS_DOEPINT(epno));
/* Handle the RX transer data ready event */
/* Handle the RX transfer data ready event */
stm32_epout(priv, epno);
}

View File

@ -1402,7 +1402,10 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
{
/* Save the new line coding in the private data structure */
#warning "There is no mechanism now for the class driver to receive EP0 SETUP OUT data"
#if 0
memcpy(&priv->linecoding, ctrlreq->buf, MIN(len, 7));
#endif
ret = 0;
/* If there is a registered callback to receive line status info, then