In case of IN transfers, the transaction is initiated by the Host by sending an IN token packet, the targeted device responds by sending one or more data packets and the host responds with a handshake packet (ACK/ NAK, etc.). If the device responds with NAK to show that it is not ready to send data when the host makes the request. The host continues to retry and the device responds with a data packet when it is ready. The host then acknowledges the receipt of the data with an ACK handshake.
Please refer to the USB 101 Section 9.2 for more details on this: https://www.cypress.com/file/134171/download
In Full-Speed (PSoC 5LP) devices, the maximum cable length is 5 meters. Please ensure that your cable is within the USB spec.
You can refer to the USBFS Bulk Wraparound code example for the implementation of Bulk transfers in case of PSoC 5LP. I am attaching the code example with this response.
Let me know it this helps. Please attach the project so that we can have a look at it, this will help us get a better insight of the issue.
USBFS_Bulk_Wraparound.zip 373.3 K
Thanks, but that doesn't actually answer my question! Is there anything I need to do in my code to deal with retries on error, or is this all taken care of for me by the USBFS library? Your sample project doesn't contain any error handling.
I can't attach my project because it relies on files outside the project directory, but it's in github here: fluxengine/main.c at master · davidgiven/fluxengine · GitHub
I had some problems with the USBUart error conditions, when transmitting data to the host, causing lockups.
I solved it by borrowing the PutString code from the library and modifying it to handle an error condition.
In this project, I am using FreeRTOS, so I was able to do a pause in the code to allow for processing.
Note the exit if we have delayed twice with no success. This usually means the USB was disconnected,
and you have to give up. The code provided by Cypress simply locks the USB and you can never recover.
This code at least attempts to send the data, and gives up (maybe not gracefully, but in my case it was acceptable).
You could modify the routine to return an error code to the calling routine should you need to.
*Edit* Also, if you are using a variant of sprintf() or printf(), make sure your heap size is set to at least 2k bytes, and the stack size set to at least 4k bytes (in the system tab of the .cydwwr Design Wide Resources editor) Insufficient stack size or heap size can cause issues like this.
// the following uint8 is borrowed from USBUART_cdc.c
// and only functions if 1 uart is being used, which in our
// case is always true
static uint8 USBUART_activeCom = 0u;
void myUSBUART_PutString(const char8 string)
uint16 bufIndex = 0u;
uint8 epNumber = USBUART_cdcDataInEp[USBUART_activeCom];
/* Get length string length (it is terminated with zero). */
strLength = strlen(string);
/* Limit length to maximum packet size of endpoint. */
sendLength = (strLength > USBUART_EP[epNumber].bufferSize) ?
USBUART_EP[epNumber].bufferSize : strLength;
/* Load IN endpoint and expose it to host. */
USBUART_LoadInEP(epNumber, (const uint8 *)&string[bufIndex], sendLength);
strLength -= sendLength;
/* If more data are present to send or full packet was sent */
if ((strLength > 0u) || (sendLength == USBUART_EP[epNumber].bufferSize))
bufIndex += sendLength;
/* Wait until host read data from IN endpoint buffer. */
while (USBUART_IN_BUFFER_FULL == USBUART_EP[epNumber].apiEpState)
// don't wait very long here. allow other code to run in the calling task
vTaskDelay(pdMS_TO_TICKS(10));// delay until reconnect
/* If last packet is exactly maximum packet size, it shall be followed
* by a zero-length packet to assure the end of segment is properly
* identified by the terminal.
if (0u == strLength)
USBUART_LoadInEP(epNumber, NULL, 0u);
while (strLength > 0u);