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

Asynchronously submits an application defined number of transfers.

xfer-async example:
  1. Finds a device by vid/pid (use vid=hhhh, pid=hhhhh and the command line).
  2. Initializes a new UsbK (usb device) handle.
  3. Configures the benchmark test device to accept/send data.
  4. Initializes a new OvlPoolK (overlapped pool) handle.
  5. Submits ASYNC_PENDING_IO_COUNT number of I/O request.
  6. Completes all I/O request submitted above.
  7. Frees the UsbK (usb device) handle.
  8. Frees the OvlPoolK (overlapped pool) handle.
  9. Frees the LstK (device list) handle created in step #1.
Console Output
Looking for device vid/pid 04D8/FA2E..
Using 04D8:FA2E (LUSBW1): Benchmark Device - Microchip Technology, Inc.
Device opened successfully!
Transfer #0 submitted for 4096 bytes.
Transfer #1 submitted for 4096 bytes.
Transfer #2 submitted for 4096 bytes.
Transfer #0 completed with 4096 bytes.
Transfer #1 completed with 4096 bytes.
Transfer #2 completed with 4096 bytes.
Transferred 12288 bytes in 3 transfers. errorCode=00000000h
#include "examples.h"
// Example configuration:
#define EP_ADDRESS 0x81
#define ASYNC_PENDING_IO_COUNT 3
#define ASYNC_TIMEOUT_MS 1000
// Globals:
typedef struct _MY_IO_REQUEST
{
DWORD Index;
DWORD ErrorCode;
DWORD BufferSize;
UCHAR Buffer[4096];
DWORD TransferLength;
struct _MY_IO_REQUEST* prev;
struct _MY_IO_REQUEST* next;
} MY_IO_REQUEST, *PMY_IO_REQUEST;
DWORD __cdecl main(int argc, char* argv[])
{
DWORD errorCode = ERROR_SUCCESS;
BOOL success;
KLST_HANDLE deviceList = NULL;
KLST_DEVINFO_HANDLE deviceInfo = NULL;
KUSB_HANDLE usbHandle = NULL;
KOVL_POOL_HANDLE ovlPool = NULL;
MY_IO_REQUEST ovlArray[ASYNC_PENDING_IO_COUNT];
PMY_IO_REQUEST requestList = NULL;
PMY_IO_REQUEST myRequest;
DWORD ovlIndex;
BM_TEST_TYPE testType = USB_ENDPOINT_DIRECTION_IN(EP_ADDRESS) ? BM_TEST_TYPE_READ : BM_TEST_TYPE_WRITE;
ULONG totalLength = 0;
/*
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();
/*
This example will use the dynamic driver api so that it can be used
with all supported drivers.
*/
LibK_LoadDriverAPI(&Usb, deviceInfo->DriverID);
/*
Initialize the device. This creates the physical usb handle.
*/
if (!Usb.Init(&usbHandle, deviceInfo))
{
errorCode = GetLastError();
printf("Init device failed. ErrorCode: %08Xh\n", errorCode);
goto Done;
}
printf("Device opened successfully!\n");
/*
Configure the benchmark test device to accept/send data.
*/
success = Bench_Configure(usbHandle, BM_COMMAND_SET_TEST, 0, &Usb, &testType);
if (!success) printf("Bench_Configure failed.\n");
/*
Initialize a new OvlK pool handle.
*/
OvlK_Init(&ovlPool, usbHandle, ASYNC_PENDING_IO_COUNT, 0);
memset(ovlArray, 0, sizeof(ovlArray));
for(ovlIndex = 0; ovlIndex < ASYNC_PENDING_IO_COUNT; ovlIndex++)
{
// Get an overlapped handle from the pool initialized above.
if (!OvlK_Acquire(&ovlArray[ovlIndex].Ovl, ovlPool))
{
errorCode = GetLastError();
printf("OvlK_Acquire failed. ErrorCode: %08Xh\n", errorCode);
goto Done;
}
ovlArray[ovlIndex].Index = ovlIndex;
ovlArray[ovlIndex].BufferSize = sizeof(ovlArray[ovlIndex].Buffer);
DL_APPEND(requestList, &ovlArray[ovlIndex]);
}
/*
Submit ASYNC_PENDING_IO_COUNT number of I/O request.
*/
DL_FOREACH(requestList, myRequest)
{
// This examples works the same for reading and writing. The endpoint address is used to
// determine which.
if (USB_ENDPOINT_DIRECTION_IN(EP_ADDRESS))
Usb.ReadPipe(usbHandle, EP_ADDRESS, myRequest->Buffer, myRequest->BufferSize, NULL, myRequest->Ovl);
else
Usb.WritePipe(usbHandle, EP_ADDRESS, myRequest->Buffer, myRequest->BufferSize, NULL, myRequest->Ovl);
// On success, all pipe transfer functions using overlapped I/O return false and set last
// error to ERROR_IO_PENDING.
myRequest->ErrorCode = GetLastError();
if (myRequest->ErrorCode != ERROR_IO_PENDING)
{
errorCode = myRequest->ErrorCode;
printf("Failed submitting transfer #%u for %u bytes.\n", myRequest->Index, myRequest->BufferSize);
break;
}
printf("Transfer #%u submitted for %u bytes.\n", myRequest->Index, myRequest->BufferSize);
}
/*
Complete all I/O request submitted above.
*/
DL_FOREACH(requestList, myRequest)
{
if (myRequest->ErrorCode == ERROR_IO_PENDING)
{
printf("Waiting %u ms for transfer #%u to complete..\n", ASYNC_TIMEOUT_MS, myRequest->Index);
success = OvlK_WaitOrCancel(myRequest->Ovl, ASYNC_TIMEOUT_MS, &myRequest->TransferLength);
if (!success)
{
errorCode = myRequest->ErrorCode = GetLastError();
printf("Transfer #%u did not complete. ErrorCode=%08Xh\n", myRequest->Index, myRequest->ErrorCode);
}
else
{
myRequest->ErrorCode = ERROR_SUCCESS;
totalLength += myRequest->TransferLength;
printf("Transfer #%u completed with %u bytes.\n", myRequest->Index, myRequest->TransferLength);
}
}
}
if (errorCode == ERROR_SUCCESS)
{
printf("Transferred %u bytes successfully.\n", totalLength, errorCode);
}
else
{
printf("Transferred %u bytes. ErrorCode=%08Xh\n", totalLength, errorCode);
}
Done:
/*
Close the usb handle.
*/
if (usbHandle) Usb.Free(usbHandle);
/*
Free the device list.
*/
LstK_Free(deviceList);
/*
Free and release all resources assigned to this pool.
*/
OvlK_Free(ovlPool);
return errorCode;
}