libusbK 
3.0
Library Documentation
© 2011-2021 Travis Lee Robinson. All rights reserved.
xfer-iso-asap.c

Transfers data over an isochronous pipe as soon as possible (ASAP).

Remarks
This is a rough example of how to transfer data isochronously as fast as possible. Real-time telemetry would be an example of such data.
xfer-iso-asap example:
  1. Finds the first EP of a device by vid/pid (use vid=hhhh, pid=hhhhh and the command line).
  2. use "intf=" on the command line to specify a specific interface. EG: intf=0
  3. use "altf=" on the command line to specify a specific alternate setting. EG: altf=1
  4. use "ep=" on the command line to specify a specific endpoint. EG: ep=81
  5. use "logfile=" on the command line to write output to a file. EG: logfile=log.txt
  6. Initializes a new UsbK (usb device) handle.
  7. Selects interface by pipe id and get descriptors.
  8. Sets the desired alternate setting.
  9. Configures the benchmark test device to send/receive data.
  10. Allocates iso buffer resources.
  11. Starts transferring until an error occurs or MAX_TRANSFERS_TOTAL is reached.
  12. Reports isochronous transfer packet information to log file.
  13. Cancels all transfers left outstanding.
  14. Frees the iso buffer resources.
  15. Frees the UsbK (usb device) handle.
  16. Frees the LstK (device list) handle.
  17. Closes log file.
Console Output using CYPRESS_FX3\BMFW_IsoSourceSink Firmware
.\xfer-iso-asap vid=04b4 pid=00fd ep=80
Looking for device vid/pid 04B4/00FD..
Using 04B4:00FD (6&28C5070&0&1): FX3 ISOSRCSNK - Cypress Semiconductor Corp.
Device opened successfully!
Device hardware fully prepared..
XFER-ISO TEST
----------------------------------------------------------
Device ID         : USB\VID_04B4&PID_00FD\6&28C5070&0&1
Device Name       : FX3 ISOSRCSNK
Interface         : 0
Alt Setting       : 1
Pipe ID           : 0x83 (Read)
Bytes Per Interval: 24576
Interval Period   : 125us

#0: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:unknown
        00 01 02 03 04 05 06 07
#1: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197357960.25
        08 09 0A 0B 0C 0D 0E 0F
#2: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196333133.61
        10 11 12 13 14 15 16 17
#3: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197219380.08
        18 19 1A 1B 1C 1D 1E 1F
#4: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196000398.76
        20 21 22 23 24 25 26 27
#5: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197595979.90
        28 29 2A 2B 2C 2D 2E 2F
#6: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196372353.18
        30 31 32 33 34 35 36 37
#7: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196549035.29
        38 39 3A 3B 3C 3D 3E 3F
#8: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:192885313.45
        40 41 42 43 44 45 46 47
#9: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:200436333.98
        48 49 4A 4B 4C 4D 4E 4F
#10: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196450839.33
        50 51 52 53 54 55 56 57
#11: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196706353.18
        58 59 5A 5B 5C 5D 5E 5F
#12: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196568686.26
        60 61 62 63 64 65 66 67
#13: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196863923.10
        68 69 6A 6B 6C 6D 6E 6F
#14: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196274333.63
        70 71 72 73 74 75 76 77
#15: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196706353.18
        78 79 7A 7B 7C 7D 7E 7F
#16: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196667000.10
        80 81 82 83 84 85 86 87
#17: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196667000.10
        88 89 8A 8B 8C 8D 8E 8F
#18: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196588341.17
        90 91 92 93 94 95 96 97
#19: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196726035.62
        98 99 9A 9B 9C 9D 9E 9F
#20: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196726035.62
        A0 A1 A2 A3 A4 A5 A6 A7
#21: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196490105.94
        A8 A9 AA AB AC AD AE AF
#22: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196235153.21
        B0 B1 B2 B3 B4 B5 B6 B7
#23: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:192356912.24
        B8 B9 BA BB BC BD BE BF
#24: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196352741.44
        C0 C1 C2 C3 C4 C5 C6 C7
#25: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:201215842.80
        C8 C9 CA CB CC CD CE CF
#26: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196923076.92
        D0 D1 D2 D3 D4 D5 D6 D7
#27: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196352741.44
        D8 D9 DA DB DC DD DE DF
#28: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196824506.96
        E0 E1 E2 E3 E4 E5 E6 E7
#29: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196962532.56
        E8 E9 EA EB EC ED EE EF
#30: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196411588.41
        F0 F1 F2 F3 F4 F5 F6 F7
#31: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196333133.61
        F8 F9 FA FB FC FD FE FF
#32: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197002004.01
        00 01 02 03 04 05 06 07
#33: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196509745.13
        08 09 0A 0B 0C 0D 0E 0F
#34: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196235153.21
        10 11 12 13 14 15 16 17
#35: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197219380.08
        18 19 1A 1B 1C 1D 1E 1F
#36: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196824506.96
        20 21 22 23 24 25 26 27
#37: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195922272.05
        28 29 2A 2B 2C 2D 2E 2F
#38: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:192885313.45
        30 31 32 33 34 35 36 37
#39: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:201030674.85
        38 39 3A 3B 3C 3D 3E 3F
#40: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195454816.58
        40 41 42 43 44 45 46 47
#41: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195513126.49
        48 49 4A 4B 4C 4D 4E 4F
#42: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:198794742.16
        50 51 52 53 54 55 56 57
#43: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196274333.63
        58 59 5A 5B 5C 5D 5E 5F
#44: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196804804.80
        60 61 62 63 64 65 66 67
#45: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197021745.67
        68 69 6A 6B 6C 6D 6E 6F
#46: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195805198.69
        70 71 72 73 74 75 76 77
#47: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197298544.91
        78 79 7A 7B 7C 7D 7E 7F
#48: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196529388.24
        80 81 82 83 84 85 86 87
#49: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196411588.41
        88 89 8A 8B 8C 8D 8E 8F
#50: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196647329.47
        90 91 92 93 94 95 96 97
#51: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196509745.13
        98 99 9A 9B 9C 9D 9E 9F
#52: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196391968.83
        A0 A1 A2 A3 A4 A5 A6 A7
#53: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196962532.56
        A8 A9 AA AB AC AD AE AF
#54: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:192771840.38
        B0 B1 B2 B3 B4 B5 B6 B7
#55: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197695324.28
        B8 B9 BA BB BC BD BE BF
#56: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197735090.01
        C0 C1 C2 C3 C4 C5 C6 C7
#57: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197278747.74
        C8 C9 CA CB CC CD CE CF
#58: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197377773.32
        D0 D1 D2 D3 D4 D5 D6 D7
#59: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197061240.85
        D8 D9 DA DB DC DD DE DF
#60: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196509745.13
        E0 E1 E2 E3 E4 E5 E6 E7
#61: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196509745.13
        E8 E9 EA EB EC ED EE EF
#62: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197199598.80
        F0 F1 F2 F3 F4 F5 F6 F7
#63: TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196391968.83
        F8 F9 FA FB FC FD FE FF
Done!
#include "examples.h"
#define MAX_OUTSTANDING_TRANSFERS 3
#define MAX_TRANSFERS_TOTAL 64
#define ISO_PACKETS_PER_TRANSFER (8)
// UINT_MAX for first interface found.
// NOTE: use "intf=" on the command line to specify a specific one. EG: intf=1
UINT gIntfIndex = UINT_MAX;
// UINT_MAX for first alt interface found.
// NOTE: use "altf=" on the command line to specify a specific one. EG: altf=2
UINT gAltfSetting = UINT_MAX;
// UINT_MAX for first ep found. (read or write)
// 0x80 for first IN (read) endpoint found
// 0x00 for first out (write) endpoint found
// NOTE: use "ep=" on the command line to specify a specific one. EG: ep=81
UINT gEpID = UINT_MAX;
typedef struct _MY_ISO_BUFFER_EL
{
PUCHAR TransferBuffer;
KOVL_HANDLE OvlHandle;
KISOCH_HANDLE IsoHandle;
UINT FrameNumber;
struct _MY_ISO_BUFFER_EL* prev;
struct _MY_ISO_BUFFER_EL* next;
} MY_ISO_BUFFER_EL, * PMY_ISO_BUFFER_EL;
typedef struct _MY_ISO_XFERS
{
ULONG TransferBufferSize;
PMY_ISO_BUFFER_EL Outstanding;
PMY_ISO_BUFFER_EL Completed;
ULONG SubmittedCount;
ULONG CompletedCount;
} MY_ISO_XFERS, * PMY_ISO_XFERS;
// Globals:
USB_INTERFACE_DESCRIPTOR gInterfaceDescriptor;
MY_ISO_XFERS gXfers;
DATA_COUNTER_STATS Dcs;
FILE* gOutFile = NULL;
int write_output(FILE* const stream, const char* fmt, ...)
{
int len;
va_list args;
va_start(args, fmt);
if (stream)
{
len = vfprintf(stream, fmt, args);
}
else
{
len = vprintf(fmt, args);
}
va_end(args);
return len;
}
/*
Reports isochronous packet information.
*/
VOID IsoXferComplete(PMY_ISO_XFERS myXfers, PMY_ISO_BUFFER_EL myBufferEL, ULONG transferLength)
{
int packetPos;
UINT goodPackets, badPackets;
char packetCounters[ISO_PACKETS_PER_TRANSFER * 3 + 1];
goodPackets = 0;
badPackets = 0;
if (gPipeInfo.PipeId & 0x80)
{
transferLength = 0;
for (packetPos = 0; packetPos < ISO_PACKETS_PER_TRANSFER; packetPos++)
{
UINT offset, length, status;
IsochK_GetPacket(myBufferEL->IsoHandle, packetPos, &offset, &length, &status);
sprintf(&packetCounters[packetPos * 3], "%02X ", myBufferEL->TransferBuffer[offset + 1]);
if (status == 0 && length != 0)
{
goodPackets++;
transferLength += length;
}
else
{
badPackets++;
}
}
}
else
{
transferLength = gXfers.TransferBufferSize;
}
Dcs.TotalBytes = 0;
mDcs_MarkStop(&Dcs, transferLength);
if (gPipeInfo.PipeId & 0x80)
{
if (myXfers->CompletedCount > 0)
{
write_output(gOutFile,
"#%u: TransferLength=%u GoodPackets=%u, BadPackets=%u, BPS-average:%.2f\n\t%s\n",
myXfers->CompletedCount, transferLength, goodPackets, badPackets, Dcs.Bps, packetCounters);
}
else
{
write_output(gOutFile,
"#%u: TransferLength=%u GoodPackets=%u, BadPackets=%u, BPS-average:unknown\n\t%s\n",
myXfers->CompletedCount, transferLength, goodPackets, badPackets, packetCounters);
}
}
else
{
write_output(gOutFile,
"#%u: TransferLength=%u\n",
myXfers->CompletedCount, transferLength);
}
Dcs.Start = Dcs.Stop;
myXfers->CompletedCount++;
}
int __cdecl main(int argc, char* argv[])
{
KLST_HANDLE deviceList = NULL;
KLST_DEVINFO_HANDLE deviceInfo = NULL;
KUSB_HANDLE usbHandle = NULL;
DWORD errorCode = ERROR_SUCCESS;
BM_TEST_TYPE testType;
UCHAR interfaceIndex;
BOOL success;
UINT deviceSpeedLength;
BYTE deviceSpeed;
KISOCH_PACKET_INFORMATION isoPacketInformation;
PMY_ISO_BUFFER_EL nextBufferEL;
PMY_ISO_BUFFER_EL nextBufferELTemp;
ULONG transferred;
BYTE bTemp;
char logFilename[128];
UINT logFilenameLength;
memset(&gXfers, 0, sizeof(gXfers));
memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor));
memset(&gPipeInfo, 0, sizeof(gPipeInfo));
/*
Find the test device. Uses "vid=hhhh pid=hhhh" arguments supplied on the
command line. (default is: vid=04D8 pid=FA2E)
*/
if (!Examples_GetTestDevice(&deviceList, &deviceInfo, argc, argv))
return GetLastError();
// use settings from command line if specified
Examples_GetArgVal(argc, argv, "intf=", &gIntfIndex, FALSE);
Examples_GetArgVal(argc, argv, "altf=", &gAltfSetting, TRUE);
Examples_GetArgVal(argc, argv, "ep=", &gEpID, TRUE);
logFilenameLength = sizeof(logFilename) - 1;
if (Examples_GetArgStr(argc, argv, "logfile", logFilename, &logFilenameLength))
gOutFile = fopen(logFilename, "w");
if (!LibK_LoadDriverAPI(&Usb, deviceInfo->DriverID))
{
errorCode = GetLastError();
printf("LibK_LoadDriverAPI failed. ErrorCode: %08lXh\n", errorCode);
goto Done;
}
{
errorCode = ERROR_NOT_SUPPORTED;
printf("DriverID %i does not support isochronous transfers using 'Isoch' functions. ErrorCode: %08lXh\n", Usb.Info.DriverID, errorCode);
goto Done;
}
/*
Initialize the device. This creates the physical usb handle.
*/
if (!Usb.Init(&usbHandle, deviceInfo))
{
errorCode = GetLastError();
printf("Usb.Init failed. ErrorCode: %08lXh\n", errorCode);
goto Done;
}
printf("Device opened successfully!\n");
/*
Select interface by pipe id and get descriptors.
*/
interfaceIndex = (UCHAR)-1;
memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor));
memset(&gPipeInfo, 0, sizeof(gPipeInfo));
while (Usb.SelectInterface(usbHandle, ++interfaceIndex, TRUE))
{
if (gIntfIndex != UINT_MAX && gIntfIndex != interfaceIndex) continue;
memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor));
memset(&gPipeInfo, 0, sizeof(gPipeInfo));
UCHAR gAltsettingIndex = (UCHAR)-1;
while (Usb.QueryInterfaceSettings(usbHandle, ++gAltsettingIndex, &gInterfaceDescriptor))
{
if (gAltfSetting == UINT_MAX || gAltfSetting == gInterfaceDescriptor.bAlternateSetting)
{
UCHAR pipeIndex = (UCHAR)-1;
while (Usb.QueryPipeEx(usbHandle, gAltsettingIndex, ++pipeIndex, &gPipeInfo))
{
if (gPipeInfo.PipeType == UsbdPipeTypeIsochronous && gPipeInfo.MaximumPacketSize)
{
// use first endpoint
if (gEpID == UINT_MAX)
break;
if ((gEpID == 0) && (gPipeInfo.PipeId & 0x80) == 0)
{
// using first write endpoint
break;
}
if ((gEpID == 0x80) && (gPipeInfo.PipeId & 0x80) == 0x80)
{
// using first read endpoint
break;
}
if (gEpID == gPipeInfo.PipeId)
{
// using a user specified read or write endpoint
break;
}
}
}
if (gPipeInfo.PipeId) break;
memset(&gPipeInfo, 0, sizeof(gPipeInfo));
}
memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor));
}
}
if (!gPipeInfo.PipeId)
{
printf("Pipe not found.\n");
goto Done;
}
if (!gPipeInfo.MaximumBytesPerInterval)
{
printf("Pipe does not have MaximumBytesPerInterval.\n");
goto Done;
}
/*
Set the desired alternate setting.
*/
success = Usb.SetAltInterface(
usbHandle,
gInterfaceDescriptor.bInterfaceNumber,
FALSE,
gInterfaceDescriptor.bAlternateSetting);
if (!success)
{
printf("Usb.SetAltInterface failed.\n");
goto Done;
}
// get the device speed
deviceSpeedLength = 1;
success = Usb.QueryDeviceInformation(usbHandle, DEVICE_SPEED, &deviceSpeedLength, &deviceSpeed);
if (!success)
{
printf("Usb.QueryDeviceInformation failed.\n");
goto Done;
}
// make sure ISO_ALWAYS_START_ASAP is enabled
bTemp = TRUE;
Usb.SetPipePolicy(usbHandle, gPipeInfo.PipeId, ISO_ALWAYS_START_ASAP, 1, &bTemp);
// get the iso packet information to help with frame calculations.
success = IsochK_CalcPacketInformation(deviceSpeed >= 3, &gPipeInfo, &isoPacketInformation);
if (!success)
{
printf("IsochK_CalcPacketInformation failed.\n");
goto Done;
}
// Configure the benchmark test device to send data.
testType = USB_ENDPOINT_DIRECTION_IN(gPipeInfo.PipeId) ? BM_TEST_TYPE_READ : BM_TEST_TYPE_WRITE;
success = Bench_Configure(usbHandle, BM_COMMAND_SET_TEST, 0, &Usb, &testType);
if (!success)
{
errorCode = GetLastError();
printf("Bench_Configure failed. ErrorCode: %08lXh\n", errorCode);
goto Done;
}
printf("Device hardware fully prepared..\n");
write_output(gOutFile, "XFER-ISO TEST\n", deviceInfo->DeviceID);
write_output(gOutFile, "----------------------------------------------------------\n");
write_output(gOutFile, "Device ID : %s\n", deviceInfo->DeviceID);
write_output(gOutFile, "Device Name : %s\n", deviceInfo->DeviceDesc);
write_output(gOutFile, "Interface : %u\n", gInterfaceDescriptor.bInterfaceNumber);
write_output(gOutFile, "Alt Setting : %u\n", gInterfaceDescriptor.bAlternateSetting);
write_output(gOutFile, "Pipe ID : 0x%02X (%s)\n", gPipeInfo.PipeId, (gPipeInfo.PipeId & 0x80) ? "Read" : "Write");
write_output(gOutFile, "Bytes Per Interval: %u\n", gPipeInfo.MaximumBytesPerInterval);
write_output(gOutFile, "Interval Period : %uus\n", isoPacketInformation.PollingPeriodMicroseconds);
write_output(gOutFile, "\n");
/*
Allocate the iso buffer resources.
*/
do
{
int pos;
gXfers.TransferBufferSize = ISO_PACKETS_PER_TRANSFER * gPipeInfo.MaximumBytesPerInterval;
success = OvlK_Init(&gXfers.OvlPool, usbHandle, MAX_OUTSTANDING_TRANSFERS, KOVL_POOL_FLAG_NONE);
if (!success)
{
errorCode = GetLastError();
printf("OvlK_Init Failed.\n");
goto Done;
}
for (pos = 0; pos < MAX_OUTSTANDING_TRANSFERS; pos++)
{
nextBufferEL = malloc(sizeof(MY_ISO_BUFFER_EL));
if (nextBufferEL != NULL)
{
memset(nextBufferEL, 0, sizeof(nextBufferEL[0]));
nextBufferEL->TransferBuffer = malloc(gXfers.TransferBufferSize);
if (!IsochK_Init(&nextBufferEL->IsoHandle, usbHandle, gPipeInfo.PipeId, ISO_PACKETS_PER_TRANSFER, nextBufferEL->TransferBuffer, gXfers.TransferBufferSize))
{
errorCode = GetLastError();
printf("IsochK_Init Failed.\n");
goto Done;
}
if (!IsochK_SetPacketOffsets(nextBufferEL->IsoHandle, gPipeInfo.MaximumBytesPerInterval))
{
errorCode = GetLastError();
printf("IsochK_SetPacketOffsets Failed.\n");
goto Done;
}
if (!OvlK_Acquire(&nextBufferEL->OvlHandle, gXfers.OvlPool))
{
errorCode = GetLastError();
printf("OvlK_Acquire Failed.\n");
goto Done;
}
DL_APPEND(gXfers.Completed, nextBufferEL);
}
}
} while (0);
mDcs_Init(&Dcs);
/*
Start reading until an error occurs or MAX_TRANSFERS_TOTAL is reached.
*/
do
{
while (errorCode == ERROR_SUCCESS && gXfers.Completed && gXfers.SubmittedCount < MAX_TRANSFERS_TOTAL)
{
nextBufferEL = gXfers.Completed;
DL_DELETE(gXfers.Completed, nextBufferEL);
DL_APPEND(gXfers.Outstanding, nextBufferEL);
OvlK_ReUse(nextBufferEL->OvlHandle);
if (gPipeInfo.PipeId & 0x80)
Usb.IsochReadPipe(nextBufferEL->IsoHandle, gXfers.TransferBufferSize, NULL, ISO_PACKETS_PER_TRANSFER, nextBufferEL->OvlHandle);
else
Usb.IsochWritePipe(nextBufferEL->IsoHandle, gXfers.TransferBufferSize, NULL, ISO_PACKETS_PER_TRANSFER, nextBufferEL->OvlHandle);
errorCode = GetLastError();
if (errorCode != ERROR_IO_PENDING)
{
printf("Usb.IsochReadPipe failed. ErrorCode: %08lXh\n", errorCode);
goto Done;
}
gXfers.SubmittedCount++;
errorCode = ERROR_SUCCESS;
}
nextBufferEL = gXfers.Outstanding;
if (!nextBufferEL)
{
printf("Done!\n");
goto Done;
}
success = Usb.GetOverlappedResult(usbHandle, nextBufferEL->OvlHandle, &transferred, TRUE);
//success = OvlK_Wait(nextBufferEL->OvlHandle, 1000, KOVL_WAIT_FLAG_NONE, (PUINT)&transferred);
if (!success)
{
errorCode = GetLastError();
printf("OvlK_Wait failed. ErrorCode: %08lXh\n", errorCode);
goto Done;
}
DL_DELETE(gXfers.Outstanding, nextBufferEL);
DL_APPEND(gXfers.Completed, nextBufferEL);
IsoXferComplete(&gXfers, nextBufferEL, transferred);
} while (errorCode == ERROR_SUCCESS);
Done:
/*
Cancel all transfers left outstanding.
*/
DL_FOREACH_SAFE(gXfers.Outstanding, nextBufferEL, nextBufferELTemp)
{
DL_DELETE(gXfers.Outstanding, nextBufferEL);
DL_APPEND(gXfers.Completed, nextBufferEL);
OvlK_WaitOrCancel(nextBufferEL->OvlHandle, 0, (PUINT)&transferred);
}
/*
Free the iso buffer resources.
*/
DL_FOREACH_SAFE(gXfers.Completed, nextBufferEL, nextBufferELTemp)
{
DL_DELETE(gXfers.Completed, nextBufferEL);
OvlK_Release(nextBufferEL->OvlHandle);
IsochK_Free(nextBufferEL->IsoHandle);
free(nextBufferEL->TransferBuffer);
free(nextBufferEL);
}
// Free the overlapped pool.
OvlK_Free(gXfers.OvlPool);
// return the device interface back to alt setting #0
Usb.SetAltInterface(usbHandle, gInterfaceDescriptor.bInterfaceNumber, TRUE, 0);
// Close the device handle.
Usb.Free(usbHandle);
// Free the device list.
LstK_Free(deviceList);
// Close the log file.
if (gOutFile)
{
fflush(gOutFile);
fclose(gOutFile);
gOutFile = NULL;
}
return errorCode;
}