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

📄 commain.cpp

📁 DVD
💻 CPP
字号:
// **********************************************************************
//  This file is a part of MaBreakers
//  MTK RS232 Communication package
// **********************************************************************
//
//  Copyright (C) 2006 MaBreaker
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
//  02110-1301, USA.
//
// **********************************************************************

//#include <vcl.h>
//#include <stdio.h>

#include "ComMain.h"

// **********************************************************************
TCom *ComPort;
// **********************************************************************

TCom::TCom(void)
{
    bSerialStart = false;
    ErrorPrint = false;

    Error = COM_ID_SUCCESS;

    // NULL Com handle
    hComm = NULL;
    Send = NULL;
    Read = NULL;

    // Retry and Delay
    bDelay = COM_DELAY;
    bRetry = 3;

    // Set COM Port defaults
    strcpy(sPort,  COM_PORT);
    ulParamBaud  = COM_BAUD;
    cParamParity = COM_PARITY;
    bParamData   = COM_DATA;
    bParamStop   = COM_STOP;
    bParamDelay  = bDelay;

    // Communication
    ctmoNew.ReadIntervalTimeout = READ_INTERVAL;
    ctmoNew.ReadTotalTimeoutMultiplier = READ_MULTIPLIER;
    ctmoNew.ReadTotalTimeoutConstant = bDelay;
    ctmoNew.WriteTotalTimeoutMultiplier = WRITE_MULTIPLIER;
    ctmoNew.WriteTotalTimeoutConstant = bDelay;
}
//---------------------------------------------------------------------------

TCom::~TCom(void)
{
    if(ComPort != NULL)
    {
        // PURGE COM ACTIONS
        PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

        // Should be deleted automatically with ComPort
        if(Read != NULL)
        {
            // Terminate the THRead
            //delete Read;
            delete Read;
            Read = NULL;
        }

        // Should be deleted automatically with ComPort
        if(Send != NULL)
        {
            //delete Send;
            delete Send;
            Send = NULL;
        }

        // Close the COM Port
        if(hComm != NULL)
        {
            CloseHandle(hComm);
            hComm = NULL;
        }
    }
}

//---------------------------------------------------------------------------
/*
void TCom::Create(void)
{
    if(ComPort == NULL)
       ComPort = new TCom();
}*/
//---------------------------------------------------------------------------
/*
void TCom::Destroy(void)
{
    if(ComPort != NULL)
    {
        // PURGE COM ACTIONS
        PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

        // Should be deleted automatically with ComPort
        if(Read != NULL)
        {
            // Terminate the THRead
            //delete Read;
            delete Read;
            Read = NULL;
        }

        // Should be deleted automatically with ComPort
        if(Send != NULL)
        {
            //delete Send;
            delete Send;
            Send = NULL;
        }

        // Close the COM Port
        if(hComm != NULL)
        {
            CloseHandle(hComm);
            hComm = NULL;
        }

        delete ComPort;
        ComPort = NULL;
    }
}*/
//---------------------------------------------------------------------------

int TCom::SerialStart(uchar bMode)
{
    DCB dcbCommPort;

    try
    {
        // Create new Send object
        //if(ComPort == NULL) Create();

        // Return if Port is already opened
        if(bSerialStart)
        {
            if(hComm != INVALID_HANDLE_VALUE)
            {
                //throw COM_ID_OPEN_ALRDY;
                return COM_ID_SUCCESS;
            }
        }

        // OPEN THE COMM PORT.
        // REPLACE "COM2" WITH A STRING OR "COM1", "COM3", ETC. TO OPEN
        // ANOTHER PORT.

        hComm = CreateFile(sPort,
            GENERIC_READ | GENERIC_WRITE,
            0,               /* comm devices must be opened w/exclusive-access */
            NULL,            /* no security attrs */
            OPEN_EXISTING,   /* comm devices must use OPEN_EXISTING */
            0,               /* not overlapped I/O */
            NULL);           /* hTemplate must be NULL for comm devices */

        // IF THE PORT CANNOT BE OPENED, FAIL OUT.
        if(hComm == INVALID_HANDLE_VALUE)
            throw COM_ID_OPEN_ERROR;

        // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
        // THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST.
        // IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER
        // THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING.
        // ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING.

        dcbCommPort.DCBlength = sizeof(DCB);

        // GET COM STATE
        if(!GetCommState(hComm, &dcbCommPort))
            throw COM_ID_GETSTATE_ERROR;

        dcbCommPort.XonLim  = XON_LIMIT;
        dcbCommPort.XoffLim = XOFF_LIMIT;

        dcbCommPort.BaudRate = ulParamBaud;     // set the baud rate
        dcbCommPort.ByteSize = bParamData;      // data size, xmit, and rcv
        dcbCommPort.Parity   = cParamParity;    // no parity bit
        dcbCommPort.StopBits = bParamStop;      // one stop bit
        dcbCommPort.fBinary  = true;

        // SET NEW COM STATE
        if(!SetCommState(hComm, &dcbCommPort))
            throw COM_ID_SETSTATE_ERROR;

        // PURGE COM ACTIONS
        if(!PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR))
            throw COM_ID_PURGE_ERROR;

        // SET QUEUE SIZE
        if(!SetupComm(hComm, READ_BUFFER, WRITE_BUFFER))
            throw COM_ID_SETUP_ERROR;

        // SET THE COMM TIMEOUTS
        if(!GetCommTimeouts(hComm,&ctmoOld))
            throw COM_ID_GETTIMEOUT_ERROR;

        // Should be already set during create
        //ctmoNew.ReadIntervalTimeout         = READ_INTERVAL;
        //ctmoNew.ReadTotalTimeoutMultiplier  = READ_MULTIPLIER;
        //ctmoNew.WriteTotalTimeoutMultiplier = WRITE_MULTIPLIER;
        ctmoNew.ReadTotalTimeoutConstant    = bDelay; // READ_CONSTANT;
        ctmoNew.WriteTotalTimeoutConstant   = bDelay; // WRITE_CONSTANT;

        // SET COM TIMEOUTS
        if(!SetCommTimeouts(hComm, &ctmoNew))
            throw COM_ID_SETTIMEOUT_ERROR;

        // Create read / write handles
        if(Send == NULL)
           Send = new TComSend();
        if(Read == NULL)
           Read = new TComRead();

        // Set error byte
        Error = COM_ID_SUCCESS;

        // Set started bit
        bSerialStart = true;
    }

    catch(int iType)
    {
        return PortMessage(iType);
    }

    catch(...)
    {
        return COM_ID_ERROR;
    }

    return COM_ID_SUCCESS;
}
//---------------------------------------------------------------------------

int TCom::SerialStop(void)
{
    try
    {
        // Return if Port is already closed
        if(!bSerialStart)
        {
            if(hComm == INVALID_HANDLE_VALUE)
            {
                //throw COM_ID_CLOSE_ALRDY;
                return COM_ID_SUCCESS;
            }
        }

        // For some reason LogProcess will hang whole program
        // If it is suspended

        // Stop log read process
        //Read->SetMode(MODE_END);

        // Should be deleted automatically with ComPort
        if(Read != NULL)
        {
            // Terminate the THRead
            delete Read;
            Read = NULL;
        }

        // Should be deleted automatically with ComPort
        if(Send != NULL)
        {
            delete Send;
            Send = NULL;
        }
        
        if(hComm)
        {
            // Purge internal COM buffer
            PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

            // Restore previous settings
            SetCommTimeouts(hComm, &ctmoOld);
    
            // Close COM port
            CloseHandle(hComm);
        }

        hComm = NULL;
    
        // Clear started bit
        bSerialStart = false;
    }
    catch(int iType)
    {
        return PortMessage(iType);
    }
    catch(...)
    {
		return COM_ID_ERROR;
    }

	return COM_ID_SUCCESS;
}
//---------------------------------------------------------------------------

int TCom::SerialReset(void)
{
    uchar bRet;

    // Backup current mode
    uchar dModeBack = Read->bMode;

    // Terminate the Threads
    delete Read;
    Read = NULL;
    delete Send;
    Send = NULL;

    if(hComm)
    {
        // Close the COM port
        CloseHandle(hComm);
    }

    hComm = NULL;

    bSerialStart = false;

    // Start new Thread in previous mode 
    bRet = SerialStart(dModeBack);

	if(bRet == COM_ID_SUCCESS)
    {
        Read->SetMode(dModeBack);        
    }
       
    return PortMessage(bRet);
}
//---------------------------------------------------------------------------

bool TCom::SerialPurge(void)
{
    bool Ret;

    // Purge COM actions
    Ret = PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

	return Ret;
}

//---------------------------------------------------------------------------

int TCom::PortMessage(int iMsg)
{
    if(iMsg == COM_ID_SUCCESS)
        return COM_ID_SUCCESS;

    // Error
    Error = iMsg;

    // Skip printing
    if(ErrorPrint == false)
        return COM_ID_ERROR;

	switch(iMsg)
	{
		case COM_ID_ERROR :
			Print->Error("Unknown COM port error", 1000 + GetLastError());
			break;

		case COM_ID_OPEN_ERROR :
			Print->Error("Can't open COM port", 1000 + GetLastError());
			break;

		case COM_ID_CLOSE_ERROR :
			Print->Error("Can't close COM port", 1000 + GetLastError());
			break;

		case COM_ID_READ_ERROR :
			Print->Error("No answer from COM port", 1000 + GetLastError());
			break;

        case COM_ID_WRITE_ERROR :
            Print->Error("Can't write to COM port", 1000 + GetLastError());
            break;

        case COM_ID_SETUP_ERROR :
            Print->Error("Can't setup COM port", 1000 + GetLastError());
            break;

        case COM_ID_PURGE_ERROR :
            Print->Error("Can't purge COM port", 1000 + GetLastError());
            break;

		case COM_ID_GETSTATE_ERROR :
			Print->Error("Can't get COM port state", 1000 + GetLastError());
			break;

		case COM_ID_SETSTATE_ERROR :
			Print->Error("Can't set given COM port values", 1000 + GetLastError());
			break;

		case COM_ID_GETTIMEOUT_ERROR :
			Print->Error("Can't get COM port timeout", 1000 + GetLastError());
			break;

		case COM_ID_SETTIMEOUT_ERROR :
			Print->Error("Can't set COM port timeout", 1000 + GetLastError());
			break;

		case COM_ID_OPEN_ALRDY:
			Print->Warning("Port is already opened");
			break;

		case COM_ID_CLOSE_ALRDY:
			Print->Warning("Port is already closed");
			break;

		case COM_ID_START_ALRDY:
			Print->Warning("Process is already started");
			break;

		case COM_ID_STOP_ALRDY:
			Print->Warning("Process is already stopped");
			break;

		case COM_ID_ZERO_LENGTH:
			Print->Warning("Zero length read/write");
			break;

		default:
			Print->Error("Unknown COM port error", 1000 + GetLastError());
			break;
	}

	return COM_ID_ERROR;
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -