⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs232module.cpp

📁 MTK平台COM口通讯的源代码。很底层的。可以学习一下。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
*  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 + -