📄 rs232module.cpp
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
* Filename:
* ---------
* Rs232Module.cpp
*
* Project:
* --------
* Maui SW - Phone Suite
*
* Description:
* ------------
* This module is for UART read/write.
*
* Author:
* -------
* Spancer
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* $Revision: 1.3 $
* $Modtime: Apr 29 2004 09:14:22 $
* $Log: //mtkvs01/vmdata/PhoneSuiteApp/archives/comm/rs232Module.cpp-arc $
*
* Dec 19 2006 mtk00871
* [STP100001266] [PhoneSuite] other enhancement
*
*
* Sep 1 2006 mtk00871
* [STP100001121] [PhoneSuite] v2.4.03 check in
*
*
* Aug 1 2006 mtk00871
* [STP100000949] [PhoneSuite] [MAUI_00204755] The maximum of phonebook number length souldn't count in
*
*
* Jan 27 2006 mtk00871
* [STP100000568] [PhoneSuite] unicode version
* check in related modificaion
*
* Rev 1.3 Apr 29 2004 09:16:50 mtk00264
*Disable the MFC trace by changing the compile option SP_DEBUG to COMM_DBG_WITH_MFC.
*
* Rev 1.2 Apr 22 2004 20:24:00 mtk00264
*Fix the bug that phone suite sometimes lost SMS.
*Resolution for 33: [BugFix] Phone suite would lost some SMS
*
* Rev 1.1 Mar 24 2004 20:35:36 mtk00264
*Solving the problem of save the second message to phone will cause the phonesuite in a un-recovery state.
*Resolution for 4489: [PhoneSuite][BugFix]
*
* Rev 1.0 Feb 27 2004 18:28:12 admin
*Initial revision.
*
* Rev 1.0 Feb 27 2004 16:42:08 admin
*Initial revision.
*
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
#include "stdafx.h"
#include "CommThread.h"
#include "rs232Module.h"
#include "commModule.h"
#include <string>
using namespace std;
Rs232Module::Rs232Module()
{
ModuleThread::ModuleThread();
hCOM = NULL;
stopEvent = NULL;
m_idxRespCommand=0;
m_hResetEvt = NULL;
m_hWriteEvt = NULL;
m_hParserEvt = NULL;
m_hWaitGtAndSpace = NULL;
m_hInProgressEvt = NULL;
m_hCleanedEvt = NULL;
m_hCancelEvt = NULL;
m_bReset = false;
m_waitGtAndSpace = false;
pduFlag = false;
cr = 0x0d;
lf = 0x0a;
}
Rs232Module::~Rs232Module()
{
}
void Rs232Module::SetDevice( string port, int baud, int flowCtrl)
{
m_port = port;
m_baud = baud;
m_flowCtrl = flowCtrl;
}
bool Rs232Module::Internal_Start(COMMTYPE &commtype)
{
COMSTAT comstat;
DWORD errors;
commtype = COMMTYPE_COM;
m_hWaitGtAndSpace = NULL;
m_hWaitGtAndSpace = ::CreateEvent(NULL, FALSE, FALSE, NULL);
CString cstr = m_port.c_str();
hCOM = ::CreateFile(cstr,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if( hCOM==INVALID_HANDLE_VALUE )
{
hCOM = NULL;
return false;
}
::ClearCommError(hCOM, &errors, &comstat);
//turn off fAbort first
DCB dcb;
if( GetCommState(hCOM, &dcb)==FALSE )
{
CloseHandle(hCOM);
hCOM = NULL;
return false;
}
dcb.DCBlength = sizeof(DCB);
dcb.Parity = NOPARITY;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.BaudRate = m_baud;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
if(m_flowCtrl == COMM_FC_HW)
dcb.fOutxCtsFlow = TRUE;
else
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = FALSE;
if(m_flowCtrl == COMM_FC_SW)
{
dcb.fOutX = TRUE;
dcb.fInX = TRUE;
}
else
{
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
}
if(m_flowCtrl == COMM_FC_SW
|| m_flowCtrl == COMM_FC_NONE)
dcb.fRtsControl = RTS_CONTROL_ENABLE;
else if(m_flowCtrl == COMM_FC_HW)
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
if(m_flowCtrl == COMM_FC_SW)
{
dcb.XonChar = 0x11;
dcb.XoffChar = 0x13;
}
else
{
dcb.XonChar = 0;
dcb.XoffChar = 0;
}
dcb.ErrorChar = 0;
dcb.EofChar = 0;
dcb.EvtChar = 0;
::ClearCommError(hCOM, &errors, &comstat);
if( SetCommState(hCOM, &dcb)==FALSE )
{
CloseHandle(hCOM);
hCOM = NULL;
return false;
}
if( ::SetupComm(hCOM, 8192, 8192)==FALSE )
{
CloseHandle(hCOM);
hCOM = NULL;
return false;
}
if( ::PurgeComm(hCOM, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR)==FALSE )
{
CloseHandle(hCOM);
hCOM = NULL;
return false;
}
// Communications Properties
COMMPROP cp;
if(GetCommProperties(hCOM, &cp) == FALSE)
{
CloseHandle(hCOM);
hCOM = NULL;
return false;
}
if(cp.dwProvSubType == PST_MODEM && cp.dwProvCapabilities == 0xcd)
commtype = COMMTYPE_USB;
else if(cp.dwProvSubType == PST_RS232 && cp.dwProvCapabilities == 0xc7)
commtype = COMMTYPE_IRDA;
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0xFFFFFFFF;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 2000;
if( ::SetCommTimeouts(hCOM, &timeouts) == FALSE )
{
CloseHandle(hCOM);
hCOM = NULL;
return false;
}
stopEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if( stopEvent == NULL )
{
CloseHandle(hCOM);
hCOM = NULL;
return false;
}
m_hResetEvt = ::CreateEvent(NULL, true, false, NULL);
if( m_hResetEvt == NULL)
{
CloseHandle(hCOM);
hCOM = NULL;
CloseHandle(stopEvent);
stopEvent = NULL;
return false;
}
m_hWriteEvt = ::CreateEvent(NULL, true, false, NULL);
if( m_hWriteEvt == NULL)
{
CloseHandle(hCOM);
hCOM = NULL;
CloseHandle(stopEvent);
stopEvent = NULL;
CloseHandle(m_hResetEvt);
m_hResetEvt = NULL;
return false;
}
m_hParserEvt = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if( m_hParserEvt == NULL)
{
CloseHandle(hCOM);
hCOM = NULL;
CloseHandle(stopEvent);
stopEvent = NULL;
CloseHandle(m_hResetEvt);
m_hResetEvt = NULL;
CloseHandle(m_hWriteEvt);
m_hWriteEvt = NULL;
return false;
}
m_hInProgressEvt = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if( m_hInProgressEvt == NULL)
{
CloseHandle(hCOM);
hCOM = NULL;
CloseHandle(stopEvent);
stopEvent = NULL;
CloseHandle(m_hResetEvt);
m_hResetEvt = NULL;
CloseHandle(m_hWriteEvt);
m_hWriteEvt = NULL;
CloseHandle(m_hParserEvt);
m_hParserEvt = NULL;
return false;
}
m_hCleanedEvt = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if( m_hCleanedEvt == NULL)
{
CloseHandle(hCOM);
hCOM = NULL;
CloseHandle(stopEvent);
stopEvent = NULL;
CloseHandle(m_hResetEvt);
m_hResetEvt = NULL;
CloseHandle(m_hWriteEvt);
m_hWriteEvt = NULL;
CloseHandle(m_hParserEvt);
m_hParserEvt = NULL;
CloseHandle(m_hInProgressEvt);
m_hParserEvt = NULL;
return false;
}
m_hCancelEvt = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if( m_hCancelEvt == NULL)
{
CloseHandle(hCOM);
hCOM = NULL;
CloseHandle(stopEvent);
stopEvent = NULL;
CloseHandle(m_hResetEvt);
m_hResetEvt = NULL;
CloseHandle(m_hWriteEvt);
m_hWriteEvt = NULL;
CloseHandle(m_hParserEvt);
m_hParserEvt = NULL;
CloseHandle(m_hInProgressEvt);
m_hParserEvt = NULL;
CloseHandle(m_hCleanedEvt);
m_hCleanedEvt = NULL;
return false;
}
if( StartThread()==false )
{
CloseHandle(hCOM);
hCOM = NULL;
CloseHandle(stopEvent);
stopEvent = NULL;
CloseHandle( m_hResetEvt);
m_hResetEvt = NULL;
CloseHandle(m_hWriteEvt);
m_hWriteEvt = NULL;
CloseHandle(m_hParserEvt);
m_hParserEvt = NULL;
CloseHandle(m_hInProgressEvt);
m_hParserEvt = NULL;
return false;
}
return true;
}
void Rs232Module::Internal_Stop()
{
StopThread();
if( hCOM!=NULL )
{
CloseHandle(hCOM);
hCOM = NULL;
}
if( stopEvent!=NULL )
{
CloseHandle(stopEvent);
stopEvent = NULL;
}
if( m_hResetEvt != NULL)
{
::CloseHandle(m_hResetEvt);
m_hResetEvt = NULL;
}
if( m_hWaitGtAndSpace != NULL)
{
::CloseHandle(m_hWaitGtAndSpace);
m_hWaitGtAndSpace = NULL;
}
if( m_hParserEvt != NULL)
{
::CloseHandle(m_hParserEvt);
m_hParserEvt = NULL;
}
if( m_hWriteEvt != NULL)
{
::CloseHandle(m_hWriteEvt);
m_hWriteEvt = NULL;
}
if(m_hInProgressEvt != NULL)
{
::CloseHandle(m_hInProgressEvt);
m_hInProgressEvt = NULL;
}
if( m_hCleanedEvt != NULL)
{
::CloseHandle(m_hCleanedEvt);
m_hCleanedEvt = NULL;
}
if( m_hCancelEvt != NULL)
{
::CloseHandle(m_hCancelEvt);
m_hCancelEvt = NULL;
}
}
void Rs232Module::StopThread()
{
if( GetHandle()==NULL )
{
return;
}
::SetEvent(stopEvent);
WaitForExit();
}
void Rs232Module::CleanData()
{
#ifdef SP_LEVEL1
TRACE("Rs232Module::CleanData() ----3\n");
#endif
// Clean data in driver
CleanDriverData();
// Clean Received data
CleanReceivedData();
if(::WaitForSingleObject( m_hCleanedEvt, 3000) == WAIT_TIMEOUT)
{
;// ASSERT(false);
}
::ResetEvent(m_hCleanedEvt);
}
void Rs232Module::CleanReceivedData()
{
#ifdef SP_LEVEL1
TRACE("Rs232Module::CleanReceivedData(): Set Reset Event ---3.3\n");
#endif
// Clean the received data and go
// to the initialized state
m_bReset = true;
::SetEvent( m_hResetEvt);
#ifdef SP_LEVEL1
TRACE("Set the Reset Event -----3.4\n");
#endif
}
void Rs232Module::CleanDriverData()
{
unsigned char buf[512];
COMSTAT comstat;
DWORD errors;
DWORD dwReadLen;
#ifdef SP_LEVEL1
TRACE("Rs232Module::CleanDriverData() ----3.2\n");
#endif
while(1)
{
if( ::WaitForSingleObject(stopEvent, 0)==WAIT_OBJECT_0 )
{
::ClearCommError(hCOM, &errors, &comstat);
#ifdef SP_LEVEL1
TRACE("Rs232Module::CleanDriverData()---3.2.1\n");
#endif
break;
}
::ClearCommError(hCOM, &errors, &comstat);
if( !comstat.cbInQue )
{
break;
}
int dwBytesRead = (DWORD) comstat.cbInQue;
if( 512 <= (int) dwBytesRead )
dwBytesRead = 512;
if( ::ReadFile(hCOM, buf, 512, &dwReadLen, NULL) )
{
#ifdef SP_LEVEL1
TRACE("Rs232Module::CleanDriverData()---3.2.3\n");
#endif
if(dwReadLen!=0)
{
continue;
}
else
{
#ifdef SP_LEVEL1
TRACE("Rs232Module::CleanDriverData()---3.2.4\n");
#endif
#if 0
string tmpStr((const char *)buf, dwReadLen);
tmpStr[dwReadLen] = '\0';
TRACE(">> CleanDriverData(): Cleaned Data %s\n", tmpStr.c_str());
#endif
}
}
else
break;
}
}
DWORD Rs232Module::ThreadFunc()
{
COMSTAT comstat;
DWORD errors;
int getDataState=0;
while(1)
{
if( ::WaitForSingleObject(stopEvent, 0)==WAIT_OBJECT_0 )
{
::ClearCommError(hCOM, &errors, &comstat);
#ifdef SP_LEVEL1
TRACE("Rs232Module::ThreadFunc(): Get Stop Event!!\n");
#endif
break;
}
::ClearCommError(hCOM, &errors, &comstat);
// Reset Event is signaled
if(::WaitForSingleObject(m_hResetEvt, 0) ==WAIT_OBJECT_0)
{
#ifdef SP_LEVEL1
TRACE("Rs232Module::ThreadFunc(): Get Reset Event!! ----3.2\n");
#endif
getDataState = 0;
writeIndex = 0;
m_idxRespCommand = 0;
result.clear();
m_bReset = false;
::ResetEvent( m_hResetEvt);
::ResetEvent( m_hParserEvt);
::SetEvent(m_hCleanedEvt);
#ifdef SP_LEVEL1
TRACE("Exit the Reset Block!! ----3.3\n");
#endif
}
// Cancel Event is signaled
if(::WaitForSingleObject(m_hCancelEvt, 0) == WAIT_OBJECT_0)
{
#ifdef SP_LEVEL1
TRACE("Rs232Module::ThreadFunc(): Get Cancel Event\n");
#endif
CancelSync();
::ResetEvent(m_hCancelEvt);
#ifdef SP_LEVEL1
TRACE("Rs232Module::ThreadFunc(): Exit Cancel Event\n");
#endif
}
if( !comstat.cbInQue )
{
Sleep(1);
continue;
}
int dwBytesRead = (DWORD) comstat.cbInQue;
if( 512 <= (int) dwBytesRead )
dwBytesRead = 512;
if( ::ReadFile(hCOM, rawchars, dwBytesRead, &dwRead, NULL) )
{
if( dwRead==0 )
continue;
m_iRead = dwRead;
DumpData(rawchars, m_iRead);
m_idxReadRawBuffer = 0;
#ifdef SP_DEBUG
if(m_iRead < 500)
{
string sDebug((const char *)rawchars, m_iRead);
sDebug[m_iRead] = '\0';
TRACE("Target: %s\n", sDebug.c_str());
}
#endif
GetOneCrLf(getDataState, &rawchars[0], m_iRead);
}
}
return 0;
}
bool Rs232Module::Write(const char *Buf, const int &size)
{
unsigned long wbytes;
CString strDebug, strTemp;
/*
if( WriteFile(hCOM, Buf, size, &wbytes, NULL)==FALSE )
{
TRACE(_T("***Rs232Module::Write() Fail--case I\n"));
return false;
}
else if( wbytes<size )
{
TRACE(_T("***Rs232Module::Write() Fail--case II, wbytes:%u, size:%d\n"), wbytes, size);
return false;
}
TRACE(_T("***Rs232Module::Write() OK\n"));
*/
int nRetryCount = 0;
int nSentBytes = 0;
while( nSentBytes < size ) {
int wbytes = 0;
int nPerSend = 0;
// reset write bytes
wbytes = 0;
// set send bytes
nPerSend = size - nSentBytes;
// write to com
BOOL bWriteResult = WriteFile(hCOM, ((char *)Buf)+nSentBytes, nPerSend, (unsigned long *)&wbytes, NULL);
// check result
if(!bWriteResult) {
DWORD dret = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dret,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the string.
OutputDebugString((LPCTSTR)lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
strDebug.Format(_T("Rs232Module::Write(): code:%d, Retry(%d): WriteFile()=FALSE, send(%d/%d), total(%d/%d).\n"), dret, nRetryCount, wbytes, nPerSend, nSentBytes, size);
OutputDebugString(strDebug);
DWORD ComError = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -