📄 bulkloopdlg.cpp
字号:
// BulkLoopDlg.cpp : implementation file
//
#include "stdafx.h"
#include "dbt.h"
#include "BulkLoop.h"
#include "BulkLoopDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// 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] = seed + i;
break;
case 3:
dwBuf[i] = seed + i;
break;
}
}
/////////////////////////////////////////////////////////////////////////////
// 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 ) {
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);
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;
dlg->OutEndpt->TimeOut = 2000;
dlg->InEndpt->TimeOut = 2000;
for (;dlg->bLooping;) {
LONG len = xfer; // Use temp var because XferData can change the value of len
success = dlg->OutEndpt->XferData(data,len);
if (success) {
Sleep(10);
success = dlg->InEndpt->XferData(inData,len);
Sleep(10);
}
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;
}
delete [] data;
delete [] inData;
dlg->m_StatusLabel.SetWindowText(" STATUS: Stopped");
dlg->XferThread = NULL;
return true;
}
/////////////////////////////////////////////////////////////////////////////
// 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_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_WM_CLOSE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_DEVICECHANGE,OnPnpEvent)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// 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
bDevNodeChange = false;
bArrived = false;
XferThread = NULL;
USBDevice = new CCyUSBDevice(m_hWnd); // Create an instance of CCyUSBDevice
FindLoopDevice();
// Select the last Alternate Interface
// USBDevice->SetAltIntfc(1);
return TRUE; // return TRUE unless you set the focus to a control
}
void CBulkLoopDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
CDialog::OnSysCommand(nID, lParam);
}
// 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();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CBulkLoopDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//___________________________________________________________________________
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");
}
// 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());
}
//___________________________________________________________________________
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);
}
void CBulkLoopDlg::OnClose()
{
if (USBDevice) delete USBDevice;
CDialog::OnClose();
}
LRESULT CBulkLoopDlg::OnPnpEvent(WPARAM wParam, LPARAM lParam)
{
if (wParam == DBT_DEVICEARRIVAL)
if (bDevNodeChange)
bArrived = true;
if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
if (bDevNodeChange) {
m_XferSize.SetWindowText("");
m_SeedValue.SetWindowText("");
m_FillPatternComBox.SetWindowText("");
m_OutEndptComBox.ResetContent();
m_InEndptComBox.ResetContent();
bDevNodeChange = false;
}
}
if (wParam == DBT_DEVNODES_CHANGED)
{
bDevNodeChange = true;
if (bArrived) {
FindLoopDevice();
bArrived = false;
bDevNodeChange = false;
}
}
return 0;
}
void CBulkLoopDlg::FindLoopDevice()
{
char s[12];
// Look for a device programmed for Bulk Loop (VID = 0547, PID = 1002)
int devices = USBDevice->DeviceCount();
int d = 0;
do {
USBDevice->Open(d); // Open automatically calls Close( ) if necessary
d++;
} while ((d < devices ) && (USBDevice->VendorID != 0x0547) && (USBDevice->ProductID != 0x1002));
if ((USBDevice->VendorID == 0x0547) && (USBDevice->ProductID == 0x1002)) {
int epts = USBDevice->EndPointCount();
CCyUSBEndPoint *endpt;
// Load the endpoint combo boxes
for (int i=1; i<epts; i++) { // Skip endpoint 0, which we know is the Control Endpoint
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.SetItemDataPtr(m_InEndptComBox.GetCount()-1,endpt);
} else {
m_OutEndptComBox.AddString(s);
m_OutEndptComBox.SetItemDataPtr(m_OutEndptComBox.GetCount()-1,endpt);
}
}
}
m_InEndptComBox.SetCurSel(0);
m_OutEndptComBox.SetCurSel(0);
OnSelchangeInCombox(); // Set the InEndpt member
OnSelchangeOutCombox(); // Set the OutEndpt member
endpt = (CCyUSBEndPoint *) m_OutEndptComBox.GetItemDataPtr(0);
sprintf(s,"%d",endpt->MaxPktSize);
m_XferSize.SetWindowText(s);
m_SeedValue.SetWindowText("2");
m_FillPatternComBox.SetCurSel(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -