Ejemplo n.º 1
0
BOOL ConnPort::ClosePort()
{
	g_iExitFlag=1;
	while(1)
	{
		static int iTimeoutCount=0;
		Sleep(10);	
		if(40==iTimeoutCount)
		{
			TerminateThread(m_hThreadRead,0);
			TerminateThread(m_hThreadWrite,0);
			TerminateThread(m_hDataParse,0);
			break;
		}
		else if(1==g_rExitFlag && 1==g_wExitFlag && 1==g_pExitFlag)
		{
			break;
		}
		else
		{
			iTimeoutCount++;
		}
	}
    EscapeCommFunction(m_hPort,CLRRTS);
    EscapeCommFunction(m_hPort,CLRDTR);

    SetCommMask(m_hPort,0);
	
	if(NULL==m_hPort)return FALSE;
	if(NULL==m_hThreadRead)return FALSE;
	if(NULL==m_hThreadWrite)return FALSE;
	if(NULL==m_hDataParse)return FALSE;
	
    if(!CloseHandle(m_hPort))return FALSE;
    if(!CloseHandle(m_hThreadRead))return FALSE;
    if(!CloseHandle(m_hThreadWrite))return FALSE;
	if(!CloseHandle(m_hDataParse))return FALSE;

	m_bIsConnect=FALSE;
    return TRUE;
}
Ejemplo n.º 2
0
// 关闭串口
_XBool _XSerialPort::close()
{
	if(!m_bOpened || m_hIDComDev == NULL) return XTrue;
	if(m_overlappedRead.hEvent != NULL) CloseHandle(m_overlappedRead.hEvent);
	if(m_overlappedWrite.hEvent != NULL) CloseHandle(m_overlappedWrite.hEvent);
	if(m_mode == SP_MODE_AUTO) //自动模式的时候开启线程
	{
		m_threadState = STATE_SET_TO_END;
		SetCommMask(m_hIDComDev,0);
		while(1)
		{//等待线程结束
			if(m_threadState == STATE_END) break;
			Sleep(1);
		}
	}
	CloseHandle(m_hIDComDev);
	m_bOpened = XFalse;
	m_hIDComDev = NULL;

	return XTrue;
}
Ejemplo n.º 3
0
void ConnPort::ResetComStatues()
{
	m_rCount=0;
	m_wCount=0;
	m_bHexShow=FALSE;

	TerminateThread(m_hThreadRead,0);
	TerminateThread(m_hThreadWrite,0);
	TerminateThread(m_hDataParse,0);

	EscapeCommFunction(m_hPort,CLRRTS);
    EscapeCommFunction(m_hPort,CLRDTR);
    SetCommMask(m_hPort,0);
	
    CloseHandle(m_hPort);
    CloseHandle(m_hThreadRead);
    CloseHandle(m_hThreadWrite);
	CloseHandle(m_hDataParse);

	m_bIsConnect=FALSE;
}
Ejemplo n.º 4
0
/*******************************************************************************
** Author:    Bill Theisen
** Purpose:   Closes the serial port by setting flag to stop ReadThread and signaling
**            the EXIT_EVENT to cause WaitCommEvent to stop pending.  Then waits for
**            ReadThread to exit.
** Comments:  
*******************************************************************************/
void DOIrisSerialPort::ClosePort( void )
{
    if( m_bReadThreadIsRunning ){
    
        // Set flag for exit and signal exit event so 
        // that WaitCommEvent() stops pending 
        m_bStopReadThread = TRUE;
        SetCommMask(m_hPort, EXIT_EVENT);
        
        
        while( m_bReadThreadIsRunning ) {
            Sleep(200);
        }
    }
    
    //m_critSecWritePort.Lock();
    if(m_hPort != INVALID_HANDLE_VALUE)
			   CloseHandle( m_hPort );
    m_hPort = INVALID_HANDLE_VALUE;
    //m_critSecWritePort.Unlock();
}
Ejemplo n.º 5
0
// Habilitacion y programacion del puerto serie
int CComm32::OpenComm()
{
	if (m_OnOpen) return ERROR_ALREADY_INITIALIZED;
	
	m_HPort=CreateFile(m_Name,GENERIC_READ+GENERIC_WRITE,
		0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);

	if (m_HPort==INVALID_HANDLE_VALUE)
		return GetLastError();
	
	m_OnOpen=true;

	if (GetFileType(m_HPort)!=FILE_TYPE_CHAR)
	{
		CloseHandle(m_HPort);
		return ERROR_OPEN_FAILED;
	}

	m_Read_Overlapped.hEvent=CreateEvent(NULL,true,true,NULL);
	if (m_Read_Overlapped.hEvent==0)
	{
		CloseAll();
		return GetLastError();
	}

	m_Write_Overlapped.hEvent=CreateEvent(NULL,true,true,NULL);
	if (m_Write_Overlapped.hEvent==0)
	{
		CloseAll();
		return GetLastError();
	}
	GetCommProperties(m_HPort,&m_CommProp);
	SetCommMask(m_HPort,m_EvtMask);
	SetCommTimeouts(m_HPort,&m_CommTimeOuts);
	GetCommModemStatus(m_HPort,&m_ModemStat);
	DWORD size=sizeof(COMMCONFIG);
	GetCommConfig(m_HPort,&m_CommConfig,&size);
	return 0;

}
Ejemplo n.º 6
0
BOOL CSerialPort::Open(LPCTSTR PortName, DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits, DWORD DesiredAccess)
  {
    Close();
    m_PortHandle = CreateFile(PortName, DesiredAccess, 0, NULL, OPEN_EXISTING, 0, 0);
    if (m_PortHandle != INVALID_HANDLE_VALUE)
      {
        DCB dcb;
        CString s;
        dcb.DCBlength = sizeof(dcb);
        GetCommState(m_PortHandle, &dcb);
        dcb.BaudRate = BaudRate;
        dcb.ByteSize = ByteSize;
        dcb.StopBits = StopBits;
        dcb.Parity = Parity;
        dcb.fDsrSensitivity = 0;
        dcb.fOutxCtsFlow = 0;
        dcb.fOutxDsrFlow = 0;
        dcb.fInX = 0;
        dcb.fOutX = 0;
        dcb.fDtrControl = DTR_CONTROL_DISABLE; //DTR and RTS 0
        dcb.fRtsControl = RTS_CONTROL_DISABLE; 
    
        SetCommState(m_PortHandle, &dcb);
    
        COMMTIMEOUTS touts;
        touts.ReadIntervalTimeout = 0;
        touts.ReadTotalTimeoutMultiplier = 0;
        touts.ReadTotalTimeoutConstant = 10;
        touts.WriteTotalTimeoutConstant = 10;
        touts.WriteTotalTimeoutMultiplier = 0;
        SetCommTimeouts(m_PortHandle, &touts);
        SetCommMask (m_PortHandle, EV_CTS | EV_DSR | EV_RING | EV_RLSD);
        PurgeComm(m_PortHandle, PURGE_TXCLEAR | PURGE_RXCLEAR);
        return TRUE;
      }
    else
      {
		return FALSE; // Use GetLastError() to know the reason
      }
  }
Ejemplo n.º 7
0
void EIO_Set(uv_work_t* req) {
  SetBaton* data = static_cast<SetBaton*>(req->data);

  if (data->rts) {
    EscapeCommFunction((HANDLE)data->fd, SETRTS);
  } else {
    EscapeCommFunction((HANDLE)data->fd, CLRRTS);
  }

  if (data->dtr) {
    EscapeCommFunction((HANDLE)data->fd, SETDTR);
  } else {
    EscapeCommFunction((HANDLE)data->fd, CLRDTR);
  }

  if (data->brk) {
    EscapeCommFunction((HANDLE)data->fd, SETBREAK);
  } else {
    EscapeCommFunction((HANDLE)data->fd, CLRBREAK);
  }

  DWORD bits = 0;

  GetCommMask((HANDLE)data->fd, &bits);

  bits &= ~(EV_CTS | EV_DSR);

  if (data->cts) {
    bits |= EV_CTS;
  }

  if (data->dsr) {
    bits |= EV_DSR;
  }

  if (!SetCommMask((HANDLE)data->fd, bits)) {
    ErrorCodeToString("Setting options on COM port (SetCommMask)", GetLastError(), data->errorString);
    return;
  }
}
Ejemplo n.º 8
0
/*------------------------------------------------------------------------------------------------------------------
-- FUNCTION: Transfer_Packet
--
-- DATE: November 25, 2015
--
-- REVISIONS: (Date and Description)
--
-- DESIGNER: Ruoqi Jia
--
-- PROGRAMMER: Ruoqi Jia
--
-- INTERFACE:  Transfer_Packet(LPVOID packet)
--					-LPVOID packet : the packet to be sent
--
-- RETURNS: 0 upon successful thread finish
--
-- NOTES:
--		Represents the sending state of the wireless protocol design.  This thread is called whenever a user chooses a
--  file to send and presses the Send button.  We confirm the line to make sure the line is available.  If confirm line
--  times out, we bring the protocol back to the Wait state to wait for an ENQ, and re-initialize the read thread.  If
--  confirm line succeeds, we send our packet using SendPacket.  When SendPacket succeeds or times out, we do a check
--  on the priority states of the sender and receiver.  If we don't have priority and the sender has priority, we enter
--  the wait state again to wait for an ENQ, otherwise we will just go directly to the read idle state.  Finally, we
--  reinitialize the read thread and return from this write thread.
----------------------------------------------------------------------------------------------------------------------*/
DWORD WINAPI Transfer_Packet(LPVOID packet)
{
	ResetEvent(Ev_Read_Thread_Finish);
	SetCommMask(hComm, RETURN_COMM_EVENT);
	WaitForSingleObject(hWrite_Lock, 2000);
	char* s = (char*)packet;
	OutputDebugString("Starting confirm line loop\n");
	if (!ConfirmLine()) 
	{
		OutputDebugString("exceeded confirm line max tries\n");

		//WAIT STATE: wait for an enq, for a specified amount of time. If we get one, set
		//the receivedENQinWait boolean flag to skip directly to acknowledging line in read thread
		receivedENQinWait = WaitForEnq();
		ReleaseMutex(hWrite_Lock);
		Initialize_Read();
		SetEvent(Ev_Send_Thread_Finish);
		delete[]s;
		return 0;
	}
	OutputDebugString("Sending packet\n");
	SendPacket(s);

	//Check Priorities
	//only when we want priority and sender doesn't want priority, we go directly to read idle. every other priority combo,
	//we go to wait state
	if ((!weHavePriority && senderHasPriority) || (weHavePriority && senderHasPriority) || (!weHavePriority && !senderHasPriority))
	{
		//WAIT STATE: wait for an enq, for a specified amount of time. If we get one, set
		//the receivedENQinWait boolean flag to skip directly to acknowledging line in read thread
		OutputDebugString("Going to wait state\n");
		receivedENQinWait = WaitForEnq();
	}else 
		SetEvent(Ev_Send_Thread_Finish);
	//going back to wait/idle state
	ReleaseMutex(hWrite_Lock);
	Initialize_Read();
	delete[]s;
	return 0;
}
Ejemplo n.º 9
0
void openXBee(char * device, HANDLE * fd)
{
    DCB  dcb;
	COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 };
	memset(&dcb,NULL,sizeof(dcb));
	dcb.DCBlength       = sizeof(dcb); 
	dcb.BaudRate        = 9600;
	dcb.Parity			= NOPARITY;
    dcb.fParity			= 0;
	dcb.StopBits        = ONESTOPBIT;
    dcb.ByteSize        = 8;
	dcb.fOutxCtsFlow    = 0;
    dcb.fOutxDsrFlow    = 0;
    dcb.fDtrControl     = DTR_CONTROL_DISABLE;
    dcb.fDsrSensitivity = 0;
    dcb.fRtsControl     = RTS_CONTROL_DISABLE;
    dcb.fOutX           = 0;
    dcb.fInX            = 0;
	dcb.fErrorChar      = 0;
    dcb.fBinary         = 1;
    dcb.fNull           = 0;
    dcb.fAbortOnError   = 0;
    dcb.wReserved       = 0;
    dcb.XonLim          = 2;
    dcb.XoffLim         = 4;
    dcb.XonChar         = 0x13;
    dcb.XoffChar        = 0x19;
    dcb.EvtChar         = 0;
	*fd = CreateFile(device, GENERIC_READ | GENERIC_WRITE,
                               0, NULL, OPEN_EXISTING,NULL,NULL);
	if (fd   == INVALID_HANDLE_VALUE)
	{
		printf("OPENCOMM Failed\n");
		COMMERR(-1, "CreateFile");
	}
	COMMERR((!SetCommMask(*fd, 0)?-1:0), "SetCommMask");
	COMMERR((!SetCommTimeouts(*fd,&cto)?-1:0), "SetCommTimeouts"); //Met en bloquant pour le passage en mode API
	COMMERR((!SetCommState(*fd,&dcb)?-1:0), "SetCommState");;
}
Ejemplo n.º 10
0
int NcrComPort::ReadByte()
{
    DCB dcb;
    int retVal;
    BYTE Byte;
    DWORD dwBytesTransferred;
    DWORD dwCommModemStatus;

    HANDLE hPort = CreateFileA(
        this->Port,
        GENERIC_READ,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL
    );

    if (!GetCommState(hPort, &dcb))
        return 0x100;

    FillDcb(dcb);

    if (!SetCommState(hPort,&dcb))
        return 0x100;

    SetCommMask (hPort, EV_RXCHAR | EV_ERR); //receive character event
    WaitCommEvent (hPort, &dwCommModemStatus, 0); //wait for character

    if (dwCommModemStatus & EV_RXCHAR) {
        ReadFile (hPort, &Byte, 1, &dwBytesTransferred, 0); //read 1
        retVal = Byte;
    } else if (dwCommModemStatus & EV_ERR)
        retVal = 0x101;

    CloseHandle(hPort);
    return retVal;

}
Ejemplo n.º 11
0
/*DWORD ReadThread(HWND hwnd)
*Purpose: Reads characters coming in from the port and calls
*the PaintRead function to print them.
*Arg 1 - Handle to the window procedure.
*/
DWORD ReadThread(HWND hwnd) {
	char message2[] = {0x01, 0x09, 0x00, 0x03, 0x01, 0x41, 0x0A, 0x41, 0xBE};
	char *inbuff = "";
	DWORD nBytesRead, dwEvent;
	COMSTAT comstat;
	COMMTIMEOUTS timeOuts;
	OVERLAPPED osRead = {0};
	osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	//Set the total timeout interval
	memset(&timeOuts, 0, sizeof(timeOuts));
	timeOuts.ReadTotalTimeoutMultiplier = 5;
	timeOuts.ReadTotalTimeoutConstant = 50;
	SetCommTimeouts(hComm, &timeOuts);

	SetCommMask(hComm, EV_RXCHAR);
	
	//Initialize packet
	packet.found = 0;
	packet.total = -1;
	packet.lrc = 0;
	while(mode == CONNECT) {
		if(WaitCommEvent(hComm, &dwEvent, NULL)) {
			ClearCommError(hComm, NULL, &comstat);
			if((dwEvent & EV_RXCHAR) && comstat.cbInQue) {
				if(!ReadFile(hComm, &inbuff, comstat.cbInQue, &nBytesRead, &osRead)) {
					break;
				}
				else {
					if(nBytesRead)
						PaintRead(hwnd, inbuff, nBytesRead);
				}
			}
		}
		ResetEvent(osRead.hEvent);
	}
	PurgeComm(hComm, PURGE_RXCLEAR);
	return 0L;
}
Ejemplo n.º 12
0
// Thread that continuously checks for characters comming in on the serial port.
DWORD WINAPI commReadThread() {
	char *charBuff;		// holds character found on serial port.
	DWORD evtMask;
	COMSTAT comstat;				// stores serial status information
	DWORD numBytesRead;
	COMMTIMEOUTS timeOuts;
	int i, read;

	gOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);	// create overlap event to prevent simultanious access to serial port

	// Timeouts in milliseconds
	memset(&timeOuts, 0, sizeof(timeOuts));
	timeOuts.ReadIntervalTimeout = 0;
	timeOuts.ReadTotalTimeoutMultiplier = 5;
	timeOuts.ReadTotalTimeoutConstant = 50;
	SetCommTimeouts(TTYInfo.hCommPort, &timeOuts);

	SetCommMask(TTYInfo.hCommPort, EV_RXCHAR);
	
	while (TTYInfo.fConnected) {	// only loops while serial port is connected.
		if (WaitCommEvent(TTYInfo.hCommPort, &evtMask, NULL)) {
			charBuff = '\0';					// stores character from serial port

			ClearCommError(TTYInfo.hCommPort, NULL, &comstat);	// get status information from serial port
			charBuff = malloc(comstat.cbInQue);

			if ((evtMask & EV_RXCHAR) && comstat.cbInQue) {	// check if queue is empty
				ReadFile(TTYInfo.hCommPort, charBuff, comstat.cbInQue, &numBytesRead, &gOverlapped);	// read a single character from the serial port
			}

			for (i = 0; i < (int)numBytesRead; i++) {
				if (charBuff[i] > 0) { // don't know why, I just had to
					interpretChar(charBuff[i]);
				}
			}
		}
	}
	return 0;
}
Ejemplo n.º 13
0
int ConnPort::OpenPort(TCHAR *szPort,int iBaudrate,int iParity,int iDataBits,int iStopBits)
{
	 DWORD dwThreadID=0;
	 g_iExitFlag=0;
	 m_hPort=NULL;
	
	 m_hPort=CreateFile(szPort,
						GENERIC_READ|GENERIC_WRITE,
						0,
						NULL,
						OPEN_EXISTING,
						FILE_FLAG_OVERLAPPED,
						NULL);
    if(!m_hPort) 
    {
        m_hPort=NULL;
        wprintf(TEXT("open port failed!!!\r\n"));
        return FALSE;
    }

   //指定端口检测的事件集
   SetCommMask(m_hPort,EV_RXCHAR);
   //设置缓冲区,内部输入、输出缓冲区大小
   SetupComm(m_hPort,1024,1024);
   //刷新缓冲区信息->输入、输出缓冲区
   PurgeComm(m_hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);

   if(!ConfigPort(iBaudrate,iParity,iDataBits,iStopBits)) return FALSE;
   if(!CommTimeouts())return FALSE;

  //创建读写线程
   m_hThreadRead	=	CreateThread(0,0,(LPTHREAD_START_ROUTINE)ReadThreadProc,	(void*)this,0,&dwThreadID);
   m_hThreadWrite	=	CreateThread(0,0,(LPTHREAD_START_ROUTINE)WriteThreadProc,	(void*)this,0,&dwThreadID);
   m_hDataParse		=   CreateThread(0,0,(LPTHREAD_START_ROUTINE)PareDataProc,		(void*)this,0,&dwThreadID);

   m_bIsConnect=TRUE;
   return TRUE;
}
Ejemplo n.º 14
0
//////////////////////////////////////////////////////////////////////
// CloseConnection
// return:   0  always
//
int CAsyncPort::CloseConnection()
{
	// not connected
	m_isConnected = FALSE;

	// disable event notification and wait for thread to halt
	SetCommMask(m_hCommDev, 0);

	// block until thread has been halted
	while (m_dwThreadID != 0) {
		Sleep(10);
	}

	// drop DTR
	EscapeCommFunction(m_hCommDev, CLRDTR);

	// purge any outstanding reads/writes and close device handle
	PurgeComm (
		m_hCommDev,
		PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR
	);

	// close device
	CloseHandle(m_hCommDev);

	// reset instance variables
	m_hCommDev = INVALID_HANDLE_VALUE;
	memset(m_szCommDevName, 0, sizeof (m_szCommDevName));
	memset(& m_commConfig, 0, sizeof (COMMCONFIG));;
	m_commConfig.dwSize = sizeof (COMMCONFIG);
	memset(& m_commProp, 0, sizeof (COMMPROP));
	memset(& m_commTimeOuts, 0, sizeof (COMMTIMEOUTS));
	memset(m_baInBuf, 0, sizeof (m_baInBuf));
	m_nInBufIndex = 0;
	m_nInBufSize = 0;

	return (0);
}
// 포트를 닫는다.
void CCommThread::ClosePort()
{
	//--> 연결되지 않았음.
//	sflag = FALSE;
	m_bConnected = FALSE;

	::SendMessage(hStartWnd, WM_COMM_OPEN, 0, 0);
	//DCB dcb;
	//SetCommState( m_hComm, &dcb);

	//--> 마스크 해제..
	SetCommMask( m_hComm, 0);
	
	Sleep(60);
	//--> 포트 비우기.
	PurgeComm( m_hComm,	PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
	
	//Sleep(60);
	
	CloseHandle(m_hComm);
	//--> 핸들 닫기
	
}
Ejemplo n.º 16
0
void EIO_Set(uv_work_t* req) {
  SetBaton* data = static_cast<SetBaton*>(req->data);

  if (data->rts) {
    EscapeCommFunction((HANDLE)data->fd, SETRTS);
  } else {
    EscapeCommFunction((HANDLE)data->fd, CLRRTS);
  }

  if (data->dtr) {
    EscapeCommFunction((HANDLE)data->fd, SETDTR);
  } else {
    EscapeCommFunction((HANDLE)data->fd, CLRDTR);
  }

  if (data->brk) {
    EscapeCommFunction((HANDLE)data->fd, SETBREAK);
  } else {
    EscapeCommFunction((HANDLE)data->fd, CLRBREAK);
  }

  DWORD bits = 0;

  GetCommMask((HANDLE)data->fd, &bits);

  bits &= ~(EV_CTS | EV_DSR);

  if (data->cts) {
    bits |= EV_CTS;
  }

  if (data->dsr) {
    bits |= EV_DSR;
  }
  // TODO check for error
  data->result = SetCommMask((HANDLE)data->fd, bits);
}
Ejemplo n.º 17
0
bool
SerialWrapper::Init(const CString& port)
{
	DCB				dcb;
	COMMTIMEOUTS	timeout;

	_port = port;
	_hport = CreateFile(
		_port,
		GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		0,
		NULL);
	if (!GetCommState(_hport, &dcb))
		return false;
	dcb.BaudRate = CBR_115200;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	if (!SetCommState(_hport, &dcb))
		return false;
	timeout.ReadIntervalTimeout = MAXDWORD; 
	timeout.ReadTotalTimeoutMultiplier = 0;
	timeout.ReadTotalTimeoutConstant = 0;
	timeout.WriteTotalTimeoutMultiplier = 0;
	timeout.WriteTotalTimeoutConstant = 0;
	if (!SetCommTimeouts(_hport, &timeout))
		return false;

	SetCommMask(_hport, EV_RXCHAR | EV_ERR);
	_readBuffer = new(std::nothrow) BYTE[BUFF_SIZE];
	if (!_readBuffer)
		return false;
	return true;
}
Ejemplo n.º 18
0
CommDevice::CommDevice(char* commName, char HFlags, unsigned long baud, unsigned int ReadSize, char EventChar)
{
    m_Read.m_Size = ReadSize;
    m_Read.m_Buffer = new char[ReadSize];
    memset(m_Read.m_Buffer, 0, m_Read.m_Size);
    // Open the Comm Port
    hComm = CreateFile(commName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    // Check for errors opening
    if (hComm == INVALID_HANDLE_VALUE)
    {
        DWORD errnum = GetLastError();
        cerr << "CreateFile Error: " << errnum << ": Unable to open " << commName << endl;
    }
    // Set up the Configuration
    m_dcb.DCBlength = sizeof(m_dcb);
    if (!GetCommState(hComm, &m_dcb))
	{
	    DWORD errnum = GetLastError();
		cerr << "GetCommState Error " << errnum << ": Unable to extract current state for " << commName << endl;
	}
    m_dcb.BaudRate = baud;
    m_dcb.ByteSize = 8;
    m_dcb.Parity = 0;
    m_dcb.StopBits = ONESTOPBIT;
    m_dcb.fNull = TRUE;
    m_dcb.EvtChar = EventChar;
    m_dcb.fOutxCtsFlow = (HFlags & H_CTS) ? TRUE : FALSE;
    m_dcb.fRtsControl = (HFlags & H_RTS) ? RTS_CONTROL_ENABLE : RTS_CONTROL_DISABLE;
    // Set the Configuration
    if (!SetCommState(hComm, &m_dcb))
    {
        DWORD errnum = GetLastError();
        cerr << "SetCommState Error " << errnum << ": Unable to configure " << commName << endl;// << "Error code: " << itoa(Error) << endl;
    }
    SetCommMask(hComm, EV_RXFLAG | EV_TXEMPTY);
}
Ejemplo n.º 19
0
// unsigned int WINAPI DOIrisSerialPort::ReadThread( LPVOID pArg )
DWORD __stdcall DOIrisSerialPort::ReadThread( LPVOID pArg )
// DWORD __stdcall ReadThread(LPVOID hwnd)
{
    unsigned long fdwCommMask;
     
    unsigned long CharsInBuffer = 0;
    unsigned long NonPacketCharsInBuffer;
    unsigned long packetlength;
 
	char * pEndChar;

    LPSerial pCaller = reinterpret_cast<LPSerial>(pArg);
	//DO_ASSERT( pCaller != NULL );
    pCaller->m_bReadThreadIsRunning = TRUE;
    
		/*
    if ( pCaller->m_msgReceiver )
    {
        pCaller->m_msgReceiver->InitializeThread();
    }
    */
    // Enable logging from this thread via pCaller->m_pRnDLog.
    
	//HRESULT hRes = E_FAIL;
    //pCaller->m_pRnDLog->AddThread( hRes );   
    //DO_ASSERT( SUCCEEDED(hRes) );

	// Setup the input and packet buffers 
    char *cBuffer = new char[pCaller->m_iInBufferLength];
    //DO_ASSERT( cBuffer != NULL );
    char *cPacketBuffer = new char[pCaller->m_iPacketBufferLength];
    //DO_ASSERT( cPacketBuffer != NULL );

    if( !SetCommMask( pCaller->m_hPort, EV_RXCHAR | EXIT_EVENT ) )
	{
        //pCaller->m_pRnDLog->LogRnDEvent( IDS_IRISCOMMON_SETCOMMMASK_FAILED );
    }

    // Main loop of read thread.
    while( !pCaller->m_bStopReadThread )
    {
        if( !WaitCommEvent(pCaller->m_hPort, &fdwCommMask, 0))
        {
            //pCaller->m_pRnDLog->LogRnDEvent( IDS_IRISCOMMON_WAITCOMMEVENT_FAILED, 
            //                                 static_cast<int>(GetLastError()) );
            break;	//	Get out of read thread while loop 
        }
        
        // Reset the comm Mask.
        if( !SetCommMask(pCaller->m_hPort, EV_RXCHAR | EXIT_EVENT)) 
		{
            //pCaller->m_pRnDLog->LogRnDEvent( IDS_IRISCOMMON_SETCOMMMASK_FAILED,
            //                                 static_cast<int>(GetLastError()));
        }
    
        if( fdwCommMask & EV_RXCHAR )
        {
            unsigned long num;
#ifdef _WIN32_WCE
            // Read all bytes received into cBuffer.
			ReadFile(pCaller->m_hPort, &cBuffer[CharsInBuffer], pCaller->m_iInBufferLength-CharsInBuffer, &num, 0);
#else
            ReadFile(pCaller->m_hPort, &cBuffer[CharsInBuffer], pCaller->m_iInBufferLength-CharsInBuffer, &num, &(pCaller->m_overlapped));
#endif // _WIN32_WCE
            CharsInBuffer += num;
            GenRecBytes = GenRecBytes+num;	
            // Check for a packet in the buffer
            while( CharsInBuffer && (pEndChar = FindChr( cBuffer, IRIS_PACKET_END_FLAG, CharsInBuffer )) != NULL )
            {
                packetlength = static_cast<unsigned long>((pEndChar - cBuffer) + 1);  // Includes IRIS_PACKET_END_FLAG char
                
                // Make sure IRIS_PACKET_END_FLAG is in new message area of buffer
                if ( packetlength <= CharsInBuffer && packetlength <= pCaller->m_iPacketBufferLength )
                {
                    // Move packet to buffer and send
                    memcpy( cPacketBuffer, cBuffer, packetlength);	// PC-Lint warning 688 expected
		    		        pCaller->PktCallRelay( cPacketBuffer, packetlength );	
                }

                // Move remaining chars in buffer to beginning of buffer and adjust char counts
                NonPacketCharsInBuffer = CharsInBuffer - packetlength;

                if( NonPacketCharsInBuffer > 0 )
				{
					// PC-Lint warning 688 expected
                    memcpy( cBuffer, &cBuffer[CharsInBuffer-NonPacketCharsInBuffer], NonPacketCharsInBuffer);
                }
                else
                {
                    NonPacketCharsInBuffer = 0;
                }
				CharsInBuffer = NonPacketCharsInBuffer; 
            }

			// Handle the case were the buffer is full but no packet is found
            if( CharsInBuffer >= pCaller->m_iInBufferLength )
            {
                CharsInBuffer = 0;
                //pCaller->m_pRnDLog->LogRnDEvent( IDS_IRISCOMMON_BUFFER_OVERFLOW );
            }
        }
        
        // Clear buffers to prevent problem when exiting thread
        if( fdwCommMask & EXIT_EVENT )
		{
            PurgeComm(pCaller->m_hPort, PURGE_RXCLEAR | PURGE_TXCLEAR | 
                                        PURGE_RXABORT | PURGE_TXABORT );
        }
    }
    

	delete [] cBuffer;
	delete [] cPacketBuffer;

    //pCaller->m_pRnDLog->RemoveThread();
/*
    if ( pCaller->m_msgReceiver )
    {
        pCaller->m_msgReceiver->ShutdownThread();
    }
*/
    pCaller->m_bReadThreadIsRunning = FALSE;


    return 0;
}
// 포트 sPortName을 dwBaud 속도로 연다.
// ThreadWatchComm 함수에서 포트에 무언가 읽혔을 때 MainWnd에 알리기
// 위해 WM_COMM_READ메시지를 보낼때 같이 보낼 wPortID값을 전달 받는다.
BOOL CCommThread::OpenPort(CString strPortName, 
					   DWORD dwBaud, BYTE byData, BYTE byStop, BYTE byParity )
{



	// Local 변수.
	COMMTIMEOUTS	timeouts;
	DCB				dcb;
	DWORD			dwThreadID;

	// overlapped structure 변수 초기화.
	m_osRead.Offset = 0;
	m_osRead.OffsetHigh = 0;
	//--> Read 이벤트 생성에 실패..
	if ( !(m_osRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) ) 	
	{
		return FALSE;
	}


	m_osWrite.Offset = 0;
	m_osWrite.OffsetHigh = 0;
	//--> Write 이벤트 생성에 실패..
	if (! (m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
	{
		return FALSE;
	}

	//--> 포트명 저장..
	m_sPortName = strPortName;

	//--> 실제적인...RS 232 포트 열기..
	m_hComm = CreateFile( m_sPortName, 
						  GENERIC_READ | GENERIC_WRITE, 0, 0,
						  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
						  NULL);


	//--> 포트 열기에 실해하면..
	if (m_hComm == (HANDLE) -1)
	{
		//AfxMessageBox("fail Port ofen");
		return FALSE;
	}
	

	//===== 포트 상태 설정. =====

	// EV_RXCHAR event 설정...데이터가 들어오면.. 수신 이벤트가 발생하게끔..
	SetCommMask( m_hComm, EV_RXCHAR);	

	// InQueue, OutQueue 크기 설정.
	SetupComm( m_hComm, BUFF_SIZE, BUFF_SIZE);	

	// 포트 비우기.
	PurgeComm( m_hComm,					
			   PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);

	// timeout 설정.
	timeouts.ReadIntervalTimeout = 0xFFFFFFFF;
	timeouts.ReadTotalTimeoutMultiplier = 0;
	timeouts.ReadTotalTimeoutConstant = 0;
	timeouts.WriteTotalTimeoutMultiplier = 2*CBR_9600 / dwBaud;;
	timeouts.WriteTotalTimeoutConstant = 0;

	SetCommTimeouts( m_hComm, &timeouts);

	
	// dcb 설정.... 포트의 실제적인..제어를 담당하는 DCB 구조체값 셋팅..
	dcb.DCBlength = sizeof(DCB);

	//--> 현재 설정된 값 중에서..
	GetCommState( m_hComm, &dcb);	
	
	//--> 보드레이트를 바꾸고..
	dcb.BaudRate = dwBaud;
	
	//--> Data 8 Bit
	dcb.ByteSize = byData;

	//--> Noparity
	dcb.Parity = byParity;

	//--> 1 Stop Bit
	dcb.StopBits = byStop;




	//--> 포트를 재..설정값으로.. 설정해보고..
	if( !SetCommState( m_hComm, &dcb) )	
	{
		return FALSE;
	}
	
	//Sleep(60);

	// 포트 감시 쓰레드 생성.
	m_bConnected = TRUE;

	::SendMessage(hStartWnd, WM_COMM_OPEN, 1, 0);
	//--> 포트 감시 쓰레드 생성.
	m_hThreadWatchComm = CreateThread( NULL, 0, 
									   (LPTHREAD_START_ROUTINE)ThreadWatchComm, 
									   this, 0, &dwThreadID);

	//--> 쓰레드 생성에 실패하면..
	if (! m_hThreadWatchComm)
	{
		//--> 열린 포트를 닫고..
		ClosePort();
		return FALSE;
	}
	check = FALSE;
	

	return TRUE;
}
DWORD	ThreadWatchComm(CCommThread* pComm)
{
   DWORD           dwEvent;
   OVERLAPPED      os;
   BOOL            bOk = TRUE;
   BYTE            buff[2048];      // 읽기 버퍼
   DWORD           dwRead;  // 읽은 바이트수.
 

   // Event, OS 설정.
   memset( &os, 0, sizeof(OVERLAPPED));
   
   //--> 이벤트 설정..
   if( !(os.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL)) )
   {
		bOk = FALSE;
		
   }

   //--> 이벤트 마스크..
   if( !SetCommMask( pComm->m_hComm, EV_RXCHAR) )
   {
	   bOk = FALSE;
	   	
   }

   //--> 이벤트나..마스크 설정에 실패함..
   if( !bOk )
   {
		//AfxMessageBox("Error while creating ThreadWatchComm, " + pComm->m_sPortName);
		return FALSE;
   }
  
   while (pComm ->m_bConnected)
   {
 		dwEvent = 0;
	
        // 포트에 읽을 거리가 올때까지 기다린다.
        WaitCommEvent( pComm->m_hComm, &dwEvent, NULL);
	
	
		//--> 데이터가 수신되었다는 메세지가 발생하면..
        if( (dwEvent & EV_RXFLAG || dwEvent & EV_RXCHAR) == (EV_RXFLAG || EV_RXCHAR) )
		//if ((dwEvent & EV_RXCHAR) == EV_RXCHAR)
        {
            // 포트에서 읽을 수 있는 만큼 읽는다.
				//--> buff 에 받아놓고..
			memset(buff, 0, sizeof(BYTE)*2048);			
			dwRead = pComm->ReadComm( buff, 512);
			//if(dwRead == 66)
			{
				pComm->SetReadData(buff, dwRead);				
			}
		
		}	
   }
   
  CloseHandle( os.hEvent);

   //--> 쓰레드 종료가 되겠죠?
   pComm->m_hThreadWatchComm = NULL;

   return TRUE;

}
Ejemplo n.º 22
0
bool CIRDriver::InitPort(CIRConfig *cfg, bool daemonize)
{
	struct ir_remote *tmp;
	if(cfg==NULL) return false;

	DEBUG("Initializing port...\n");

	KillThread(&IRThreadHandle,&IRThreadEvent);
	KillThread(&DaemonThreadHandle,&DaemonThreadEvent);
	cbuf_start=cbuf_end=0;
	
	if(ov.hEvent)
	{
		SetEvent(ov.hEvent);	// singal it
		Sleep(100);				// wait a tiny bit
		CloseHandle(ov.hEvent);	// and close it
		ov.hEvent=NULL;
	}

	if(hPort)
	{
		SetCommMask(hPort,0);	// stop any waiting on the port
		Sleep(100);				// wait a tiny bit
		CloseHandle(hPort);		// and close it
		hPort=NULL;
	}

	if((hPort=CreateFile(
		cfg->port,GENERIC_READ | GENERIC_WRITE,
		0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0))==INVALID_HANDLE_VALUE)
	{
		hPort=NULL;
		return false;
	}

	DCB dcb;
	if(!GetCommState(hPort,&dcb))
	{
		CloseHandle(hPort);
		hPort=NULL;
		return false;
	}
	if (cfg->animax) dcb.fDtrControl=DTR_CONTROL_ENABLE; //set DTR high, the animax receiver needs this for power
	else
		dcb.fDtrControl=DTR_CONTROL_DISABLE; // set the transmit LED to off initially.
	dcb.fRtsControl=RTS_CONTROL_ENABLE;

	dcb.BaudRate = cfg->speed;					
	devicetype = cfg->devicetype;				
	virtpulse = cfg->virtpulse;					

	if(!SetCommState(hPort,&dcb))
	{
		CloseHandle(hPort);
		hPort=NULL;
		DEBUG("SetCommState failed.\n");
		return false;
	}
	tmp=global_remotes;
	while (tmp!=NULL) {
		if (!(tmp->flags&SPECIAL_TRANSMITTER)) tmp->transmitter=cfg->transmittertype;
		tmp=tmp->next;
	}
	SetTransmitPort(hPort,cfg->transmittertype);

	if(cfg->sense==-1)
	{
		/* Wait for receiver to settle (since we just powered it on) */
		Sleep(1000);
		DWORD state;
		if(!GetCommModemStatus(hPort,&state))
		{
			CloseHandle(hPort);
			hPort=NULL;
			return false;
		}
		sense=(state & MS_RLSD_ON) ? 1 : 0;
		DEBUG("Sense set to %d\n",sense);
	}
	else
		sense=cfg->sense;

	if((ov.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL))==NULL)
	{
		CloseHandle(hPort);
		hPort=NULL;
		return false;
	}

	/* Start the thread */
	/* THREAD_PRIORITY_TIME_CRITICAL combined with the REALTIME_PRIORITY_CLASS */
	/* of this program results in the highest priority (26 out of 31) */
	if((IRThreadHandle=
		AfxBeginThread(IRThread,(void *)this,THREAD_PRIORITY_TIME_CRITICAL))==NULL)
	{
		CloseHandle(hPort);
		CloseHandle(ov.hEvent);
		hPort=ov.hEvent=NULL;
		return false;
	}

	if(daemonize)
	{

		/* Start the thread */
		/* THREAD_PRIORITY_IDLE combined with the REALTIME_PRIORITY_CLASS */
		/* of this program still results in a really high priority. (16 out of 31) */
		if((DaemonThreadHandle=
			AfxBeginThread(DaemonThread,(void *)this,THREAD_PRIORITY_IDLE))==NULL)
		{
			KillThread(&IRThreadHandle,&IRThreadEvent);
			CloseHandle(hPort);
			CloseHandle(ov.hEvent);
			hPort=ov.hEvent=NULL;
			return false;
		}
	}

	DEBUG("Port initialized.\n");
	
	return true;
}
Ejemplo n.º 23
0
void CIRDriver::ThreadProc(void)
{
	/* Virtually no error checking is done here, because */
	/* it's pretty safe to assume that everything works, */
	/* and we have nowhere to report errors anyway.      */

	/* We use two timers in case the high resolution doesn't   */
	/* last too long before wrapping around (is that true?     */
	/* is it really only a 32 bit timer or a true 64 bit one?) */

	__int64 hr_time, hr_lasttime, hr_freq;	// high-resolution
	time_t lr_time, lr_lasttime;			// low-resolution

	DWORD status;
	GetCommModemStatus(hPort, &status);
	int prev=(status & MS_RLSD_ON) ? 1 : 0;

	/* Initialize timer stuff */
	QueryPerformanceFrequency((LARGE_INTEGER *)&hr_freq);

	/* Get time (both LR and HR) */
	time(&lr_lasttime);
	QueryPerformanceCounter((LARGE_INTEGER *)&hr_lasttime);
	
	HANDLE events[2]={ov.hEvent,IRThreadEvent};

	for(;;)
	{
		/* We want to be notified of DCD or RX changes */
		if(SetCommMask(hPort, devicetype ? EV_RLSD : EV_RXCHAR)==0)	
		{
			DEBUG("SetCommMask returned zero, error=%d\n",GetLastError());
		}
		/* Reset the event */
		ResetEvent(ov.hEvent);
		/* Start waiting for the event */
		DWORD event;
		if(WaitCommEvent(hPort,&event,&ov)==0 && GetLastError()!=997)
		{
			DEBUG("WaitCommEvent error: %d\n",GetLastError());
		}

		/* Wait for the event to get triggered */
		int res=WaitForMultipleObjects(2,events,FALSE,INFINITE);
		
		/* Get time (both LR and HR) */
		QueryPerformanceCounter((LARGE_INTEGER *)&hr_time);
		time(&lr_time);
		
		if(res==WAIT_FAILED)
		{
			DEBUG("Wait failed.\n");
			continue;
		}
		
		if(res==(WAIT_OBJECT_0+1))
		{
			DEBUG("IRThread terminating\n");
			AfxEndThread(0);
			return;
		}
		
		if(res!=WAIT_OBJECT_0)
		{
			DEBUG("Wrong object\n");
			continue;
		}

		int dcd;
		if (devicetype) {				
			GetCommModemStatus(hPort,&status);

			dcd = (status & MS_RLSD_ON) ? 1 : 0;

			if(dcd==prev)
			{
				/* Nothing changed?! */
				/* Continue without changing time */
				continue;
			}

			prev=dcd;
		}

		int deltv=lr_time-lr_lasttime;
		if (devicetype && (deltv>15)) {		
			/* More than 15 seconds passed */
			deltv=0xFFFFFF;
			if(!(dcd^sense))
			{
				/* sense had to be wrong */
				sense=sense?0:1;
				DEBUG("sense was wrong!\n");
			}
		} else
			deltv=(int)(((hr_time-hr_lasttime)*1000000) / hr_freq);
	
		lr_lasttime=lr_time;
		hr_lasttime=hr_time;
		
		int data;				
		if (devicetype) {		
			data = (dcd^sense) ? (deltv) : (deltv | 0x1000000);	

			if(SetData(data))
				SetEvent(hDataReadyEvent);
		} else {
			data = deltv;	

			SetData(data-100);						
			if(SetData(virtpulse | 0x1000000))		
				SetEvent(hDataReadyEvent);			
			PurgeComm(hPort,PURGE_RXCLEAR);			
		}
	}
}
Ejemplo n.º 24
0
void irtiny::CIRDriver::threadProc()
{
    Event overlappedEvent = Event::manualResetEvent();
    OVERLAPPED ov = { 0 };
    ov.hEvent = overlappedEvent.get();

    HANDLE const events[2] = { ov.hEvent, finishEvent_.get() };

    // Send a byte to force RTS
    ::WriteFile(serialPort_.get(), "x", 1, nullptr, &ov);

    ::Sleep(100);

    for (;;)
    {
        overlappedEvent.resetEvent();

        // We want to be notified of RX changes
        if (SetCommMask(serialPort_.get(), EV_RXCHAR) == 0)
        {
            //DEBUG("SetCommMask returned zero, error=%d\n",GetLastError());
        }
        // Start waiting for the event
        DWORD event;
        if (WaitCommEvent(serialPort_.get(), &event, &ov) == 0 && GetLastError() != 997)
        {
            //DEBUG("WaitCommEvent error: %d\n",GetLastError());
        }

        switch (WaitForMultipleObjects(2, events, FALSE, INFINITE))
        {
        default:
            continue;

        case WAIT_OBJECT_0:
            while (true)
            {
                uint8_t buf[2];
                DWORD bytesRead = 0;
                auto const readSuccessful = ReadFile(serialPort_.get(), buf, 2, &bytesRead, &ov);
                if (bytesRead == 2)
                {
                    uint16_t const val = MAKEWORD(buf[1], buf[0]) & 0x7FFF;
                    bool const level = (buf[0] & 0x80) != 0;
                    double const unit = 1.0 / 115200.0;
                    DWORD const deltv = static_cast<DWORD>(1.0e+6 * unit * double(val));
                    DWORD const data = level
                        ? (deltv | 0x1000000)
                        : deltv;
                    setData(data);
                }
                else
                {
                    ::ClearCommError(serialPort_.get(), nullptr, nullptr);
                    ::PurgeComm(serialPort_.get(), PURGE_RXABORT | PURGE_RXCLEAR);
                    break;
                }
            }
            break;

        case WAIT_OBJECT_0 + 1:
            return;
        }
    }
}
Ejemplo n.º 25
0
//
// Initialize the port. This can be port 1 to MaxSerialPortNum.
///初始化串口。只能是1-MaxSerialPortNum
//
//parity:
//  n=none
//  e=even
//  o=odd
//  m=mark
//  s=space
//data:
//  5,6,7,8
//stop:
//  1,1.5,2
//
BOOL CSerialPort::InitPort(HWND pPortOwner,	// the owner (CWnd) of the port (receives message)
                           UINT  portnr,		// portnumber (1..MaxSerialPortNum)
                           UINT  baud,			// baudrate
                           char  parity,		// parity
                           UINT  databits,		// databits
                           UINT  stopbits,		// stopbits
                           DWORD dwCommEvents,	// EV_RXCHAR, EV_CTS etc
                           UINT  writebuffersize,// size to the writebuffer

                           DWORD   ReadIntervalTimeout,
                           DWORD   ReadTotalTimeoutMultiplier,
                           DWORD   ReadTotalTimeoutConstant,
                           DWORD   WriteTotalTimeoutMultiplier,
                           DWORD   WriteTotalTimeoutConstant )

{
    assert(portnr > 0 && portnr < 200);
    assert(pPortOwner != NULL);

    // if the thread is alive: Kill
    if (m_bThreadAlive)
    {
        do
        {
            SetEvent(m_hShutdownEvent);
        } while (m_bThreadAlive);
        //TRACE("Thread ended\n");
    }

    // create events
    if (m_ov.hEvent != NULL)
        ResetEvent(m_ov.hEvent);
    else
        m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if (m_hWriteEvent != NULL)
        ResetEvent(m_hWriteEvent);
    else
        m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if (m_hShutdownEvent != NULL)
        ResetEvent(m_hShutdownEvent);
    else
        m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    // initialize the event objects
    ///事件数组初始化,设定优先级别
    m_hEventArray[0] = m_hShutdownEvent;	// highest priority
    m_hEventArray[1] = m_ov.hEvent;
    m_hEventArray[2] = m_hWriteEvent;

    // initialize critical section
    ///初始化临界资源
    InitializeCriticalSection(&m_csCommunicationSync);

    // set buffersize for writing and save the owner
    m_pOwner = pPortOwner;

    if (m_szWriteBuffer != NULL)
        delete [] m_szWriteBuffer;
    m_szWriteBuffer = new char[writebuffersize];

    m_nPortNr = portnr;

    m_nWriteBufferSize = writebuffersize;
    m_dwCommEvents = dwCommEvents;

    BOOL bResult = FALSE;
    CString szPort;
    //char *szBaud = new char[50];


    /*
    多个线程操作相同的数据时,一般是需要按顺序访问的,否则会引导数据错乱,
    无法控制数据,变成随机变量。为解决这个问题,就需要引入互斥变量,让每
    个线程都按顺序地访问变量。这样就需要使用EnterCriticalSection和
    LeaveCriticalSection函数。
    */
    // now it critical!
    EnterCriticalSection(&m_csCommunicationSync);

    // if the port is already opened: close it
    ///串口已打开就关掉
    if (m_hComm != NULL)
    {
        CloseHandle(m_hComm);
        m_hComm = NULL;
    }

    // prepare port strings
    szPort.Format("\\\\.\\COM%d", portnr);///可以显示COM10以上端口//add by itas109 2014-01-09

    // stop is index 0 = 1 1=1.5 2=2
    int mystop;
    int myparity;
    switch(stopbits)
    {
    case 0:
        mystop = ONESTOPBIT;
        break;
    case 1:
        mystop = ONE5STOPBITS;
        break;
    case 2:
        mystop = TWOSTOPBITS;
        break;
    }
    myparity = 0;
    parity = toupper(parity);
    switch(parity)
    {
    case 'N':
        myparity = 0;
        break;
    case 'O':
        myparity = 1;
        break;
    case 'E':
        myparity = 2;
        break;
    case 'M':
        myparity = 3;
        break;
    case 'S':
        myparity = 4;
        break;
    }
    //sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, mystop);

    // get a handle to the port
    /*
    通信程序在CreateFile处指定串口设备及相关的操作属性,再返回一个句柄,
    该句柄将被用于后续的通信操作,并贯穿整个通信过程串口打开后,其属性
    被设置为默认值,根据具体需要,通过调用GetCommState(hComm,&&dcb)读取
    当前串口设备控制块DCB设置,修改后通过SetCommState(hComm,&&dcb)将其写
    入。运用ReadFile()与WriteFile()这两个API函数实现串口读写操作,若为异
    步通信方式,两函数中最后一个参数为指向OVERLAPPED结构的非空指针,在读
    写函数返回值为FALSE的情况下,调用GetLastError()函数,返回值为ERROR_IO_PENDING,
    表明I/O操作悬挂,即操作转入后台继续执行。此时,可以用WaitForSingleObject()
    来等待结束信号并设置最长等待时间
    */
    m_hComm = CreateFile(szPort,						// communication port string (COMX)
                         GENERIC_READ | GENERIC_WRITE,	// read/write types
                         0,								// comm devices must be opened with exclusive access
                         NULL,							// no security attributes
                         OPEN_EXISTING,					// comm devices must use OPEN_EXISTING
                         FILE_FLAG_OVERLAPPED,			// Async I/O
                         0);							// template must be 0 for comm devices

    ///创建失败
    if (m_hComm == INVALID_HANDLE_VALUE)
    {
        // port not found
        //delete [] szBaud;

        return FALSE;
    }

    // set the timeout values
    ///设置超时
    m_CommTimeouts.ReadIntervalTimeout		 = ReadIntervalTimeout * 1000;
    m_CommTimeouts.ReadTotalTimeoutMultiplier  = ReadTotalTimeoutMultiplier * 1000;
    m_CommTimeouts.ReadTotalTimeoutConstant	= ReadTotalTimeoutConstant * 1000;
    m_CommTimeouts.WriteTotalTimeoutMultiplier = WriteTotalTimeoutMultiplier * 1000;
    m_CommTimeouts.WriteTotalTimeoutConstant   = WriteTotalTimeoutConstant * 1000;

    // configure
    ///配置
    ///分别调用Windows API设置串口参数
    if (SetCommTimeouts(m_hComm, &m_CommTimeouts))///设置超时
    {
        /*
        若对端口数据的响应时间要求较严格,可采用事件驱动方式。
        事件驱动方式通过设置事件通知,当所希望的事件发生时,Windows
        发出该事件已发生的通知,这与DOS环境下的中断方式很相似。Windows
        定义了9种串口通信事件,较常用的有以下三种:
        	EV_RXCHAR:接收到一个字节,并放入输入缓冲区;
        	EV_TXEMPTY:输出缓冲区中的最后一个字符,发送出去;
        	EV_RXFLAG:接收到事件字符(DCB结构中EvtChar成员),放入输入缓冲区
        在用SetCommMask()指定了有用的事件后,应用程序可调用WaitCommEvent()来等待事
        件的发生。SetCommMask(hComm,0)可使WaitCommEvent()中止
        */
        if (SetCommMask(m_hComm, dwCommEvents))///设置通信事件
        {
            if (GetCommState(m_hComm, &m_dcb))///获取当前DCB参数
            {
                //m_dcb.EvtChar = 'q';
                //m_dcb.fRtsControl = RTS_CONTROL_ENABLE;		// set RTS bit high!
                m_dcb.BaudRate = baud;  // add by mrlong
                m_dcb.Parity   = myparity;
                m_dcb.ByteSize = databits;
                m_dcb.StopBits = mystop;
                m_dcb.fBinary = TRUE;// 指定是否允许二进制模式
                m_dcb.fParity = TRUE;// 指定是否允许奇偶校验
                //m_dcb.EvtChar = 'q';
                //if (BuildCommDCB(szBaud, &m_dcb))///填写DCB结构
                //{
                if (SetCommState(m_hComm, &m_dcb))///配置DCB
                    ; // normal operation... continue
                else
                    ProcessErrorMessage("SetCommState()");
                //}
                //else
                //	ProcessErrorMessage("BuildCommDCB()");
            }
            else
                ProcessErrorMessage("GetCommState()");
        }
        else
            ProcessErrorMessage("SetCommMask()");
    }
    else
        ProcessErrorMessage("SetCommTimeouts()");

    //delete [] szBaud;

    // flush the port
    ///终止读写并清空接收和发送
    PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

    // release critical section
    ///释放临界资源
    LeaveCriticalSection(&m_csCommunicationSync);

    //TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);

    return TRUE;
}
Ejemplo n.º 26
0
// COMx for windows, returns NULL on error
tUartHandle UartOpen(char* szPortName)
{
	HANDLE serial_handle; 
	DCB  dcb;

	memset(&dcb,0,sizeof(dcb));

	/* -------------------------------------------------------------------- */
	// set DCB to configure the serial port
	dcb.DCBlength       = sizeof(dcb);

	dcb.fOutxCtsFlow    = 0;
	dcb.fOutxDsrFlow    = 0;
	dcb.fDtrControl     = DTR_CONTROL_ENABLE; // enable for power
	dcb.fDsrSensitivity = 0;
	dcb.fRtsControl     = RTS_CONTROL_ENABLE; // enable for power
	dcb.fOutX           = 0;
	dcb.fInX            = 0;

	/* ----------------- misc parameters ----- */
	dcb.fErrorChar      = 0;
	dcb.fBinary         = 1;
	dcb.fNull           = 0;
	dcb.fAbortOnError   = 0;
	dcb.wReserved       = 0;
	dcb.XonLim          = 2;
	dcb.XoffLim         = 4;
	dcb.XonChar         = 0x13;
	dcb.XoffChar        = 0x19;
	dcb.EvtChar         = 0;

	/* ----------------- defaults ----- */
	dcb.BaudRate = 4800;
	dcb.Parity   = NOPARITY;
	dcb.fParity  = 0;
	dcb.StopBits = ONESTOPBIT;
	dcb.ByteSize = 8;


	/* -------------------------------------------------------------------- */
	// opening serial port
	serial_handle = CreateFile(szPortName, GENERIC_READ | GENERIC_WRITE,
		0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);

	if (serial_handle == INVALID_HANDLE_VALUE)
	{
		//printf("Cannot open port \n");
		return NULL;
	}

	SetCommMask(serial_handle, 0);

	if(!SetCommState(serial_handle, &dcb))
	{
		//printf("Error setting up COM params\n");
		CloseHandle(serial_handle);
		return NULL;
	}

	return serial_handle;
}
//
// Initialize the port. This can be port 1 to 4.
//
BOOL CSerialPort::InitPort(CWnd* pPortOwner,	// the owner (CWnd) of the port (receives message)
						   UINT  portnr,		// portnumber (1..4)
						   UINT  baud,			// baudrate
						   char  parity,		// parity 
						   UINT  databits,		// databits 
						   UINT  stopbits,		// stopbits 
						   DWORD dwCommEvents,	// EV_RXCHAR, EV_CTS etc
						   UINT  writebuffersize)	// size to the writebuffer
{
	//assert(portnr > 0 && portnr < 5);
	assert(pPortOwner != NULL);

	// if the thread is alive: Kill
	if (m_bThreadAlive)
	{
		do
		{
			SetEvent(m_hShutdownEvent);
		} while (m_bThreadAlive);
		TRACE("Thread ended\n");
	}

	// create events
	if (m_ov.hEvent != NULL)
		ResetEvent(m_ov.hEvent);
	m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	if (m_hWriteEvent != NULL)
		ResetEvent(m_hWriteEvent);
	m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	
	if (m_hShutdownEvent != NULL)
		ResetEvent(m_hShutdownEvent);
	m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	// initialize the event objects
	m_hEventArray[0] = m_hShutdownEvent;	// highest priority
	m_hEventArray[1] = m_ov.hEvent;
	m_hEventArray[2] = m_hWriteEvent;

	// initialize critical section
	InitializeCriticalSection(&m_csCommunicationSync);
	
	// set buffersize for writing and save the owner
	m_pOwner = pPortOwner;

	if (m_szWriteBuffer != NULL)
		delete [] m_szWriteBuffer;
	m_szWriteBuffer = new char[writebuffersize];

	m_nPortNr = portnr;

	m_nWriteBufferSize = writebuffersize;
	m_dwCommEvents = dwCommEvents;

	BOOL bResult = FALSE;
	char *szPort = new char[50];
	char *szBaud = new char[50];

	// now it critical!
	EnterCriticalSection(&m_csCommunicationSync);

	// if the port is already opened: close it
	if (m_hComm != NULL)
	{
		CloseHandle(m_hComm);
		m_hComm = NULL;
	}

	// prepare port strings
	sprintf(szPort, "COM%d", portnr);
	sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);

	// get a handle to the port
	m_hComm = CreateFile(szPort,						// communication port string (COMX)
					     GENERIC_READ | GENERIC_WRITE,	// read/write types
					     0,								// comm devices must be opened with exclusive access
					     NULL,							// no security attributes
					     OPEN_EXISTING,					// comm devices must use OPEN_EXISTING
					     FILE_FLAG_OVERLAPPED,			// Async I/O
					     0);							// template must be 0 for comm devices

	if (m_hComm == INVALID_HANDLE_VALUE)
	{
		// port not found
		delete [] szPort;
		delete [] szBaud;

		return FALSE;
	}

	// set the timeout values
	m_CommTimeouts.ReadIntervalTimeout = 1000;
	m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
	m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
	m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
	m_CommTimeouts.WriteTotalTimeoutConstant = 1000;

	// configure
	if (SetCommTimeouts(m_hComm, &m_CommTimeouts))
	{						   
		if (SetCommMask(m_hComm, dwCommEvents))
		{
			if (GetCommState(m_hComm, &m_dcb))
			{
				m_dcb.fRtsControl = RTS_CONTROL_ENABLE;		// set RTS bit high!
				if (BuildCommDCB(szBaud, &m_dcb))
				{
					if (SetCommState(m_hComm, &m_dcb))
						; // normal operation... continue
					else
						ProcessErrorMessage("SetCommState()");
				}
				else
					ProcessErrorMessage("BuildCommDCB()");
			}
			else
				ProcessErrorMessage("GetCommState()");
		}
		else
			ProcessErrorMessage("SetCommMask()");
	}
	else
		ProcessErrorMessage("SetCommTimeouts()");

	delete [] szPort;
	delete [] szBaud;

	// flush the port
	PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

	// release critical section
	LeaveCriticalSection(&m_csCommunicationSync);

	TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);

	return TRUE;
}
Ejemplo n.º 28
0
/*-----------------------------------------------------------------------------

FUNCTION: SetupCommPort( int Port )

PURPOSE: Setup Communication Port with our settings

-----------------------------------------------------------------------------*/
BOOL SetupCommPort(int port)
{
    DWORD dwReadStatId;
    DWORD dwWriteStatId;
	int sav_port,sav_pause;
    DCB dcb = {0};
	char PORTNAME[10];

	if (!port) return(false);

	sav_port=TTY.PORT;
	sav_pause=TTY.read_pause;
    TTY.read_pause=1;
    
	BreakDownCommPort();

	TTY.PORT = port ;

	// set tty structure for the specified port
	
	sprintf(PORTNAME,"\\\\.\\COM%d",port);
	PACKET.readstate=0;
	PACKET.number=0;
	PACKET.old_number=0;
	PACKET.info=0;

    // open communication port handle
//    TTY.COMDEV = CreateFile( PORTNAME,GENERIC_READ | GENERIC_WRITE, 
//                  0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,0);

    TTY.COMDEV = CreateFile( PORTNAME,GENERIC_READ | GENERIC_WRITE, 
                  0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

    if (TTY.COMDEV == INVALID_HANDLE_VALUE) goto failed;
    
    if (!GetCommState(TTY.COMDEV, &dcb))      // get current DCB settings
	{ report_error("GetCommState");goto failed; }

   
    // update DCB rate, byte size, parity, and stop bits size
   
	dcb.DCBlength = sizeof(dcb);
    dcb.BaudRate = TTY.BAUDRATE;
    dcb.ByteSize = 8;
    
	dcb.Parity   = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
	dcb.EvtChar = '\0';

   
    // update flow control settings
   
    dcb.fDtrControl     =  DTR_CONTROL_ENABLE;
    dcb.fRtsControl     =  RTS_CONTROL_ENABLE;

	if (TTY.FLOW_CONTROL)
	{
      dcb.fOutxCtsFlow    = TRUE;
      dcb.fOutxDsrFlow    = TRUE;
	}
	else
	{
      dcb.fOutxCtsFlow    = FALSE;
      dcb.fOutxDsrFlow    = FALSE;
	}

    dcb.fDsrSensitivity = FALSE;;
    dcb.fOutX           = FALSE;
    dcb.fInX            = FALSE;
    dcb.fTXContinueOnXoff = FALSE;
    dcb.XonChar         = 0;
    dcb.XoffChar        = 0;
    dcb.XonLim          = 0;
    dcb.XoffLim         = 0;
    dcb.fParity = FALSE; //TRUE;

    if (!SetCommState(TTY.COMDEV, &dcb))     // set new state
	{ report_error("SetCommState failed"); goto failed;}
	
	// set comm buffer sizes
    if (!SetupComm(TTY.COMDEV, 1024, 1024))
	{  report_error("SetupComm failed");goto failed;}

    if (!EscapeCommFunction(TTY.COMDEV, SETDTR))        // raise DTR
	{  report_error("EscapeCommFunction failed");goto failed;}

	  SetCommMask (TTY.COMDEV, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

      
    // start the reader and writer threads

	fThreadDone = FALSE;

    TTY.READERTHREAD =  
		CreateThread( NULL, 1000, (LPTHREAD_START_ROUTINE) ReaderProc, 0, 0, &dwReadStatId);
    if (TTY.READERTHREAD == NULL)
	{ report_error("CreateThread failed"); goto failed;}

	TTY.WRITERTHREAD =
		CreateThread( NULL, 1000, (LPTHREAD_START_ROUTINE) WriterProc, 0, 0, &dwWriteStatId);
    if (TTY.WRITERTHREAD == NULL)
	{ report_error("CreateWriterThread failed"); goto failed;}

	write_logfile("COMPORT opened: %s", PORTNAME);
	TTY.amount_to_write=0;	
	TTY.read_pause=sav_pause;

    return TRUE;

failed:
		{  
			char sztemp[100];
 	        write_logfile("COMPORT open failed");
		
			sprintf(sztemp, "The Port COM%d is not available. Please select another Com-Port.",TTY.PORT);
			report_error(sztemp);
		
			TTY.read_pause=sav_pause;
			TTY.PORT=sav_port;
			TTY.COMDEV=INVALID_HANDLE_VALUE;
			TTY.CONNECTED=FALSE;
			TTY.amount_to_write=0;
			return FALSE;
		}
}
//---------------------------------------------------------------------------
// Attempt to open a com port.  Keep the handle in ComID.
// Set the starting baud rate to 115200.
//
// 'portnum'   - number 0 to MAX_PORTNUM-1.  This number provided will 
//               be used to indicate the port number desired when calling
//               all other functions in this library.
//
// 'port_zstr' - zero terminate port name.  For this platform
//               use format COMX where X is the port number.
//
//
// Returns: TRUE(1)  - success, COM port opened
//          FALSE(0) - failure, could not open specified port
//
bool OpenCOM(int portnum, char *port_zstr)
{
   char tempstr[80];
   short fRetVal;
   COMMTIMEOUTS CommTimeOuts;
   DCB dcb;

   // open COM device
   if ((ComID[portnum] =
      CreateFile( port_zstr, GENERIC_READ | GENERIC_WRITE,
                  0, 
                  NULL,                 // no security attrs
                  OPEN_EXISTING,
                  FILE_FLAG_OVERLAPPED, // overlapped I/O
                  NULL )) == (HANDLE) -1 )
   {
      ComID[portnum] = 0;
      return (FALSE) ;
   }
   else
   {
      // create events for detection of reading and write to com port 
      osRead[portnum].hEvent = CreateEvent(NULL,TRUE,FALSE,tempstr);  
      osWrite[portnum].hEvent = CreateEvent(NULL,TRUE,FALSE,tempstr); 

      // get any early notifications
      SetCommMask(ComID[portnum], EV_RXCHAR | EV_TXEMPTY | EV_ERR | EV_BREAK);

      // setup device buffers
      SetupComm(ComID[portnum], 2048, 2048);

      // purge any information in the buffer
      PurgeComm(ComID[portnum], PURGE_TXABORT | PURGE_RXABORT |
                           PURGE_TXCLEAR | PURGE_RXCLEAR );

      // set up for overlapped non-blocking I/O 
      CommTimeOuts.ReadIntervalTimeout = 0; 
      CommTimeOuts.ReadTotalTimeoutMultiplier = 20; 
      CommTimeOuts.ReadTotalTimeoutConstant = 40; 
      CommTimeOuts.WriteTotalTimeoutMultiplier = 20; 
      CommTimeOuts.WriteTotalTimeoutConstant = 40; 
      SetCommTimeouts(ComID[portnum], &CommTimeOuts);

      // setup the com port
      GetCommState(ComID[portnum], &dcb);

	  dcb.BaudRate = CBR_115200;             // current baud rate 
      dcb.fBinary = TRUE;                    // binary mode, no EOF check 
      dcb.fParity = FALSE;                   // enable parity checking 
      dcb.fOutxCtsFlow = FALSE;              // CTS output flow control 
      dcb.fOutxDsrFlow = FALSE;              // DSR output flow control 
      dcb.fDtrControl = DTR_CONTROL_ENABLE;  // DTR flow control type 
      dcb.fDsrSensitivity = FALSE;           // DSR sensitivity 
      dcb.fTXContinueOnXoff = TRUE;          // XOFF continues Tx 
      dcb.fOutX = FALSE;                     // XON/XOFF out flow control 
      dcb.fInX = FALSE;                      // XON/XOFF in flow control 
      dcb.fErrorChar = FALSE;                // enable error replacement 
      dcb.fNull = FALSE;                     // enable null stripping 
      dcb.fRtsControl = RTS_CONTROL_ENABLE;  // RTS flow control 
      dcb.fAbortOnError = FALSE;             // abort reads/writes on error 
      dcb.XonLim = 0;                        // transmit XON threshold 
      dcb.XoffLim = 0;                       // transmit XOFF threshold 
      dcb.ByteSize = 8;                      // number of bits/byte, 4-8 
      dcb.Parity = NOPARITY;                 // 0-4=no,odd,even,mark,space 
      dcb.StopBits = ONESTOPBIT;             // 0,1,2 = 1, 1.5, 2 
      dcb.XonChar = 0;                       // Tx and Rx XON character 
      dcb.XoffChar = 1;                      // Tx and Rx XOFF character 
      dcb.ErrorChar = 0;                     // error replacement character 
      dcb.EofChar = 0;                       // end of input character 
      dcb.EvtChar = 0;                       // received event character 

      fRetVal = SetCommState(ComID[portnum], &dcb);
   }

   // check if successfull
   if (!fRetVal)
   {
      CloseHandle(ComID[portnum]);
      ComID[portnum] = 0;
	  return false;
   }

   return true;
}
Ejemplo n.º 30
0
BOOL ARRAY3600OBJ::SetupComPort(int port)
{	
	connected=FALSE;
	int sav_port;
    DCB dcb = {0};
	char PORTNAME[10];

	sav_port=comport;
    BreakDownComPort();
	comport= port ;

	// set tty structure for the specified port	
	if (!port) goto failed;
	sprintf(PORTNAME,"\\\\.\\COM%d",port);
    comdev = CreateFile( PORTNAME,GENERIC_READ | GENERIC_WRITE, 
                  0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

    if (comdev == INVALID_HANDLE_VALUE) goto failed;  
    if (!GetCommState(comdev, &dcb))      // get current DCB settings
	{ report_error("GetCommState");goto failed; }

    // update DCB rate, byte size, parity, and stop bits size
	dcb.DCBlength = sizeof(dcb);
	dcb.BaudRate = baudrate;
    dcb.ByteSize = 8;
	dcb.Parity   = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
	dcb.EvtChar = '\0';
    // update flow control settings
    dcb.fDtrControl     =  DTR_CONTROL_ENABLE;
    dcb.fRtsControl     =  RTS_CONTROL_ENABLE;
    dcb.fOutxCtsFlow    = FALSE;
    dcb.fOutxDsrFlow    = FALSE;
    dcb.fDsrSensitivity = FALSE;;
    dcb.fOutX           = FALSE;
    dcb.fInX            = FALSE;
    dcb.fTXContinueOnXoff = FALSE;
    dcb.XonChar         = 0;
    dcb.XoffChar        = 0;
    dcb.XonLim          = 0;
    dcb.XoffLim         = 0;
    dcb.fParity = FALSE; //TRUE;
    if (!SetCommState(comdev, &dcb))     // set new state
	{ report_error("SetCommState failed"); goto failed;}
    if (!SetupComm(comdev, 1024, 1024))  // set comm buffer sizes
	{  report_error("SetupComm failed");goto failed;}
    if (!EscapeCommFunction(comdev, SETDTR))        // raise DTR
	{  report_error("EscapeCommFunction failed");goto failed;}
	SetCommMask (comdev, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

	return(TRUE);

failed:
		{  
			char sztemp[100];
			sprintf(sztemp, "The Port COM%d is not available. Please select another Com-Port.",port);
 	        write_logfile("COMPORT %d open failed.",port);		
			report_error(sztemp);		
			comport=sav_port;
			comdev=INVALID_HANDLE_VALUE;
			connected=FALSE;
			return FALSE;
		}

}