Here are the important snippets:
#include "stdafx.h"
#include "resource.h"
#include "MCA.h"
#include <math.h>
#include <sysinfo.h>
static DWORD WINAPI MCAProc(void* pmca)
{
CMCA* p = (CMCA*) pmca;
p->Service();
return 0;
}
CMCA::CMCA(TCHAR* szPort)
{
DWORD dwError;
OSVERSIONINFO osvi;
// What OS version are we running?
memset(&osvi,0,sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
m_CE_Version = (short) osvi.dwMajorVersion;
// Define a critical section to prevent spectrum reads while updating.
InitializeCriticalSection(&m_csSync);
// Define a critical section to prevent reads while getting Flow.
InitializeCriticalSection(&m_csRead);
m_hPort = CreateFile(szPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (m_hPort == INVALID_HANDLE_VALUE)
{
dwError = GetLastError();
MessageBox(GetForegroundWindow(), TEXT("MCA port failed to initialize."), TEXT("Sabre"), MB_ICONEXCLAMATION | MB_SYSTEMMODAL | MB_OK);
return ;
}
if ( !EscapeCommFunction(m_hPort, CLRIR) )
dwError = GetLastError();
EscapeCommFunction(m_hPort, SETRTS); // Prevent counts
DCB dcb;
dcb.DCBlength = sizeof(DCB);
GetCommState(m_hPort, &dcb);
dcb.BaudRate = CBR_115200;
dcb.fParity = FALSE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fOutX = FALSE; // Dont use XON/XOFF
dcb.fInX = FALSE; // Dont use XON/XOFF
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
dcb.fDummy2 = FALSE;
// dcb.wReserved = 0;
// dcb.XonLim = 0;
// dcb.XoffLim = 0;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
// dcb.XonChar = 0;
// dcb.XoffChar = 0;
// dcb.ErrorChar = 0;
// dcb.EofChar = 0;
// dcb.EvtChar = 0;
// dcb.wReserved1 = 0;
if (SetCommState(m_hPort, &dcb))
{
COMMTIMEOUTS cto;
// Set Read timeout values to return immediately on a character.
cto.ReadIntervalTimeout = MAXDWORD;
cto.ReadTotalTimeoutMultiplier = 0;
cto.ReadTotalTimeoutConstant = 0; // If no character in xxx ms, then return.
cto.WriteTotalTimeoutMultiplier = 100;
cto.WriteTotalTimeoutConstant = 500;
SetCommTimeouts(m_hPort, &cto);
}
else
{
DWORD dwError = GetLastError();
MessageBox(GetForegroundWindow(), _T("Error setting I/O Port."), _T("Comm Port"), MB_ICONINFORMATION | MB_SYSTEMMODAL | MB_OK);
}
SetCommMask(m_hPort, EV_CTS|EV_RXCHAR);
DWORD dwID;
m_bShutdown = FALSE;
m_hThread = CreateThread(NULL, 0, MCAProc, this, 0, &dwID);
}
void CMCA::Service( void )
{
m_dtLastCountTick = COleDateTime::GetCurrentTime();
DWORD dwLastKeepAlive = GetTickCount();
DWORD dwCount;
BYTE buf[1024], nORcount = 0;
//static BYTE nDot = 0;
SetThreadPriority(this->m_hThread, NORMAL_PRIORITY);
while ( !m_bShutdown )
{
dwCount = 0;
if ( TryEnterCriticalSection(&m_csRead) )
{
ReadFile(m_hPort, buf, 1024, &dwCount, NULL);
LeaveCriticalSection(&m_csRead); // Unlock.
}
Sleep(10);
}
m_hThread = NULL; // Exiting will shut down the thread.
return;
}
BOOL CMCA::GetADCCode(short nChan, BOOL bCalibrating, short *pnValue)
{
BOOL bRes = FALSE; // Default result is FAILED.
static short nSkipped = 0;
static short tries = 0;
if ( pnValue )
{
DWORD dwCount;
short nValue;
nSkipped = 0;
if ( !TryEnterCriticalSection(&m_csRead) )
return bRes;
SetThreadPriority(this->m_hThread, THREAD_PRIORITY_ABOVE_NORMAL);
if ( TransmitCommChar(m_hPort, CMD_GET_FLOW_ADC) )
{
DWORD dwEvent;
dwCount = 0;
SetCommMask(m_hPort, EV_RXCHAR);
WaitCommEvent(m_hPort, &dwEvent, NULL);
Sleep(1);
ReadFile(m_hPort, m_buf, 2, &dwCount, NULL);
ATLTRACE(_T(" returned %d bytes\n"), dwCount);
}
SetThreadPriority(this->m_hThread, NORMAL_PRIORITY);
LeaveCriticalSection(&m_csRead);
Sleep(20);
*pnValue = m_nFlowValue;
}
return bRes;
}