The CDC VCOM device I'm talking to stalls when it gets a 64-byte packet. I've read where I could send a zero-length packet afterwards, but I don't see a way to do so. Doesn't the MCUXpresso SDK Host stack have a provision for doing this automatically? If so, I don't see it.
My workaround is to lie about the packet length and set it to 65. This works the device I'm using because it is another one of our company's products and we impose a proprietary protocol that handle it. But if I need to talk with a 3rd party device, this probably won't work.
The endpoint size is 64 bytes. Since the SDK has no provision to automatically handle this, I've decided to pad the message out to 65 bytes, which the device will simply ignore. This avoids code complication and risk. Supposedly, some SDK's can be configured to handle this situation with a setting change, but not this one. Also, if the SDK does get updated, I don't want to have to revisit this issue.
Mark,
Hey Mark, thanks for the response. It looks and sounds like the MCUXpresso SDK USB Host Stack just isn't sophisticated enough to handle this natively. Modifying the NXP USB stack is not something I'm comfortable with, especially since this is my first USB project, I'm working with legacy code, and we've discovered this rather late in the development cycle. I was really hoping that I had simply missed a configuration setting somewhere, and that the stack would automatically take care of protocol issues like this.
Hi
What is the particular endpoint size? CDC receivers tends to queue received data and pass it to the application only after receiving a frame of less that the endpoint size (in a similar way that control endpoints use a non-full size frame to detect the end of a control block - including zero data frame).
In the uTasker project CDC bulk endpoints are defined with a flag (USB_ENDPOINT_TERMINATES) that automatically terminates with a zero length data frame as follows in case the transmitted size happens to complete with a full-length data packet. If you can identify a similar location in the NXP stack (when it knows that the application has not queued further data for transmission) you could add a similar endpoint control flag to do the same.
if (ptrUsbQueue->USB_queue.chars == usNonAcknowledged) { // no further data waiting in the output buffer which has not already been placed in the output FIFO buffers
if (ptrUsbQueue->USB_queue.chars == 0) { // no more data queued
if (fnControlEndpoint(iEndpoint, iChannel, (USB_CONTROL_ENDPOINT | USB_ENDPOINT_TERMINATES)) != 0) { // if the endpoint is a control end point (or has termination characteristics) send zero data on termination if last frame was the same length as the endpoint
if ((tx_queue->usCompleteMessage % tx_queue->usMax_frame_length) == 0) {
FNSEND_ZERO_DATA(ptrUSB_HW, iEndpoint); // send a zero frame to terminate status stage
usNonAcknowledged = 1; // ensure that the transmitter state is not deactivated yet
}
}
....
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or product development requirements