stmfx07: usb: flush txfifo if not empty after SETUP
After a SETUP packet on a control endpoint the transmit FIFO should usually be empty. If something bad happened, e.g. PC and device got out of sync, we want to clear the fifo. This should fix #668.
This commit is contained in:
parent
973efabddb
commit
a4f1568b7d
@ -248,6 +248,30 @@ uint16_t stm32fx07_ep_read_packet(usbd_device *usbd_dev, uint8_t addr,
|
||||
return len;
|
||||
}
|
||||
|
||||
static void stm32fx07_flush_txfifo(usbd_device *usbd_dev, int ep)
|
||||
{
|
||||
uint32_t fifo;
|
||||
/* set IN endpoint NAK */
|
||||
REBASE(OTG_DIEPCTL(ep)) |= OTG_DIEPCTL0_SNAK;
|
||||
/* wait for core to respond */
|
||||
while (!(REBASE(OTG_DIEPINT(ep)) & OTG_DIEPINTX_INEPNE)) {
|
||||
/* idle */
|
||||
}
|
||||
/* get fifo for this endpoint */
|
||||
fifo = (REBASE(OTG_DIEPCTL(ep)) & OTG_DIEPCTL0_TXFNUM_MASK) >> 22;
|
||||
/* wait for core to idle */
|
||||
while (!(REBASE(OTG_GRSTCTL) & OTG_GRSTCTL_AHBIDL)) {
|
||||
/* idle */
|
||||
}
|
||||
/* flush tx fifo */
|
||||
REBASE(OTG_GRSTCTL) = (fifo << 6) | OTG_GRSTCTL_TXFFLSH;
|
||||
/* reset packet counter */
|
||||
REBASE(OTG_DIEPTSIZ(ep)) = 0;
|
||||
while ((REBASE(OTG_GRSTCTL) & OTG_GRSTCTL_TXFFLSH)) {
|
||||
/* idle */
|
||||
}
|
||||
}
|
||||
|
||||
void stm32fx07_poll(usbd_device *usbd_dev)
|
||||
{
|
||||
/* Read interrupt status register. */
|
||||
@ -297,6 +321,14 @@ void stm32fx07_poll(usbd_device *usbd_dev)
|
||||
type = USB_TRANSACTION_OUT;
|
||||
}
|
||||
|
||||
if (type == USB_TRANSACTION_SETUP
|
||||
&& (REBASE(OTG_DIEPTSIZ(ep)) & OTG_DIEPSIZ0_PKTCNT)) {
|
||||
/* SETUP received but there is still something stuck
|
||||
* in the transmit fifo. Flush it.
|
||||
*/
|
||||
stm32fx07_flush_txfifo(usbd_dev, ep);
|
||||
}
|
||||
|
||||
/* Save packet size for stm32f107_ep_read_packet(). */
|
||||
usbd_dev->rxbcnt = (rxstsp & OTG_GRXSTSP_BCNT_MASK) >> 4;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user