1328 lines
34 KiB
C++
1328 lines
34 KiB
C++
#include "../stdafx.h"
|
||
|
||
#include <process.h>
|
||
|
||
#include "CMMIO_SERIAL.H "
|
||
|
||
//////////////////////////////////////////////////////////////////
|
||
/////////////////////////////////////////////////////////////////
|
||
#define LONG_TIMEOUT 5000
|
||
#define MAXBLOCK 4096
|
||
/*
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Code - Text for debug window
|
||
static char Codes[][6] =
|
||
{
|
||
"<NUL>","<SOH>","<STX>","<ETX>","<EOT>","<ENQ>","<ACK>","<BEL>",
|
||
"<BS>","<HT>","<LF>","<VT>","<FF>","<CR>","<SO>","<SI>","<DLE>",
|
||
"<DC1>","<DC2>","<DC3>","<DC4>","<NAK>","<SYN>","<ETB>","<CAN>",
|
||
"<EM>","<SUB>","<ESC>","<FS>","<GS>","<RS>","<VS>"
|
||
};
|
||
*/
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CPSerial() : Constructor
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CSerialTask() : Function to run ReceiveTask() method as a task
|
||
//
|
||
|
||
unsigned int WINAPI CSerialTask(LPVOID CSerialPtr)
|
||
{
|
||
TRACE(TEXT("Serial task has started \n"));
|
||
// Call the ControlTask function in the specified plugin
|
||
static_cast<CPSerial*>(CSerialPtr)->ReceiveTask();
|
||
|
||
TRACE(TEXT("Serial task has completed \n"));
|
||
|
||
_endthreadex(0);
|
||
|
||
return (0);
|
||
}
|
||
|
||
CPSerial::CPSerial()
|
||
{
|
||
// Serial port is not open
|
||
m_PortHandle = INVALID_HANDLE_VALUE;
|
||
m_IsWrtingData = FALSE;
|
||
// Default port settings
|
||
m_Port = 1;
|
||
m_Baud = CBR_115200;
|
||
m_Parity = 'N';
|
||
m_Bits = 8;
|
||
m_StopBits = 1;
|
||
m_HandShake = CS_HANDSHAKE_FOR_SO7;
|
||
m_RXTimeout = CS_DEFAULT_RX_TIMEOUT;
|
||
m_TXTimeout = CS_DEFAULT_TX_TIMEOUT;
|
||
m_iRecvState = FALSE;
|
||
m_iRecvBytes = 0;
|
||
memset(m_RecvData, 0,MAX_RECIEVE_BUFFER_SIZE);
|
||
// Everything else set to NULL
|
||
m_ThreadHandle = nullptr;
|
||
//m_TXHead = NULL;
|
||
//m_TXTail = NULL;
|
||
//m_RXHead = NULL;
|
||
//m_RXTail =NULL;
|
||
memset(&m_ReceiveOLap, 0, sizeof(OVERLAPPED));
|
||
memset(&m_TransmitOLap, 0, sizeof(OVERLAPPED));
|
||
memset(&m_ReadOLap, 0, sizeof(OVERLAPPED));
|
||
memset(&m_WriteOLap, 0, sizeof(OVERLAPPED));
|
||
|
||
//事件最常用在多线程同步互斥机制。
|
||
//1、HANDLE CreateEvent(
|
||
//
|
||
// LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES结构指针,可为NULL
|
||
// BOOL bManualReset, // 手动/自动
|
||
// // TRUE:表示手动,在WaitForSingleObject后必须手动调用ResetEvent清除信号
|
||
// // FALSE:表示自动,在WaitForSingleObject后,系统自动清除事件信号
|
||
// BOOL bInitialState, //初始状态,FALSE为无信号,TRUE为有信号
|
||
// LPCTSTR lpName //事件的名称
|
||
//);
|
||
//
|
||
//2、SetEvent:设置为激活触发状态。
|
||
//
|
||
//3、ResetEvent:设置为未激活触发状态。
|
||
//
|
||
//4、WaitForSingleObject:检测信号,如果未激活,代码就会处于挂起状态,不再往下执行。
|
||
//
|
||
//————————————————
|
||
//版权声明:本文为CSDN博主「AI浩」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。
|
||
//原文链接:https ://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/108380956
|
||
|
||
m_hWaitCMMResponse = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||
m_hNewRx = CreateEvent(nullptr, TRUE, FALSE, nullptr); // to trigger OnRx
|
||
m_ReadOLap.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||
|
||
//m_RXTempPtr = NULL;
|
||
m_DebugInPtr = 0;
|
||
m_DebugCount = 0;
|
||
m_Item = 0;
|
||
m_MaxTXRetries = 5;
|
||
m_iRecvCount = 252;
|
||
/*
|
||
// CriticalSection for locking lists
|
||
InitializeCriticalSection( &m_QueueLock );
|
||
InitializeCriticalSection( &m_WriteLock );
|
||
InitializeCriticalSection( &m_ReadLock );
|
||
*/
|
||
// IsValidBuffer = FALSE;
|
||
CurrentPointer = 0;
|
||
|
||
m_hWaitCMMResponse = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||
m_hNewRx = CreateEvent(nullptr, TRUE, FALSE, nullptr); // to trigger OnRx
|
||
// pParent = NULL;
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// ~CPSerial() : Destructor - Close the port and free up the CriticalSection
|
||
|
||
CPSerial::~CPSerial()
|
||
{
|
||
if (IsOpen())
|
||
{
|
||
TRACE(TEXT("Warning : closing serial port in destructor\n"));
|
||
Close();
|
||
}
|
||
while (GetNextReceived()); // mp 3/3/99 prevents leaks
|
||
/*
|
||
DeleteCriticalSection( &m_QueueLock );
|
||
DeleteCriticalSection( &m_ReadLock );
|
||
DeleteCriticalSection( &m_WriteLock );
|
||
*/
|
||
// close the overlapped io event
|
||
CloseHandle(m_ReadOLap.hEvent);
|
||
CloseHandle(m_WriteOLap.hEvent);
|
||
//
|
||
CloseHandle(m_hWaitCMMResponse);
|
||
CloseHandle(m_hNewRx);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// OpenPort() : Opens the serial port using the parameters set by default
|
||
// or a call to SetPort
|
||
|
||
DWORD CPSerial::Open()
|
||
{
|
||
CString PortName;
|
||
COMMTIMEOUTS CommTimeOut;
|
||
int Ok;
|
||
unsigned int ThreadID;
|
||
|
||
// Ensure the debug window is registered
|
||
// RegisterDebugWindow( );
|
||
|
||
// Close the port incase it is already open
|
||
Close();
|
||
|
||
// Start of assuming the worst
|
||
Ok = FALSE;
|
||
|
||
// Format the file name and open it
|
||
// COM<number> opens ports from 1..9 for two-difit ports it's becessary to use \\\\.\\COM<num>
|
||
#if 0
|
||
PortName.Format( TEXT("\\\\.\\COM%d"), m_Port );
|
||
#else
|
||
PortName.Format(TEXT("COM%d"), m_Port);
|
||
#endif
|
||
m_PortHandle = CreateFile(PortName, GENERIC_WRITE | GENERIC_READ, 0, nullptr,
|
||
OPEN_EXISTING,
|
||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
||
nullptr);
|
||
if (IsOpen())
|
||
{
|
||
// Setup the port according to the stored parameters
|
||
if (ProgramPort(m_Port, m_Baud, m_Parity, m_Bits, m_StopBits, m_HandShake))
|
||
{
|
||
// Setup the timeouts
|
||
CommTimeOut.ReadIntervalTimeout = 25;
|
||
CommTimeOut.ReadTotalTimeoutMultiplier = 1;
|
||
CommTimeOut.ReadTotalTimeoutConstant = 1;
|
||
CommTimeOut.WriteTotalTimeoutMultiplier = 1;
|
||
CommTimeOut.WriteTotalTimeoutConstant = m_TXTimeout;
|
||
if (SetCommTimeouts(m_PortHandle, &CommTimeOut))
|
||
{
|
||
// Setup the buffer sizes
|
||
if (SetupComm(m_PortHandle, 2048, 2048))
|
||
{
|
||
// Setup the event masks for the monitoring task
|
||
if (SetCommMask(m_PortHandle, EV_RXCHAR | EV_TXEMPTY | EV_BREAK |
|
||
EV_CTS | EV_DSR | EV_ERR | EV_RLSD))
|
||
{
|
||
// Initialize the Overlapping structures and start the
|
||
// monitoring task
|
||
m_ReceiveOLap.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||
m_TransmitOLap.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||
m_ThreadHandle = (HANDLE)_beginthreadex(nullptr, 0, CSerialTask, this,
|
||
0, &ThreadID);
|
||
//Sleep(1000);
|
||
Ok = TRUE;
|
||
}
|
||
}
|
||
}
|
||
// clear msg waiting
|
||
m_iNbMsgWaiting = 0;
|
||
}
|
||
|
||
// Things have gone wrong so close the port
|
||
if (Ok == FALSE)
|
||
{
|
||
TRACE(_T("CmmIO> Port OPEN issue -> CLOSED\n"), Ok);
|
||
Close();
|
||
}
|
||
}
|
||
TRACE(_T("CmmIO> Port OPEN = %d \n"), Ok);
|
||
// Return the state
|
||
return (IsOpen());
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// IsOpen() : returns true if the serial port is open
|
||
//
|
||
|
||
int CPSerial::IsOpen()
|
||
{
|
||
return (m_PortHandle != INVALID_HANDLE_VALUE);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// SetPort() : Store the serial settings. If the port is open then these
|
||
// settings are applied now
|
||
|
||
int CPSerial::SetPort(int Port, int Baud, char Parity, int Bits, int StopBits, int HandShake)
|
||
{
|
||
// Use the current settings if the value has the default of 0
|
||
m_Port = Port;
|
||
if (Baud == 0)
|
||
Baud = m_Baud;
|
||
if (Parity == 0)
|
||
Parity = m_Parity;
|
||
if (Bits == 0)
|
||
Bits = m_Bits;
|
||
if (StopBits == 0)
|
||
StopBits = m_StopBits;
|
||
if (HandShake == 0)
|
||
HandShake = m_HandShake;
|
||
|
||
|
||
// If the values are ok then store them
|
||
if (ProgramPort(Port, Baud, Parity, Bits, StopBits, HandShake))
|
||
{
|
||
m_Port = Port;
|
||
m_Baud = Baud;
|
||
m_Parity = Parity;
|
||
m_Bits = Bits;
|
||
m_StopBits = StopBits;
|
||
m_HandShake = HandShake;
|
||
return (TRUE);
|
||
}
|
||
return (FALSE);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// GetPortData() : return the current settings
|
||
//
|
||
|
||
void CPSerial::GetPortData(int* Port, int* Baud, char* Parity, int* Bits, int* StopBits, int* HandShake)
|
||
{
|
||
// return the requested settings
|
||
if (Port)
|
||
*Port = m_Port;
|
||
if (m_Baud)
|
||
*Baud = m_Baud;
|
||
if (Parity)
|
||
*Parity = m_Parity;
|
||
if (Bits)
|
||
*Bits = m_Bits;
|
||
if (StopBits)
|
||
*StopBits = m_StopBits;
|
||
if (HandShake)
|
||
*HandShake = m_HandShake;
|
||
}
|
||
|
||
DWORD CPSerial::SendWriteFile(const char* Buffer, DWORD Bytes)
|
||
{
|
||
DWORD BytesWritten;
|
||
BOOL WriteState;
|
||
WriteState = WriteFile(m_PortHandle, &Buffer[0], Bytes, &BytesWritten,
|
||
&m_WriteOLap);
|
||
return WriteState;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// ClosePort() : Close the port and shut down the monitoring thread
|
||
//
|
||
|
||
DWORD CPSerial::Close()
|
||
{
|
||
//struct SerialList *Free;
|
||
HANDLE Port;
|
||
|
||
// If the port is open then close it
|
||
if (IsOpen())
|
||
{
|
||
Port = m_PortHandle;
|
||
m_PortHandle = INVALID_HANDLE_VALUE;
|
||
CloseHandle(Port);
|
||
if (WaitForSingleObject(m_ThreadHandle, (5 * LONG_TIMEOUT)) != WAIT_OBJECT_0)
|
||
TRACE(TEXT("ERR:Serial port thread failed to terminate\n"));
|
||
m_ThreadHandle = nullptr;
|
||
CloseHandle(m_ReceiveOLap.hEvent);
|
||
CloseHandle(m_TransmitOLap.hEvent);
|
||
}
|
||
|
||
CMMIO::Close();
|
||
//ZH
|
||
/*
|
||
// Delete the contents of the temp rx pointer if any
|
||
delete[] m_RXTempPtr;
|
||
m_RXTempPtr = NULL;
|
||
|
||
// Clear down all internal lists
|
||
EnterCriticalSection( &m_QueueLock );
|
||
while( m_RXHead )
|
||
{
|
||
Free = m_RXHead;
|
||
m_RXHead = m_RXHead->Next;
|
||
delete[] Free->Buffer;
|
||
delete Free;
|
||
}
|
||
m_RXHead = NULL;
|
||
while( m_TXHead )
|
||
{
|
||
Free = m_TXHead;
|
||
m_TXHead = m_TXHead->Next;
|
||
delete[] Free->Buffer;
|
||
delete Free;
|
||
}
|
||
m_TXHead = NULL;
|
||
|
||
LeaveCriticalSection( &m_QueueLock );
|
||
*/
|
||
return (TRUE);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Send functions // [8/11/2004]
|
||
//
|
||
|
||
DWORD CPSerial::Send(LPCSTR buffer, int l, BOOL /*needsResponse=FALSE*/)
|
||
{
|
||
m_IsWrtingData = TRUE;
|
||
return (WritePort(buffer, static_cast<DWORD>(l)));
|
||
}
|
||
|
||
/*
|
||
DWORD CPSerial::Send(CString buffer)
|
||
{
|
||
char LocBuffer[MAX_OUTPUT_BUFFER_SIZE];
|
||
int length = buffer.GetLength ();
|
||
if (length >MAX_OUTPUT_BUFFER_SIZE)
|
||
{
|
||
length = MAX_OUTPUT_BUFFER_SIZE;
|
||
}
|
||
unsigned short* ptr = (unsigned short*)buffer.GetBuffer (MAX_OUTPUT_BUFFER_SIZE);
|
||
for (int i=0;i<length;i++)
|
||
{
|
||
LocBuffer[i] = (char)(ptr[i] & 0xff);
|
||
}
|
||
DWORD res = Send(LocBuffer,length);
|
||
return res;
|
||
}
|
||
*/
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// WritePort() : Writes the specifed bytes to the serial port
|
||
//
|
||
|
||
DWORD CPSerial::WritePort(const char* Buffer, DWORD Bytes)
|
||
{
|
||
DWORD BytesWritten, TotalWritten, Error;
|
||
BOOL WriteState;
|
||
int Retrys;
|
||
|
||
TotalWritten = 0;
|
||
|
||
// Check that the port is open
|
||
if (IsOpen())
|
||
{
|
||
// Enter a critical section incase this is been used from multiple threads
|
||
//EnterCriticalSection(&m_WriteLock);
|
||
|
||
// The following retry loop is required because a TRACE output from NT running
|
||
// in remote debug mode will kill any tranmission on any serial port !!!!!!!
|
||
// don`t you just love NT.
|
||
Retrys = 0;
|
||
do
|
||
{
|
||
Retrys++;
|
||
BytesWritten = 0;
|
||
// Write the data
|
||
WriteState = WriteFile(m_PortHandle, &Buffer[TotalWritten],
|
||
Bytes - TotalWritten, &BytesWritten,
|
||
&m_WriteOLap);
|
||
if (!WriteState)
|
||
{
|
||
Sleep(5);
|
||
// Ensure the write is going on in the background
|
||
if (GetLastError() == ERROR_IO_PENDING)
|
||
{
|
||
// And wait for it to finish
|
||
WaitForSingleObject(m_WriteOLap.hEvent, LONG_TIMEOUT); // GER
|
||
GetOverlappedResult(m_PortHandle, &m_WriteOLap, &BytesWritten,
|
||
FALSE);
|
||
}
|
||
else
|
||
{
|
||
// Gone wrong so clear any erros
|
||
ClearCommError(m_PortHandle, &Error, nullptr);
|
||
BytesWritten = 0;
|
||
}
|
||
}
|
||
TotalWritten += BytesWritten;
|
||
}
|
||
while (Retrys <= m_MaxTXRetries && TotalWritten < Bytes);
|
||
|
||
//ZH
|
||
/*
|
||
// Written some bytes so add then to the debug list
|
||
if( BytesWritten )
|
||
AddToDebug( Buffer, BytesWritten, 2 );
|
||
*/
|
||
// Remember to leave the critical section
|
||
//LeaveCriticalSection( &m_WriteLock );
|
||
}
|
||
|
||
return (TotalWritten);
|
||
}
|
||
|
||
|
||
//==========================================================================
|
||
|
||
int CPSerial::ReadBlock(BYTE* abIn, int MaxLength)
|
||
{
|
||
BOOL JudgeRead;
|
||
COMSTAT ComStat;
|
||
DWORD dwErrorFlags, dwLength;
|
||
ClearCommError(m_PortHandle, &dwErrorFlags, &ComStat);
|
||
if (dwErrorFlags > 0)
|
||
{
|
||
PurgeComm(m_PortHandle, PURGE_RXABORT | PURGE_RXCLEAR);
|
||
return 0;
|
||
}
|
||
dwLength = (static_cast<DWORD>(MaxLength) < ComStat.cbInQue ? MaxLength : ComStat.cbInQue);
|
||
memset(abIn, 0, MaxLength);
|
||
//如果有字符即读入
|
||
if (dwLength)
|
||
{
|
||
JudgeRead = ReadFile(m_PortHandle, abIn, dwLength, &dwLength, &m_ReceiveOLap); //读出字符至abIn处
|
||
if (!JudgeRead)
|
||
{
|
||
//如果重叠操作未完成,等待直到操作完成
|
||
if (GetLastError() == ERROR_IO_PENDING)
|
||
{
|
||
// WaitForSingleObject(m_osRead.hEvent,INFINITE);
|
||
GetOverlappedResult(m_PortHandle, &m_ReceiveOLap, &dwLength, TRUE);
|
||
m_ReceiveOLap.Offset = 0;
|
||
// m_osRead.Offset=(m_osRead.Offset+dwLength)%MAXBLOCK;
|
||
}
|
||
else
|
||
dwLength = 0;
|
||
}
|
||
}
|
||
return dwLength;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// ReceiveTask() : Internal function, this runs as a thread and provides the
|
||
// OnRecieve and OnTransmit events
|
||
|
||
void CPSerial::ReceiveTask(void)
|
||
{
|
||
//DWORD BytesWritten;
|
||
DWORD Events;
|
||
unsigned long State;
|
||
|
||
do
|
||
{
|
||
Sleep(2);
|
||
BYTE abIn[MAXBLOCK];
|
||
int len;
|
||
len = ReadBlock(abIn, MAXBLOCK);
|
||
if ((len > 0) && (len < MAX_RECIEVE_BUFFER_SIZE))
|
||
{
|
||
//memset(m_RecvData, 0, m_iRecvBytes);
|
||
memcpy(m_RecvData, abIn, len);
|
||
m_iRecvBytes = len;
|
||
m_iRecvState = TRUE;
|
||
}
|
||
// Events=0;
|
||
//
|
||
// // Wait for a comm event
|
||
// State=WaitCommEvent(m_PortHandle,&Events,&m_ReceiveOLap);
|
||
// if(!State)
|
||
// {
|
||
// // Since we are using overlapping IO we may have to wait
|
||
// // for the result
|
||
// if(GetLastError() == ERROR_IO_PENDING)
|
||
// GetOverlappedResult(m_PortHandle,&m_ReceiveOLap,&State,TRUE);
|
||
// }
|
||
////m_iRecvState=FALSE;
|
||
// // If we have a result then OK otherwise the event was probable
|
||
// // the serial port being closed and we shall exit the loop
|
||
// if( State && IsOpen( ) )
|
||
// {
|
||
// // Check the events and act accordingly
|
||
// if( Events & EV_RXCHAR )
|
||
// {
|
||
// OnReceive( );
|
||
// }
|
||
// //ZH
|
||
// /*
|
||
// if( Events & EV_TXEMPTY )
|
||
// {
|
||
// if( m_TXHead )
|
||
// {
|
||
// GetOverlappedResult(m_PortHandle,&m_TransmitOLap,&BytesWritten,TRUE);
|
||
// if( BytesWritten )
|
||
// AddToDebug( m_TXHead->Buffer, BytesWritten, 2 );
|
||
// OnTransmit( 0, BytesWritten );
|
||
// SendBuffer(TRUE);
|
||
// }
|
||
// }
|
||
// */
|
||
// if(Events & EV_BREAK)
|
||
// TRACE(_T("Break detected\n"));
|
||
// if(Events & EV_CTS)
|
||
// TRACE(_T("CTS Changed State\n"));
|
||
// if(Events & EV_DSR)
|
||
// TRACE(_T("DSR Changed State\n"));
|
||
// if(Events & EV_ERR)
|
||
// TRACE(_T("Line error\n"));
|
||
// if(Events & EV_RLSD)
|
||
// TRACE(_T("EV_RLSD error\n"));
|
||
// }
|
||
|
||
// Go round while the port is open
|
||
}
|
||
while (IsOpen());
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// OnReceive() : Default OnReceive()
|
||
// V114
|
||
|
||
void CPSerial::OnReceive()
|
||
{
|
||
// Dummy OnReceieve if not used
|
||
char s[MAX_RECIEVE_BUFFER_SIZE] = {0};
|
||
s[1] = '\0';
|
||
CurrentPointer = 0;
|
||
if (m_HandShake == CS_HANDSHAKE_FOR_TRESASTR_E)
|
||
{
|
||
int num = ReadPort(s, MAX_RECIEVE_BUFFER_SIZE);
|
||
if ((num > 0) && (num < MAX_RECIEVE_BUFFER_SIZE))
|
||
{
|
||
if (m_IsWrtingData)
|
||
{
|
||
memset(m_RecvData, 0,MAX_RECIEVE_BUFFER_SIZE);
|
||
m_IsWrtingData = FALSE;
|
||
m_iRecvBytes = 0;
|
||
}
|
||
TRACE1("----RECV%d----\r\n", num);
|
||
TRACE3("%02X %02X %02X ", s[0], s[1], s[2]);
|
||
TRACE3("%02X %02X %02X ", s[3], s[4], s[5]);
|
||
TRACE3("%02X %02X %02X\r\n", s[6], s[7], s[8]);
|
||
for (int i = 0; i < num; i++)
|
||
{
|
||
m_RecvData[m_iRecvBytes++] = s[i];
|
||
}
|
||
m_iRecvState = TRUE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int num = ReadPort(s, m_iRecvCount);
|
||
if ((num > 0) && (num < MAX_RECIEVE_BUFFER_SIZE))
|
||
{
|
||
// memset(m_RecvData,0,m_iRecvBytes);
|
||
memcpy(m_RecvData, s, num);
|
||
m_iRecvBytes = num;
|
||
m_iRecvState = TRUE;
|
||
}
|
||
}
|
||
//LineReceive(s, num);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// ReadPort() : Read the specifed number of bytes.
|
||
//
|
||
|
||
DWORD CPSerial::ReadPort(char* Buffer, DWORD Bytes)
|
||
{
|
||
DWORD BytesRead, Error;
|
||
BOOL ReadState;
|
||
|
||
BytesRead = 0;
|
||
// Check the port is open
|
||
if (IsOpen())
|
||
{
|
||
// Enter a critical section incase this is been used from multiple threads
|
||
// EnterCriticalSection(&m_ReadLock);
|
||
// Start the read
|
||
ReadState = ReadFile(m_PortHandle, Buffer, Bytes, &BytesRead, &m_ReadOLap);
|
||
if (!ReadState)
|
||
{
|
||
Sleep(3);
|
||
// the specifed number of bytes were not available so
|
||
// the read will continue in the background aslong as
|
||
// GetLastError() returns ERROR_IO_PENDING
|
||
if (GetLastError() == ERROR_IO_PENDING)
|
||
{
|
||
// Wait for the read to complete
|
||
WaitForSingleObject(m_ReadOLap.hEvent, LONG_TIMEOUT); // GER
|
||
|
||
// get the result of the read
|
||
if (GetOverlappedResult(m_PortHandle, &m_ReadOLap, &BytesRead, FALSE) == 0)
|
||
Error = GetLastError();
|
||
}
|
||
else
|
||
{
|
||
// Gone wrong so clear any erros
|
||
ClearCommError(m_PortHandle, &Error, nullptr);
|
||
BytesRead = 0;
|
||
}
|
||
}
|
||
|
||
//ZH
|
||
/*
|
||
// Read some bytes so add then to the debug list
|
||
if( BytesRead )
|
||
AddToDebug( Buffer, BytesRead, 1 );
|
||
*/
|
||
// LeaveCriticalSection( &m_ReadLock );
|
||
}
|
||
|
||
return (BytesRead);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// ReadPort() : Read the specifed number of bytes into a CString class.
|
||
//
|
||
#if 0
|
||
DWORD CPSerial::ReadPort(CString &Buffer,DWORD Bytes)
|
||
{
|
||
DWORD BytesRead;
|
||
|
||
USES_CONVERSION;
|
||
BytesRead = ReadPort( T2A(Buffer.GetBuffer( Bytes + 1 )), Bytes );
|
||
Buffer.ReleaseBuffer( );
|
||
|
||
return(BytesRead);
|
||
}
|
||
#endif
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// ProgramPort() : Internal function to setup the serial port
|
||
//
|
||
|
||
int CPSerial::ProgramPort(int Port, int Baud, char Parity, int Bits, int StopBits, int HandShake)
|
||
{
|
||
CString Param, Params;
|
||
DCB SerialDCB;
|
||
int Ok;
|
||
|
||
// Build up the serial port settings
|
||
Params.Format(TEXT("com%d"), Port);
|
||
Param.Format(TEXT(" baud=%d"), Baud);
|
||
Params += Param;
|
||
Param.Format(TEXT(" parity=%c"), Parity);
|
||
Params += Param;
|
||
Param.Format(TEXT(" data=%d"), Bits);
|
||
Params += Param;
|
||
Param.Format(TEXT(" stop=%d"), StopBits);
|
||
Params += Param;
|
||
Ok = FALSE;
|
||
memset(&SerialDCB, 0, sizeof(SerialDCB));
|
||
SerialDCB.DCBlength = sizeof(SerialDCB);
|
||
|
||
// Place them in the DCB structure, this also validates them if the
|
||
// serial port is not open
|
||
if (BuildCommDCB(Params, &SerialDCB))
|
||
{
|
||
// If the port is open
|
||
if (IsOpen())
|
||
{
|
||
// Set the handshake bits
|
||
switch (HandShake)
|
||
{
|
||
case CS_HANDSHAKE_RTSCTS:
|
||
SerialDCB.fOutxCtsFlow = TRUE;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
break;
|
||
case CS_HANDSHAKE_RTSCTS_DTRDSR:
|
||
SerialDCB.fOutxCtsFlow = TRUE;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||
SerialDCB.fOutxDsrFlow = TRUE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_HANDSHAKE;
|
||
break;
|
||
case CS_HANDSHAKE_XONXOFF:
|
||
SerialDCB.fOutX = TRUE;
|
||
SerialDCB.fInX = TRUE;
|
||
SerialDCB.XonChar = 17;
|
||
SerialDCB.XoffChar = 19;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_DISABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_DISABLE;
|
||
break;
|
||
case CS_HANDSHAKE_NONE:
|
||
SerialDCB.fRtsControl = RTS_CONTROL_ENABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
break;
|
||
case CS_HANDSHAKE_FOR_SO7:
|
||
SerialDCB.fDsrSensitivity = FALSE;
|
||
SerialDCB.XonChar = 17;
|
||
SerialDCB.XoffChar = 19;
|
||
SerialDCB.fOutX = FALSE;
|
||
SerialDCB.fInX = FALSE;
|
||
SerialDCB.fErrorChar = FALSE;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_ENABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
SerialDCB.fOutxCtsFlow = FALSE;
|
||
SerialDCB.fOutxDsrFlow = FALSE;
|
||
SerialDCB.XonLim = 2048;
|
||
SerialDCB.XoffLim = 512;
|
||
break;
|
||
case CS_HANDSHAKE_FOR_TRESASTR_E:
|
||
SerialDCB.EofChar = 26;
|
||
SerialDCB.XonChar = 17;
|
||
SerialDCB.XoffChar = 19;
|
||
SerialDCB.fOutX = TRUE;
|
||
SerialDCB.fInX = TRUE;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_DISABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
SerialDCB.fDsrSensitivity = FALSE;
|
||
SerialDCB.XonLim = 256;
|
||
SerialDCB.XoffLim = 256;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// Finally apply the params to the port
|
||
if (SetCommState(m_PortHandle, &SerialDCB))
|
||
{
|
||
Ok = TRUE;
|
||
}
|
||
else
|
||
{
|
||
GetCommState(m_PortHandle, &SerialDCB);
|
||
SerialDCB.BaudRate = Baud; // set the baud rate
|
||
SerialDCB.ByteSize = static_cast<BYTE>(Bits); // data size, xmit, and rcv
|
||
SerialDCB.StopBits = static_cast<BYTE>(StopBits); // one stop bit
|
||
switch (Parity)
|
||
{
|
||
case 'O':
|
||
case 'o':
|
||
SerialDCB.Parity = ODDPARITY; // odd parity bit
|
||
break;
|
||
case 'E':
|
||
case 'e':
|
||
SerialDCB.Parity = EVENPARITY; // even parity bit
|
||
break;
|
||
default:
|
||
SerialDCB.Parity = NOPARITY; // no parity bit
|
||
break;
|
||
}
|
||
// Set the handshake bits
|
||
switch (HandShake)
|
||
{
|
||
case CS_HANDSHAKE_RTSCTS:
|
||
SerialDCB.fOutxCtsFlow = TRUE;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
break;
|
||
case CS_HANDSHAKE_XONXOFF:
|
||
SerialDCB.fOutX = TRUE;
|
||
SerialDCB.fInX = TRUE;
|
||
SerialDCB.XonChar = 17;
|
||
SerialDCB.XoffChar = 19;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_DISABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_DISABLE;
|
||
break;
|
||
case CS_HANDSHAKE_NONE:
|
||
SerialDCB.fRtsControl = RTS_CONTROL_ENABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
break;
|
||
case CS_HANDSHAKE_FOR_SO7:
|
||
SerialDCB.fDsrSensitivity = FALSE;
|
||
SerialDCB.XonChar = 17;
|
||
SerialDCB.XoffChar = 19;
|
||
SerialDCB.fOutX = FALSE;
|
||
SerialDCB.fInX = FALSE;
|
||
SerialDCB.fErrorChar = FALSE;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_ENABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
SerialDCB.fOutxCtsFlow = FALSE;
|
||
SerialDCB.fOutxDsrFlow = FALSE;
|
||
SerialDCB.XonLim = 2048;
|
||
SerialDCB.XoffLim = 512;
|
||
break;
|
||
case CS_HANDSHAKE_FOR_TRESASTR_E:
|
||
SerialDCB.EofChar = 26;
|
||
SerialDCB.XonChar = 17;
|
||
SerialDCB.XoffChar = 19;
|
||
SerialDCB.fOutX = TRUE;
|
||
SerialDCB.fInX = TRUE;
|
||
SerialDCB.fRtsControl = RTS_CONTROL_DISABLE;
|
||
SerialDCB.fDtrControl = DTR_CONTROL_ENABLE;
|
||
SerialDCB.fDsrSensitivity = FALSE;
|
||
SerialDCB.XonLim = 256;
|
||
SerialDCB.XoffLim = 256;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// Finally apply the params to the port
|
||
if (SetCommState(m_PortHandle, &SerialDCB))
|
||
{
|
||
Ok = TRUE;
|
||
}
|
||
}
|
||
TRACE(_T("CmmIO> Port was OPEN, ProgramPort done \n"));
|
||
}
|
||
else
|
||
{
|
||
TRACE(_T("CmmIO> Port was not OPEN ProgramPort not done \n"));
|
||
Ok = TRUE;
|
||
}
|
||
}
|
||
return (Ok);
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// OnTransmit() : Default OnTransmit()
|
||
//
|
||
|
||
void CPSerial::OnTransmit(int /*Item*/, DWORD /*Error*/)
|
||
{
|
||
// Dummy OnTransmit if not used
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// SetTimeouts() : Sets the rx and tx timeouts
|
||
//
|
||
|
||
void CPSerial::SetTimeouts(int RXTimeout, int TXTimeout)
|
||
{
|
||
COMMTIMEOUTS CommTimeOut;
|
||
|
||
// Store the timeouts
|
||
m_RXTimeout = RXTimeout;
|
||
m_TXTimeout = TXTimeout;
|
||
|
||
// If the port is open then configure the port also
|
||
// Currently we only use the Fixed timeouts
|
||
if (IsOpen())
|
||
{
|
||
CommTimeOut.ReadIntervalTimeout = 25;
|
||
CommTimeOut.ReadTotalTimeoutMultiplier = 1;
|
||
CommTimeOut.ReadTotalTimeoutConstant = 0;
|
||
CommTimeOut.WriteTotalTimeoutMultiplier = 0;
|
||
CommTimeOut.WriteTotalTimeoutConstant = m_TXTimeout;
|
||
SetCommTimeouts(m_PortHandle, &CommTimeOut);
|
||
}
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// AddToDebug() : Add the data to the debug output. State is 1 = rx 2 = tx
|
||
// 3 = user
|
||
|
||
void CPSerial::AddToDebug(const char* /*Ptr*/, DWORD /*BytesToCopy*/, int /*State*/)
|
||
{
|
||
//ZH
|
||
#if 0
|
||
// We are messing with pointers so use the CriticalSection
|
||
EnterCriticalSection(&m_QueueLock);
|
||
|
||
// If ptr = NULL the change to string containing <NULL>
|
||
if( Ptr == NULL )
|
||
{
|
||
BytesToCopy = 0;
|
||
//Ptr = _T("<NULL>");
|
||
Ptr = "<NULL>";
|
||
}
|
||
|
||
// If zero length then use length of string instead
|
||
if( BytesToCopy == 0)
|
||
BytesToCopy = strlen( Ptr );
|
||
|
||
// If length of data is greater then the debug buffer then just
|
||
// use the end of the data
|
||
if(BytesToCopy > CS_DEBUG_SIZE)
|
||
{
|
||
Ptr += BytesToCopy - CS_DEBUG_SIZE;
|
||
BytesToCopy = CS_DEBUG_SIZE;
|
||
}
|
||
|
||
// If the data will wrap around then just copy the first block
|
||
if( ( m_DebugInPtr + BytesToCopy ) > CS_DEBUG_SIZE)
|
||
{
|
||
// Copy data to the end of the debug buffer
|
||
memcpy(m_DebugData + m_DebugInPtr, Ptr, CS_DEBUG_SIZE - m_DebugInPtr);
|
||
memset(m_DebugState + m_DebugInPtr, State, CS_DEBUG_SIZE - m_DebugInPtr);
|
||
m_DebugWnd.AddData( m_DebugData + m_DebugInPtr,
|
||
m_DebugState + m_DebugInPtr,
|
||
CS_DEBUG_SIZE - m_DebugInPtr );
|
||
|
||
// Move on by the amount copied
|
||
Ptr += CS_DEBUG_SIZE - m_DebugInPtr;
|
||
BytesToCopy -= CS_DEBUG_SIZE - m_DebugInPtr;
|
||
|
||
// Point at the begining of the buffer
|
||
m_DebugInPtr = 0;
|
||
}
|
||
|
||
// Copy the rest into the buffer
|
||
memcpy(m_DebugData + m_DebugInPtr, Ptr, BytesToCopy);
|
||
memset(m_DebugState + m_DebugInPtr, State, BytesToCopy);
|
||
m_DebugWnd.AddData( m_DebugData + m_DebugInPtr,
|
||
m_DebugState + m_DebugInPtr, BytesToCopy );
|
||
m_DebugInPtr += BytesToCopy;
|
||
m_DebugCount += BytesToCopy;
|
||
|
||
// Keep a count of howmany bytes are in the buffer
|
||
if( m_DebugCount > CS_DEBUG_SIZE )
|
||
m_DebugCount = CS_DEBUG_SIZE;
|
||
|
||
// All done so out of the CriticalSection
|
||
LeaveCriticalSection(&m_QueueLock);
|
||
#endif
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// FlushPort() : Removes all characters in the serial buffer
|
||
//
|
||
/*
|
||
int CPSerial::FlushPort(void)
|
||
{
|
||
int TXTimeout,RXTimeout;
|
||
char FlushBuffer[256];
|
||
DWORD BytesRead,BytesTotal;
|
||
struct SerialList *Free;
|
||
|
||
if( IsOpen( ) )
|
||
{
|
||
// We are messing with pointers so use the CriticalSection
|
||
EnterCriticalSection(&m_QueueLock);
|
||
|
||
// Make a copy of the timeouts and set back to the defaults
|
||
RXTimeout = m_RXTimeout;
|
||
TXTimeout = m_TXTimeout;
|
||
SetTimeouts( 10, 10 );
|
||
|
||
// Read all data from the port
|
||
BytesTotal=0;
|
||
while( ( BytesRead = ReadPort( FlushBuffer, 256 ) ) == 256 )
|
||
BytesTotal+=BytesRead;
|
||
BytesTotal+=BytesRead;
|
||
|
||
// Clear the Received list
|
||
while(m_RXHead)
|
||
{
|
||
Free=m_RXHead;
|
||
m_RXHead=m_RXHead->Next;
|
||
delete[] Free->Buffer;
|
||
delete Free;
|
||
}
|
||
|
||
// put the timeouts back
|
||
SetTimeouts( RXTimeout, TXTimeout );
|
||
|
||
m_iNbMsgWaiting = 0;
|
||
|
||
// All done so out of the CriticalSection
|
||
LeaveCriticalSection(&m_QueueLock);
|
||
}
|
||
return(BytesTotal);
|
||
}
|
||
*/
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// MaxPort() :
|
||
//
|
||
|
||
int CPSerial::MaxPort()
|
||
{
|
||
// return the max port, :-)
|
||
return (8);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Transmit() : Adds data into a list to be transmitted when possible.
|
||
// the function OnTransmit() will be called for each block of
|
||
// data sent.
|
||
//
|
||
|
||
int CPSerial::Transmit(const char* /*Buffer*/, DWORD /*Bytes*/)
|
||
{
|
||
/*
|
||
struct SerialList *Ptr;
|
||
int Start;
|
||
|
||
// Is the port open
|
||
if( IsOpen( ) )
|
||
{
|
||
TRACE(_T("CmmIo> Port OPEN ... transmitting %d bytes \n"),Bytes);
|
||
// Yes so CriticalSection again
|
||
EnterCriticalSection(&m_QueueLock);
|
||
// Create a new list entry structure for the block of data
|
||
Ptr = new struct SerialList;
|
||
Ptr->Buffer = new char[Bytes];
|
||
Ptr->Bytes = Bytes;
|
||
Ptr->Next = NULL;
|
||
Ptr->Item = m_Item++;
|
||
if(Ptr->Item == 0 )
|
||
Ptr->Item = m_Item++;
|
||
memcpy( Ptr->Buffer, Buffer, Bytes );
|
||
|
||
// Add it into the list
|
||
if( m_TXTail )
|
||
{
|
||
Start = FALSE;
|
||
m_TXTail->Next = Ptr;
|
||
}
|
||
else
|
||
{
|
||
Start = TRUE;
|
||
m_TXHead = Ptr;
|
||
}
|
||
m_TXTail = Ptr;
|
||
|
||
// If the list was empty then start sending the data, otherwise
|
||
// it will be sentout when the previous data has been sent
|
||
if(Start)
|
||
SendBuffer(FALSE);
|
||
|
||
// All done so out of the CriticalSection
|
||
LeaveCriticalSection(&m_QueueLock);
|
||
|
||
//return the ID for this block
|
||
return( Ptr->Item );
|
||
}
|
||
else{
|
||
TRACE(_T("CmmIo> Port NOT OPEN ... FAILED TO TRANSMIT %d bytes \n"),Bytes);
|
||
}
|
||
*/
|
||
|
||
return (0);
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// AddReceived() : Helper function, this adds a block of data to a list which
|
||
// read back by GetNextReceived()
|
||
//
|
||
|
||
/*
|
||
int CPSerial::AddReceived( const char *Buffer,DWORD Bytes)
|
||
{
|
||
DWORD index = 0; //primary buffer index
|
||
struct SerialList *Ptr;
|
||
static char Buffer2[1000]; // result buffer
|
||
static char* pBuffer2 = &Buffer2[0];
|
||
unsigned char c;
|
||
bool bArmed;
|
||
int count;
|
||
static int escape = 0;
|
||
static int tilde = 0;
|
||
static int tildeseqcount = 0;
|
||
|
||
bool bDone = false;
|
||
bool bEventRequest = false;
|
||
|
||
// ATLTRACE("AddReceived> pBuffer2 = %x\n",pBuffer2);
|
||
// ATLTRACE("Content %s\n",Buffer);
|
||
if (Bytes==0){
|
||
// TRACE("CMMIO> Exiting , no real input");
|
||
return TRUE;
|
||
}
|
||
do {
|
||
bArmed = false;
|
||
for (;index<Bytes;index++){
|
||
c=Buffer[index] & 0xff;
|
||
//ATLTRACE("== %02x% ==\n",c); //copy char one by one
|
||
if ((c!='\r') && (c!='\n') && bArmed){ // out of CR/LF sequence...
|
||
break;
|
||
}
|
||
else if((c=='\r') || (c=='\n') || (c < 32)){ // Don't work with unprintable characters line 0 -GER
|
||
if (index !=0) bArmed = true;// don't make an empty record if LF is first char !
|
||
// but still skip it
|
||
}
|
||
else {
|
||
*(pBuffer2++) = c ; //copy char one by one
|
||
//new
|
||
if (tilde){
|
||
if(++tildeseqcount == 2) bArmed = true;
|
||
}
|
||
if (escape ==1){
|
||
if(c!='z' && c!='O')bArmed = true; //not a CLP or PRB
|
||
else escape = 0; // reset if part of POS / POINT Msg
|
||
}
|
||
///n
|
||
}
|
||
|
||
if( c>0x80 ){
|
||
++ escape; // max will be 1
|
||
// ATLTRACE(" ESCAPE ___>> %d\n",escape);
|
||
}
|
||
|
||
if( c=='~' ){
|
||
++ tilde; // max = 1
|
||
// ATLTRACE(" TILDE ESC___>> %d\n",tilde);
|
||
}
|
||
|
||
}
|
||
if (index == Bytes) bDone=true;
|
||
// else TRACE("\nCMMIO> (Serial)Splitting received stream....\n");
|
||
|
||
// We are messing with pointers so use the CriticalSection
|
||
if (bArmed ){
|
||
EnterCriticalSection(&m_QueueLock);
|
||
//Allocate a new list and add it in
|
||
count = pBuffer2-(&Buffer2[0]);
|
||
Ptr = new struct SerialList;
|
||
Ptr->Buffer = new char[count + 1 ];
|
||
Ptr->Bytes = count;
|
||
Ptr->Next = NULL;
|
||
memcpy( Ptr->Buffer, Buffer2, count );
|
||
Ptr->Buffer[count] = 0;
|
||
|
||
memcpy(m_sLastMessage,Buffer2,count); //copy to last message
|
||
m_sLastMessage[count]=0;
|
||
|
||
if( m_RXTail )
|
||
m_RXTail->Next = Ptr;
|
||
else
|
||
m_RXHead = Ptr;
|
||
m_RXTail = Ptr;
|
||
|
||
// All done so out of the CriticalSection
|
||
++m_iNbMsgWaiting;
|
||
LeaveCriticalSection( &m_QueueLock );
|
||
pBuffer2=&Buffer2[0]; // reset out buffer
|
||
count = 0;
|
||
escape = 0;
|
||
//new
|
||
tilde = 0;
|
||
tildeseqcount = 0;
|
||
///n
|
||
|
||
bEventRequest = true;
|
||
}
|
||
} while (!bDone);
|
||
// ATLTRACE ("CMMIO> Done\n");
|
||
|
||
//ZH
|
||
#if 0
|
||
if(bEventRequest){
|
||
if (!(pParent->m_bNoFireEvent)) {
|
||
// ATLTRACE("CmmIO Serial> Setting Event m_hNewRx \n");
|
||
SetEvent(m_hNewRx);// tell the system to fire event if needed...
|
||
}
|
||
else {
|
||
// ATLTRACE("CmmIO Serial> Setting Event pParent->m_hCmmResponded \n");
|
||
// SetEvent(pParent->m_hCmmResponded);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
// if(bEventRequest){
|
||
// if (pParent){
|
||
// SetEvent(pParent->m_hCmmResponded);
|
||
// }
|
||
// }
|
||
|
||
// else ATLTRACE("--- AddReceived> Leaving with part of msg in buffer, pBuffer2= %x\n",pBuffer2);
|
||
return(TRUE);
|
||
}
|
||
*/
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// GetNextReceived() : Helper function, receives messages placed in the queue
|
||
// by AddReceievd()
|
||
//
|
||
//ZH
|
||
/*
|
||
char *CPSerial::GetNextReceived(void)
|
||
{
|
||
struct SerialList *Free;
|
||
|
||
// If there is a previous block then delete it
|
||
delete[] m_RXTempPtr;
|
||
m_RXTempPtr = NULL;
|
||
|
||
// We are messing with pointers so use the CriticalSection
|
||
EnterCriticalSection(&m_QueueLock);
|
||
|
||
// If there any more to return
|
||
if( m_RXHead )
|
||
{
|
||
Free = m_RXHead;
|
||
m_RXHead = m_RXHead->Next;
|
||
|
||
// Point the temp pointer at the block
|
||
m_RXTempPtr = Free->Buffer;
|
||
|
||
// delete the list entry
|
||
delete Free;
|
||
--m_iNbMsgWaiting; // mp
|
||
}
|
||
if( m_RXHead == NULL )
|
||
m_RXTail = NULL;
|
||
|
||
// All done so out of the CriticalSection
|
||
LeaveCriticalSection( &m_QueueLock );
|
||
|
||
return( m_RXTempPtr );
|
||
}
|
||
*/
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// HexToInt() : Helper function, converts the specifed number of bytes from
|
||
// ascii hex
|
||
//
|
||
|
||
int CPSerial::HexToInt(char* Data, int Bytes)
|
||
{
|
||
int Byte;
|
||
int HexChar, Value;
|
||
|
||
Value = 0;
|
||
for (Byte = 0; Byte < Bytes; Byte++)
|
||
{
|
||
Value <<= 4;
|
||
HexChar = *Data++ -= '0';
|
||
if (HexChar > 32)
|
||
HexChar -= 39;
|
||
else if (HexChar > 9)
|
||
HexChar -= 7;
|
||
Value += HexChar;
|
||
}
|
||
|
||
return (Value);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Private functions
|
||
//
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// RegisterDebugWindow() : Registers the window class for the debug window.
|
||
//
|
||
//ZH
|
||
/*
|
||
void CPSerial::RegisterDebugWindow()
|
||
{
|
||
// Register the CSerialRaw window for future use
|
||
WNDCLASS wndcls;
|
||
memset( &wndcls, 0, sizeof( WNDCLASS ) );
|
||
wndcls.lpfnWndProc = DefWindowProc;
|
||
wndcls.hInstance = AfxGetInstanceHandle( );
|
||
wndcls.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||
wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
|
||
wndcls.lpszClassName = TEXT("CPSerial");
|
||
AfxRegisterClass( &wndcls );
|
||
}
|
||
*/
|
||
|
||
|
||
#if 0
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// SendBuffer() : Internal function, this writes the next block of data
|
||
// queued to the serial port.
|
||
|
||
void CPSerial::SendBuffer(int Next)
|
||
{
|
||
struct SerialList *Free;
|
||
// DWORD BytesWritten;
|
||
|
||
// We are messing with pointers so use the CriticalSection
|
||
EnterCriticalSection(&m_QueueLock);
|
||
|
||
// If we been told to go the next then do it
|
||
if(Next && m_TXHead)
|
||
{
|
||
Free=m_TXHead;
|
||
m_TXHead=m_TXHead->Next;
|
||
delete[] Free->Buffer;
|
||
delete Free;
|
||
|
||
}
|
||
|
||
// If there is still some data then send it
|
||
if(m_TXHead)
|
||
// WriteFile(m_PortHandle,m_TXHead->Buffer,m_TXHead->Bytes,&BytesWritten,&m_TransmitOLap);
|
||
WritePort(m_TXHead->Buffer,m_TXHead->Bytes);
|
||
else
|
||
m_TXTail=NULL;
|
||
|
||
// All done so out of the CriticalSection
|
||
LeaveCriticalSection(&m_QueueLock);
|
||
}
|
||
#endif
|