STM32F407 CDC Host - IN transaction always returns NAK
I've setup an STM32F407 as a CDC Host on the HS peripheral with Full Speed (FS) comms, but the IN transaction always returns a NAK and no Device data is received on the Bulk Data pipe. I used the USB Host example from ST.com (userfunction that only transmit a message when the application=ready and a button is pushed, a receive api USBH_CDC_Receive is called within the transmit call back. I also tried a while loop with just receive after sending a message).
The STM32 Host appears to enumerate the CDC device correctly (status=CDC_CLASS at end of process). The USBH_CDC_Transmit function correctly sends an OUT transaction, an ACK acknowledge byte is returned, the USBH_CDC_TransmitCallback is triggered, and everything is visible as expected via the packet sniffer.
When using the USBH_CDC_Receive for an IN transaction, the packet sniffer sees an apparently correct sequence, but the Device always returns NAK.
When using a PC based CDC Host, the IN transaction causes the Device to return data correctly, and is shown clearly on the packet sniffer.
STM32 CDC Host details
cube 6.0.1
discovery board F407VGT MB997D,
HAL version 2017,
ST example downloaded from ST.com, this a good slide pack that shows the example as well https://blog.brichacek.net/wp-content/uploads/2015/10/STM32F4-and-USB.pdf
clock details 8Mhz, USB 48 Mhz,
linecoding info - SetLineCoding[115200,0,0,8],
NVIC interrupt settings USB OTG Global (highest), USB OTG Endpoint IN (second), USB OTG Endpoint OUT(second) as per MxCube
]
Steps taken so far
- Experimented with inserting Delay timings between subsequent reads
- Used different OTG devices with same result (Comms setup but not receive). (I can see the various descriptors and see that they are different devices)
- I have used messages with various lengths like newline, cr, Hello, Hello this is a test etc.
- I have plugged and unplugged the device, with nicely re-enumerates
- I added the line coding api call after the Application state is ready as per ST's application note and tried different line codings despite the device also being an OTG device
- DMA is not enabled
- single stepped the process thru STV2Link and IDE:
I can see with the IDE debugger that the USB Host channel interrupt for receive is working in STMF4xxx_HAL_HCD.c where the driver loops thru the 12 channels/endpoints and find channel 4 and calls HCD_HC_IN_IRQHandler. In this call I can see that it checks all statuses like BHERR, STALL and it lands on
"else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)" and ....
if (hhcd->hc[ch_num].state == HC_NAK)
{
hhcd->hc[ch_num].urb_state = URB_NOTREADY;
and returns to main and the whole process repeats
Questions
1 Does there need to be a specific step between completion of Enumeration and issuing an IN transaction?
2 Are and What line codings are necessary?
3 Any suggestions for further debugging and or tests?
Thanks Paul
edits: I used the transmit callback routine to trigger my oscilloscope to catch the rx/tx line data. See attached screenshot. As you can see data packets do occur although these could be the NAKs.
