📄 communication.cpp
字号:
//---------------------------------------------------------------------------
// Pixelworks Inc. Company Confidential Strictly Private
//
// $Archive: /SwTools/FlashUpgrader/Communication.cpp $
// $Revision: 1.2 $
// $Author: ckerchner $
// $Date: 2004/11/23 00:31:35 $
//
// --------------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------------
// Copyright 1997 (c) Pixelworks Inc.
//
// Pixelworks owns the sole copyright to this software. Under international
// copyright laws you (1) may not make a copy of this software except for
// the purposes of maintaining a single archive copy, (2) may not derive
// works herefrom, (3) may not distribute this work to others. These rights
// are provided for information clarification, other restrictions of rights
// may apply as well.
//
// This is an unpublished work.
// --------------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>>>>> WARRANTEE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------------
// Pixelworks Inc. MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THE USE OF
// THIS SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE.
// --------------------------------------------------------------------------
#include "stdafx.h"
#include "Communication.h"
// TODO: Enable the following line for maximum debug TRACE message output.
//#define _MAX_DEBUG
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
#define MAX_READ_BUFFER (2048)
#define AMOUNT_TO_READ (512)
#define MAX_WRITE_BUFFER (2048)
#define MAX_WRITE_SIZE (1024)
#define HEAP_WRITEBUFFER_LIMIT (1024)
// We need ReadIntervalTimeout here to cause the read operations that we
// do to actually timeout and become overlapped. Specifying 1 here causes
// ReadFile to return very quickly so that our reader thread will continue
// execution.
static COMMTIMEOUTS TimeoutsDefault = {0x01, 0, 0, 0, 0};
#define STATUS_CHECK_TIMEOUT 500
#define WRITE_CHECK_TIMEOUT 500
#define EVENTFLAGS_DEFAULT EV_TXEMPTY | EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD
#define PURGE_FLAGS PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR
#define DEFAULT_BAUD_RATE 57600
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
CCommunication::CCommunication()
{
m_eComm = ccNONE;
#ifdef BUILD_USB_CONFIG
m_pUsb = NULL;
#endif
m_hPortHandle = INVALID_HANDLE_VALUE;
m_bOriginalTimeoutsValid = FALSE;
ZeroMemory(&m_OriginalTimeouts, sizeof(COMMTIMEOUTS));
m_dwModemStatus = 0;
ZeroMemory(&m_ComStatus, sizeof(COMSTAT));
m_dwComError = 0;
m_dwEventFlags = EVENTFLAGS_DEFAULT;
m_hKillEvent = NULL;
m_hWriteDataEvent = NULL;
m_hReaderThread = NULL;
m_hWriterThread = NULL;
m_hParentWnd = 0;
m_dwMainThreadId = 0;
m_bPostedDataToReadMessage = FALSE;
m_bConnected = FALSE;
m_nBaudRate = DEFAULT_BAUD_RATE;
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
CCommunication::~CCommunication()
{
Disconnect();
if (m_hKillEvent)
{
SetEvent(m_hKillEvent);
if (m_hWriterThread)
{
ResumeThread(m_hWriterThread);
WaitForSingleObject(m_hWriterThread, INFINITE);
CloseHandle(m_hWriterThread);
}
if (m_hReaderThread)
{
ResumeThread(m_hReaderThread);
WaitForSingleObject(m_hReaderThread, INFINITE);
CloseHandle(m_hReaderThread);
}
CloseHandle(m_hKillEvent);
}
if (m_hWriteDataEvent)
{
CloseHandle(m_hWriteDataEvent);
}
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
BOOL CCommunication::Initialize(HWND hWnd)
{
m_hParentWnd = hWnd;
m_dwMainThreadId = ::GetCurrentThreadId();
#ifdef BUILD_USB_CONFIG
if (m_eComm == ccUSB)
{
return m_pUsb->Initialize(10);
}
else // Serial
#endif
{
m_hWriteDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hKillEvent = ::CreateEvent(NULL, // security attribute
TRUE, // TRUE= manual reset
FALSE, // FALSE= not signaled
NULL); // event name (string)
m_hWriteBufferEmptyEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
if (0 == m_hWriteDataEvent || 0 == m_hKillEvent)
{
TRACE("CreateEvent failed\n");
return FALSE;
}
DWORD dwThreadId = 0;
m_hReaderThread = ::CreateThread(
NULL, // pointer to thread security attributes
0, // initial thread stack size, in bytes
ReaderThreadProc, // pointer to thread function
this, // argument for new thread
0, // creation flags
&dwThreadId);
m_hWriterThread = ::CreateThread(
NULL, // pointer to thread security attributes
0, // initial thread stack size, in bytes
WriterThreadProc, // pointer to thread function
this, // argument for new thread
0, // creation flags
&dwThreadId);
if (0 == m_hReaderThread || 0 == m_hWriterThread)
{
TRACE("CreateThread failed\n");
return FALSE;
}
}
return TRUE;
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
BOOL CCommunication::SetCommPort(int nPort)
{
if (GetPortOpen())
{
TRACE("Already open to port %d\n", m_nPort);
return FALSE;
}
m_nPort = nPort;
return TRUE;
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
BOOL CCommunication::GetPortOpen()
{
return (INVALID_HANDLE_VALUE != m_hPortHandle);
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
BOOL CCommunication::SetPortOpen(BOOL bStatus)
{
if (bStatus)
{
// Want to open port
if (GetPortOpen())
{
TRACE("Already open to port %d\n", m_nPort);
return FALSE;
}
if (0 == m_nPort)
{
TRACE("Port not set\n");
return FALSE;
}
return Connect();
}
else
{
// Want to close port
return Disconnect();
}
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
BOOL CCommunication::SetBaudRate(int nBaudRate)
{
if (m_eComm == ccUSB)
{
// Don't need to do anything...
}
else // Serial
{
m_nBaudRate = nBaudRate;
if (m_hPortHandle)
{
return UpdateCommState(nBaudRate);
}
}
return TRUE;
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
BOOL CCommunication::Connect()
{
if (m_eComm == ccUSB)
{
// Dont do anything for USB
}
else
{
if (INVALID_HANDLE_VALUE != m_hPortHandle)
{
TRACE("Port already open\n");
return FALSE;
}
// Empty arrays from any previous connections
m_ReaderByteArray.RemoveAll();
m_WriterByteArray.RemoveAll();
ASSERT(m_nPort);
CString cstrPort;
//if (m_nPort > 9)
//{
cstrPort.Format("\\\\.\\COM%d", m_nPort);
//}
//else
//{
// cstrPort.Format("COM%d", m_nPort);
//}
// open communication port handle
m_hPortHandle = CreateFile((LPCSTR)cstrPort,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0);
if (m_hPortHandle == INVALID_HANDLE_VALUE)
{
TRACE("CreateFile failed\n");
return FALSE;
}
if (FALSE == GetCommTimeouts(m_hPortHandle, &m_OriginalTimeouts))
{
TRACE("GetCommTimeouts failed\n");
return FALSE;
}
m_bOriginalTimeoutsValid = TRUE;
// Set port state
if (FALSE == UpdateCommState(m_nBaudRate))
{
TRACE("<CCommunication::Connect> UpdateCommState failed\n");
return FALSE;
}
// Set comm buffer sizes
if (FALSE == SetupComm(m_hPortHandle, MAX_READ_BUFFER, MAX_WRITE_BUFFER))
{
TRACE("SetupComm failed\n");
return FALSE;
}
// raise DTR
/*
if (FALSE == EscapeCommFunction(m_hPortHandle, SETDTR))
{
TRACE("EscapeCommFunction failed\n");
return FALSE;
}
*/
m_bConnected = TRUE;
ResumeThread(m_hReaderThread);
ResumeThread(m_hWriterThread);
}
return TRUE;
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
BOOL CCommunication::Disconnect()
{
BOOL bStatus = TRUE;
if (m_eComm == ccUSB)
{
// Don't need to do anything for USB
}
else
{
if (INVALID_HANDLE_VALUE == m_hPortHandle)
{
return TRUE;
}
m_bConnected = FALSE; // this will suspend the read and writer threads
// lower DTR
/*
if (FALSE == EscapeCommFunction(m_hPortHandle, CLRDTR))
{
TRACE("EscapeCommFunction failed\n");
bStatus = FALSE;
}
*/
// restore original comm timeouts
if (m_bOriginalTimeoutsValid)
{
if (FALSE == SetCommTimeouts(m_hPortHandle, &m_OriginalTimeouts))
{
TRACE("<CCommunication::Disconnect> SetCommTimeouts failed\n");
bStatus = FALSE;
}
m_bOriginalTimeoutsValid = FALSE;
}
// Purge reads/writes, input buffer and output buffer
if (FALSE == PurgeComm(m_hPortHandle, PURGE_FLAGS))
{
TRACE("PurgeComm failed\n");
bStatus = FALSE;
}
HANDLE hPort = m_hPortHandle;
TRACE("<CCommunication::Disconnect> \n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -