#include "examples.h"
#define REGION(mRegionName) 1
#define EP_TX 0x01
#define EP_RX 0x81
#define MAX_TRANSFER_SIZE 4096
#define MAX_PENDING_IO 3
#define MAX_PENDING_TRANSFERS_RX 64
#define MAX_PENDING_TRANSFERS_TX 3
#define STREAM_TIMEOUT_RX 1000
#define STREAM_TIMEOUT_TX -1
#define UPDATE_STATS_INTERVAL_SECS (1.0)
KUSB_DRIVER_API Usb;
DATA_COUNTER_STATS Dcs;
UCHAR gRxBuffer[MAX_TRANSFER_SIZE];
UCHAR gTxBuffer[MAX_TRANSFER_SIZE];
UINT gRxBufferLen = sizeof(gRxBuffer);
UINT gTxBufferLen = sizeof(gTxBuffer);
VOID FillTxBufferForWrite(void);
VOID ProcessRxBufferFromRead(void);
#if REGION( RX Stream Callback Functions - ProtoTypes)
INT KUSB_API StmRx_Complete(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode);
KSTM_COMPLETE_RESULT KUSB_API StmRx_BeforeComplete(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in PINT ErrorCode);
#endif
#if REGION( TX Stream Callback Functions - ProtoTypes)
INT KUSB_API StmTx_Complete(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode);
#endif
DWORD __cdecl main(int argc, char* argv[])
{
KLST_HANDLE deviceList = NULL;
KLST_DEVINFO_HANDLE deviceInfo = NULL;
KUSB_HANDLE usbHandle = NULL;
KSTM_HANDLE streamRx = NULL;
KSTM_HANDLE streamTx = NULL;
DWORD errorCode = ERROR_SUCCESS;
DWORD totalTransferLength = 0;
BOOL success;
BM_TEST_TYPE testType = BM_TEST_TYPE_LOOP;
KSTM_CALLBACK streamCallbacks;
if (!Examples_GetTestDevice(&deviceList, &deviceInfo, argc, argv))
return GetLastError();
LibK_LoadDriverAPI(&Usb, deviceInfo->DriverID);
if (!Usb.Init(&usbHandle, deviceInfo))
{
errorCode = GetLastError();
printf("Usb.Init failed. ErrorCode: %08Xh\n", errorCode);
goto Done;
}
printf("Device opened successfully!\n");
success = Bench_Configure(usbHandle, BM_COMMAND_SET_TEST, 0, &Usb, &testType);
memset(&streamCallbacks, 0, sizeof(streamCallbacks));
streamCallbacks.Complete = StmRx_Complete;
streamCallbacks.BeforeComplete = StmRx_BeforeComplete;
success = StmK_Init(
&streamRx,
usbHandle,
EP_RX,
MAX_TRANSFER_SIZE,
MAX_PENDING_TRANSFERS_RX,
MAX_PENDING_IO,
&streamCallbacks,
((STREAM_TIMEOUT_RX) == -1) ? KSTM_FLAG_NONE : KSTM_FLAG_USE_TIMEOUT | (STREAM_TIMEOUT_RX & KSTM_FLAG_TIMEOUT_MASK));
if (!success)
{
errorCode = GetLastError();
printf("StmK_Init failed. ErrorCode: %08Xh\n", errorCode);
goto Done;
}
memset(&streamCallbacks, 0, sizeof(streamCallbacks));
streamCallbacks.Complete = StmTx_Complete;
success = StmK_Init(
&streamTx,
usbHandle,
EP_TX,
MAX_TRANSFER_SIZE,
MAX_PENDING_TRANSFERS_TX,
MAX_PENDING_IO,
&streamCallbacks,
((STREAM_TIMEOUT_TX) == -1) ? KSTM_FLAG_NONE : KSTM_FLAG_USE_TIMEOUT | (STREAM_TIMEOUT_TX & KSTM_FLAG_TIMEOUT_MASK));
if (!success)
{
errorCode = GetLastError();
printf("StmK_Init failed. ErrorCode: %08Xh\n", errorCode);
goto Done;
}
if (success) success = StmK_Start(streamTx);
if (success) success = StmK_Start(streamRx);
if (!success)
{
errorCode = GetLastError();
printf("StmK_Start failed. ErrorCode: %08Xh\n", errorCode);
goto Done;
}
printf("[Start Stream] successful!\n");
while(_kbhit()) _getch();
mDcs_Init(&Dcs);
FillTxBufferForWrite();
do
{
UINT length;
while((success = StmK_Write(streamTx, gTxBuffer, 0, gTxBufferLen, &length)))
{
FillTxBufferForWrite();
}
if (GetLastError() != ERROR_NO_MORE_ITEMS)
{
errorCode = GetLastError();
printf("StmK_Write failed. ErrorCode: %08Xh\n", errorCode);
break;
}
success = StmK_Read(streamRx, gRxBuffer, 0, sizeof(gRxBuffer), &length);
if (!success)
{
errorCode = GetLastError();
printf("StmK_Read failed. ErrorCode: %08Xh\n", errorCode);
break;
}
gRxBufferLen = length;
ProcessRxBufferFromRead();
totalTransferLength += length;
mDcs_MarkStop(&Dcs, length);
if (Dcs.Duration >= UPDATE_STATS_INTERVAL_SECS)
{
printf("Bytes transferred:%d total:%d BPS:%.2f\n", (int)Dcs.TotalBytes, totalTransferLength, Dcs.Bps);
Dcs.Start.QuadPart = Dcs.Stop.QuadPart;
Dcs.TotalBytes = 0;
}
}
while(!_kbhit());
StmK_Stop(streamTx, 0);
StmK_Stop(streamRx, 0);
printf("[Stop Stream] successful!\n");
Done:
if (streamTx) StmK_Free(streamTx);
if (streamRx) StmK_Free(streamRx);
UsbK_Free(usbHandle);
LstK_Free(deviceList);
return errorCode;
}
VOID FillTxBufferForWrite(void)
{
gTxBufferLen = sizeof(gTxBuffer);
}
VOID ProcessRxBufferFromRead(void)
{
}
#if REGION( RX Stream Callback Functions )
INT KUSB_API StmRx_Complete(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode)
{
return ErrorCode;
}
KSTM_COMPLETE_RESULT KUSB_API StmRx_BeforeComplete(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in PINT ErrorCode)
{
return KSTM_COMPLETE_RESULT_VALID;
}
#endif
#if REGION( TX Stream Callback Functions )
INT KUSB_API StmTx_Complete(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode)
{
return ErrorCode;
}
#endif