Hello,
I have a Cypress FX2 based device with customer firmware. There is EP6 that is configured as AUTOIN=0. The FX2 is itself is configured as a slave device with internal master. within the poll() loop the code regulary checks if the internal state of the device has changed. If yes then it sends out 4 bytes of statuses onto the EP6FIFOBUF. (IN data, EP6 is configured as a INT pipe).
My problem is as follows:
I need to NAK every incoming IN request until I have anything at all to send out (SIE level) - I would assume that this is done by the SIE autmatically (if the FIFO is empty, all reads are NAKed), but this is not the case at all, no NAK is seen by our USB sniffer. If I set the EP6BCL to zero, then a zero length transfer goes out, however after that I am unable to send ANYTHING (not zero length) on that EP. If I send all the time 4 bytes of statuses, then the whole device works fine. I need to strip the USB communication, otherwise it will hog the CPU quite a lot (the PC based driver is a Windows KMDF driver, that automatically polls this endpoint and does it quite fast, doesn't seem to treat the polling interval fine).
I also tried to set INPKTEND to 0x06 or 0x86 without any luck. I am just UNABLE to see NAK on the USB level.
How should this be done? Thanks,
"- I would assume that this is done by the SIE autmatically (if the FIFO is empty, all reads are NAKed), but this is not the case at all, no NAK is seen by our USB sniffer."
Is it a hardware bus analyzer? Software sniffers can't see NAK on the bus. Just hardware bus analyzer can observe it.
NAK handling is completed on the PC hardware - host controller. PC device driver has no chance to play with it. As software sniffers watches the traffic between the device drivers, system and top-most one, NAK is not leaked out to software sniffers.
On the firmware side, The endpoint automatically sends NAK, when no data is loaded to it. As you described, put the status data to the endpoint buffer, just when the data is ready. While no data is available, just leave the endpoint alone; load nothing.
On the host side, What is the device driver? HID, CyUSB or WinUSB ? There are two types of device driver, with or without read-ahead.
HID has a read-ahead input buffer on the device driver; it periodically sends IN transaction to the device, without any help of PC app. The data sent by the device is stored on the device driver buffer (cyclic buffer). The host app reads out the data from this buffer.
CyUSB and WinUSB are generic device driver. The IN transactions start by the host app, such as WinUSB_ReadPipe call. While the device is NAKing, the read call doesn't finish. Then, you have to apply asynchronous (OVERLAPPED) call, so as to do other tasks on the other threads. When the read call finishes, IN transactions also stop on the bus. To keep the IN transactions, the host app has to issue another read call, immediately after the last call finishes.
Tsuneo
Hello Tsuneo,
thank you for all the suggestions and explanattions. Actually I used totalphase's Beagle (hardware analyzer), but neverthless it turned out that I was lame enough to not SEE the NAKs themselves, they were surely present, the FX2 did it naturally all good, automatically. Anyhow the driver was a custom amde CyUSB based stuff. Thanks again,