Asynchronously loops data from one endpoint to another.
#define EP_TX 0x01
#define EP_RX 0x81
#define EP_PACKET_SIZE 64
#define XFER_LENGTH (EP_PACKET_SIZE*16)
#define XFER_TIMEOUT 1000
#define MAX_XFERS 512
#define MAX_PENDING_IO 3
static DWORD g_LoopCounter = 0;
static DWORD g_ErrorCode = ERROR_SUCCESS;
typedef struct _MY_XFER_EL
{
UCHAR Buffer[XFER_LENGTH];
DWORD Length;
DWORD ErrorCode;
struct _MY_XFER_EL* prev;
struct _MY_XFER_EL* next;
} MY_XFER_EL;
VOID OnDataNeeded(MY_XFER_EL* xfer, UCHAR PipeID)
{
static DWORD CounterTx = 0;
xfer->Length = XFER_LENGTH;
printf("[Tx-%03u] PipeID=%02Xh Length=%u\n", ++CounterTx, PipeID, xfer->Length);
}
VOID OnDataArrival(MY_XFER_EL* xfer, UCHAR PipeID)
{
static DWORD CounterRx = 0;
printf("[Rx-%03u] PipeID=%02Xh Length=%u\n", ++CounterRx, PipeID, xfer->Length);
}
MY_XFER_EL** AvailList,
MY_XFER_EL** WaitList,
UCHAR PipeID)
{
MY_XFER_EL* move = *AvailList;
{
move->Length = XFER_LENGTH;
Usb.
ReadPipe(usbHandle, PipeID, move->Buffer, move->Length, NULL, move->Ovl);
}
else
{
OnDataNeeded(move, PipeID);
Usb.
WritePipe(usbHandle, PipeID, move->Buffer, move->Length, NULL, move->Ovl);
}
if ((move->ErrorCode = GetLastError()) != ERROR_IO_PENDING)
{
g_ErrorCode = move->ErrorCode;
printf("Usb.WritePipe failed on pipe-id %02Xh. ErrorCode: %08Xh\n",
PipeID, g_ErrorCode);
g_LoopCounter = MAX_XFERS;
return FALSE;
}
return TRUE;
}
BOOL Xfer_Wait(MY_XFER_EL* PendingList, ULONG Timeout, UCHAR PipeID)
{
if (PendingList->ErrorCode != ERROR_IO_PENDING)
Timeout = 0;
{
if (PendingList->ErrorCode == ERROR_IO_PENDING)
{
g_ErrorCode = PendingList->ErrorCode = GetLastError();
printf("Failed getting i/o results. ErrorCode: %08Xh\n", g_ErrorCode);
g_LoopCounter = MAX_XFERS;
}
return FALSE;
}
{
OnDataArrival(PendingList, PipeID);
}
return TRUE;
}
VOID Xfer_Recycle(MY_XFER_EL** WaitList, MY_XFER_EL** AvailList)
{
MY_XFER_EL* move = *WaitList;
if (g_LoopCounter < MAX_XFERS)
}
DWORD __cdecl main(int argc, char* argv[])
{
int i;
BOOL success;
MY_XFER_EL xfersTx[MAX_PENDING_IO];
MY_XFER_EL xfersRx[MAX_PENDING_IO];
MY_XFER_EL* xferAvailListTx = NULL;
MY_XFER_EL* xferAvailListRx = NULL;
MY_XFER_EL* xferWaitListTx = NULL;
MY_XFER_EL* xferWaitListRx = NULL;
memset(xfersTx, 0, sizeof(xfersTx));
memset(xfersRx, 0, sizeof(xfersRx));
for (i = 0; i < MAX_PENDING_IO; i++)
{
}
return GetLastError();
if (!Usb.
Init(&usbHandle, deviceInfo))
{
g_ErrorCode = GetLastError();
printf("Usb.Init failed. ErrorCode: %08Xh\n", g_ErrorCode);
goto Done;
}
printf("Device opened successfully!\n");
OvlK_Init(&gOvlPool, usbHandle, (MAX_PENDING_IO + 1) * 2, 0);
success = Bench_Configure(usbHandle, BM_COMMAND_SET_TEST, 0, NULL, &testType);
if (!success) goto Done;
do
{
while (xferAvailListRx && xferAvailListTx && g_LoopCounter < MAX_XFERS)
{
g_LoopCounter++;
Xfer_Submit(usbHandle, &xferAvailListRx, &xferWaitListRx, EP_RX);
Xfer_Submit(usbHandle, &xferAvailListTx, &xferWaitListTx, EP_TX);
}
if (xferWaitListTx && xferWaitListRx)
{
Xfer_Wait(xferWaitListRx, XFER_TIMEOUT, EP_RX);
Xfer_Wait(xferWaitListTx, XFER_TIMEOUT, EP_TX);
Xfer_Recycle(&xferWaitListTx, &xferAvailListTx);
Xfer_Recycle(&xferWaitListRx, &xferAvailListRx);
}
}
while(xferWaitListTx && xferWaitListRx);
Done:
return g_ErrorCode;
}