// Serial.cpp // #include "stdafx.h" #include "Serial.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CSERIAL, CObject) CSERIAL::CSERIAL( ) { dev = NULL; setcom = FALSE ; bufread.Rstemp(); state = TRUE; } CSERIAL::~CSERIAL( ) { Release(); } DWORD CommWatchProc(LPVOID lpData) { DWORD dwEvtMask; OVERLAPPED os; CSERIAL* npComm = (CSERIAL*) lpData; unsigned char InData[951]; int nLength; if ( npComm == NULL || !npComm->IsKindOf( RUNTIME_CLASS( CSERIAL ) ) ) return (DWORD)(-1); memset( &os, 0, sizeof( OVERLAPPED )); os.hEvent = CreateEvent( NULL, // no security TRUE, // explicit reset req FALSE, // initial event reset NULL ) ; // no name if ( os.hEvent == NULL ) { MessageBox( NULL, "Failed to create event for thread!", "comm Error!", MB_ICONEXCLAMATION | MB_OK ); return ( FALSE ) ; } if (!SetCommMask(npComm->dev, EV_RXCHAR )) return ( FALSE ) ; while (npComm->setcom ) { dwEvtMask = 0 ; WaitCommEvent(npComm->dev, &dwEvtMask, NULL); if(npComm->state) { npComm->state = FALSE; npComm->evt.Lock(50); if((dwEvtMask & EV_RXCHAR) == EV_RXCHAR ) if (nLength = npComm->Input(InData, 950 )) npComm->SetReadData(InData, nLength); npComm->evt.Unlock(); } npComm->state = TRUE; } CloseHandle( os.hEvent ) ; return( TRUE ) ; } void CSERIAL::SetReadData(unsigned char *buf, int TOL) { int x; for(x = 0; x < TOL; x++) bufread.Txchar(buf[x]); SendMessage(hwnd, WM_RECEIVEDATA, TOL, 0); } void CSERIAL::SetHwnd(HWND hd) { hwnd=hd; } void CSERIAL::Setting(int port,DWORD rate,BYTE bytesize,BYTE stop,BYTE parity) { bPort=port; dwBaudRate=rate; bByteSize=bytesize; bStopBits=stop; bParity=parity; } BOOL CSERIAL::Init() { osWrite.Offset = 0; osWrite.OffsetHigh = 0; osRead.Offset = 0; osRead.OffsetHigh = 0; osRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if (osRead.hEvent == NULL) { return FALSE ; } osWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if (NULL == osWrite.hEvent) { CloseHandle( osRead.hEvent ) ; return FALSE; } return TRUE ; } BOOL CSERIAL::Startcom( ) { char szPort[ 15 ] ; BOOL fRetVal ; COMMTIMEOUTS CommTimeOuts ; if (bPort > 125) lstrcpy( szPort, "\\\\.\\TELNET" ) ; else if((bPort >= 0) && (bPort <= 9)) wsprintf( szPort, "COM%d", bPort ) ; else if((bPort >= 10) && (bPort <= 125)) wsprintf( szPort, "\\\\.\\COM%d", bPort ) ; if ((dev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // no security attrs OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // overlapped I/O NULL )) == (HANDLE) -1 ) return ( FALSE ); else { SetCommMask( dev, EV_RXCHAR); SetupComm( dev, 10000, 10000 ); PurgeComm( dev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier = 10; CommTimeOuts.ReadTotalTimeoutConstant = 100; CommTimeOuts.WriteTotalTimeoutMultiplier = 10; CommTimeOuts.WriteTotalTimeoutConstant = 100; SetCommTimeouts( dev, &CommTimeOuts ); } fRetVal = Setcom(); if (fRetVal) { setcom = TRUE; CString str; str.Format("COM%d", bPort); AfxMessageBox(str + " Connected !!"); AfxBeginThread((AFX_THREADPROC)CommWatchProc,(LPVOID)this); } else { setcom = FALSE; CloseHandle(dev); } return ( fRetVal ); } BOOL CSERIAL::Setcom() { BOOL fRetVal; DCB dcb; dcb.DCBlength = sizeof( DCB ); GetCommState( dev, &dcb ); dcb.BaudRate = dwBaudRate; dcb.ByteSize = bByteSize; fRetVal = SetCommState( dev, &dcb ); return ( fRetVal ); } int CSERIAL::Input(BYTE *lpszBlock, int nMaxLength ) { BOOL fReadStat ; COMSTAT ComStat ; DWORD dwErrorFlags; DWORD dwLength; ClearCommError( dev, &dwErrorFlags, &ComStat ); dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ); if (dwLength > 0) { fReadStat = ReadFile( dev, lpszBlock, dwLength, &dwLength, &osRead); } return ( dwLength ); } BOOL CSERIAL::Release() { if (setcom) Stopcom( ); CloseHandle( osRead.hEvent ); CloseHandle( osWrite.hEvent ); return ( TRUE ); } BOOL CSERIAL::Stopcom() { setcom = FALSE; SetCommMask( dev, 0 ); EscapeCommFunction( dev, CLRDTR ); PurgeComm( dev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); CloseHandle( dev ); return ( TRUE ); } BOOL CSERIAL::Output(unsigned char* lpByte , DWORD dwBytesToWrite) { BOOL fWriteStat ; DWORD dwBytesWritten; Sleep(7); fWriteStat = WriteFile( dev, lpByte, dwBytesToWrite, &dwBytesWritten, &osWrite ); return ( TRUE ); } CBUFFER::CBUFFER() { Rstemp(); } void CBUFFER::Rstemp() { start = end = 0; memset(temp,0,19500); } unsigned int CBUFFER::Length() { return ((start-end)+19500)%19500; } BOOL CBUFFER::Rxchar(unsigned char *ch) { if(Length() == 0) return FALSE; *ch = temp[end++]; if(end >= 19499) end = 0; return TRUE; } BOOL CBUFFER::Txchar(unsigned char ch) { if(Length() == 19499) return FALSE; temp[start++] = ch; if(start >= 19499) start = 0; return TRUE; }