📄 bulkloopdlg.cpp
字号:
// BulkLoopDlg.cpp : implementation file
//
#include "stdafx.h"
#include "BulkLoop.h"
#include "BulkLoopDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*Summary
Fills buf with data per the selected method
*/
void stuffBuff(PUCHAR buf, LONG len, LONG seed, int method) {
DWORD *dwBuf = (DWORD *) buf;
srand((UINT)seed);
int cnt = (method == 3) ? len / 4 : len;
for (int i=0; i<cnt; i++)
switch (method) {
case 0:
buf[i] = (CHAR) seed;
break;
case 1:
buf[i] = rand();
break;
case 2:
buf[i] = (UCHAR)seed + i;
break;
case 3:
dwBuf[i] = seed + i;
break;
}
}
/*Summary
The looping Bulk Xfer Thread function
The looping xfers need to run in a separate thread so as to be stoppable
via a click on the "Stop" button. Otherwise, that click will never get
serviced and the app will loop indefinitely.
The "Start" button on click handler just calls this routine, passing a pointer
to the dialog (main window) object. That way, this routine has access to all
the public members of the CBulkLoopDlg class.
*/
UINT XferLoop( LPVOID params ) {
OVERLAPPED outOvLap, inOvLap;
CBulkLoopDlg *dlg = (CBulkLoopDlg *) params;
char s[24]; ZeroMemory(s, 24);
dlg->m_XferSize.GetLine(0,s,8);
LONG xfer = atol(s);
PUCHAR data = new UCHAR[xfer]; ZeroMemory(data,xfer);
PUCHAR inData = new UCHAR[xfer]; ZeroMemory(inData,xfer);
outOvLap.hEvent = CreateEvent(NULL, false, false, "CYUSB_OUT");
inOvLap.hEvent = CreateEvent(NULL, false, false, "CYUSB_IN");
dlg->m_SeedValue.GetLine(0,s,8);
LONG seed = atol(s);
int stopOnError = dlg->m_StopOnErrorChkBox.GetCheck();
stuffBuff(data,xfer,seed,dlg->m_FillPatternComBox.GetCurSel());
dlg->m_StatusLabel.SetWindowText(" STATUS: Transferring data . . .");
dlg->m_SuccessCount.SetWindowText("0");
dlg->m_FailureCount.SetWindowText("0");
bool success;
LONG nSuccess = 0;
LONG nFailure = 0;
if (dlg->m_DisableTimeoutChkBox.GetCheck())
{
dlg->OutEndpt->TimeOut = 0;
dlg->InEndpt->TimeOut = 0;
}
else
{
dlg->OutEndpt->TimeOut = 2000;
dlg->InEndpt->TimeOut = 2000;
}
for (;dlg->bLooping;) {
LONG outlen,inlen,len;
outlen = inlen = len = xfer; // Use temp var because XferData can change the value of len
UCHAR *outContext = dlg->OutEndpt->BeginDataXfer(data,outlen,&outOvLap);
UCHAR *inContext = dlg->InEndpt->BeginDataXfer(inData,inlen,&inOvLap);
dlg->OutEndpt->WaitForXfer(&outOvLap,2000);
dlg->InEndpt->WaitForXfer(&inOvLap,2000);
success = dlg->OutEndpt->FinishDataXfer(data, outlen, &outOvLap,outContext);
success = dlg->InEndpt->FinishDataXfer(inData,inlen, &inOvLap,inContext);
if (success) {
bool pass = (memcmp(data,inData,len) == 0);
if (pass)
nSuccess++;
else
nFailure++;
} else
nFailure++;
sprintf(s,"%d",nSuccess);
dlg->m_SuccessCount.SetWindowText(s);
sprintf(s,"%d",nFailure);
dlg->m_FailureCount.SetWindowText(s);
if ((!success) && stopOnError) dlg->bLooping = false;
}
CloseHandle(outOvLap.hEvent);
CloseHandle(inOvLap.hEvent);
delete [] data;
delete [] inData;
dlg->m_StatusLabel.SetWindowText(" STATUS: Stopped");
dlg->XferThread = NULL;
dlg->USBDevice->Close();
return true;
}
/*Summary
CBulkLoopDlg dialog
*/
CBulkLoopDlg::CBulkLoopDlg(CWnd* pParent /*=NULL*/)
: CDialog(CBulkLoopDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CBulkLoopDlg)
m_DataValueRadioBtns = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDI_CYICON);
}
void CBulkLoopDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBulkLoopDlg)
DDX_Control(pDX, IDC_DISABLE_TIMEOUT, m_DisableTimeoutChkBox);
DDX_Control(pDX, IDC_TEST_BTN, m_TestBtn);
DDX_Control(pDX, IDC_RESET_BTN, m_RefreshBtn);
DDX_Control(pDX, IDC_DEVICELIST_COMBOX, m_DeviceListComBox);
DDX_Control(pDX, IDC_START_BTN, m_StartBtn);
DDX_Control(pDX, IDC_STATUS_LABEL, m_StatusLabel);
DDX_Control(pDX, IDC_FILLPATTERN_COMBOX, m_FillPatternComBox);
DDX_Control(pDX, IDC_STOP_ON_ERROR_CHKBOX, m_StopOnErrorChkBox);
DDX_Control(pDX, IDC_SEED_EDIT, m_SeedValue);
DDX_Control(pDX, IDC_FAILURE_LABEL, m_FailureCount);
DDX_Control(pDX, IDC_SUCCESS_LABEL, m_SuccessCount);
DDX_Control(pDX, IDC_XFERSIZE_EDIT, m_XferSize);
DDX_Control(pDX, IDC_IN_COMBOX, m_InEndptComBox);
DDX_Control(pDX, IDC_OUT_COMBOX, m_OutEndptComBox);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CBulkLoopDlg, CDialog)
//{{AFX_MSG_MAP(CBulkLoopDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_START_BTN, OnStartBtn)
ON_CBN_SELCHANGE(IDC_OUT_COMBOX, OnSelchangeOutCombox)
ON_CBN_SELCHANGE(IDC_IN_COMBOX, OnSelchangeInCombox)
ON_BN_CLICKED(IDC_RESET_BTN, OnResetBtn)
ON_BN_CLICKED(IDC_REFRESH_BTN, OnRefreshBtn)
ON_BN_CLICKED(IDC_TEST_BTN, OnTestBtn)
ON_CBN_SELCHANGE(IDC_DEVICELIST_COMBOX, OnSelchangeDeviceListCombox)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*Summary
CBulkLoopDlg message handlers
*/
BOOL CBulkLoopDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
XferThread = NULL;
USBDevice = new CCyUSBDevice(m_hWnd); // Create an instance of CCyUSBDevice
OnRefreshBtn();
m_XferSize.SetWindowText("1024");
m_SeedValue.SetWindowText("2");
m_FillPatternComBox.SetCurSel(0);
return TRUE; // return TRUE unless you set the focus to a control
}
void CBulkLoopDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
CDialog::OnSysCommand(nID, lParam);
}
/*Summary
If you add a minimize button to your dialog, you will need the code below
to draw the icon. For MFC applications using the document/view model,
this is automatically done for you by the framework.
*/
void CBulkLoopDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
/*Summary
The system calls this to obtain the cursor to display while the user drags
the minimized window.
*/
HCURSOR CBulkLoopDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//___________________________________________________________________________
/*Summary
Executes on start button click. Gets the end points of the device and starts the thread xferloop
*/
void CBulkLoopDlg::OnStartBtn()
{
if (XferThread) {
bLooping = false;
// InEndpt->Abort();
// InEndpt->Reset();
// OutEndpt->Abort();
// OutEndpt->Reset();
m_StartBtn.SetWindowText("Start");
} else {
char s[12];
ZeroMemory(s,12);
m_XferSize.GetLine(0,s,8);
LONG xfer = atol(s);
if (xfer > 2048) {
xfer = 2048;
m_XferSize.SetWindowText("2048");
}
int n = USBDevice->DeviceCount();
int i = m_DeviceListComBox.GetCurSel();
if(i==0xffffffff)// for no selection
return;
if (n != 0)
{
USBDevice->Open(DeviceIndex);
OutEndpt = USBDevice->EndPoints[m_OutEndptComBox.GetItemData(m_OutEndptComBox.GetCurSel())];
InEndpt = USBDevice->EndPoints[m_InEndptComBox.GetItemData(m_InEndptComBox.GetCurSel())];
// Launch the looping thread (Calls XferLoop() function, above.)
if (xfer && USBDevice->IsOpen()) {
bLooping = true;
XferThread = AfxBeginThread(XferLoop, this);
}
m_StartBtn.SetWindowText("Stop");
}
}
}
//___________________________________________________________________________
void CBulkLoopDlg::OnSelchangeOutCombox()
{
// OutEndpt = (CCyUSBEndPoint *) m_OutEndptComBox.GetItemDataPtr(m_OutEndptComBox.GetCurSel());
}
//___________________________________________________________________________
void CBulkLoopDlg::OnSelchangeInCombox()
{
// InEndpt = (CCyUSBEndPoint *) m_InEndptComBox.GetItemDataPtr(m_InEndptComBox.GetCurSel());
}
//___________________________________________________________________________
/*Summary
Executes on selecting the device list combox. Selecting the end point.
*/
void CBulkLoopDlg::OnSelchangeDeviceListCombox()
{
int i;
char s[12];
//DeviceIndex = m_DeviceListComBox.GetCurSel();
USBDevice->Open(DeviceIndex);
int epts = USBDevice->EndPointCount();
CCyUSBEndPoint *endpt;
// Load the endpoint combo boxes
// Skip endpoint 0, which we know is the Control Endpoint
for (i=1; i<epts; i++)
{
endpt = USBDevice->EndPoints[i];
if (endpt->Attributes == 2) // Bulk
{
sprintf(s, "0x%02X", endpt->Address);
if (endpt->Address & 0x80)
{
m_InEndptComBox.AddString(s);
m_InEndptComBox.SetItemData(m_InEndptComBox.GetCount()-1,i);
}
else
{
m_OutEndptComBox.AddString(s);
m_OutEndptComBox.SetItemData(m_OutEndptComBox.GetCount()-1,i);
}
}
}
m_InEndptComBox.SetCurSel(0);
m_OutEndptComBox.SetCurSel(0);
OnSelchangeInCombox(); // Set the InEndpt member
OnSelchangeOutCombox(); // Set the OutEndpt member
}
/*Summary
Executes on Reset button click. Resets the USB device, releases the resources allocated.
*/
void CBulkLoopDlg::OnResetBtn()
{
if (XferThread) OnStartBtn(); // Hit the "Stop" button, resetting endpoints
USBDevice->Reset();
delete USBDevice;
// Clear the combo boxes
m_InEndptComBox.ResetContent();
m_OutEndptComBox.ResetContent();
// Temporarily save the Xfer size and Seed values
char s1[12];
char s2[12];
m_XferSize.GetWindowText(s1,8);
m_SeedValue.GetWindowText(s2,8);
int fillmethod = m_FillPatternComBox.GetCurSel();
// Re-initialize the combo boxes, USBDevice, etc
OnInitDialog();
// Restore the previous values for these controls
m_XferSize.SetWindowText(s1);
m_SeedValue.SetWindowText(s2);
m_FillPatternComBox.SetCurSel(fillmethod);
}
/*Summary
Executes on Refresh button click. Stops the thread, if it is running, aborts and resets the endpoint.
Refresh the Checks for all the devices connected.
*/
void CBulkLoopDlg::OnRefreshBtn()
{
int i;
// if we are currently running loopback, stop
if (XferThread)
{
bLooping = false;
InEndpt->Abort();
InEndpt->Reset();
OutEndpt->Abort();
OutEndpt->Reset();
m_StartBtn.SetWindowText("Start");
}
// clear the combo boxes
m_DeviceListComBox.ResetContent();
m_InEndptComBox.ResetContent();
m_OutEndptComBox.ResetContent();
// make sure there is at lesat one device out there
if (USBDevice->DeviceCount())
{
// search for all connected devices, and add them to the device
// combo box
for (i = 0; i < USBDevice->DeviceCount(); i++)
{
USBDevice->Open(i);
//Only display the Bulkloop back compatinle device, other device will not be displayed
//Get config descriptor
USB_CONFIGURATION_DESCRIPTOR ConfDesc;
USBDevice->GetConfigDescriptor(&ConfDesc);
if(ConfDesc.bNumInterfaces==1)
{// Number of interface one
//Get Interface descriptor
USB_INTERFACE_DESCRIPTOR IntfDesc;
USBDevice->GetIntfcDescriptor(&IntfDesc);
if(IntfDesc.bAlternateSetting==0)
{//
if(IntfDesc.bNumEndpoints==4)
{// Number of endpoint is four
m_DeviceListComBox.AddString(USBDevice->DeviceName);
DeviceIndex = i;
return;
}
}
}
}
m_DeviceListComBox.SetCurSel(0);
OnSelchangeDeviceListCombox(); // This will set the device index and load the ep lists
}
}
void CBulkLoopDlg::OnTestBtn()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -