Browse Source

I think the STM32 UST OTG FS host driver is finally finished

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5065 7fd9a85b-ad96-42d3-883c-3090e2eb8679
sbg
patacongo 13 years ago
parent
commit
6389a944b5
  1. 2
      nuttx/ChangeLog
  2. 82
      nuttx/arch/arm/src/stm32/stm32_otgfshost.c

2
nuttx/ChangeLog

@ -3211,3 +3211,5 @@
is now required to enabled strerror(). Add an option is now required to enabled strerror(). Add an option
CONFIG_LIBC_STRERROR_SHORT that can be used to output shortened CONFIG_LIBC_STRERROR_SHORT that can be used to output shortened
strings by strerror(). strings by strerror().
* arch/arm/src/stm32/stm32_usbotghost.c: Finally... the USB OTG FS
appears to handle NAKing correctly is complete.

82
nuttx/arch/arm/src/stm32/stm32_otgfshost.c

@ -809,7 +809,7 @@ static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx,
uint32_t eptype; uint32_t eptype;
unsigned int avail; unsigned int avail;
/* Save the recon for the halt. We need this in the channel halt interrrupt /* Save the reason for the halt. We need this in the channel halt interrrupt
* handling logic to know what to do next. * handling logic to know what to do next.
*/ */
@ -1474,6 +1474,9 @@ static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
FAR uint8_t *buffer, size_t buflen) FAR uint8_t *buffer, size_t buflen)
{ {
FAR struct stm32_chan_s *chan; FAR struct stm32_chan_s *chan;
uint16_t start;
uint16_t elapsed;
size_t xfrlen;
int ret = OK; int ret = OK;
/* Loop until the transfer completes (i.e., buflen is decremented to zero) /* Loop until the transfer completes (i.e., buflen is decremented to zero)
@ -1481,22 +1484,19 @@ static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
*/ */
chan = &priv->chan[chidx]; chan = &priv->chan[chidx];
chan->buffer = buffer; start = stm32_getframe();
chan->buflen = buflen;
/* There is a bug in the code at present. With debug OFF, this driver while (buflen > 0)
* overruns the typical FLASH device and there are many problems with {
* NAKS. Sticking a big delay here allows the device (FLASH drive) to /* Transfer one packet at a time. The hardware is capable of queueing
* catch up but sacrifices driver performance. * multiple OUT packets, but I just haven't figured out how to handle
*/ * the case where a single OUT packet in the group is NAKed.
*/
#if !defined(CONFIG_DEBUG_VERBOSE) || !defined(CONFIG_DEBUG_USB) xfrlen = MIN(chan->maxpacket, buflen);
#warning "REVISIT this delay" chan->buffer = buffer;
usleep(50*1000); chan->buflen = xfrlen;
#endif
while (chan->buflen > 0)
{
/* Set up for the wait BEFORE starting the transfer */ /* Set up for the wait BEFORE starting the transfer */
ret = stm32_chan_waitsetup(priv, chan); ret = stm32_chan_waitsetup(priv, chan);
@ -1556,29 +1556,49 @@ static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx,
ret = stm32_chan_wait(priv, chan); ret = stm32_chan_wait(priv, chan);
/* EAGAIN indicates that the device NAKed the transfer and we need /* Handle transfer failures */
* do try again. NAK retries are not yet supported for OUT transfers
* so any unsuccessful response will cause us to abort the OUT
* transfer.
*/
if (ret != OK) if (ret != OK)
{ {
udbg("Transfer failed: %d\n", ret); udbg("Transfer failed: %d\n", ret);
break;
}
}
/* There is a bug in the code at present. With debug OFF, this driver /* Check for a special case: If (1) the transfer was NAKed and (2)
* overruns the typical FLASH device and there are many problems with * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we
* NAKS. Sticking a big delay here allows the device (FLASH drive) to * should be able to just flush the Rx and Tx FIFOs and try again.
* catch up but sacrifices driver performance. * We can detect this latter case becasue the then the transfer
*/ * buffer pointer and buffer size will be unaltered.
*/
#if !defined(CONFIG_DEBUG_VERBOSE) || !defined(CONFIG_DEBUG_USB) elapsed = stm32_getframe() - start;
#warning "REVISIT this delay" if (ret != -EAGAIN || /* Not a NAK condition OR */
usleep(50*1000); elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */
#endif chan->buflen != xfrlen) /* Data has been partially transferred */
{
/* Break out and return the error */
break;
}
/* Is this flush really necessary? What does the hardware do with the
* data in the FIFO when the NAK occurs? Does it discard it?
*/
stm32_flush_txfifos(OTGFS_GRSTCTL_TXFNUM_HALL);
/* Get the device a little time to catch up. Then retry the transfer
* using the same buffer pointer length.
*/
usleep(20*1000);
}
else
{
/* Successfully transferred. Update the buffer pointer and length */
buffer += xfrlen;
buflen -= xfrlen;
}
}
return ret; return ret;
} }

Loading…
Cancel
Save