?? cp210xtestdlg.cpp
字號:
// CP210x TestDlg.cpp : implementation file
//
// by Novia Wijaya
// Created June 2, 2004
// Last Modified June 3, 2004
#include "stdafx.h"
#include "CP210xTest.h"
#include "CP210xTestDlg.h"
#include "SiUSBXp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
bool m_Running = false;
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCP210xTestDlg dialog
CCP210xTestDlg::CCP210xTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCP210xTestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCP210xTestDlg)
m_port1 = 0;
m_port2 = 0;
m_output = _T("");
m_port_num = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCP210xTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCP210xTestDlg)
DDX_Text(pDX, IDC_OUTPUT, m_output);
DDX_Text(pDX, IDC_PORT_NUM, m_port_num);
DDV_MinMaxUInt(pDX, m_port_num, 0, 256);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCP210xTestDlg, CDialog)
//{{AFX_MSG_MAP(CCP210xTestDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(ID_EXIT, OnExit)
ON_BN_CLICKED(IDC_START, OnStart)
ON_BN_CLICKED(IDC_UPDATE_DEVICE_LIST, OnUpdateDeviceList)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCP210xTestDlg message handlers
BOOL CCP210xTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 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
// TODO: Add extra initialization here
// Get devices, init. combo box with their names
FillDeviceList();
return TRUE; // return TRUE unless you set the focus to a control
}
void CCP210xTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
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 CCP210xTestDlg::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 CCP210xTestDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
/**
* Quit the program
*/
void CCP210xTestDlg::OnExit()
{
CDialog::OnCancel();
}
void CCP210xTestDlg::FillDeviceList()
{
SI_DEVICE_STRING devStr;
DWORD dwNumDevices = 0;
CComboBox* pDevList = (CComboBox*)GetDlgItem(IDC_DEVICE_SELECT1);
if (pDevList)
{
int numDevs = pDevList->GetCount();
for (int i = 0; i < numDevs; i++)
{
pDevList->DeleteString(0);
}
SI_STATUS status = SI_GetNumDevices(&dwNumDevices);
if (status == SI_SUCCESS)
{
for (DWORD d = 0; d < dwNumDevices; d++)
{
status = SI_GetProductString(d, devStr, SI_RETURN_SERIAL_NUMBER);
if (status == SI_SUCCESS)
{
if (pDevList) // Fill device list
pDevList->AddString(devStr);
}
}
}
pDevList->SetCurSel(0);
}
}
/**
* Start sending data between two devices if the port numbers specified are correct
*/
void CCP210xTestDlg::OnStart()
{
UpdateData(TRUE);
if (!m_Running)
{
m_Running = true;
GetDlgItem(IDC_START)->SetWindowText("Running");
GetDlgItem(IDC_OUTPUT)->SetWindowText("");
// Get the CP210x device list
CComboBox* pDevList = (CComboBox*)GetDlgItem(IDC_DEVICE_SELECT1);
DCB dcbPortInitState, dcbPort;
// Format our COM Port string
CString COMPort;
COMPort.Format("\\\\.\\COM%u", m_port_num);
// Create the Handle to the COM Port
HANDLE hDev = CreateFile(COMPort, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
BeginWaitCursor();
if(hDev == INVALID_HANDLE_VALUE)
m_output = "Error: Invalid Handle Value for Device 1.";
else
{
if (pDevList)
{
// Open selected device.
if (pDevList->GetCurSel() >= 0)
{
DWORD device = pDevList->GetCurSel();
SI_STATUS status = SI_Open(device, &m_hUSBDevice);
// setup the COM Port
if (status == SI_SUCCESS)
{
if(!PurgeComm(hDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) // device 1 fails
{
m_output = "Error: Failed to purge COM port for device 1.";
}
else
{
if(!GetCommState(hDev, &dcbPortInitState)) // com port fails to get its current state
{
m_output = "Error: Failed to get current state of com port.";
}
else
{
dcbPort = dcbPortInitState;
dcbPort.BaudRate = 57600;
dcbPort.Parity = NOPARITY;
dcbPort.ByteSize = 8;
dcbPort.StopBits = ONESTOPBIT;
if(!SetCommState(hDev, &dcbPort)) // fails to set port 1 state
{
m_output = "Error: Failed to set the state of com port.";
}
else
{
// Clear the CP210x device's buffers
status = SI_FlushBuffers(m_hUSBDevice, TRUE, TRUE);
if (status != SI_SUCCESS)
m_output = "Error: Failed to purge device.";
// Set the CP210x device's baud rate
status = SI_SetBaudRate(m_hUSBDevice, 57600);
if (status != SI_SUCCESS)
m_output = "Error: Failed to set baud rate 57600 for device.";
if(Transfer(&m_hUSBDevice, &hDev))
{
m_output = "Data transfered successfully.";
}
else
{
m_output = "Error: Failed to transfer data.";
}
// Closing the COM Port handle
if (hDev != INVALID_HANDLE_VALUE) CloseHandle(hDev);
hDev = INVALID_HANDLE_VALUE;
}
}
}
// Close the CP210x device handle
status = SI_Close(m_hUSBDevice);
if (status != SI_SUCCESS)
m_output = "Error: Error closing device.";
}
else
{
m_output = "Error: Failed open device.";
}
}
}
}
m_Running = false;
GetDlgItem(IDC_START)->SetWindowText("Start Data Transfer");
}
UpdateData(FALSE);
}
/**
* Perform write on device 1, read on device 2, write on device 2, and read on device 1.
* Return true if the data is transfered successfully, false otherwise.
*/
bool CCP210xTestDlg::Transfer(HANDLE* hDev1, HANDLE* hDev2)
{
BYTE dataSent[] = { 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88 };
BYTE dataRead[64];
bool success = false;
UINT timeout = 3000;
DWORD toBeWritten = 64, toBeRead = 64;
DWORD* written = (DWORD*)malloc(sizeof(DWORD));
DWORD* read = (DWORD*)malloc(sizeof(DWORD));
SI_STATUS status;
status = SI_Write(*hDev1, (LPVOID)dataSent, toBeWritten, written);
if(status != SI_SUCCESS)
{
MessageBox("Surprise Removal on Device 1 Write!");
}
else
success = true;
if(*written != toBeWritten)
success = false;
if(success) // continue to read the data from the other device if the previous write succeed
{
success = false;
DelayMS(60);
if(!ReadFile(*hDev2, dataRead, toBeRead, read, NULL))
{
MessageBox("Surprise Removal on Device 2 Read!");
CloseHandle(*hDev2);
*hDev2 = INVALID_HANDLE_VALUE;
}
else
success = true;
if(success) // compare the data sent and received by the two devices if the read succeed
{
for(int i = 0; i < 64 && success; ++i)
{
if(dataSent[i] != dataRead[i])
success = false;
}
}
}
if(success) // do the opposite direction if the previous transfer succeed
{
success = false;
dataRead[64];
*written = 0;
*read = 0;
if(!WriteFile(*hDev2, (LPCVOID)dataSent, toBeWritten, written, NULL))
{
MessageBox("Surprise Removal on Device 2 Write!");
CloseHandle(*hDev2);
*hDev2 = INVALID_HANDLE_VALUE;
}
else
success = true;
if(*written != toBeWritten)
success = false;
if(success) // continue to read the data from the other device if the previous write succeed
{
success = false;
DelayMS(60);
status = SI_Read(*hDev1, dataRead, toBeRead, read);
if(status != SI_SUCCESS)
{
MessageBox("Surprise Removal on Device 1 Read!");
}
else
success = true;
if(success) // compare the data sent and received by the two devices if the read succeed
{
for(int i = 0; i < 64 && success; ++i)
{
if(dataSent[i] != dataRead[i])
success = false;
}
}
}
}
delete read;
delete written;
return success;
}
/**
* To delay the program
* @param delay The amount of delay time in milliseconds
*/
void CCP210xTestDlg::DelayMS(UINT delay)
{
DWORD start, end;
start = end = GetTickCount();
// Wait for 'delay' milliseconds.
while ((end - start) < delay)
{
end = GetTickCount();
}
}
void CCP210xTestDlg::OnUpdateDeviceList()
{
// TODO: Add your control notification handler code here
FillDeviceList();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -