Question
USB HS Failure to ACK Bulk OUT packet
Posted on March 09, 2016 at 15:55
#ulpi #usb #stm32f4
Hi All,
I'm working on a STM32F429-based USB HighSpeed peripheral which exchanges MIDI data with a host computer.If you're not familiar with MIDI, don't worry about it - just know that in the land of USB it's represented as 2 x bulk endpoints. In a nutshell - the problem I'm seeing is that sometimes the STM32 fails to provide a handshake packet (NAK, ACK, or otherwise) in response to a OUT packet to the incoming bulk endpoint of the device. I'm reaching out to see if anyone has experienced a similar issue, hopefully with a workaround/solution. My configuration is as follows:- Hardware: STM32F4x9I-EVAL board (Rev B)
- Libraries: STM32 USB OTG Library v2.20 (includes SPL v1.6.0)
- USB Config: Using the USB-HS core with the on-board ULPI PHY enabled
- Host: Win7-64 PC
I'm looking at the trace from a USB protocol analyzer and can see the following series of events:
- I send a 'large' packet of data to the device. I have the bulk endpoint defined as 512 bytes, so the result is the host starts sending many back-to-back 512byte OUT packets.
- Several transfers are successfully accepted by the device, where success is defined as: A) OUT, DATAx, ACK ... or B) OUT, DATAx, NAK, PING, ACK, OUT, DATAx, ACK. In both these cases the STM32 has accepted the data transfer.
- At some point (~50 transfers later), the host sends a OUT, DATAx...but the STM32 never responds with a handshake byte (ACK, NAK, NYET, STALL)
- The host recognizes it never receives a handshake and as a result sends a PING to check the endpoint status. The STM32 responds in kind with an ACK, meaning the endpoint is ready.
- The host thinking the endpoint is now ready, attempts the OUT, DATAx again...but still...no handshake packet back from the STM
- Steps 3-5 occur for many transactions (100K+)...and then for some reason the STM32 finally decides to ACK an OUT transaction. It transfers some more data, but then falls back into the bad behavior of steps 3-5.
It's worth noting that this problem does not occur if I use either the USB-FS core of the USB-HS core with on-chip FS PHY. But this is at a significantly data rate.
The only other ISR running in the system is SysTick, and it's as low as a priority as it can get. I'm not currently do anything with the incoming data. I'm merely trying to test the raw transfer speed. My ''_DataOut'' handler within the USB ISR is very simplistic.The MIDI data handler within is simply a stub at this point.uint8_t usbd_MIDI_DataOut(
void
*pdev, uint8_t epnum)
{
// ------------------------------------------------------------------------
// Determine how many bytes have been received and handle them
// Note: USB should NAK until endpoint is re-prepared for new reception
// ------------------------------------------------------------------------
uint32_t rx_count = ((USB_OTG_CORE_HANDLE *)pdev)->dev.out_ep[epnum].xfer_count;
usbd_MIDI_RX(rx_buffer, rx_count);
// ------------------------------------------------------------------------
// Re-Prepare the OUT endpoint to receive the next packet from the host
// uint32_t DCD_EP_PrepareRx(USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len)
// ------------------------------------------------------------------------
DCD_EP_PrepareRx(pdev, midi_driver_config.base_ep_out, rx_buffer, MIDI_EP_SIZE);
return
USBD_OK;
}
void
usbd_MIDI_RX(uint8_t* buffer, uint32_t len)
{
// ReadUsbRcvdData(buffer, len);
}
The USB trace is seen below.
#ulpi #usb #stm32f4