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

Transfers data over an isochronous pipe at a fixed interval.

Remarks
This is a rough example of how to transfer data isochronously that is time sensitive. A fixed frequency audio sample would be an example of such data.
xfer-iso 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 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: StartFrame=09FC72A3h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:unknown
        00 01 02 03 04 05 06 07
#1: StartFrame=09FC72A4h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197377773.32
        08 09 0A 0B 0C 0D 0E 0F
#2: StartFrame=09FC72A5h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196274333.63
        10 11 12 13 14 15 16 17
#3: StartFrame=09FC72A6h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197695324.28
        18 19 1A 1B 1C 1D 1E 1F
#4: StartFrame=09FC72A7h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196117705.74
        20 21 22 23 24 25 26 27
#5: StartFrame=09FC72A8h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196706353.18
        28 29 2A 2B 2C 2D 2E 2F
#6: StartFrame=09FC72A9h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:191364609.69
        30 31 32 33 34 35 36 37
#7: StartFrame=09FC72AAh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:202146822.95
        38 39 3A 3B 3C 3D 3E 3F
#8: StartFrame=09FC72ABh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197179821.48
        40 41 42 43 44 45 46 47
#9: StartFrame=09FC72ACh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196215568.86
        48 49 4A 4B 4C 4D 4E 4F
#10: StartFrame=09FC72ADh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196450839.33
        50 51 52 53 54 55 56 57
#11: StartFrame=09FC72AEh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196883637.09
        58 59 5A 5B 5C 5D 5E 5F
#12: StartFrame=09FC72AFh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196824506.96
        60 61 62 63 64 65 66 67
#13: StartFrame=09FC72B0h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196254741.47
        68 69 6A 6B 6C 6D 6E 6F
#14: StartFrame=09FC72B1h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196667000.10
        70 71 72 73 74 75 76 77
#15: StartFrame=09FC72B2h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196686674.67
        78 79 7A 7B 7C 7D 7E 7F
#16: StartFrame=09FC72B3h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196137270.55
        80 81 82 83 84 85 86 87
#17: StartFrame=09FC72B4h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196923076.92
        88 89 8A 8B 8C 8D 8E 8F
#18: StartFrame=09FC72B5h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197002004.01
        90 91 92 93 94 95 96 97
#19: StartFrame=09FC72B6h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196078587.81
        98 99 9A 9B 9C 9D 9E 9F
#20: StartFrame=09FC72B7h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197002004.01
        A0 A1 A2 A3 A4 A5 A6 A7
#21: StartFrame=09FC72B8h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196765412.33
        A8 A9 AA AB AC AD AE AF
#22: StartFrame=09FC72B9h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195941797.89
        B0 B1 B2 B3 B4 B5 B6 B7
#23: StartFrame=09FC72BAh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196962532.56
        B8 B9 BA BB BC BD BE BF
#24: StartFrame=09FC72BBh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196765412.33
        C0 C1 C2 C3 C4 C5 C6 C7
#25: StartFrame=09FC72BCh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196176411.89
        C8 C9 CA CB CC CD CE CF
#26: StartFrame=09FC72BDh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197100751.88
        D0 D1 D2 D3 D4 D5 D6 D7
#27: StartFrame=09FC72BEh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196627662.77
        D8 D9 DA DB DC DD DE DF
#28: StartFrame=09FC72BFh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:192790743.28
        E0 E1 E2 E3 E4 E5 E6 E7
#29: StartFrame=09FC72C0h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:198834951.46
        E8 E9 EA EB EC ED EE EF
#30: StartFrame=09FC72C1h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197794768.61
        F0 F1 F2 F3 F4 F5 F6 F7
#31: StartFrame=09FC72C2h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196608000.00
        F8 F9 FA FB FC FD FE FF
#32: StartFrame=09FC72C3h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196785106.60
        00 01 02 03 04 05 06 07
#33: StartFrame=09FC72C4h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196726035.62
        08 09 0A 0B 0C 0D 0E 0F
#34: StartFrame=09FC72C5h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196470470.67
        10 11 12 13 14 15 16 17
#35: StartFrame=09FC72C6h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196765412.33
        18 19 1A 1B 1C 1D 1E 1F
#36: StartFrame=09FC72C7h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197041491.28
        20 21 22 23 24 25 26 27
#37: StartFrame=09FC72C8h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195902750.10
        28 29 2A 2B 2C 2D 2E 2F
#38: StartFrame=09FC72C9h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195008926.80
        30 31 32 33 34 35 36 37
#39: StartFrame=09FC72CAh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:198593939.39
        38 39 3A 3B 3C 3D 3E 3F
#40: StartFrame=09FC72CBh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196254741.47
        40 41 42 43 44 45 46 47
#41: StartFrame=09FC72CCh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196962532.56
        48 49 4A 4B 4C 4D 4E 4F
#42: StartFrame=09FC72CDh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196726035.62
        50 51 52 53 54 55 56 57
#43: StartFrame=09FC72CEh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:192942100.10
        58 59 5A 5B 5C 5D 5E 5F
#44: StartFrame=09FC72CFh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:198153598.06
        60 61 62 63 64 65 66 67
#45: StartFrame=09FC72D0h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:198493690.06
        68 69 6A 6B 6C 6D 6E 6F
#46: StartFrame=09FC72D1h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196588341.17
        70 71 72 73 74 75 76 77
#47: StartFrame=09FC72D2h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196923076.92
        78 79 7A 7B 7C 7D 7E 7F
#48: StartFrame=09FC72D3h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196785106.60
        80 81 82 83 84 85 86 87
#49: StartFrame=09FC72D4h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196195988.42
        88 89 8A 8B 8C 8D 8E 8F
#50: StartFrame=09FC72D5h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197160048.13
        90 91 92 93 94 95 96 97
#51: StartFrame=09FC72D6h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195941797.89
        98 99 9A 9B 9C 9D 9E 9F
#52: StartFrame=09FC72D7h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196647329.47
        A0 A1 A2 A3 A4 A5 A6 A7
#53: StartFrame=09FC72D8h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196923076.92
        A8 A9 AA AB AC AD AE AF
#54: StartFrame=09FC72D9h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196509745.13
        B0 B1 B2 B3 B4 B5 B6 B7
#55: StartFrame=09FC72DAh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196509745.13
        B8 B9 BA BB BC BD BE BF
#56: StartFrame=09FC72DBh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196785106.60
        C0 C1 C2 C3 C4 C5 C6 C7
#57: StartFrame=09FC72DCh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196608000.00
        C8 C9 CA CB CC CD CE CF
#58: StartFrame=09FC72DDh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:196765412.33
        D0 D1 D2 D3 D4 D5 D6 D7
#59: StartFrame=09FC72DEh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:193074732.40
        D8 D9 DA DB DC DD DE DF
#60: StartFrame=09FC72DFh TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:200313805.40
        E0 E1 E2 E3 E4 E5 E6 E7
#61: StartFrame=09FC72E0h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:195396541.44
        E8 E9 EA EB EC ED EE EF
#62: StartFrame=09FC72E1h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197417411.39
        F0 F1 F2 F3 F4 F5 F6 F7
#63: StartFrame=09FC72E2h TransferLength=196608 GoodPackets=8, BadPackets=0, BPS-average:197100751.88
        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;
UINT FrameNumber;
ULONG LastStartFrame;
} 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->LastStartFrame != 0)
{
write_output(gOutFile,
"#%u: StartFrame=%08Xh TransferLength=%u GoodPackets=%u, BadPackets=%u, BPS-average:%.2f\n\t%s\n",
myXfers->CompletedCount, myBufferEL->FrameNumber, transferLength, goodPackets, badPackets, Dcs.Bps, packetCounters);
}
else
{
write_output(gOutFile,
"#%u: StartFrame=%08Xh TransferLength=%u GoodPackets=%u, BadPackets=%u, BPS-average:unknown\n\t%s\n",
myXfers->CompletedCount, myBufferEL->FrameNumber, transferLength, goodPackets, badPackets, packetCounters);
}
}
else
{
write_output(gOutFile,
"#%u: StartFrame=%08Xh TransferLength=%u\n",
myXfers->CompletedCount, myBufferEL->FrameNumber, transferLength);
}
Dcs.Start = Dcs.Stop;
myXfers->CompletedCount++;
myXfers->LastStartFrame = myBufferEL->FrameNumber;
}
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 disabled
bTemp = FALSE;
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);
//Usb.ResetPipe(usbHandle, gPipeInfo.PipeId);
/*
Set a start frame. Add 5ms of startup delay.
*/
Usb.GetCurrentFrameNumber(usbHandle, &gXfers.FrameNumber);
// Give plenty of time to queue up all of our transfers BEFORE the bus starts consuming them
// Note that this is also the startup delay in milliseconds. IE: (6*2)=12ms
gXfers.FrameNumber += (MAX_OUTSTANDING_TRANSFERS * 2);
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);
nextBufferEL->FrameNumber = gXfers.FrameNumber;
if (gPipeInfo.PipeId & 0x80)
Usb.IsochReadPipe(nextBufferEL->IsoHandle, gXfers.TransferBufferSize, &gXfers.FrameNumber, ISO_PACKETS_PER_TRANSFER, nextBufferEL->OvlHandle);
else
Usb.IsochWritePipe(nextBufferEL->IsoHandle, gXfers.TransferBufferSize, &gXfers.FrameNumber, 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;
}