Home |
Isochronous Transfers |
Isochronous TransfersIsochronous transactions differ in many ways from other transactions. Isochronous endpoints produce or consume a continues, real-time stream of data. On Full-Speed devices, exactly one packet is transferred in every frame (millisecond). For High-Speed, the interval of packets can be a different number of microframes (see function RTUEndpointInterval). High-Speed devices also support sending up to three physical packets per interval as one large logical packet. RTUEndpointPacketSize returns the size of such logical packets. The USB protocol provides no error detection or recovery for Isochronous transfers. If no data is transferred or the data is corrupted, no error information is passed to the application. No retries are performed and subsequent packets of a partially failed transaction are nevertheless transferred. No buffering is provided. If an application does not listen on an IN Isochronous endpoint, the produced data is lost. If an application must be sure to capture all isochronous data, it will have to work with at least 2 input buffers to ensure that data continues to be captured when the first buffer is full. Due to the design of some host controllers, at most 1 second worth of Isochronous transactions can be pending at any one time on a single endpoint. For example, if an Isochronous IN endpoint with an interval of 1 frame uses a packet size of 100 bytes, the application may not start transactions for more than 100000 bytes. It does not matter if a single large or many small transactions span more than 1 second. This limitation applies per endpoint. Applications using several Isochronous endpoints can queue up to 1 second worth of transactions on each endpoint. For High-Speed Isochronous endpoints, the amount of transaction time submitted in a single call to RTUStartIO must be an integral number of milliseconds. For example, if function RTUEndpointInterval reports that the endpoint is serviced every 2 microframes (i.e. ever 250 microseconds), then a multiple of 4 packets must be submitted in a single call to RTUStartIO. For Isochronous IN transactions on systems which do not implement cache coherence in hardware, the I/O buffer address used to receive data must be an integral multiple of the system cache line size (value RTU_CACHE_LINE_SIZE in file Rtucfg.h). In addition, the allocated block of memory holding the buffer must have a size which is an integral multiple of the system cache line size. This restriction does not apply to x86 systems. RTUSB-32 supports two different methods of handling Isochronous transactions which span more than one [micro]frame. The default method (pipe option RTUIsoBufferList not set) works the same way as with all other endpoint types: One contiguous buffer is passed to RTUStartIO and one packet is transferred per [micro]frame. The buffer address is advanced by the endpoint's maximum packet size in each [micro]frame, regardless of the number of bytes transferred with the preceding packet. Example: an IN endpoint has an interval of 1 frame and a packet size of 100 bytes. The application submits a 1000 byte transaction with RTUStartIO(Pipe, Data, 1000). RTUSB-32 will prepare the transaction such that it will span 10 frames. In the first frame, data will be received to offset 0 of Data. RTUSB-32 has no control over how many bytes the device will actually send. It may send any amount ranging from 0 to 100 bytes (if more than 100 bytes are received, an error is returned). On the next frame, data is received to address Data plus 100, regardless of how many bytes were received in the first frame. The third frame will receive to address Data plus 200, etc. After the tenth frame, the transaction completes and RTUSB-32 will subtract the number of bytes missing in the last frame from the Len parameter passed to RTUStartIO and return that value from RTUIOWait or RTUIOWaitTimed. In this example, if the last packet received contained 80 bytes, RTUSB-32 would report the transaction as having transferred 980 bytes, even if previous frames also had missing bytes. For Isochronous OUT endpoints, RTUSB-32 always sends a complete logical packet per interval to the device. Therefore, it is important that the Len parameter of RTUStartIO is an integer multiple of the packet size of the respective endpoint. However, the device is free to discard parts of the data. Pipe Option RTUIsoBufferListFor Isochronous endpoints with pipe option RTUIsoBufferList set, an array of RTUIsoBuffer structures must be passed to RTUStartIO. Each entry in this array describes the transfer for one [micro]frame. This way, the error code or frame number and number of received bytes is available for each [micro]frame, even if a transaction spans many packets. For OUT endpoints, the application can specify the number of bytes to send in each packet. Using pipe option RTUIsoBufferList is recommended. For further details, please see function RTUStartIO.
|