I've been trying to understand how the USB-API handles it's buffers. Everything in this question / discussion relates to CDC TX.
First, context :
st = USBCDC_intfStatus(intfNum, &bytesSent, &bytesRecieved);
if ((st & kUSBCDC_busNotAvailable) || (st & kUSBCDC_waitingForSend)){
return 0;
}
I use the above code snippet to wait until it's OK to send more data to the USB intf. This snippet works as advertised.
However, I've noticed that this reports the CDC interface is ready to accept more data _before_ the API calls USBCDC_handleSendCompleted(). The reason I noticed it is because I was using the handler to prepare for the next dataset. If I use a flag that I set before initiating a send and clear in the handler, my data integrity problems go away at the expense of greatly reduced throughput (throughput measured as actual number of bytes transferred, not number of good bytes). I need to be able to find out when the source buffer can be nuked, ie, when it's made it's way into the EP buffer, not when it's sent off the host. When attempting to figure out what was going on, I notice the following :
There seem to be two end-point buffers in the API (XY), and the API switches between them. It looks like it's allowing one to be filled in from the source while the other is sent away by USB. It looks tailormade for handling large source buffers. This is behaviour that I would like to be able to make use of from the application space as well, with smaller source buffers.
The actual transfer from source buffer to EP buffer is done by memcpyDMA() in usbdma.c. This function is essentially called from within an Interrupt context, and if I'm reading this right, it's triggering DMA and looping on the interrupt flag!?
I'm also having some trouble following this line of code :
*pCT1 = byte_count; //Set counter for usb In-Transaction
Am I correct in assuming that this is what tells the USB peripheral hardware (and not the API) that the endpoint buffer is ready to be transmitted? If so, could someone help me understand what's going on. If not, how does the endpoint buffer, after being filled by memcpyDMA(), get transmitted over to the host?