📄 canrecvdlg.cpp
字号:
// CANRecvDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CANRecv.h"
#include "CANRecvDlg.h"
#include "..\..\include\adscan.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
DWORD WINAPI CCANRecvDlg::ListenThreadProc(PVOID pContext);
DWORD WINAPI CCANRecvDlg::CountingThreadProc(PVOID pContext);
// initialize variable
WORD CCANRecvDlg::m_nPort = 0;
ULONG CCANRecvDlg::m_nIndex = 0;
ULONG CCANRecvDlg::m_nPreIndex = 0;
int CCANRecvDlg::m_nBufferSize = 0;
PVOID CCANRecvDlg::m_pData = NULL;
HANDLE CCANRecvDlg::m_hListenEvent = NULL;
HANDLE CCANRecvDlg::m_hKillListenThread = NULL;
BOOL CCANRecvDlg::m_bKillListenThread = FALSE;
HANDLE CCANRecvDlg::m_hCountingEvent = NULL;
HANDLE CCANRecvDlg::m_hKillCountingThread = NULL;
BOOL CCANRecvDlg::m_bKillCountingThread = FALSE;
CListBox* CCANRecvDlg::m_lstDisplay = NULL;
CStatic* CCANRecvDlg::m_lbBufferIndex = NULL;
/////////////////////////////////////////////////////////////////////////////
// CCANRecvDlg dialog
CCANRecvDlg::CCANRecvDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCANRecvDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCANRecvDlg)
m_nDevNum = 1;
m_sBufferIndex = _T("");
m_nBufferSize = 8;
m_nIndex = 0;
m_nPreIndex = 0;
m_pData = NULL;
m_nCount = 0;
m_bKillListenThread = FALSE;
m_pListenThread = NULL;
m_hListenEvent = NULL;
m_bKillCountingThread = FALSE;
m_pCountingThread = NULL;
m_hCountingEvent = NULL;
m_nProtocolType = CANBUS_PROTOCOL_20B;
m_sFilter = _T("SINGLE"); // or _T("DOUBLE")
m_nFilterCode0 = 255;
m_nFilterCode1 = 255;
m_nFilterCode2 = 255;
m_nFilterCode3 = 255;
m_nFilterMask0 = 255;
m_nFilterMask1 = 255;
m_nFilterMask2 = 255;
m_nFilterMask3 = 255;
m_bOpen = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCANRecvDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCANRecvDlg)
DDX_Text(pDX, IDC_DEV_NUM, m_nDevNum);
DDX_Text(pDX, IDC_BUFFER_INDEX, m_sBufferIndex);
DDX_Text(pDX, IDC_RECV_SIZE, m_nBufferSize);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCANRecvDlg, CDialog)
//{{AFX_MSG_MAP(CCANRecvDlg)
ON_BN_CLICKED(IDC_INIT_BTN, OnInitBtn)
ON_BN_CLICKED(IDC_CLEAR_COUNT_BTN, OnClearCountBtn)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_CLEAR_LIST_BTN, OnClearListBtn)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCANRecvDlg message handlers
BOOL CCANRecvDlg::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
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// initialization value
m_nBTR0 = 0x03; // set baud rate to 125K
m_nBTR1 = 0x1c; // the detailed information, please refer to help file.
m_nAcpCode = 0; // set accept code is 0
m_nAcpMask = 0xff; // set mask value is 0xff
m_nIntMask = 0x1; // set interrupt enable for receive and transmit
m_nOutCtrlCode = 0xfa; // set output control code to 0xfa
m_lstDisplay = (CListBox *)GetDlgItem( IDC_REC_LIST );
m_lbBufferIndex = (CStatic *)GetDlgItem( IDC_BUFFER_INDEX );
return TRUE; // return TRUE unless you set the focus to a control
}
void CCANRecvDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
// if m_bOpen is true, then free resources usage
if (m_bOpen)
{
if (CANPortClose(m_nPort) != SUCCESS)
{
MessageBox(_T( "CANPortClose error!" ), NULL, MB_ICONERROR);
}
CloseThreadHandling(m_nPort);
FreeMsgMem();
m_bOpen = FALSE;
}
CDialog::OnClose();
}
void CCANRecvDlg::OnClearListBtn()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_lstDisplay->ResetContent();
}
void CCANRecvDlg::OnClearCountBtn()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_nCount = 0;
m_sBufferIndex = _T( " Count : 0 " );
UpdateData( FALSE );
}
void CCANRecvDlg::OnInitBtn()
{
UpdateData (TRUE);
BOOL bReady;
// Before using driver, we need to call CANPortOpen
if (CANPortOpen(m_nDevNum, &m_nPort, &m_nHostID, &m_nBaudRate) != SUCCESS)
{
MessageBox(_T( "CANPortOpen error!" ), NULL, MB_ICONERROR);
return;
}
// Set protocol usage
if (CANSetProtocolType(m_nPort, m_nProtocolType) != SUCCESS)
{
MessageBox(_T( "CANSetProtocol error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Initialize baud rate and interrupt bits
if (CANInit(m_nPort, m_nBTR0, m_nBTR1, (UCHAR) m_nIntMask) != SUCCESS)
{
MessageBox(_T( "CANInit error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set output control code
if (CANSetOutCtrl(m_nPort, m_nOutCtrlCode) != SUCCESS)
{
MessageBox(_T( "CANSetOutCtrl error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
if (m_nProtocolType == CANBUS_PROTOCOL_20A)
{
// Set accept code for 2.0A only
if (CANSetAcp(m_nPort, m_nAcpCode, m_nAcpMask) != SUCCESS)
{
MessageBox(_T( "CANSetAcp error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
}
else
{
// Set accept code for 2.0B only
PT_FilterSetting ssFilterSetting;
if (m_sFilter.Compare(_T("DOUBLE")) == 0)
ssFilterSetting.dwFilterType = PELICAN_DOUBLE_FILTER;
if (m_sFilter.Compare(_T("SINGLE")) == 0)
ssFilterSetting.dwFilterType = PELICAN_SINGLE_FILTER;
ssFilterSetting.uchAcceptCode0 = m_nFilterCode0;
ssFilterSetting.uchAcceptCode1 = m_nFilterCode1;
ssFilterSetting.uchAcceptCode2 = m_nFilterCode2;
ssFilterSetting.uchAcceptCode3 = m_nFilterCode3;
ssFilterSetting.uchAcceptMask0 = m_nFilterMask0;
ssFilterSetting.uchAcceptMask1 = m_nFilterMask1;
ssFilterSetting.uchAcceptMask2 = m_nFilterMask2;
ssFilterSetting.uchAcceptMask3 = m_nFilterMask3;
if (CANSetAcpEx(m_nPort, &ssFilterSetting) != SUCCESS)
{
MessageBox(_T( "CANSetAcp error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
}
// Set baud rate again
if (CANSetBaud(m_nPort, m_nBTR0, m_nBTR1) != SUCCESS)
{
MessageBox(_T( "CANSetBaud error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set to operation mode
if (CANSetNormal(m_nPort) != SUCCESS)
{
MessageBox(_T( "CANSetNormal error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Enabled the recieve interrupt only
CANEnableRxInt(m_nPort);
// allocate resources
CreateThreadHandling(m_nPort);
AllocMsgMem();
// Set a buffer pointer to driver
CANSetBufferPtr( m_nPort, m_pData, m_nBufferSize, &bReady );
if ( !bReady )
{
MessageBox(_T( "CANSetBufferPtr error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set a buffer index to driver
CANSetCountPtr( m_nPort, &m_nIndex, &bReady );
if ( !bReady )
{
MessageBox(_T( "CANSetCountPtr error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Enable the event usage
CANEnableEvent( m_nPort, TRUE );
// Everything is OK, then update the flag
m_bOpen = TRUE;
}
LONG CCANRecvDlg::CreateThreadHandling(WORD wPort)
{
// Set up the dispatch thread and it's kill flag.
m_bKillListenThread = FALSE;
m_pListenThread = NULL;
m_bKillCountingThread = FALSE;
m_pCountingThread = NULL;
m_hListenEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hKillListenThread = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hCountingEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hKillCountingThread = CreateEvent(NULL, TRUE, FALSE, NULL);
if ((m_hListenEvent == NULL) ||
(m_hKillListenThread == NULL) ||
(m_hCountingEvent == NULL) ||
(m_hKillCountingThread == NULL))
return CANCreateEventFailed;
m_pListenThread = CreateThread(
NULL,0, ListenThreadProc, (PVOID)wPort, 0, NULL);
m_pCountingThread = CreateThread(
NULL,0, CountingThreadProc, (PVOID)wPort, 0, NULL);
if ((m_pListenThread == NULL ) || (m_pCountingThread == NULL))
{
return(CANCreateThreadFailed); // failure
}
return SUCCESS;
}
LONG CCANRecvDlg::CloseThreadHandling(WORD wPort)
{
if (m_pListenThread)
{
m_bKillListenThread = TRUE;
SetEvent(m_hListenEvent);
WaitForSingleObject(m_hKillListenThread, 3000);
CloseHandle(m_pListenThread);
m_pListenThread = NULL;
}
if (m_pCountingThread)
{
m_bKillCountingThread = TRUE;
SetEvent(m_hCountingEvent);
WaitForSingleObject(m_hKillCountingThread, 3000);
CloseHandle(m_pCountingThread);
m_pCountingThread = NULL;
}
return SUCCESS;
}
DWORD CCANRecvDlg::ListenThreadProc(PVOID pContext)
{
// Wait for the event that any CAN port action creates.
while ( !m_bKillListenThread )
{
ListenEventHandler((WORD)pContext);
}
return(0);
}
LONG CCANRecvDlg::ListenEventHandler(WORD wPort)
{
CString s;
BOOL bReady = FALSE;
DWORD ret = 0;
CAN_MSG_T* msg = (CAN_MSG_T*)m_pData;
if (m_bKillListenThread || (!m_hListenEvent))
{
SetEvent (m_hKillListenThread);
ExitThread(0);
}
// handling routine
CANWaitForFIFOEvent( wPort, INFINITE, &bReady);
if ( bReady )
{
/*I will not capture the half buffer ready event.
// half buffer
HWND ActhWnd;
ActhWnd = (HWND)GetActiveWindow( );
::MessageBox(ActhWnd, _T( " Receive Data Buffer half full!" ), _T("Driver Message"), MB_OK);
*/
}
CANWaitForFIFOEvent( wPort, INFINITE, &bReady);
if ( bReady )
{
//I will capture the full buffer ready event.
HWND ActhWnd;
ActhWnd = (HWND)GetActiveWindow( );
::MessageBox(ActhWnd, _T( " Receive Data Finished! Below is Data:" ), _T("Driver Message"), MB_OK);
for ( int i = 0; i < m_nBufferSize; i++ )
{
s.Format(_T( "RECV%5d: ID = %u, Len = %u, %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH" ),
i+1,
msg[i].id,
msg[i].dlen,
msg[i].data[0],
msg[i].data[1],
msg[i].data[2],
msg[i].data[3],
msg[i].data[4],
msg[i].data[5],
msg[i].data[6],
msg[i].data[7]);
m_lstDisplay->AddString( s );
}
}
return SUCCESS;
}
DWORD CCANRecvDlg::CountingThreadProc(PVOID pContext)
{
// Wait for the event that any CAN port action creates.
while ( !m_bKillCountingThread )
{
CountingEventHandler((WORD)pContext);
}
return(0);
}
LONG CCANRecvDlg::CountingEventHandler(WORD wPort)
{
CString s;
if (m_bKillCountingThread || (!m_hCountingEvent))
{
SetEvent (m_hKillCountingThread);
ExitThread(0);
}
// handling routine
if ( m_nIndex != m_nPreIndex )
{
m_nPreIndex = m_nIndex;
s.Format( _T("Buffer Index : %d"), m_nPreIndex );
m_lbBufferIndex->SetWindowText( s );
}
Sleep(300);
return SUCCESS;
}
LONG CCANRecvDlg::AllocMsgMem()
{
m_pData = ( PCAN_MSG_T )GlobalAlloc( GPTR, m_nBufferSize*sizeof(CAN_MSG_T) );
GlobalLock( m_pData );
return SUCCESS;
}
LONG CCANRecvDlg::FreeMsgMem()
{
if (m_pData)
{
GlobalUnlock( m_pData );
GlobalFree( m_pData );
}
return SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -