示例#1
0
}	
void    WinSerial::setupLink()
{

        int     ret;
        DCB     dcb = {0};
        COMMTIMEOUTS cto = {10,10,10,10,10};

        dcb.DCBlength = sizeof(DCB);

        cto.ReadIntervalTimeout = 100;

sprintf(logchunk, "opening com port <%s>\n", mDevName);
log(logchunk);
        mPortFh = CreateFile(mDevName, GENERIC_READ | GENERIC_WRITE,
                                         0,
                                         0,
                                         OPEN_EXISTING, 
                                         0,
                                         0
                                         );

   	if (mPortFh == INVALID_HANDLE_VALUE) 
   	{
       		// Handle the error.
       		printf ("CreateFile failed with error %ld.\n", GetLastError());
       		exit(1);
   	}

sprintf(logchunk, " port %d\n", mPortFh);
log(logchunk);
        assert(mPortFh);
        ret = GetCommState(mPortFh, &dcb);

        if (!ret)
        {
                fprintf(stderr, "GetCommState failed %d\n",
                                 GetLastError());
                exit(2);
        } 
 //       dcb.BaudRate = CBR_57600;
        dcb.BaudRate = CBR_256000;
    	dcb.ByteSize    = 8;
    	dcb.StopBits    = ONESTOPBIT;
    	dcb.Parity      = NOPARITY;
    	dcb.fDtrControl = DTR_CONTROL_DISABLE;
    	dcb.fOutX       = FALSE;
    	dcb.fInX        = FALSE;
    	dcb.fNull       = FALSE;
    	dcb.fRtsControl = RTS_CONTROL_DISABLE;

// need to send binary data
	dcb.fBinary = 1;

//    *  fInX, fOutX,fOutXDsrFlow, fOutXCtsFlow are set to FALSE
//    * fDtrControl is set to DTR_CONTROL_ENABLE
//    * fRtsControl is set to RTS_CONTROL_ENABLE

   
  

        ret = SetCommState(mPortFh, &dcb);
        if (!ret)
        {
                fprintf(stderr, "SetCommState failed %d\n",
                                GetLastError());
                exit(3);
        }

        ret = SetCommTimeouts(mPortFh, &cto);
        if (!ret)
        {
                fprintf(stderr, "SetCommTimeouts failed %d\n",
                                GetLastError());
                exit(3);
        }

	log("setup\n");
	mSetup = 1;
示例#2
0
int main(void){

	/* I searched for this topic and found no real leads so i looked it up.
	 * Opening the serial port
	 * First point is to open a connection. Before opening any connection several informations must be acquired.
	 * 
	 * The name of the serial port.(Usually COM1-COM6 )
	 * The direction of communication.
	 * (It is possible to set the communication to an asynchronic mode but it is far mor complex and unintuitive than the synchronic mode used here)
	 */

	LPCSTR portname = "COM4";
	DWORD  accessdirection =GENERIC_READ | GENERIC_WRITE;
	HANDLE hSerial = CreateFile(portname,
		accessdirection,
		0,
		0,
		OPEN_EXISTING,
		0,
		0);
	if (hSerial == INVALID_HANDLE_VALUE) {
		//call GetLastError(); to gain more information
		printf("Error 1\n");
	}
	
	/*
	 * After opening the port further settings like Baudrate, Byte size, the number of stopbits and the Parity need to be set.
	 */
	 
	DCB dcbSerialParams = {0};
	dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
	if (!GetCommState(hSerial, &dcbSerialParams)) {
		 //could not get the state of the comport
	}
	dcbSerialParams.BaudRate=9600;
	dcbSerialParams.ByteSize=8;
	dcbSerialParams.StopBits=ONESTOPBIT;
	dcbSerialParams.Parity=NOPARITY;
	if(!SetCommState(hSerial, &dcbSerialParams)){
		 //analyse error
		 printf("Error 2\n");
	}	
	
	/* Finally timeouts need to be set so that the program does not hang up when receiving nothing. */
	COMMTIMEOUTS timeouts={0};
	timeouts.ReadIntervalTimeout=50;
	timeouts.ReadTotalTimeoutConstant=50;
	timeouts.ReadTotalTimeoutMultiplier=10;
	timeouts.WriteTotalTimeoutConstant=50;
	timeouts.WriteTotalTimeoutMultiplier=10;
	if(!SetCommTimeouts(hSerial, &timeouts)){
		//handle error
		 printf("Error 3\n");
    }
	
	{
		uint8_t symbol = 'A';
		for(symbol = 'A'; symbol <= 'Z'; ++symbol){
			(void)writeToSerialPort(hSerial, &symbol, 1);
		}
	}
	
	/* Closing: when the serial port is not longer needed, it can be freed by closing the associated handle. */
	CloseHandle(hSerial);
	
	printf("Hello\n");
	
	
} /* main */
示例#3
0
serial_source open_serial_source(const char *device, int baud_rate,
				 int non_blocking,
				 void (*message)(serial_source_msg problem))
/* Effects: opens serial port device at specified baud_rate. If non_blocking
     is true, read_serial_packet calls will be non-blocking (writes are
     always blocking, for now at least)
   Returns: descriptor for serial forwarder at host:port, or
     NULL for failure (bad device or bad baud rate)
 */
{
#ifndef LOSE32
  struct termios newtio;
  int fd;
  tcflag_t baudflag = parse_baudrate(baud_rate);

  if (!baudflag)
    return NULL;

  fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);

  if (fd < 0)
    return NULL;

  /* Serial port setting */
  memset(&newtio, 0, sizeof(newtio));
  newtio.c_cflag = CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR | IGNBRK;
  cfsetispeed(&newtio, baudflag);
  cfsetospeed(&newtio, baudflag);

  /* Raw output_file */
  newtio.c_oflag = 0;

  if (tcflush(fd, TCIFLUSH) >= 0 &&
      tcsetattr(fd, TCSANOW, &newtio) >= 0)
    {
      serial_source src = malloc(sizeof *src);

      if (src)
	{
	  memset(src, 0, sizeof *src);
	  src->fd = fd;
	  src->non_blocking = non_blocking;
	  src->message = message;
	  src->send.seqno = 37;

	  return src;
	}
    }
  close(fd);

  return NULL;
#else // LOSE32
	LPCTSTR       ComName = (LPCTSTR)device;
    HANDLE        hComm;
	DCB           dcb;
    serial_source src;

	int buflen = MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,0);
	MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,buflen);
	
	//syncronize
	hComm = CreateFile(ComName,  GENERIC_READ | GENERIC_WRITE,  0,  NULL,  OPEN_EXISTING,
					FILE_ATTRIBUTE_NORMAL, NULL);

    if (hComm == INVALID_HANDLE_VALUE) {
        return NULL;
    }

    PurgeComm(hComm, PURGE_RXCLEAR);

	GetCommState(hComm, &dcb); 
	dcb.BaudRate = baud_rate;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.fParity = FALSE;
	dcb.StopBits = ONESTOPBIT;
    if (SetCommState(hComm, &dcb) == 0) {
        return NULL;
    }

    src = malloc(sizeof *src);

    if (src) {
	  memset(src, 0, sizeof *src);
	  src->hComm = hComm;
	  src->non_blocking = non_blocking;
	  src->message = message;
	  src->send.seqno = 37;

	}

	return src;

#endif // LOSE32
}
示例#4
0
	int setAttributes(int baudRate, Parity parity, int dataBits, StopBits bits, Handshake hs, int readTimeout, int writeTimeout)
	{
		DCB dcb;
		if (!GetCommState(this->handle, &dcb))
		{
			return GetLastError();
		}

		dcb.BaudRate = baudRate;
		dcb.Parity = (byte)parity;
		dcb.ByteSize = (byte)dataBits;

        switch (bits)
        {
        case StopBits_10:
            dcb.StopBits = ONESTOPBIT;
            break;
        case StopBits_15:
            dcb.StopBits = ONE5STOPBITS;
            break;
        case StopBits_20:
            dcb.StopBits = TWOSTOPBITS;
            break;
        default:
            break;
        }

		// Clear Handshake flags
		dcb.fOutxCtsFlow = 0;
		dcb.fOutX = 0;
		dcb.fInX = 0;
		dcb.fRtsControl = 0;

		// Set Handshake flags
		switch (hs)
		{
		case Handshake_None:
			break;
		case Handshake_XonXoff:
			dcb.fOutX = 1;
			dcb.fInX = 1;
			break;
		case Handshake_RequestToSend:
			dcb.fOutxCtsFlow = 1;
			dcb.fRtsControl = 1;
			break;
		case Handshake_RequestToSendXonXoff:
			dcb.fOutX = 1;
			dcb.fInX = 1;
			dcb.fOutxCtsFlow = 1;
			dcb.fRtsControl = 1;
			break;
		default: // Shouldn't happen
			break;
		}

		if (!SetCommState(handle, &dcb))
		{
			return GetLastError();
		}
		return S_OK;
	}
示例#5
0
void serialDriver::open(std::string com_port, long baud_rate, int databits, sdff_serial_paritymodes parity, double stopbits, sdff_serial_handshaking handshaking){
    std::string par="NO_PARITY";
    if (parity==sdffserEVEN) par="EVEN_PARITY";
    if (parity==sdffserODD) par="ODD_PARITY";
    std::string name="serialDriver::open(port="+com_port+", baud_rate="+inttostr(baud_rate)+", databits="+inttostr(databits)+", stopbits="+floattostr(stopbits)+" parity="+par+")";
    if (ports.find(com_port)!=ports.end()) {
        SEQUENCER_ERRORV(SEQUENCER_SERERROR_PORTALREADYOPEN_NUM, name, com_port.c_str());
    }

    BOOL fSuccess;
    DCB dcb;      /* device control block */
    BYTE StopBits;
    if (stopbits==1) {
        StopBits=ONESTOPBIT;
    } else if (stopbits==1.5) {
        StopBits=ONE5STOPBITS;
    } else if (stopbits==2) {
        StopBits=TWOSTOPBITS;
    } else {
        SEQUENCER_ERRORV(SEQUENCER_SERERROR_IMPOSSIBLEARG_NUM, name, com_port.c_str(), floattostr(stopbits).c_str(), "stop_bits", "1, 1.5, 2");
    }
    BYTE Parity=NOPARITY;
    DWORD fParity;
    if (parity==sdffserEVEN) {
        Parity=EVENPARITY;
        fParity=TRUE;
    } else if (parity==sdffserODD) {
        Parity=ODDPARITY;
        fParity=TRUE;
    } else if (parity==sdffserNOPARITY) {
        Parity=NOPARITY;
        fParity=FALSE;
    }

    ports[com_port] = CreateFileA(com_port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (ports[com_port]==INVALID_HANDLE_VALUE) {
        ports.erase(com_port);
        win32_error(name);
    }
    fSuccess = GetCommState(ports[com_port], &dcb);
    if (!fSuccess) {
        CloseHandle(ports[com_port]);
        ports.erase(com_port);
        win32_error(name);
    }

    /* configure the port */

    dcb.BaudRate = baud_rate;
    dcb.ByteSize = databits;
    dcb.Parity = Parity;
    dcb.StopBits = StopBits;

    /* configure handshaking */
	switch (handshaking) {
	case sdffserNOHANDSHAKING:
		dcb.fOutxCtsFlow = false;					// Disable CTS monitoring
		dcb.fOutxDsrFlow = false;					// Disable DSR monitoring
		dcb.fDtrControl = DTR_CONTROL_DISABLE;		// Disable DTR monitoring
		dcb.fOutX = false;							// Disable XON/XOFF for transmission
		dcb.fInX = false;							// Disable XON/XOFF for receiving
		dcb.fRtsControl = RTS_CONTROL_DISABLE;		// Disable RTS (Ready To Send)
		break;

	case sdffserHARDWARE:
		dcb.fOutxCtsFlow = true;					// Enable CTS monitoring
		dcb.fOutxDsrFlow = true;					// Enable DSR monitoring
		dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;	// Enable DTR handshaking
		dcb.fOutX = false;							// Disable XON/XOFF for transmission
		dcb.fInX = false;							// Disable XON/XOFF for receiving
		dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;	// Enable RTS handshaking
		break;

	case sdffserXONXOFF:
		dcb.fOutxCtsFlow = false;					// Disable CTS (Clear To Send)
		dcb.fOutxDsrFlow = false;					// Disable DSR (Data Set Ready)
		dcb.fDtrControl = DTR_CONTROL_DISABLE;		// Disable DTR (Data Terminal Ready)
		dcb.fOutX = true;							// Enable XON/XOFF for transmission
		dcb.fInX = true;							// Enable XON/XOFF for receiving
		dcb.fRtsControl = RTS_CONTROL_DISABLE;		// Disable RTS (Ready To Send)
		break;
	}
    fSuccess = SetCommState(ports[com_port], &dcb);
    if (!fSuccess) {
        CloseHandle(ports[com_port]);
        ports.erase(com_port);
        win32_error(name);
    }


    COMMTIMEOUTS commTimeout;

    if(GetCommTimeouts(ports[com_port], &commTimeout))
    {
        commTimeout.ReadIntervalTimeout     = 500;
        commTimeout.ReadTotalTimeoutConstant     = 100;
        commTimeout.ReadTotalTimeoutMultiplier     = 500;
        commTimeout.WriteTotalTimeoutConstant     = 100;
        commTimeout.WriteTotalTimeoutMultiplier = 500;
    } else {
        CloseHandle(ports[com_port]);
        ports.erase(com_port);
        win32_error(name);
    }


    if(!SetCommTimeouts(ports[com_port], &commTimeout)) {
        CloseHandle(ports[com_port]);
        ports.erase(com_port);
        win32_error(name);
    }
}
示例#6
0
COMMNG cmserial_create(UINT port, UINT8 param, UINT32 speed) {

	TCHAR	commstr[16];
	HANDLE	hdl;
	DCB		dcb;
	UINT	i;
	COMMNG	ret;
	CMSER	serial;

	wsprintf(commstr, _T("COM%u"), port);
	hdl = CreateFile(commstr, GENERIC_READ | GENERIC_WRITE,
												0, 0, OPEN_EXISTING, 0, NULL);
	if (hdl == INVALID_HANDLE_VALUE) {
		goto cscre_err1;
	}
	GetCommState(hdl, &dcb);
	for (i=0; i<NELEMENTS(cmserial_speed); i++) {
		if (cmserial_speed[i] >= speed) {
			dcb.BaudRate = cmserial_speed[i];
			break;
		}
	}
	dcb.ByteSize = (UINT8)(((param >> 2) & 3) + 5);
	switch(param & 0x30) {
		case 0x10:
			dcb.Parity = ODDPARITY;
			break;

		case 0x30:
			dcb.Parity = EVENPARITY;
			break;

		default:
			dcb.Parity = NOPARITY;
			break;
	}
	switch(param & 0xc0) {
		case 0x80:
			dcb.StopBits = ONE5STOPBITS;
			break;

		case 0xc0:
			dcb.StopBits = TWOSTOPBITS;
			break;

		default:
			dcb.StopBits = ONESTOPBIT;
			break;
	}
	SetCommState(hdl, &dcb);
	ret = (COMMNG)_MALLOC(sizeof(_COMMNG) + sizeof(_CMSER), "SERIAL");
	if (ret == NULL) {
		goto cscre_err2;
	}
	ret->connect = COMCONNECT_MIDI;
	ret->read = serialread;
	ret->write = serialwrite;
	ret->getstat = serialgetstat;
	ret->msg = serialmsg;
	ret->release = serialrelease;
	serial = (CMSER)(ret + 1);
	serial->hdl = hdl;
	return(ret);

cscre_err2:
	CloseHandle(hdl);

cscre_err1:
	return(NULL);
}
示例#7
0
文件: cmt1.cpp 项目: GYengera/mrpt
//////////////////////////////////////////////////////////////////////////////////////////
// Open a communication channel to the given serial port name.
XsensResultValue Cmt1s::open(  const char *portName,
						const uint32_t baudRate,
						uint32_t readBufSize,
						uint32_t writeBufSize)
{
	MRPT_UNUSED_PARAM(readBufSize); MRPT_UNUSED_PARAM(writeBufSize);
	m_endTime = 0;

	CMT1LOG("L1: Open port %s at %d baud\n", portName, baudRate);

	if (m_isOpen)
	{
		CMT1LOG("L1: Port already open\n");
		return (m_lastResult = XRV_ALREADYOPEN);
	}
	m_baudrate = baudRate;

#ifdef _WIN32
	char winPortName[32];

	// Open port
	sprintf(winPortName, "\\\\.\\%s", portName);
	m_handle = CreateFileA(winPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
									OPEN_EXISTING, 0, NULL);
	if (m_handle == INVALID_HANDLE_VALUE)
	{
		CMT1LOG("L1: Port cannot be opened\n");
		return (m_lastResult = XRV_INPUTCANNOTBEOPENED);
	}

	// Once here, port is open
	m_isOpen = true;

	//Get the current state & then change it
	GetCommState(m_handle, &m_commState);	// Get current state

	m_commState.BaudRate = baudRate;			// Setup the baud rate
	m_commState.Parity = NOPARITY;				// Setup the Parity
	m_commState.ByteSize = 8;					// Setup the data bits
	m_commState.StopBits = TWOSTOPBITS;			// Setup the stop bits
	m_commState.fDsrSensitivity = FALSE;		// Setup the flow control
	m_commState.fOutxCtsFlow = FALSE;			// NoFlowControl:
	m_commState.fOutxDsrFlow = FALSE;
	m_commState.fOutX = FALSE;
	m_commState.fInX = FALSE;
	if (!SetCommState(m_handle, (LPDCB)&m_commState)) {// Set new state
		// Bluetooth ports cannot always be opened with 2 stopbits
		// Now try to open port with 1 stopbit.
		m_commState.StopBits = ONESTOPBIT;
		if (!SetCommState(m_handle, (LPDCB)&m_commState)) {
			CloseHandle(m_handle);
			m_handle = INVALID_HANDLE_VALUE;
			m_isOpen = false;
			return (m_lastResult = XRV_INPUTCANNOTBEOPENED);
		}
	}
	m_port = atoi(&portName[3]);
	sprintf(m_portname, "%s", portName);

	setTimeout(m_timeout);

	// Other initialization functions
	EscapeCommFunction(m_handle, SETRTS);		// Enable RTS (for Xbus Master use)
	// Set DTR (Calibration sensors need DTR to startup, won't hurt otherwise
	EscapeCommFunction(m_handle, SETDTR);
	SetupComm(m_handle,readBufSize,writeBufSize);	// Set queue size

	// Remove any 'old' data in buffer
	//PurgeComm(m_handle, PURGE_TXCLEAR | PURGE_RXCLEAR);
	PurgeComm(m_handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
#else // !_WIN32
	// Open port
	m_handle = ::open(portName, O_RDWR | O_NOCTTY);
	// O_RDWR: Read+Write
	// O_NOCTTY: Raw input, no "controlling terminal"
	// O_NDELAY: Don't care about DCD signal

	if (m_handle < 0) {
		// Port not open
		return m_lastResult = XRV_INPUTCANNOTBEOPENED;
	}

	// Once here, port is open
	m_isOpen = true;

	/* Start configuring of port for non-canonical transfer mode */
	// Get current options for the port
	tcgetattr(m_handle, &m_commState);

	// Set baudrate.
	cfsetispeed(&m_commState, baudRate);
	cfsetospeed(&m_commState, baudRate);

	// Enable the receiver and set local mode
	m_commState.c_cflag |= (CLOCAL | CREAD);
	// Set character size to data bits and set no parity Mask the characte size bits
	m_commState.c_cflag &= ~(CSIZE|PARENB);
	m_commState.c_cflag |= CS8;		// Select 8 data bits
	m_commState.c_cflag |= CSTOPB;	// send 2 stop bits
	// Disable hardware flow control
	m_commState.c_cflag &= ~CRTSCTS;
	m_commState.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
	// Disable software flow control
	m_commState.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
	// Set Raw output
	m_commState.c_oflag &= ~OPOST;
	// Timeout 0.001 sec for first byte, read minimum of 0 bytes
	m_commState.c_cc[VMIN]     = 0;
	m_commState.c_cc[VTIME]    = (m_timeout+99)/100;	// 1

	// Set the new options for the port
	tcsetattr(m_handle,TCSANOW, &m_commState);

	m_port = 0;
	sprintf(m_portname, "%s", portName);

	tcflush(m_handle, TCIOFLUSH);

	// setting RTS and DTR; RTS for Xbus Master, DTR for calibration sensors
	int cmbits;
	if (ioctl(m_handle, TIOCMGET, &cmbits) < 0)
	{
		return (m_lastResult = XRV_ERROR);
	}

	cmbits |= TIOCM_RTS|TIOCM_DTR;

	if (ioctl(m_handle, TIOCMSET, &cmbits) < 0)
	{
		return (m_lastResult = XRV_ERROR);
	}
#endif // !_WIN32

	CMT1LOG("L1: Port opened\n");
	return (m_lastResult = XRV_OK);
}
示例#8
0
Serial::Serial(char *portName)
{
    //We're not yet connected
    this->connected = false;

    //Try to connect to the given port through CreateFile
    this->hSerial = CreateFile(portName,
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

    //Check if the connection was successfull
    if(this->hSerial==INVALID_HANDLE_VALUE)
    {
        //If not successful display an Error
        if(GetLastError()==ERROR_FILE_NOT_FOUND){

            //Print Error if neccessary
            printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);

        }
        else
        {
            printf("ERROR!!!");
        }
    }
    else
    {
        //If connected we try to set the comm parameters
        DCB dcbSerialParams = {0};

        //Try to get the current
        if (!GetCommState(this->hSerial, &dcbSerialParams))
        {
            //If impossible, show an error
            printf("failed to get current serial parameters!");
        }
        else
        {
            //Define serial connection parameters for the arduino board
            dcbSerialParams.BaudRate=CBR_9600;
            dcbSerialParams.ByteSize=8;
            dcbSerialParams.StopBits=ONESTOPBIT;
            dcbSerialParams.Parity=NOPARITY;

             //Set the parameters and check for their proper application
             if(!SetCommState(hSerial, &dcbSerialParams))
             {
                printf("ALERT: Could not set Serial Port parameters");
             }
             else
             {
                 //If everything went fine we're connected
                 this->connected = true;
                 //We wait 2s as the arduino board will be reseting
                 Sleep(ARDUINO_WAIT_TIME);
             }
        }
    }

}
示例#9
0
/*
打开串口
*/
HANDLE CComInit::OpenComm(int ncom)
{
	memset( &m_read_os, 0, sizeof( OVERLAPPED ) ) ;    
	memset( &m_write_os, 0, sizeof( OVERLAPPED ) ) ;
	
	CString Com;
	Com.Format(_T("COM%d"),ncom);
	HANDLE hCom = CreateFile(Com,GENERIC_READ | GENERIC_WRITE,
		0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

	if(INVALID_HANDLE_VALUE==hCom)
	{
		CloseHandle(hCom);
		return hCom;
	}
	//创建事件
	m_read_os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	m_write_os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	if(NULL == m_read_os.hEvent || NULL == m_write_os.hEvent){
		CloseHandle(hCom);
		CloseHandle(m_read_os.hEvent);
		CloseHandle(m_write_os.hEvent);
		hCom = INVALID_HANDLE_VALUE;
		return hCom;
	}
	//设置com事件类型,参见msdn
	SetCommMask(hCom,EV_RXCHAR | EV_TXEMPTY);
	SetupComm( hCom, 1024,512 );//设置缓冲区大小;
	PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR
		| PURGE_RXCLEAR ); //清干净输入、输出缓冲区

	DCB dcb={0};
	dcb.DCBlength=sizeof(dcb);
	BOOL bres=GetCommState(hCom,&dcb);
	if(!bres)
	{
		CloseHandle(hCom);
		hCom=INVALID_HANDLE_VALUE;
		return hCom;
	}
	dcb.ByteSize=8;//后改
	dcb.fParity=0;
	dcb.BaudRate=CBR_9600;
	dcb.StopBits=ONESTOPBIT;

	bres=SetCommState(hCom,&dcb);
	if(!bres)
	{
		CloseHandle(hCom);
		hCom=INVALID_HANDLE_VALUE;
		return hCom;
	}
	COMMTIMEOUTS comm_time={0};
	comm_time.ReadIntervalTimeout=MAXDWORD;
	bres=SetCommTimeouts(hCom,&comm_time);
//	SetupComm(m_hComWndScreen, 4096, 1024);

	if(!bres)
	{
		CloseHandle(hCom);
		CloseHandle(m_read_os.hEvent);
		CloseHandle(m_write_os.hEvent);
		hCom = INVALID_HANDLE_VALUE;
		return hCom;
	}
	return hCom;
}
示例#10
0
static co_rc_t coserial_main(int argc, char *argv[])
{
	co_rc_t rc;
	co_module_t module;
	HANDLE out_handle, in_handle;
	int select_time;

	rc = handle_parameters(&g_daemon_parameters, argc, argv);
	if (!CO_OK(rc))
		return rc;

	rc = co_reactor_create(&g_reactor);
	if (!CO_OK(rc))
		return rc;

	co_debug("connecting to monitor");

	module = CO_MODULE_SERIAL0 + g_daemon_parameters.index;
	rc = co_user_monitor_open(g_reactor, monitor_receive,
				  g_daemon_parameters.instance,
				  &module, 1,
				  &g_monitor_handle);
	if (!CO_OK(rc))
		return rc;

	if (g_daemon_parameters.filename_specified == PTRUE) {
		char name [strlen(g_daemon_parameters.filename) + 4+1];
		DCB dcb;
		COMMTIMEOUTS commtimeouts = {
			1,	/* ReadIntervalTimeout */
			0,	/* ReadTotalTimeoutMultiplier */
			0,	/* ReadTotalTimeoutConstant */
			0,	/* WriteTotalTimeoutMultiplier */
			0 };	/* WriteTotalTimeoutConstant */

		if (g_daemon_parameters.filename[0] != '\\') {
			/* short windows name */
			if (strncasecmp(g_daemon_parameters.filename, "COM", 3) != 0)
				co_terminal_print("warning: host serial device '%s' is not a COM port\n",
						    g_daemon_parameters.filename);
			snprintf(name, sizeof(name), "\\\\.\\%s", g_daemon_parameters.filename);
		} else {
			/* windows full name device */
			strncpy(name, g_daemon_parameters.filename, sizeof(name));
		}

		co_debug("open device '%s'", name);
		out_handle = \
		in_handle = CreateFile (name,
				GENERIC_READ | GENERIC_WRITE, 0, NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
		if (in_handle == INVALID_HANDLE_VALUE) {
			co_terminal_print_last_error(g_daemon_parameters.filename);
			return CO_RC(ERROR);
		}

		if (g_daemon_parameters.mode_specified == PTRUE) {
			co_debug("set mode: %s", g_daemon_parameters.mode);

			if (!GetCommState(in_handle, &dcb)) {
				co_terminal_print_last_error("GetCommState");
				return CO_RC(ERROR);
			}

			/* Set defaults. user can overwrite ot */
			dcb.fOutxCtsFlow = FALSE; /* Disable Handshake */
			dcb.fDtrControl = DTR_CONTROL_ENABLE;
			dcb.fRtsControl = RTS_CONTROL_ENABLE;

			if (!BuildCommDCB(g_daemon_parameters.mode, &dcb)) {
				/*co_terminal_print_last_error("colinux-serial-daemon: BuildCommDCB");*/
				co_terminal_print("colinux-serial-daemon: error in mode parameter '%s'\n",
							g_daemon_parameters.mode);
				return CO_RC(ERROR);
			}

			if (!SetCommState(in_handle, &dcb)) {
				co_terminal_print_last_error("SetCommState");
				return CO_RC(ERROR);
			}
		} else {
			if (!EscapeCommFunction(in_handle, SETDTR)) {
				co_terminal_print_last_error("Warning EscapeCommFunction DTR");
				/* return CO_RC(ERROR); */
			}

			if (!EscapeCommFunction(in_handle, SETRTS)) {
				co_terminal_print_last_error("Warning EscapeCommFunction RTS");
				/* return CO_RC(ERROR); */
			}
		}

		if (!SetCommTimeouts(in_handle, &commtimeouts)) {
			co_terminal_print_last_error("SetCommTimeouts");
			return CO_RC(ERROR);
		}

		if (!SetupComm(in_handle, 2048, 2048)) {
			co_terminal_print_last_error("SetupComm");
			return CO_RC(ERROR);
		}

		select_time = -1;
	} else {
		co_debug("std input/output");
		out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
		in_handle  = GetStdHandle(STD_INPUT_HANDLE);
		select_time = 100;
	}

	co_debug("connected");

	rc = co_winnt_reactor_packet_user_create(g_reactor,
						 out_handle, in_handle,
						 std_receive, &g_reactor_handle);
	if (!CO_OK(rc))
		return rc;

	co_terminal_print("colinux-serial-daemon: running\n");

	while (CO_OK(rc)) {
		rc = co_reactor_select(g_reactor, select_time);
		if (CO_RC_GET_CODE(rc) == CO_RC_BROKEN_PIPE)
			return CO_RC(OK); /* Normal, if linux shut down */

		if (!g_daemon_parameters.filename_specified)
			if ( _kbhit() )
				send_userinput();
	}

	return -1;
}
示例#11
0
bool PrinterSerial::RawConnect( string device, int baudrate ) {
#ifdef WIN32
  if ( IsConnected() || device_handle != INVALID_HANDLE_VALUE ) {
    Disconnect();
    if ( device_handle != INVALID_HANDLE_VALUE )
      return false;
  }

  device_handle = CreateFile( device.c_str(),
			      GENERIC_READ | GENERIC_WRITE,
			      0,
			      NULL,
			      OPEN_EXISTING,
			      FILE_ATTRIBUTE_NORMAL,
			      NULL );
  if ( device_handle == INVALID_HANDLE_VALUE ) {
    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error opening port %s"), device.c_str() );
    err_str[ 256 ] = '\0';

    ostringstream os;
    os << err_str << " (" << GetLastError() << ")"<< endl;
    LogError( os.str().c_str() );
    return false;
  }

  DCB dcb = { 0 };
  dcb.DCBlength = sizeof( dcb );

  if ( ! GetCommState( device_handle, &dcb ) ) {
    CloseHandle( device_handle );
    device_handle = INVALID_HANDLE_VALUE;
    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error getting port %s state"), device.c_str() );
    err_str[ 255 ] = '\0';

    ostringstream os;
    os << err_str << " (" << GetLastError() << ")"<< endl;
    LogError( os.str().c_str() );
    return false;
  }

  dcb.BaudRate = baudrate;
  dcb.fBinary = 1;
  dcb.fParity = 0;
  dcb.fOutxCtsFlow = 0;
  dcb.fOutxDsrFlow = 0;
  dcb.fDtrControl = DTR_CONTROL_ENABLE;
  dcb.fDsrSensitivity = 0;
  dcb.fOutX = 0;
  dcb.fInX = 0;
  dcb.fNull = 0;
  dcb.fRtsControl = RTS_CONTROL_ENABLE;
  dcb.ByteSize = 8;
  dcb.Parity = NOPARITY;
  dcb.StopBits = ONESTOPBIT;

  if ( ! SetCommState( device_handle, &dcb ) ) {
    CloseHandle( device_handle );
    device_handle = INVALID_HANDLE_VALUE;
    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error setting port %s state"), device.c_str() );
    err_str[ 255 ] = '\0';

    ostringstream os;
    os << err_str << " (" << GetLastError() << ")"<< endl;
    LogError( os.str().c_str() );
    return false;
  }

  COMMTIMEOUTS ct;

  if ( ! GetCommTimeouts( device_handle, &ct ) ) {
    CloseHandle( device_handle );
    device_handle = INVALID_HANDLE_VALUE;
    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error getting port %s timeouts"), device.c_str() );
    err_str[ 255 ] = '\0';

    ostringstream os;
    os << err_str << " (" << GetLastError() << ")"<< endl;
    LogError( os.str().c_str() );
    return false;
  }

  ct.ReadIntervalTimeout = 5;
  ct.ReadTotalTimeoutConstant = max_recv_block_ms;
  ct.ReadTotalTimeoutMultiplier = 0;
  ct.WriteTotalTimeoutConstant = max_recv_block_ms;
  ct.WriteTotalTimeoutMultiplier= 0;

  if ( ! SetCommTimeouts( device_handle, &ct ) ) {
    CloseHandle( device_handle );
    device_handle = INVALID_HANDLE_VALUE;
    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error setting port %s timeouts"), device.c_str() );
    err_str[ 255 ] = '\0';
    ostringstream os;
    os << err_str << " (" << GetLastError() << ")"<< endl;
    LogError( os.str().c_str() );
    return false;
  }

  *raw_recv = '\0';

#else
  // Verify speed is valid and convert to posix value
  speed_t speed = B0;
  bool custom_baud = false;

  switch ( baudrate ) {
  case 50: speed = B50; break;
  case 75: speed = B75; break;
  case 110: speed = B110; break;
  case 134: speed = B134; break;
  case 150: speed = B150; break;
  case 200: speed = B200; break;
  case 300: speed = B300; break;
  case 600: speed = B600; break;
  case 1200: speed = B1200; break;
  case 1800: speed = B1800; break;
  case 2400: speed = B2400; break;
  case 4800: speed = B4800; break;
  case 9600: speed = B9600; break;
  case 19200: speed = B19200; break;
  case 38400: speed = B38400; break;
  case 57600: speed = B57600; break;
  case 115200: speed = B115200; break;
  case 230400: speed = B230400; break;
  default:
    ostringstream ostr;
    ostr << "Nonstandard baudrate " << baudrate << endl;
    LogLine( ostr.str().c_str() );
    speed = baudrate;
    custom_baud = true;
    // char err_str[ 256 ];
    // snprintf( err_str, 256, _( %d\n"), baudrate );
    // if ( err_str[ 254 ] != '\0' )
    //   err_str[ 254 ] = '\n';
    // err_str[ 255 ] = '\0';
    //LogError( err_str );
    // return false;
  }

  if ( IsConnected() || device_fd >= 0 ) {
    Disconnect();
    if ( device_fd >= 0 )
      return false;
  }

  // Open file
  if ( ( device_fd = open( device.c_str(), O_RDWR | O_NOCTTY ) ) < 0 ) {
    int err = errno;
    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error opening port %s"), device.c_str() );
    err_str[ 255 ] = '\0';

    ostringstream os;
    os << err_str << ": " << strerror( err ) << endl;
    LogError( os.str().c_str() );
    return false;
  }

  // Configure port
  struct termios attribs;
  if ( tcgetattr( device_fd, &attribs ) < 0 ) {
    int err = errno;
    close( device_fd );
    device_fd = -1;

    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error getting port %s state"), device.c_str() );
    err_str[ 255 ] = '\0';

    ostringstream os;
    os << err_str << ": " << strerror( err ) << endl;
    LogError( os.str().c_str() );
    return false;
  }

  // Use RAW settings, except add ICANON.  ICANON makes the port line buffered
  // and read will return immediately when a newline is received.
  // HUPCL lowers the modem control lines (hang up) when the port is closed
  cfmakeraw( &attribs );
  attribs.c_lflag |= ICANON;
  attribs.c_cflag |= HUPCL;

  if( tcsetattr( device_fd, TCSANOW, &attribs ) < 0 ) {
    close( device_fd );
    device_fd = -1;

    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error enabling port %s raw mode\n"), device.c_str() );
    if ( err_str[ 254 ] != '\0' )
      err_str[ 254 ] = '\n';
    err_str[ 255 ] = '\0';

    LogError( err_str );
    return false;
  }

  // Set port speed
  bool baudrate_succeeded = false;

#if HAVE_ASM_TERMBITS_H
  if ( custom_baud ) {
    // non-standard baud rate
    baudrate_succeeded = set_custom_baudrate( device_fd, speed );
  } else {
    baudrate_succeeded = cfsetispeed( &attribs, speed ) >= 0 
                      && cfsetospeed( &attribs, speed ) >= 0
                      && tcsetattr( device_fd, TCSANOW, &attribs )  >= 0;
  }
#else
  baudrate_succeeded = cfsetispeed( &attribs, speed ) >= 0 
                    && cfsetospeed( &attribs, speed ) >= 0
                    && tcsetattr( device_fd, TCSANOW, &attribs )  >= 0;
#endif

  if ( ! baudrate_succeeded ) {
    close( device_fd );
    device_fd = -1;
    char err_str[ 256 ];
    snprintf( err_str, 256, _("Error setting port %s baudrate to %d\n"), device.c_str(), baudrate );
    if ( err_str[ 254 ] != '\0' )
      err_str[ 254 ] = '\n';
    err_str[ 255 ] = '\0';

    LogError( err_str );
    return false;
  }

#endif

  char msg[ 256 ];
  memcpy( msg, "--- ", 4 );
  snprintf( msg + 4, 256 - 4, _("Connected to port %s at %d baud\n"), device.c_str(), baudrate );
  if ( msg[ 254 ] != '\0' )
    msg[ 254 ] = '\n';
  msg[ 255 ] = '\0';
  LogLine( msg );

  // Reset line number
  prev_cmd_line_number = 0;

  return true;
}
示例#12
0
BOOL SerialOpen(int port, int baud) {
	HANDLE Comport;
	DCB myDCB;
	COMMTIMEOUTS CTout;
	char str[100];

	if (port > 9)
		sprintf(str, "\\\\.\\COM%d", port);
	else
		sprintf(str, "COM%d", port);

	// Open the serial port
	if ((Comport = CreateFile(str, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
		return FALSE;

	// Configure Serial port (Setup Comm)

	// Buffer sizes
	if (!SetupComm(Comport, 128, 128))
		return FALSE;

	// Setup DCB using current values
	if (!GetCommState(Comport, &myDCB))
		return FALSE;

	myDCB.fInX = FALSE;     // Turn off xon/xoff handler
	myDCB.fOutX = FALSE;
	myDCB.fOutxDsrFlow = FALSE;
	myDCB.fOutxCtsFlow = FALSE;    // no hardware flow control.
	myDCB.BaudRate = baud;
	myDCB.DCBlength = sizeof(DCB);
	myDCB.fBinary = 1;
	myDCB.fParity = 0;
	myDCB.fDtrControl = DTR_CONTROL_DISABLE;
	myDCB.fDsrSensitivity = 0;
	myDCB.fTXContinueOnXoff = 1;
	myDCB.fNull = 0;
	myDCB.fRtsControl = RTS_CONTROL_DISABLE;
	myDCB.fDummy2 = 0;
	myDCB.wReserved = 0;
	myDCB.Parity = NOPARITY;
	myDCB.StopBits = ONESTOPBIT;
	myDCB.wReserved1 = 0;
	myDCB.ByteSize = 8;

	if (!SetCommState(Comport, &myDCB))
		return FALSE;

	// Set timeouts
	CTout.ReadIntervalTimeout = 0xffffffff;
	CTout.ReadTotalTimeoutMultiplier = 0;
	CTout.ReadTotalTimeoutConstant = 0;
	CTout.WriteTotalTimeoutMultiplier = 0;
	CTout.WriteTotalTimeoutConstant = 5000;         // don't hang if CTS is locked, for example

	SetCommTimeouts(Comport, &CTout);
	EscapeCommFunction(Comport, SETDTR);
	PurgeComm(Comport, PURGE_TXCLEAR | PURGE_RXCLEAR);

	SerialPort = Comport;

	return TRUE;
}
示例#13
0
// 打开串口
HANDLE CMySerialPort::OpenPort()
{
    if (IsOpen())
    {
        return m_portHandle;
    }

    if (0 >= m_strComName.GetLength())
    {
        LOG.err_log("请先设置串口参数");
        CString strTip = "请先设置串口参数";
        SHOWTIP(strTip);
        return INVALID_HANDLE_VALUE;
    }

    // 以重叠方式打开串口
    m_strComName = "\\\\.\\" + m_strComName;
    m_portHandle = CreateFile(m_strComName,
        GENERIC_READ|GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        0, //FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
        NULL);

    if (INVALID_HANDLE_VALUE == m_portHandle)
    {
        CString strTip;
        LOG.err_log("打开串口[%s]失败", (LPCSTR)m_strComName);
        strTip.Format("打开串口[%s]失败", m_strComName);
        SHOWTIP(strTip);
        return INVALID_HANDLE_VALUE;
    }

    // 设置串口参数
    DCB dcb;
    BOOL ret = GetCommState(m_portHandle, &dcb);
    if (FALSE == ret)
    {
        LOG.err_log("获取串口默认配置参数失败");
        CString strTip("获取串口默认配置参数失败");
        SHOWTIP(strTip);
        return INVALID_HANDLE_VALUE;
    }
    dcb.BaudRate = m_baud;
    dcb.StopBits = m_stopbits;
    dcb.Parity = m_check;
    dcb.ByteSize = m_databits;
    //dcb.fParity = FALSE; // 禁止奇偶检查
    //dcb.fBinary = TRUE;//是否允许传二进制 
    if (FALSE == SetCommState(m_portHandle,&dcb))
    {
        LOG.err_log("配置串口参数失败!");
        CString strTip("配置串口参数失败!");
        SHOWTIP(strTip);
        return INVALID_HANDLE_VALUE;
    }
    
    // 设置缓冲区大小
    if (FALSE == SetupComm(m_portHandle, 1024, 1024))
    {
        LOG.err_log("缓冲区设置失败!");
        CString strTip("缓冲区设置失败!");
        SHOWTIP(strTip);
        return INVALID_HANDLE_VALUE;
    }

    // 设置串口超时时间
    COMMTIMEOUTS CommTimeOuts;
    CommTimeOuts.ReadIntervalTimeout = 100;
    CommTimeOuts.ReadTotalTimeoutMultiplier = 100;
    CommTimeOuts.ReadTotalTimeoutConstant = 100;

    CommTimeOuts.WriteTotalTimeoutMultiplier = 500;
    CommTimeOuts.WriteTotalTimeoutConstant = 2000;
    if(false == SetCommTimeouts(m_portHandle,&CommTimeOuts))
    {
        LOG.err_log("设置读写超时时间失败!");
        CString strTip("设置读写超时时间失败!");
        SHOWTIP(strTip);
        return INVALID_HANDLE_VALUE;
    }

    // 清空发送和接收缓冲区
    PurgeComm(m_portHandle, PURGE_TXCLEAR|PURGE_RXCLEAR);

    m_bClosePort = false;

    return m_portHandle;
}
//open
//	Opens the serial port using stored information
//	Sets the baud rate to the stored baud rate
//	8 data bits, no parity, one stop bit
bool serial_port::serial_open()
{
    printf("SerialPort: Opening serial port %s at baud rate %d.\n", port_name, baud_rate);

#ifdef WINDOWS
    file_descriptor = CreateFile(port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

    if((int)file_descriptor < 0)
    {
        printf("SerialPort: Port %s could not be opened: %d.\n", port_name, file_descriptor);
        return false;
    }

    SetupComm(file_descriptor, 1, 128);
    GetCommState(file_descriptor, &dcb);

    dcb.BaudRate = baud_rate;                   //Set baud rate
    dcb.ByteSize = 8;                           //8 data bits
    dcb.Parity = NOPARITY;                      //Parity = none
    dcb.StopBits = ONESTOPBIT;                  //One stop bit
    dcb.fAbortOnError = TRUE;                   //Abort on error
    dcb.fOutX = FALSE;                          //XON/XOFF off for transmit
    dcb.fInX = FALSE;                           //XON/XOFF off for receive
    dcb.fOutxCtsFlow = FALSE;                   //Turn off CTS flow control
    dcb.fRtsControl = RTS_CONTROL_DISABLE;      //Options DISABLE, ENABLE, HANDSHAKE
    dcb.fOutxDsrFlow = FALSE;                   //Turn off DSR flow control
    dcb.fDtrControl = DTR_CONTROL_DISABLE;      //Disable DTR control

    SetCommState(file_descriptor, &dcb);

    COMMTIMEOUTS timeouts = {0};
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant=50;
    timeouts.ReadTotalTimeoutMultiplier=10;
    timeouts.WriteTotalTimeoutConstant=50;
    timeouts.WriteTotalTimeoutMultiplier=10;
    SetCommTimeouts(file_descriptor, &timeouts);
#endif

#ifdef LINUX
    file_descriptor = open(port_name, O_RDWR | O_NOCTTY | O_NDELAY);

    if(file_descriptor < 0)
    {
        printf("SerialPort: Port %s could not be opened: %d.\n", port_name, file_descriptor);
        return false;
    }

    serial_struct ss;
    ioctl(file_descriptor, TIOCGSERIAL, &ss);
    ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST | ASYNCB_LOW_LATENCY;
    ss.custom_divisor = (ss.baud_base + (baud_rate / 2)) / baud_rate;
    int closestSpeed = ss.baud_base / ss.custom_divisor;

    if((float)closestSpeed < ((float)baud_rate * (98.0f/100.0f)) || (float)closestSpeed > ((float)baud_rate * (102.0f/100.0f)))
    {
        printf("SerialPort: Cannot set %s to %d.  Closest possible speed is %d.\n", port_name, baud_rate, closestSpeed);
    }
    else
    {
        printf("SerialPort: %s speed set to %d.\n", port_name, baud_rate);
    }

    fcntl(file_descriptor, F_SETFL, 0);
#endif

    printf("SerialPort: Serial port %s opened successfully.\n", port_name);
    return true;
}
示例#15
0
ATMO_BOOL CAtmoClassicConnection::OpenConnection() {
#if defined(_ATMO_VLC_PLUGIN_)
     char *serdevice = m_pAtmoConfig->getSerialDevice();
     if(!serdevice)
        return ATMO_FALSE;
#else
     int portNummer = m_pAtmoConfig->getComport();
     m_dwLastWin32Error = 0;
	 if(portNummer < 1) return ATMO_FALSE; // make no real sense;-)
#endif

	 CloseConnection();

#if !defined(_ATMO_VLC_PLUGIN_)
     char serdevice[16];  // com4294967295
     sprintf(serdevice,"com%d",portNummer);
#endif

#if defined(WIN32)

     m_hComport = CreateFile(serdevice, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
     if(m_hComport == INVALID_HANDLE_VALUE) {
//      we have a problem here can't open com port... somebody else may use it?
//	    m_dwLastWin32Error = GetLastError();
	    return ATMO_FALSE;
     }
     /* change serial settings (Speed, stopbits etc.) */
     DCB dcb; // für comport-parameter
     dcb.DCBlength = sizeof(DCB);
     GetCommState (m_hComport, &dcb); // ger current serialport settings
     dcb.BaudRate  = 38400;        // set speed
     dcb.ByteSize  = 8;            // set databits
     dcb.Parity    = NOPARITY;     // set parity
     dcb.StopBits  = ONESTOPBIT;   // set one stop bit
     SetCommState (m_hComport, &dcb);    // apply settings

#else

     int bconst = B38400;
     m_hComport = open(serdevice,O_RDWR |O_NOCTTY);
     if(m_hComport < 0) {
	    return ATMO_FALSE;
     }

     struct termios tio;
     memset(&tio,0,sizeof(tio));
     tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
     tio.c_iflag = (INPCK | BRKINT);
     cfsetispeed(&tio, bconst);
     cfsetospeed(&tio, bconst);
     if(!tcsetattr(m_hComport, TCSANOW, &tio)) {
         tcflush(m_hComport, TCIOFLUSH);
     } else {
         // can't change parms
        close(m_hComport);
        m_hComport = -1;
        return false;
     }

#endif

     return true;
}
示例#16
0
bool SerialPort::Initialize() {
    TCHAR sysPortName[20];
    DCB PortDCB;

#if (WINDOWSPC>0)
    // Do not use COMn , use \\.\COMnn  on PC version
    _stprintf(sysPortName, _T("\\\\.\\%s"), GetPortName());
#else
    // Do not use COMn , use COMn:  on WinCE version
    _stprintf(sysPortName, _T("%s:"), GetPortName());
#endif
    StartupStore(_T(". ComPort %u Initialize <%s> speed=%u bit=%u %s"),GetPortIndex()+1,GetPortName(),_dwPortSpeed,8-_dwPortBit,NEWLINE);

    hPort = CreateFile(sysPortName, // Pointer to the name of the port
            GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode
            0, // Share mode
            NULL, // Pointer to the security attribute
            OPEN_EXISTING, // How to open the serial port
            FILE_ATTRIBUTE_NORMAL, // Port attributes
            NULL); // Handle to port with attribute
    // to copy

    if (hPort == INVALID_HANDLE_VALUE) {
        DWORD dwError = GetLastError();
        StartupStore(_T("... ComPort %u Init failed, error=%u%s"), GetPortIndex() + 1, dwError, NEWLINE); // 091117
        StatusMessage(MB_OK, NULL, TEXT("%s %s"), gettext(TEXT("_@M762_")), GetPortName());

        goto failed;
    }
    StartupStore(_T(". ComPort %u  <%s> is now open%s"), GetPortIndex() + 1, GetPortName(), NEWLINE);


    PortDCB.DCBlength = sizeof (DCB);
    // Get the default port setting information.
    if (GetCommState(hPort, &PortDCB)==0) {
    	StartupStore(_T("... ComPort %u GetCommState failed, error=%u%s"),GetPortIndex()+1,GetLastError(),NEWLINE);
        // @M759 = Unable to Change Settings on Port
        StatusMessage(MB_OK|MB_ICONINFORMATION, NULL, TEXT("%s %s"), gettext(TEXT("_@M759_")), GetPortName());
        goto failed;
    }
    // Change the DCB structure settings.
    PortDCB.BaudRate = _dwPortSpeed; // Current baud 
    PortDCB.fBinary = TRUE; // Binary mode; no EOF check 
    PortDCB.fParity = TRUE; // Enable parity checking  
    PortDCB.fOutxCtsFlow = FALSE; // CTS output flow control: when TRUE, and CTS off, output suspended
    PortDCB.fOutxDsrFlow = FALSE; // DSR output flow control 
    PortDCB.fDtrControl = DTR_CONTROL_ENABLE; 
    
    PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity 
    PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx 
    PortDCB.fOutX = FALSE; // No XON/XOFF out flow control 
    PortDCB.fInX = FALSE; // No XON/XOFF in flow control 
    PortDCB.fErrorChar = FALSE; // Disable error replacement 
    PortDCB.fNull = FALSE; // Disable null removal
    PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control 

    PortDCB.fAbortOnError = FALSE;
    switch (_dwPortBit) {
        case bit7E1:
            PortDCB.ByteSize = 7;
            PortDCB.Parity = EVENPARITY;
            break;
        case bit8N1:
        default:
            PortDCB.ByteSize = 8;
            PortDCB.Parity = NOPARITY;
            break;
    }

    PortDCB.StopBits = ONESTOPBIT;
    PortDCB.EvtChar = '\n'; // wait for end of line, RXFLAG should detect it

    if (!SetCommState(hPort, &PortDCB)) {
        DWORD dwError = GetLastError();
        StartupStore(_T("... ComPort %u Init <%s> change setting FAILED, error=%u%s"), GetPortIndex() + 1, GetPortName(), dwError, NEWLINE); // 091117
		// @M759 = Unable to Change Settings on Port
    	StatusMessage(MB_OK, TEXT("Error"), TEXT("%s %s"), gettext(TEXT("_@M759_")), GetPortName());

        goto failed;
    }

    if (SetRxTimeout(RXTIMEOUT) == -1) {
        DWORD dwError = GetLastError();
        StartupStore(_T("... ComPort %u Init <%s> change TimeOut FAILED, error=%u%s"), GetPortIndex() + 1, GetPortName(), dwError, NEWLINE); // 091117
        // LKTOKEN  _@M760_ = "Unable to Set Serial Port Timers" 
        StatusMessage(MB_OK, TEXT("Error"), TEXT("%s %s"), gettext(TEXT("_@M760_")), GetPortName());        

        goto failed;
    }

    SetupComm(hPort, 1024, 1024);

    // Direct the port to perform extended functions SETDTR and SETRTS
    // SETDTR: Sends the DTR (data-terminal-ready) signal.
    // SETRTS: Sends the RTS (request-to-send) signal. 
    EscapeCommFunction(hPort, SETDTR);
    EscapeCommFunction(hPort, SETRTS);

    if(!ComPort::Initialize()) {
        // no need to log failed of StartRxThread it's already made in ComPort::Initialize();
        goto failed;
    }

    StartupStore(_T(". ComPort %u Init <%s> end OK%s"), GetPortIndex() + 1, GetPortName(), NEWLINE);
    return true;
        
failed:
    if(hPort != INVALID_HANDLE_VALUE) {
        if (!CloseHandle(hPort)) {
            StartupStore(_T("... ComPort %u Init <%s> close failed, error=%u%s"),GetPortIndex() + 1, GetPortName(),NEWLINE);
        } else {
            StartupStore(_T("... ComPort %u Init <%s> closed%s"),GetPortIndex() + 1, GetPortName(),NEWLINE);
        }
        hPort = INVALID_HANDLE_VALUE;

#if (WINDOWSPC>0) || NEWCOMM // 091206
        Sleep(2000); // needed for windows bug
#endif
#if !(WINDOWSPC>0)
        if (_PollingMode) Sleep(2000);
#endif
    }
    return false;
}
示例#17
0
Serial::Serial()
{
	//We're not yet connected
	this->connected = false;

	HKEY hKey;
	if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Tyler Menezes\\Rfid Login", 0, KEY_READ, &hKey) != ERROR_SUCCESS){
		delete hKey;
		return; // Token not recognized.
	}

	std::wstring port;
	GetStringRegKey(hKey, L"Port", port, L"COM3");

	//Try to connect to the given port throuh CreateFile
	this->hSerial = CreateFile(port.c_str(),
			GENERIC_READ | GENERIC_WRITE,
			0,
			NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,
			NULL);

	//Check if the connection was successfull
	if(this->hSerial==INVALID_HANDLE_VALUE)
	{
		//If not success full display an Error
		if(GetLastError()==ERROR_FILE_NOT_FOUND){

			//Print Error if neccessary
			printf("ERROR: Handle was not attached. Reason: %s not available.\n");

		}
		else
		{
			printf("ERROR!!!");
		}
	}
	else
	{
		//If connected we try to set the comm parameters
		DCB dcbSerialParams = {0};

		//Try to get the current
		if (!GetCommState(this->hSerial, &dcbSerialParams))
		{
			//If impossible, show an error
			printf("failed to get current serial parameters!");
		}
		else
		{
			//Define serial connection parameters for the arduino board
			dcbSerialParams.BaudRate=CBR_9600;
			dcbSerialParams.ByteSize=8;
			dcbSerialParams.StopBits=ONESTOPBIT;
			dcbSerialParams.Parity=NOPARITY;

			 //Set the parameters and check for their proper application
			 if(!SetCommState(hSerial, &dcbSerialParams))
			 {
				printf("ALERT: Could not set Serial Port parameters");
			 }
			 else
			 {
				 //If everything went fine we're connected
				 this->connected = true;
				 //We wait 2s as the arduino board will be reseting
				 Sleep(ARDUINO_WAIT_TIME);
			 }
		}
	}

}
示例#18
0
static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf)
{
    DCB dcb;
    COMMTIMEOUTS timeouts;

    /*
     * Set up the serial port parameters. If we can't even
     * GetCommState, we ignore the problem on the grounds that the
     * user might have pointed us at some other type of two-way
     * device instead of a serial port.
     */
    if (GetCommState(serport, &dcb)) {
	const char *str;

	/*
	 * Boilerplate.
	 */
	dcb.fBinary = true;
	dcb.fDtrControl = DTR_CONTROL_ENABLE;
	dcb.fDsrSensitivity = false;
	dcb.fTXContinueOnXoff = false;
	dcb.fOutX = false;
	dcb.fInX = false;
	dcb.fErrorChar = false;
	dcb.fNull = false;
	dcb.fRtsControl = RTS_CONTROL_ENABLE;
	dcb.fAbortOnError = false;
	dcb.fOutxCtsFlow = false;
	dcb.fOutxDsrFlow = false;

	/*
	 * Configurable parameters.
	 */
	dcb.BaudRate = conf_get_int(conf, CONF_serspeed);
        logeventf(serial->logctx, "Configuring baud rate %lu", dcb.BaudRate);

	dcb.ByteSize = conf_get_int(conf, CONF_serdatabits);
        logeventf(serial->logctx, "Configuring %u data bits", dcb.ByteSize);

	switch (conf_get_int(conf, CONF_serstopbits)) {
	  case 2: dcb.StopBits = ONESTOPBIT; str = "1"; break;
	  case 3: dcb.StopBits = ONE5STOPBITS; str = "1.5"; break;
	  case 4: dcb.StopBits = TWOSTOPBITS; str = "2"; break;
	  default: return "Invalid number of stop bits (need 1, 1.5 or 2)";
	}
        logeventf(serial->logctx, "Configuring %s data bits", str);

	switch (conf_get_int(conf, CONF_serparity)) {
	  case SER_PAR_NONE: dcb.Parity = NOPARITY; str = "no"; break;
	  case SER_PAR_ODD: dcb.Parity = ODDPARITY; str = "odd"; break;
	  case SER_PAR_EVEN: dcb.Parity = EVENPARITY; str = "even"; break;
	  case SER_PAR_MARK: dcb.Parity = MARKPARITY; str = "mark"; break;
	  case SER_PAR_SPACE: dcb.Parity = SPACEPARITY; str = "space"; break;
	}
        logeventf(serial->logctx, "Configuring %s parity", str);

	switch (conf_get_int(conf, CONF_serflow)) {
	  case SER_FLOW_NONE:
	    str = "no";
	    break;
	  case SER_FLOW_XONXOFF:
	    dcb.fOutX = dcb.fInX = true;
	    str = "XON/XOFF";
	    break;
	  case SER_FLOW_RTSCTS:
	    dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
	    dcb.fOutxCtsFlow = true;
	    str = "RTS/CTS";
	    break;
	  case SER_FLOW_DSRDTR:
	    dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
	    dcb.fOutxDsrFlow = true;
	    str = "DSR/DTR";
	    break;
	}
        logeventf(serial->logctx, "Configuring %s flow control", str);

	if (!SetCommState(serport, &dcb))
	    return "Unable to configure serial port";

	timeouts.ReadIntervalTimeout = 1;
	timeouts.ReadTotalTimeoutMultiplier = 0;
	timeouts.ReadTotalTimeoutConstant = 0;
	timeouts.WriteTotalTimeoutMultiplier = 0;
	timeouts.WriteTotalTimeoutConstant = 0;
	if (!SetCommTimeouts(serport, &timeouts))
	    return "Unable to configure serial timeouts";
    }

    return NULL;
}
示例#19
0
/**
 * @brief Opens the serial device
 *
 * @param pDevice Pointer to string containing device name to open
 * @param baudRate The baud rate to open, valid values are 9600, 38400, 57600, 115200
 * @param timeoutMs Read timeout in milliseconds
 *
 * @return Status of open, 0 on success, -1 on failure to open
 */
int SerialDevice::openDevice(const char* pDevice, const unsigned int baudRate, unsigned int timeoutMs)
{
#ifdef WIN32

    // Open serial port on Windows
    m_deviceHandle = CreateFileA(pDevice, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (m_deviceHandle == INVALID_HANDLE_VALUE)
    {
        if(GetLastError() == ERROR_FILE_NOT_FOUND)
        {
            printf("SerialDevice: Error, serial device not found\n");
        }
        else
        {
            printf("SerialDevice: Error while opening serial device\n");
        }

        return -1;
    }

    // Set parameters
    DCB dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    // Get the port parameters
    if (!GetCommState(m_deviceHandle, &dcbSerialParams))
    {
        printf("SerialDevice: Error, could not get serial port params\n");
        return -1;
    }

    switch (baudRate)
    {
    case 9600:
        dcbSerialParams.BaudRate = CBR_9600;
        break;
    case 38400:
        dcbSerialParams.BaudRate = CBR_38400;
        break;
    case 57600:
        dcbSerialParams.BaudRate = CBR_57600;
        break;
    case 115200:
        dcbSerialParams.BaudRate = CBR_115200;
        break;
    default:
        printf("SerialDevice: Invalid baud rate specified: %i\n", baudRate);
        return -1;
    }

    dcbSerialParams.ByteSize = 8;                 // 8 data bits
    dcbSerialParams.StopBits = ONESTOPBIT;        // One stop bit
    dcbSerialParams.Parity = NOPARITY;            // No parity

    if (!SetCommState(m_deviceHandle, &dcbSerialParams))
    {
        printf("SerialDevice: Error setting CommState\n");
        return -1;
    }

    // Set Timeout
    m_timeouts.ReadIntervalTimeout = 0;
    m_timeouts.ReadTotalTimeoutConstant = (DWORD)timeoutMs; // Set the Timeout in Milliseconds
    m_timeouts.ReadTotalTimeoutMultiplier = 0;
    m_timeouts.WriteTotalTimeoutConstant = MAXDWORD;
    m_timeouts.WriteTotalTimeoutMultiplier = 0;

    if(!SetCommTimeouts(m_deviceHandle, &m_timeouts))
    {
        printf("SerialDevice: Error setting CommTimeouts\n");
        return -1;
    }
#endif

#ifdef __linux__
    speed_t speedSetting;

    // Open device
    m_deviceFd = open(pDevice, O_RDWR | O_NOCTTY | O_NDELAY);

    if (m_deviceFd == -1)
    {
        return -1;
    }

    // Open the device in nonblocking mode
    fcntl(m_deviceFd, F_SETFL, FNDELAY);

    // Set parameters
    tcgetattr(m_deviceFd, &m_portSettings);		// Get the current options of the port
    bzero(&m_portSettings, sizeof(m_portSettings));		// Clear all the options

    switch (baudRate)
    {
    case 9600:
        speedSetting = B9600;
        break;
    case 38400:
        speedSetting = B38400;
        break;
    case 57600:
        speedSetting = B57600;
        break;
    case 115200:
        speedSetting = B115200;
        break;
    default:
        printf("SerialDevice: Invalid baud rate specified: %i\n", baudRate);
        return -1;
    }
    cfsetispeed(&m_portSettings, speedSetting);
    cfsetospeed(&m_portSettings, speedSetting);
    m_portSettings.c_cflag |= (CLOCAL | CREAD |  CS8);
    m_portSettings.c_iflag |= (IGNPAR | IGNBRK );
    m_portSettings.c_cc[VTIME] = timeoutMs / 100;   // Timeout is in 1/10th second increments
    m_portSettings.c_cc[VMIN] = 0;
    tcsetattr(m_deviceFd, TCSANOW, &m_portSettings);
#endif
    return 0;
}
Serial::Serial(char *portName)
{
	wchar_t  PortName[100];
	std::mbstowcs(PortName, portName, 100);

	//We're not yet connected
	this->connected = false;

	//Try to connect to the given port throuh CreateFile
	this->hSerial = CreateFile(PortName,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	//Check if the connection was successfull
	if (this->hSerial == INVALID_HANDLE_VALUE)
	{
		//If not success full display an Error
		if (GetLastError() == ERROR_FILE_NOT_FOUND) {

			//Print Error if neccessary
			printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);

		}
		else
		{
			printf("ERROR!!!");
		}
	}
	else
	{
		//If connected we try to set the comm parameters
		DCB dcbSerialParams = { 0 };

		//Try to get the current
		if (!GetCommState(this->hSerial, &dcbSerialParams))
		{
			//If impossible, show an error
			printf("failed to get current serial parameters!");
		}
		else
		{
			//Define serial connection parameters for the arduino board
			dcbSerialParams.BaudRate = CBR_115200;
			dcbSerialParams.ByteSize = 8;
			dcbSerialParams.StopBits = ONESTOPBIT;
			dcbSerialParams.Parity = NOPARITY;
			//Setting the DTR to Control_Enable ensures that the Arduino is properly
			//reset upon establishing a connection
			dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;

			//Set the parameters and check for their proper application
			if (!SetCommState(hSerial, &dcbSerialParams))
			{
				printf("ALERT: Could not set Serial Port parameters");
			}
			else
			{
				//If everything went fine we're connected
				this->connected = true;
				//Flush any remaining characters in the buffers 
				PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
				//We wait 2s as the arduino board will be reseting
				Sleep(ARDUINO_WAIT_TIME);
			}
		}
	}

}
示例#21
0
Serial::Serial(TCHAR *strPort,int nRate,BOOL bSoftHandshake)
{
	m_bBacked=FALSE;
	m_bOK=TRUE;
	int nDelay[] = {2000, 1000, 400};

	m_hComm = CreateFile(strPort,
						 GENERIC_READ|GENERIC_WRITE,
						 0,
						 NULL,
						 OPEN_EXISTING,
						 FILE_ATTRIBUTE_NORMAL,
						 NULL);

	if(m_hComm == INVALID_HANDLE_VALUE)
	{
		m_bOK=FALSE;
		return;
	}
	
	int nTry = 3;
	BOOL bPass;
	while (nTry-- > 0)
	{
//		bPass = FlushFileBuffers(m_hComm);
//		if(!bPass)	break;

		bPass = EscapeCommFunction(m_hComm,CLRDTR);
		if(!bPass)	break;

		Sleep(nDelay[nTry]);
		bPass = EscapeCommFunction(m_hComm,SETDTR);
		if(!bPass)	break;
		
		DCB dcb;
		bPass = GetCommState(m_hComm,&dcb);
		if(!bPass)	break;
		
		dcb.fBinary = TRUE;
		dcb.BaudRate = nRate;
		dcb.EvtChar = 0x0D;
		
		dcb.fParity = FALSE;
		dcb.Parity = 0;
		dcb.ByteSize = 8;
		dcb.StopBits = 0;

		if (!bSoftHandshake)
		{
			dcb.fInX = FALSE;
			dcb.fOutX = FALSE;
			dcb.fOutxDsrFlow = FALSE;
			dcb.fOutxCtsFlow = FALSE;
		}
		else
		{
			dcb.fInX  = TRUE;
			dcb.fOutX = TRUE;
			dcb.fOutxDsrFlow = FALSE;
			dcb.fOutxCtsFlow = FALSE;
		}
		dcb.fDtrControl = DTR_CONTROL_ENABLE;
		dcb.fRtsControl = RTS_CONTROL_ENABLE;
		
		bPass = SetCommState(m_hComm,&dcb);
		if(!bPass)	break;

		Sleep(nDelay[nTry]);
		bPass = SetCommMask(m_hComm,EV_RXCHAR|EV_RXFLAG);
		if(!bPass)	break;
		
		bPass = SetupComm(m_hComm,1024,1024);
		if(!bPass)	break;
		
		bPass = PurgeComm(m_hComm,PURGE_RXABORT|PURGE_RXCLEAR);
		if(!bPass)	break;

		COMMTIMEOUTS timeouts;
		memset(&timeouts,0,sizeof(COMMTIMEOUTS));	//缺省超时设置
		timeouts.ReadIntervalTimeout=MAXDWORD;			//读时如果缓冲区有数据,直接返回,否则等待
		timeouts.ReadTotalTimeoutConstant=10000;		//最长10秒
		timeouts.ReadTotalTimeoutMultiplier=MAXDWORD;	//
		timeouts.WriteTotalTimeoutConstant=0;			//写时不计算超时
		timeouts.WriteTotalTimeoutMultiplier=0;			//
		bPass = SetCommTimeouts(m_hComm,&timeouts);
		if(!bPass)	break;

		if(bPass)
			break;
	}

	m_bOK=bPass;
}
示例#22
0
文件: uart.c 项目: BridgeHill/unabto
void uart_initialize(uint8_t channel, const void* name, uint32_t baudrate, uint8_t databits, uart_parity parity, uart_stopbits stopbits)
{
  const char* pipeIdentifier = "\\\\.\\pipe\\";
  int pipeIdentifierLength = strlen(pipeIdentifier);
  char nameBuffer[1024];

  uart_channel* uartChannel = look_up_uart_channel(channel);

  queue_init(&uartChannel->receiveQueue, uartChannel->receiveQueueBuffer, sizeof(uartChannel->receiveQueueBuffer));

  if (memcmp(pipeIdentifier, name, pipeIdentifierLength) != 0 && strlen(name) > 4 && ((const char*)name)[0] != '\\') // it's a com port higher than 9
  {
    sprintf_s(nameBuffer, sizeof(nameBuffer), "\\\\.\\%s", name);
    name = nameBuffer;
  }

  uartChannel->hPort = CreateFileA((LPCSTR)name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  if (uartChannel->hPort == INVALID_HANDLE_VALUE)
  {
    //DWORD error = GetLastError();
    //char* errorString = strerror(error);
    //NABTO_LOG_TRACE(("Error:%l", error));
    NABTO_LOG_FATAL(("Unable to open COM port '%s'!", (const char*)name));
  }

  if (memcmp(pipeIdentifier, name, pipeIdentifierLength) == 0) // it's a pipe
  {
    DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT;
    if (!SetNamedPipeHandleState(uartChannel->hPort, &mode, NULL, NULL))
    {
      //DWORD error = GetLastError();
      //char* errorString = strerror(error);
      //NABTO_LOG_TRACE(("Error:%l", error));
      NABTO_LOG_FATAL(("Unable to make pipe non-blocking '%s'!", (const char*)name));
    }
  }
  else // it's a COM port
  {
    // Configure com port
    memset(&uartChannel->dcb, 0, sizeof(DCB));
    uartChannel->dcb.DCBlength = sizeof(DCB);

    if (!GetCommState(uartChannel->hPort, &uartChannel->dcb))
    {
      NABTO_LOG_FATAL(("Unable to get COM port state!"));
    }

    uartChannel->dcb.BaudRate = baudrate;

    if (databits < 5 || 8 < databits)
    {
      NABTO_LOG_FATAL(("Invalid number of databits for UART!"));
    }
    uartChannel->dcb.ByteSize = databits;

    switch (parity)
    {
      case UART_PARITY_NONE:
        uartChannel->dcb.Parity = NOPARITY;
        break;

      case UART_PARITY_EVEN:
        uartChannel->dcb.fParity = TRUE;
        uartChannel->dcb.fErrorChar = FALSE;
        uartChannel->dcb.Parity = EVENPARITY;
        break;

      case UART_PARITY_ODD:
        uartChannel->dcb.fParity = TRUE;
        uartChannel->dcb.fErrorChar = FALSE;
        uartChannel->dcb.Parity = ODDPARITY;
        break;

      case UART_PARITY_MARK:
        uartChannel->dcb.fParity = TRUE;
        uartChannel->dcb.fErrorChar = FALSE;
        uartChannel->dcb.Parity = MARKPARITY;
        break;

      case UART_PARITY_SPACE:
        uartChannel->dcb.fParity = TRUE;
        uartChannel->dcb.fErrorChar = FALSE;
        uartChannel->dcb.Parity = SPACEPARITY;
        break;

      default:
        NABTO_LOG_FATAL(("Invalid number of databits for UART!"));
    }

    switch (stopbits)
    {
      case UART_STOPBITS_ONE:
        uartChannel->dcb.StopBits = ONESTOPBIT;
        break;

      case UART_STOPBITS_TWO:
        uartChannel->dcb.StopBits = TWOSTOPBITS;
        break;

      default:
        NABTO_LOG_FATAL(("Invalid number of stopbits for UART!"));
    }

    uartChannel->dcb.fBinary = TRUE;

    if (!SetCommState(uartChannel->hPort, &uartChannel->dcb))
    {
      NABTO_LOG_FATAL(("Unable to set COM port state!"));
    }

    // set event masks so the receive queue can be polled.
    if (!SetCommMask(uartChannel->hPort, EV_RXCHAR | EV_ERR))
    {
      DWORD error = GetLastError();
      NABTO_LOG_FATAL(("Unable to set COM port state (%lu)!", error));
    }

    // set read timeouts so ReadFile performs non-blocking reads.
    // RMW the port's timeouts structure
    if (!GetCommTimeouts(uartChannel->hPort, &uartChannel->timeouts))
    {
      NABTO_LOG_FATAL(("Unable to get COM port timeouts!"));
    }

    uartChannel->timeouts.ReadIntervalTimeout = MAXDWORD;
    uartChannel->timeouts.ReadTotalTimeoutConstant = 1;
    uartChannel->timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
    uartChannel->timeouts.WriteTotalTimeoutConstant = 200;
    uartChannel->timeouts.WriteTotalTimeoutMultiplier = 1;

    if (!SetCommTimeouts(uartChannel->hPort, &uartChannel->timeouts))
    {
      NABTO_LOG_FATAL(("Unable to set COM port timeouts!"));
    }
  }
}
示例#23
0
//
// 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 < MaxSerialPortNum+1);
	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;
}
示例#24
0
int SerialPort::init (const char device[]) 
{
#ifdef WIN32
	idCom=CreateFile(device,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if(idCom==INVALID_HANDLE_VALUE ) 
	{	
		idCom=NULL;
		printf("Error Opening port Win32\n");
		return(PORT_ERROR_CREATEFILE);
	}
	else
	{	
		GetCommState(idCom,&dcb);

		dcb.BaudRate=CBR_9600;
		dcb.fBinary=1;
		dcb.fOutxCtsFlow=0;
		dcb.fOutxDsrFlow=0;
		dcb.fDtrControl=1;////??????????
		//dcb.fDtrControl=DTR_CONTROL_DISABLE;////??????????
		dcb.fDsrSensitivity=0;
		dcb.fTXContinueOnXoff=1;
		dcb.fOutX=0;
		dcb.fInX=0;
		dcb.fErrorChar=0;
		dcb.fNull=0;
		dcb.fRtsControl=1;
		dcb.fAbortOnError=1;
		dcb.XonLim=2048;
		dcb.XoffLim=512;
		dcb.ByteSize=8;
		dcb.Parity=0;
		dcb.StopBits=0;
	//		dcb.StopBits=ONESTOPBIT;
		dcb.XonChar=17;
		dcb.XoffChar=19;
		dcb.ErrorChar=0;
		dcb.EofChar=0;
		dcb.EvtChar=0;
		dcb.DCBlength=sizeof(dcb);
		if(SetCommState(idCom,&dcb)==0)
		{
			CloseHandle(idCom);
			idCom=NULL;
			printf("Unable to configure port\n");
			return(PORT_ERROR_SETDCB);
		}
		timeouts.ReadIntervalTimeout=PORT_COMMS_INTERVAL_TIMEOUT;
		timeouts.ReadTotalTimeoutMultiplier=PORT_COMMS_TOTAL_TIMEOUT_MULTIPLIER;
		timeouts.ReadTotalTimeoutConstant=PORT_COMMS_TOTAL_TIMEOUT_CONSTANT;
		timeouts.WriteTotalTimeoutMultiplier=0;
		timeouts.WriteTotalTimeoutConstant=0;
		SetCommTimeouts(idCom,&timeouts);

	/*	unsigned long flus=0;
		int ret;
		do
		{
			char dummy[1000];
			ret=ReadFile(idCom,dummy,1000,&flus,NULL);
			if(flus!=0)
				printf("%d bytes have been flushed\n",flus);
		}while(flus!=0);*/

		return(PORT_OK);
	}
	
#else	
	if(serialPort!=-1)
		close();
  	struct termios serialSettings;
	serialPort=-1;
	serialPort = open (device, O_RDWR |O_NOCTTY);

	if(serialPort==-1) 
	{
		printf("Error al abrir el puerto\n");
		return PORT_ERROR;
	}

   	serialSettings.c_cc[VMIN] = 0;
  	serialSettings.c_cc[VTIME] = 1;
 
  	serialSettings.c_oflag = 0;
   	serialSettings.c_iflag = ( IGNPAR ) ;//DRL( IGNBRK | IGNPAR ) ;
   	serialSettings.c_cflag = ( CLOCAL| CREAD | B9600 | CS8 );
   	serialSettings.c_lflag = 0;   

   	cfsetospeed (&serialSettings, B9600);
   	cfsetispeed (&serialSettings, B9600);

   	if(tcsetattr (serialPort, TCSANOW, &serialSettings)!=0)
		return PORT_ERROR;
	else return PORT_OK;

#endif
}
// Automatic protocol detection
DFUEngine::Result DFURequestsCOM::AutomaticPassiveBCSP()
{
	// Ensure that any previous transport is disconnected
	impl_->transport.Disconnect();

	// Purge any operations in progress
	if (!PurgeComm(impl_->com, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
	{
		return DFUEngine::fail_os;
	}

	// Read the current COM port settings
	DCB dcb;
	COMMTIMEOUTS timeouts;
	if (!GetCommState(impl_->com, &dcb) || !GetCommTimeouts(impl_->com, &timeouts))
	{
		return DFUEngine::fail_os;
	}
	
	// Set the basic COM port configuration
	dcb.fBinary = true;
	dcb.fParity = comParity != NOPARITY;
	dcb.fOutxCtsFlow = true;
	dcb.fOutxDsrFlow = false;
	dcb.fDsrSensitivity = false;
	dcb.fOutX = false;
	dcb.fInX = false;
	dcb.fErrorChar = false;
	dcb.fNull = false;
	dcb.fAbortOnError = false;
	dcb.ByteSize = comDataBits;
	dcb.Parity = comParity;
	dcb.StopBits = comStopBits;
	if (!SetCommState(impl_->com, &dcb))
	{
		return DFUEngine::fail_os;
	}

	// Set the timeouts for reading
	uint32 timeout = impl_->baud && impl_->baud->next
		             ? comReceiveMilliseconds
					 : comReceiveMillisecondsSingle;
	timeouts.ReadIntervalTimeout = MAXDWORD;
	timeouts.ReadTotalTimeoutConstant = timeout;
	timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
	if (!SetCommTimeouts(impl_->com, &timeouts))
	{
		return DFUEngine::fail_os;
	}

	// Attempt to reset the connection using the handshaking lines
	dcb.fDtrControl = DTR_CONTROL_DISABLE;
	dcb.fRtsControl = RTS_CONTROL_DISABLE;
	if (!SetCommState(impl_->com, &dcb))
	{
		return DFUEngine::fail_os;
	}
	Sleep(comHandshakeMilliseconds);
	dcb.fDtrControl = DTR_CONTROL_ENABLE;
	dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
	if (!SetCommState(impl_->com, &dcb))
	{
		return DFUEngine::fail_os;
	}

	// Loop through each of the baud rates
	int bufferLength = 2 * sizeof(bcspSync);
	SmartPtr<uint8, true> buffer(new uint8[bufferLength]);
	bool connected = false;
	for (BaudRateList *pos = impl_->baud;
	     !connected && pos; pos = pos->next)
	{
		// Check for an abort request
		DFUEngine::Result result = CheckAbort();
		if (!result) return result;

		// Configure the port for this baud rate
		int baudRate = pos->baud;
		Progress(DFUEngine::transport_bcsp_passive_le, baudRate);
		dcb.BaudRate = baudRate;
		if (!SetCommState(impl_->com, &dcb))
		{
			return DFUEngine::fail_os;
		}

		// Look for the BCSP sync message
		int bufferUsed = 0;
		uint32 endTick = GetTickCount() + timeout;
		while (!connected && (int32(GetTickCount() - endTick) < 0))
		{
			// Ensure that there is sufficient space in the buffer
			DWORD read;
			int bufferLeave = sizeof(bcspSync) - 1;
			if (bufferLeave < bufferUsed)
			{
				// Shuffle the existing contents down
				memmove(buffer, buffer + bufferUsed - bufferLeave,
				        bufferLeave);
				bufferUsed = bufferLeave;
			}

			// Read some more data from the serial port
#if !defined _WINCE && !defined _WIN32_WCE
			OVERLAPPED overlapped;
			overlapped.Offset = 0;
			overlapped.OffsetHigh = 0;
			HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
			if(!event) return DFUEngine::fail_os;

			overlapped.hEvent = event;
			if (!ReadFile(impl_->com, buffer + bufferUsed,
			              bufferLength - bufferUsed, &read, &overlapped)
				&& (GetLastError() != ERROR_IO_PENDING))
			{
				CloseHandle(event);
				return DFUEngine::fail_os;
			}

			// Wait for the operation to complete
			WaitForSingleObject(event, timeout);
			CloseHandle(event);

			// Get the result
			if (!GetOverlappedResult(impl_->com, &overlapped, &read, false))
			{
				return DFUEngine::fail_os;
			}
#else
			// Set the serial port timeouts to return immediately
			COMMTIMEOUTS timeouts;
			memset(&timeouts, 0, sizeof(timeouts));
			timeouts.ReadIntervalTimeout = MAXDWORD;
			timeouts.ReadTotalTimeoutConstant = 0;
			timeouts.ReadTotalTimeoutMultiplier = 0;
			timeouts.WriteTotalTimeoutMultiplier = 0;
			timeouts.WriteTotalTimeoutConstant = 0;
			if (!SetCommTimeouts(impl_->com, &timeouts))
			{
				return DFUEngine::fail_os;
			}

			// Read any waiting data
			if (!ReadFile(impl_->com, buffer + bufferUsed,
				bufferLength - bufferUsed, &read, 0))
			{
				return DFUEngine::fail_os;
			}
#endif

			// Update the buffer position
			bufferUsed += read;

			// Check if the BCSP sync message has been received
			for (int offset = 0;
			     !connected && (offset + int(sizeof(bcspSync)) <= bufferUsed);
				 ++offset)
			{
				connected = !memcmp(buffer + offset,
				                    bcspSync, sizeof(bcspSync));
			}
		}

		// Store the baud rate and link establishment if successful
		if (connected)
		{
			FreeBaudRateList(impl_->baud);
			impl_->baud = new BaudRateList;
			impl_->baud->next = 0;
			impl_->baud->baud = baudRate;

			impl_->sync = sync_enabled;
		}
	}

	// Return an error if failed to connect
	if (!connected) return DFUEngine::fail_com_connect;

	// Attempt to start the actual transport
	DFUEngine::Result result = impl_->transport.ConnectBCSP(impl_->port, impl_->baud->baud, true, false, impl_->com);
	if (!result) return result;

	// Check if private channels work
	result = TestPrivateChannel();
	if (!result)
	{
		// Try tunnelling if appropriate
		if ((impl_->protocol == protocol_unknown)
			|| (impl_->protocol == protocol_bcsp_tunnel))
		{
			// Try again with tunnelling
            result = impl_->transport.ConnectBCSP(impl_->port, impl_->baud->baud, true, true, impl_->com);
            if (result)
                result = TestPrivateChannel();
			if (!result) return result;

			// Store the protocol if successful
			impl_->protocol = protocol_bcsp_tunnel;
		}
		else return result;
	}

	// Successful if this point reached
	return DFUEngine::success;
}
示例#26
0
/****************************************************************************
 * Opens com port
 *
 * \param comPort  Com port to be opened.
 * \param baud     Baud rate
 * \param 
 * \return         Opens the com port
 *****************************************************************************/
void CComPort::OpenComPort(unsigned int comPort, unsigned int baud)
{    
	CString buff;
	
    DWORD        bytes_read    = 0;     // Number of bytes read from port    
    DWORD        bytes_written = 0;    // Number of bytes written to the port    
    
    int   bStatus;
    DCB          comSettings;          // Contains various port settings    

	

	COMMTIMEOUTS CommTimeouts;

	

	if(comPortHandle)
	{
		// If com port is already open, close it.
		CloseComPort();
		
	}    
	          
	buff = comPortStrng[comPort];	
    
    // Open COM port    
    if ((comPortHandle =  CreateFile(buff,                // open com5:                    
    	GENERIC_READ | GENERIC_WRITE, // for reading and writing                    
    	0,                            // exclusive access                    
    	NULL,                         // no security attributes                    
    	OPEN_EXISTING,                                  
    	FILE_ATTRIBUTE_NORMAL,                    
    	NULL)) == INVALID_HANDLE_VALUE)    
    {        
    	// error processing code goes here		
		MessageBox(NULL, "Not able to open com port!", NULL, 0);
		comPortHandle = NULL;
			
	}  
	else
	{
		// Set timeouts in milliseconds    
		CommTimeouts.ReadIntervalTimeout         = 0;
		CommTimeouts.ReadTotalTimeoutMultiplier  = 0;
		CommTimeouts.ReadTotalTimeoutConstant    = 5; // Read time out 5ms.
		CommTimeouts.WriteTotalTimeoutMultiplier = 1;
		CommTimeouts.WriteTotalTimeoutConstant   = 500; // Write time out 500ms.


		(void)SetCommTimeouts(comPortHandle,&CommTimeouts);
	    
	    
		
		// Set Port parameters.    
		// Make a call to GetCommState() first in order to fill    
		// the comSettings structure with all the necessary values.    
		// Then change the ones you want and call SetCommState().    
		GetCommState(comPortHandle, &comSettings);

		baud = baudTable[baud];

			
		
		comSettings.BaudRate = baud;
		comSettings.StopBits = ONESTOPBIT;
		comSettings.ByteSize = 8;
		comSettings.Parity   = NOPARITY;   // No Parity
		comSettings.fParity  = FALSE;
		comSettings.fRtsControl = RTS_CONTROL_ENABLE; // Keep the RTS ON, to trigger bootloader enter bootload mode. 
		bStatus = SetCommState(comPortHandle, &comSettings);
	    
		
		if (bStatus == 0)    
		{        
			// error processing code goes here    
			MessageBox(NULL, "Error in setting the COM port!", NULL, 0);
			CloseComPort();
		} 
		
	}
}
示例#27
0
/******************************************************************************
 * @func :	ReadConfig
 * 
 * Rôle  :	Initialisation de donnees membres
 * @parm :	LPCSTR | szIni | fichier de configuration
 *****************************************************************************/
BOOL CSerialPort::bReadConfig(LPCTSTR pszFileName)
{
	TCHAR szPort[ 64 ];
	long lSizeDataMax;
	BOOL bReturn;

	bReturn = CThreadInterface::bReadConfig(pszFileName);
#ifndef TEST
	//TRACE_LOG_MSG(_T("! CThreadInterface::bReadConfig !"));
	// taille du buffer
	lSizeDataMax = iGetPrivateProfileInt(_T("Config"),_T("m_lSizeDataMax"),1024,pszFileName);
	//TRACE_LOG_MSG(_T("! m_lSizeDataMax !"));

	if (lSizeDataMax > 0)
	{
		if (m_pRxBuffer == NULL) 
		{
			m_pRxBuffer = (BYTE*)malloc(lSizeDataMax + 16);
		}
		else if (m_lSizeDataMax != lSizeDataMax)
		{
			m_pRxBuffer = (BYTE*)realloc(m_pRxBuffer,lSizeDataMax + 16);
		}
		m_lSizeDataMax = lSizeDataMax;
	}
	//TRACE_LOG_MSG(_T("! if (m_pRxBuffer == NULL) !"));

	// port com
	m_nNumPort = iGetPrivateProfileInt(_T("Config"),_T("m_nNumPort"),m_nNumPort,pszFileName);
	//TRACE_LOG_MSG(_T("! m_nNumPort !"));
	m_DCB.DCBlength = sizeof(DCB);
	//TRACE_LOG_MSG(_T("! sizeof(DCB) !"));
	memset(&m_DCB,0,sizeof(m_DCB));
	//TRACE_LOG_MSG(_T("! memset !"));
#ifdef _WIN32_WCE
	_stprintf( szPort, _T("COM%d:"), m_nNumPort );
#else
	_stprintf( szPort, _T("\\\\.\\COM%d"), m_nNumPort );
#endif
	//TRACE_LOG_MSG(_T("! szPort !"));
	m_hTTY = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM/*FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED*/, NULL );
	//TRACE_LOG_MSG(_T("! CreateFile !"));
	if (m_hTTY != INVALID_HANDLE_VALUE)
	{
		GetCommState( m_hTTY, &m_DCB );
		CloseHandle(m_hTTY);
		m_hTTY = INVALID_HANDLE_VALUE;
		//TRACE_LOG_MSG(_T("! CreateFile  ok!"));
	}
	else
	{
		TRACE_DEBUG_LAST_ERROR(eDebug,eConfig,GetLastError());
		TRACE_LOG_MSG(_T("! CreateFile fail!"));
	}
	//TRACE_LOG_MSG(_T("! m_hTTY !"));
	m_DCB.BaudRate = iGetPrivateProfileInt(_T("Com"), _T("BaudRate"),m_DCB.BaudRate, pszFileName);
	m_DCB.ByteSize = iGetPrivateProfileInt(_T("Com"), _T("ByteSize"), m_DCB.ByteSize, pszFileName);
	m_DCB.Parity = iGetPrivateProfileInt(_T("Com"), _T("Parity"), m_DCB.Parity, pszFileName);
	m_DCB.fParity = iGetPrivateProfileInt(_T("Com"), _T("fParity"), m_DCB.fParity, pszFileName);
	m_DCB.StopBits = iGetPrivateProfileInt(_T("Com"), _T("StopBits"),m_DCB.StopBits, pszFileName); 
	m_DCB.fBinary = iGetPrivateProfileInt(_T("Com"), _T("fBinary"), m_DCB.fBinary, pszFileName);
	m_DCB.fOutxCtsFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxCtsFlow"),m_DCB.fOutxCtsFlow, pszFileName);
	m_DCB.fOutxDsrFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxDsrFlow"),m_DCB.fOutxDsrFlow, pszFileName);
	m_DCB.fDtrControl = iGetPrivateProfileInt(_T("Com"), _T("fDtrControl"), m_DCB.fDtrControl, pszFileName);
	m_DCB.fDsrSensitivity = iGetPrivateProfileInt(_T("Com"), _T("fDsrSensitivity"), m_DCB.fDsrSensitivity, pszFileName);
	m_DCB.fTXContinueOnXoff = iGetPrivateProfileInt(_T("Com"), _T("fTXContinueOnXoff"),m_DCB.fTXContinueOnXoff, pszFileName);
	m_DCB.fOutX = iGetPrivateProfileInt(_T("Com"), _T("fOutX"), m_DCB.fOutX, pszFileName);
	m_DCB.fInX = iGetPrivateProfileInt(_T("Com"), _T("fInX"),m_DCB.fInX, pszFileName);
	m_DCB.fErrorChar = iGetPrivateProfileInt(_T("Com"), _T("fErrorChar"),m_DCB.fErrorChar, pszFileName);
	m_DCB.fNull = iGetPrivateProfileInt(_T("Com"), _T("fNull"),m_DCB.fNull, pszFileName);
	m_DCB.fRtsControl = iGetPrivateProfileInt(_T("Com"), _T("fRtsControl"), m_DCB.fRtsControl, pszFileName);
	m_DCB.fAbortOnError = iGetPrivateProfileInt(_T("Com"), _T("fAbortOnError"), m_DCB.fAbortOnError, pszFileName);
	m_DCB.XonLim = iGetPrivateProfileInt(_T("Com"), _T("XonLim"),m_DCB.XonLim, pszFileName);
	m_DCB.XoffLim = iGetPrivateProfileInt(_T("Com"), _T("XoffLim"),m_DCB.XoffLim, pszFileName);
	m_DCB.ErrorChar = iGetPrivateProfileInt(_T("Com"), _T("ErrorChar"),m_DCB.ErrorChar, pszFileName);
	m_DCB.XonChar = iGetPrivateProfileInt(_T("Com"), _T("XonChar"), m_DCB.XonChar, pszFileName);
	m_DCB.XoffChar = iGetPrivateProfileInt(_T("Com"), _T("XoffChar"), m_DCB.XoffChar, pszFileName);
	m_DCB.fDummy2 = 17;
	m_DCB.wReserved = 0;
	m_DCB.EofChar = iGetPrivateProfileInt(_T("Com"), _T("EofChar"), m_DCB.EofChar, pszFileName);//'\n';
	m_DCB.EvtChar = iGetPrivateProfileInt(_T("Com"), _T("EvtChar"), m_DCB.EvtChar, pszFileName);//'\r'; 
	//TRACE_LOG_MSG(_T("! all DCB !"));
#else
	HANDLE hf  ;
	long filelen = openFile(pszFileName, hf);
	// taille du buffer
	lSizeDataMax = iGetPrivateProfileInt(_T("Config"),_T("m_lSizeDataMax"),1024,hf, filelen);
	_tprintf(_T(" lSizeDataMax\n"));

	if (lSizeDataMax > 0)
	{
		if (m_pRxBuffer == NULL) 
		{
#ifndef TEST
			m_pRxBuffer = (BYTE*)malloc(lSizeDataMax + 16);
#else
			m_pRxBuffer = (BYTE*)HeapAlloc(getPrivateHeap(), 1, lSizeDataMax + 16);
#endif
		}
		else if (m_lSizeDataMax != lSizeDataMax)
		{
			_tprintf(_T("AV %d \n"),m_pRxBuffer);
			m_pRxBuffer = (BYTE*)realloc(m_pRxBuffer,lSizeDataMax + 16);
			_tprintf(_T("AV %d \n"),m_pRxBuffer);
		}
		m_lSizeDataMax = lSizeDataMax;
	}

	// port com
	m_nNumPort = iGetPrivateProfileInt(_T("Config"),_T("m_nNumPort"),m_nNumPort,hf, filelen);
	m_DCB.DCBlength = sizeof(DCB);
	memset(&m_DCB,0,sizeof(m_DCB));
	_tprintf(_T(" memset\n"));
	closeFile(hf);
#ifdef _WIN32_WCE
	_tprintf(_T(" _WIN32_WCE\n"));

	_stprintf( szPort, _T("COM%d:"), m_nNumPort );
#else
	_stprintf( szPort, _T("\\\\.\\COM%d"), m_nNumPort );
#endif
	_tprintf(_T(" m_hTTY\n"));

	m_hTTY = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM/*FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED*/, NULL );
	
	_tprintf(_T(" CreateFile\n"));
	if (m_hTTY != INVALID_HANDLE_VALUE)
	{
	_tprintf(_T(" INVALID_HANDLE_VALUE\n"));
		GetCommState( m_hTTY, &m_DCB );
		CloseHandle(m_hTTY);
		m_hTTY = INVALID_HANDLE_VALUE;
	}
	else
	{
	_tprintf(_T(" TRACE_DEBUG_LAST_ERROR\n"));

		TRACE_DEBUG_LAST_ERROR(eDebug,eConfig,GetLastError());
	}
	filelen = openFile(pszFileName, hf);

	_tprintf(_T(" TRACE_DEBUG_LAST_ERROR\n"));
	m_DCB.BaudRate = iGetPrivateProfileInt(_T("Com"), _T("BaudRate"),m_DCB.BaudRate, hf, filelen);
	m_DCB.ByteSize = iGetPrivateProfileInt(_T("Com"), _T("ByteSize"), m_DCB.ByteSize, hf, filelen);
	m_DCB.Parity = iGetPrivateProfileInt(_T("Com"), _T("Parity"), m_DCB.Parity, hf, filelen);
	m_DCB.fParity = iGetPrivateProfileInt(_T("Com"), _T("fParity"), m_DCB.fParity, hf, filelen);
	m_DCB.StopBits = iGetPrivateProfileInt(_T("Com"), _T("StopBits"),m_DCB.StopBits, hf, filelen); 
	m_DCB.fBinary = iGetPrivateProfileInt(_T("Com"), _T("fBinary"), m_DCB.fBinary, hf, filelen);
	m_DCB.fOutxCtsFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxCtsFlow"),m_DCB.fOutxCtsFlow, hf, filelen);
	m_DCB.fOutxDsrFlow = iGetPrivateProfileInt(_T("Com"), _T("fOutxDsrFlow"),m_DCB.fOutxDsrFlow, hf, filelen);
	m_DCB.fDtrControl = iGetPrivateProfileInt(_T("Com"), _T("fDtrControl"), m_DCB.fDtrControl, hf, filelen);
	m_DCB.fDsrSensitivity = iGetPrivateProfileInt(_T("Com"), _T("fDsrSensitivity"), m_DCB.fDsrSensitivity, hf, filelen);
	m_DCB.fTXContinueOnXoff = iGetPrivateProfileInt(_T("Com"), _T("fTXContinueOnXoff"),m_DCB.fTXContinueOnXoff, hf, filelen);
	m_DCB.fOutX = iGetPrivateProfileInt(_T("Com"), _T("fOutX"), m_DCB.fOutX, hf, filelen);
	m_DCB.fInX = iGetPrivateProfileInt(_T("Com"), _T("fInX"),m_DCB.fInX, hf, filelen);
	m_DCB.fErrorChar = iGetPrivateProfileInt(_T("Com"), _T("fErrorChar"),m_DCB.fErrorChar, hf, filelen);
	m_DCB.fNull = iGetPrivateProfileInt(_T("Com"), _T("fNull"),m_DCB.fNull, hf, filelen);
	m_DCB.fRtsControl = iGetPrivateProfileInt(_T("Com"), _T("fRtsControl"), m_DCB.fRtsControl, hf, filelen);
	m_DCB.fAbortOnError = iGetPrivateProfileInt(_T("Com"), _T("fAbortOnError"), m_DCB.fAbortOnError, hf, filelen);
	m_DCB.XonLim = iGetPrivateProfileInt(_T("Com"), _T("XonLim"),m_DCB.XonLim, hf, filelen);
	m_DCB.XoffLim = iGetPrivateProfileInt(_T("Com"), _T("XoffLim"),m_DCB.XoffLim, hf, filelen);
	m_DCB.ErrorChar = iGetPrivateProfileInt(_T("Com"), _T("ErrorChar"),m_DCB.ErrorChar, hf, filelen);
	m_DCB.XonChar = iGetPrivateProfileInt(_T("Com"), _T("XonChar"), m_DCB.XonChar, hf, filelen);
	m_DCB.XoffChar = iGetPrivateProfileInt(_T("Com"), _T("XoffChar"), m_DCB.XoffChar, hf, filelen);
	m_DCB.fDummy2 = 17;
	m_DCB.wReserved = 0;
	m_DCB.EofChar = iGetPrivateProfileInt(_T("Com"), _T("EofChar"), m_DCB.EofChar, hf, filelen);//'\n';
	m_DCB.EvtChar = iGetPrivateProfileInt(_T("Com"), _T("EvtChar"), m_DCB.EvtChar, hf, filelen);//'\r'; 
	_tprintf(_T(" m_DCB\n"));
	
	closeFile(hf);
	_tprintf(_T(" closeFile(hf);\n"));
#endif
	if (!bReturn) TRACE_DEBUG(eDebug,eConfig,_T(__FILE__),_T(__FUNCTION__),__LINE__,_T("Error"));

	return bReturn;
}
CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd)
					:CSerial (id, cmd) {
	InstallationSuccessful = false;
	hCom = INVALID_HANDLE_VALUE; // else destructor may close an invalid handle
	rx_retry = 0;
    rx_retry_max = 0;

	// open the port in NT object space (recommended by Microsoft)
	// allows the user to open COM10+ and custom port names.
	std::string prefix="\\\\.\\";
	std::string tmpstring;
	if(!cmd->FindStringBegin("realport:",tmpstring,false)) return;

#if SERIAL_DEBUG
		if(dbg_modemcontrol)
			fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n",
				PIC_FullIndex(),tmpstring.c_str());
#endif

	prefix.append(tmpstring);

	// rxdelay: How many milliseconds to wait before causing an
	// overflow when the application is unresponsive.
	if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) {
		if(!(rx_retry_max<=10000)) {
			rx_retry_max=0;
		}
	}

	const char* tmpchar=prefix.c_str();

	LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str());
	hCom = CreateFile (tmpchar,
					   GENERIC_READ | GENERIC_WRITE, 0,
									  // must be opened with exclusive-access
	                   NULL,          // no security attributes
	                   OPEN_EXISTING, // must use OPEN_EXISTING
	                   0,             // non overlapped I/O
	                   NULL           // hTemplate must be NULL for comm devices
	                  );

	if (hCom == INVALID_HANDLE_VALUE) {
		int error = GetLastError ();
		LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.",
			COMNUMBER, tmpstring.c_str());
		if (error == 2) {
			LOG_MSG ("The specified port does not exist.");
		} else if (error == 5) {
			LOG_MSG ("The specified port is already in use.");
		} else {
			LOG_MSG ("Windows error %d occurred.", error);
		}
		return;
	}

	dcb.DCBlength=sizeof(dcb);
	fSuccess = GetCommState (hCom, &dcb);

	if (!fSuccess) {
		// Handle the error.
		LOG_MSG ("GetCommState failed with error %d.\n", (int)GetLastError ());
		hCom = INVALID_HANDLE_VALUE;
		return;
	}

	// initialize the port
	dcb.BaudRate=CBR_9600;
	dcb.fBinary=true;
	dcb.fParity=true;
	dcb.fOutxCtsFlow=false;
	dcb.fOutxDsrFlow=false;
	dcb.fDtrControl=DTR_CONTROL_DISABLE;
	dcb.fDsrSensitivity=false;
	
	dcb.fOutX=false;
	dcb.fInX=false;
	dcb.fErrorChar=0;
	dcb.fNull=false;
	dcb.fRtsControl=RTS_CONTROL_DISABLE;
	dcb.fAbortOnError=false;

	dcb.ByteSize=8;
	dcb.Parity=NOPARITY;
	dcb.StopBits=ONESTOPBIT;

	fSuccess = SetCommState (hCom, &dcb);

	if (!fSuccess) {
		// Handle the error.
		LOG_MSG ("SetCommState failed with error %d.\n", (int)GetLastError ());
		hCom = INVALID_HANDLE_VALUE;
		return;
	}

	// Configure timeouts to effectively use polling
	COMMTIMEOUTS ct;
	ct.ReadIntervalTimeout = MAXDWORD;
	ct.ReadTotalTimeoutConstant = 0;
	ct.ReadTotalTimeoutMultiplier = 0;
	ct.WriteTotalTimeoutConstant = 0;
	ct.WriteTotalTimeoutMultiplier = 0;
	SetCommTimeouts (hCom, &ct);

	CSerial::Init_Registers();
	InstallationSuccessful = true;
	receiveblock=false;

	ClearCommBreak (hCom);
	setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick
}
示例#29
0
/* Sets up a serial port for RTU communications */
static int _modbus_rtu_connect(modbus_t *ctx)
{
#if defined(_WIN32)
    DCB dcb;
#else
    struct termios tios;
    speed_t speed;
#endif
    modbus_rtu_t *ctx_rtu = ctx->backend_data;

    if (ctx->debug) {
        printf("Opening %s at %d bauds (%c, %d, %d)\n",
               ctx_rtu->device, ctx_rtu->baud, ctx_rtu->parity,
               ctx_rtu->data_bit, ctx_rtu->stop_bit);
    }

#if defined(_WIN32)
    /* Some references here:
     * http://msdn.microsoft.com/en-us/library/aa450602.aspx
     */
    win32_ser_init(&ctx_rtu->w_ser);

    /* ctx_rtu->device should contain a string like "COMxx:" xx being a decimal number */
    ctx_rtu->w_ser.fd = CreateFileA(ctx_rtu->device,
                                    GENERIC_READ | GENERIC_WRITE,
                                    0,
                                    NULL,
                                    OPEN_EXISTING,
                                    0,
                                    NULL);

    /* Error checking */
    if (ctx_rtu->w_ser.fd == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "ERROR Can't open the device %s (%s)\n",
                ctx_rtu->device, strerror(errno));
        return -1;
    }

    /* Save params */
    ctx_rtu->old_dcb.DCBlength = sizeof(DCB);
    if (!GetCommState(ctx_rtu->w_ser.fd, &ctx_rtu->old_dcb)) {
        fprintf(stderr, "ERROR Error getting configuration (LastError %d)\n",
                (int)GetLastError());
        return -1;
    }

    /* Build new configuration (starting from current settings) */
    dcb = ctx_rtu->old_dcb;

    /* Speed setting */
    switch (ctx_rtu->baud) {
    case 110:
        dcb.BaudRate = CBR_110;
        break;
    case 300:
        dcb.BaudRate = CBR_300;
        break;
    case 600:
        dcb.BaudRate = CBR_600;
        break;
    case 1200:
        dcb.BaudRate = CBR_1200;
        break;
    case 2400:
        dcb.BaudRate = CBR_2400;
        break;
    case 4800:
        dcb.BaudRate = CBR_4800;
        break;
    case 9600:
        dcb.BaudRate = CBR_9600;
        break;
    case 19200:
        dcb.BaudRate = CBR_19200;
        break;
    case 38400:
        dcb.BaudRate = CBR_38400;
        break;
    case 57600:
        dcb.BaudRate = CBR_57600;
        break;
    case 115200:
        dcb.BaudRate = CBR_115200;
        break;
    default:
        dcb.BaudRate = CBR_9600;
        printf("WARNING Unknown baud rate %d for %s (B9600 used)\n",
               ctx_rtu->baud, ctx_rtu->device);
    }

    /* Data bits */
    switch (ctx_rtu->data_bit) {
    case 5:
        dcb.ByteSize = 5;
        break;
    case 6:
        dcb.ByteSize = 6;
        break;
    case 7:
        dcb.ByteSize = 7;
        break;
    case 8:
    default:
        dcb.ByteSize = 8;
        break;
    }

    /* Stop bits */
    if (ctx_rtu->stop_bit == 1)
        dcb.StopBits = ONESTOPBIT;
    else /* 2 */
        dcb.StopBits = TWOSTOPBITS;

    /* Parity */
    if (ctx_rtu->parity == 'N') {
        dcb.Parity = NOPARITY;
        dcb.fParity = FALSE;
    } else if (ctx_rtu->parity == 'E') {
        dcb.Parity = EVENPARITY;
        dcb.fParity = TRUE;
    } else {
        /* odd */
        dcb.Parity = ODDPARITY;
        dcb.fParity = TRUE;
    }

    /* Hardware handshaking left as default settings retrieved */

    /* No software handshaking */
    dcb.fTXContinueOnXoff = TRUE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;

    /* Binary mode (it's the only supported on Windows anyway) */
    dcb.fBinary = TRUE;

    /* Don't want errors to be blocking */
    dcb.fAbortOnError = FALSE;

    /* TODO: any other flags!? */

    /* Setup port */
    if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) {
        fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n",
                (int)GetLastError());
        return -1;
    }
#else
    /* The O_NOCTTY flag tells UNIX that this program doesn't want
       to be the "controlling terminal" for that port. If you
       don't specify this then any input (such as keyboard abort
       signals and so forth) will affect your process

       Timeouts are ignored in canonical input mode or when the
       NDELAY option is set on the file via open or fcntl */
    ctx->s = open(ctx_rtu->device, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL);
    if (ctx->s == -1) {
        fprintf(stderr, "ERROR Can't open the device %s (%s)\n",
                ctx_rtu->device, strerror(errno));
        return -1;
    }

    /* Save */
    tcgetattr(ctx->s, &(ctx_rtu->old_tios));

    memset(&tios, 0, sizeof(struct termios));

    /* C_ISPEED     Input baud (new interface)
       C_OSPEED     Output baud (new interface)
    */
    switch (ctx_rtu->baud) {
    case 110:
        speed = B110;
        break;
    case 300:
        speed = B300;
        break;
    case 600:
        speed = B600;
        break;
    case 1200:
        speed = B1200;
        break;
    case 2400:
        speed = B2400;
        break;
    case 4800:
        speed = B4800;
        break;
    case 9600:
        speed = B9600;
        break;
    case 19200:
        speed = B19200;
        break;
    case 38400:
        speed = B38400;
        break;
    case 57600:
        speed = B57600;
        break;
    case 115200:
        speed = B115200;
        break;
    default:
        speed = B9600;
        if (ctx->debug) {
            fprintf(stderr,
                    "WARNING Unknown baud rate %d for %s (B9600 used)\n",
                    ctx_rtu->baud, ctx_rtu->device);
        }
    }

    /* Set the baud rate */
    if ((cfsetispeed(&tios, speed) < 0) ||
        (cfsetospeed(&tios, speed) < 0)) {
        return -1;
    }

    /* C_CFLAG      Control options
       CLOCAL       Local line - do not change "owner" of port
       CREAD        Enable receiver
    */
    tios.c_cflag |= (CREAD | CLOCAL);
    /* CSIZE, HUPCL, CRTSCTS (hardware flow control) */

    /* Set data bits (5, 6, 7, 8 bits)
       CSIZE        Bit mask for data bits
    */
    tios.c_cflag &= ~CSIZE;
    switch (ctx_rtu->data_bit) {
    case 5:
        tios.c_cflag |= CS5;
        break;
    case 6:
        tios.c_cflag |= CS6;
        break;
    case 7:
        tios.c_cflag |= CS7;
        break;
    case 8:
    default:
        tios.c_cflag |= CS8;
        break;
    }

    /* Stop bit (1 or 2) */
    if (ctx_rtu->stop_bit == 1)
        tios.c_cflag &=~ CSTOPB;
    else /* 2 */
        tios.c_cflag |= CSTOPB;

    /* PARENB       Enable parity bit
       PARODD       Use odd parity instead of even */
    if (ctx_rtu->parity == 'N') {
        /* None */
        tios.c_cflag &=~ PARENB;
    } else if (ctx_rtu->parity == 'E') {
        /* Even */
        tios.c_cflag |= PARENB;
        tios.c_cflag &=~ PARODD;
    } else {
        /* Odd */
        tios.c_cflag |= PARENB;
        tios.c_cflag |= PARODD;
    }

    /* Read the man page of termios if you need more information. */

    /* This field isn't used on POSIX systems
       tios.c_line = 0;
    */

    /* C_LFLAG      Line options

       ISIG Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT signals
       ICANON       Enable canonical input (else raw)
       XCASE        Map uppercase \lowercase (obsolete)
       ECHO Enable echoing of input characters
       ECHOE        Echo erase character as BS-SP-BS
       ECHOK        Echo NL after kill character
       ECHONL       Echo NL
       NOFLSH       Disable flushing of input buffers after
       interrupt or quit characters
       IEXTEN       Enable extended functions
       ECHOCTL      Echo control characters as ^char and delete as ~?
       ECHOPRT      Echo erased character as character erased
       ECHOKE       BS-SP-BS entire line on line kill
       FLUSHO       Output being flushed
       PENDIN       Retype pending input at next read or input char
       TOSTOP       Send SIGTTOU for background output

       Canonical input is line-oriented. Input characters are put
       into a buffer which can be edited interactively by the user
       until a CR (carriage return) or LF (line feed) character is
       received.

       Raw input is unprocessed. Input characters are passed
       through exactly as they are received, when they are
       received. Generally you'll deselect the ICANON, ECHO,
       ECHOE, and ISIG options when using raw input
    */

    /* Raw input */
    tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    /* C_IFLAG      Input options

       Constant     Description
       INPCK        Enable parity check
       IGNPAR       Ignore parity errors
       PARMRK       Mark parity errors
       ISTRIP       Strip parity bits
       IXON Enable software flow control (outgoing)
       IXOFF        Enable software flow control (incoming)
       IXANY        Allow any character to start flow again
       IGNBRK       Ignore break condition
       BRKINT       Send a SIGINT when a break condition is detected
       INLCR        Map NL to CR
       IGNCR        Ignore CR
       ICRNL        Map CR to NL
       IUCLC        Map uppercase to lowercase
       IMAXBEL      Echo BEL on input line too long
    */
    if (ctx_rtu->parity == 'N') {
        /* None */
        tios.c_iflag &= ~INPCK;
    } else {
        tios.c_iflag |= INPCK;
    }

    /* Software flow control is disabled */
    tios.c_iflag &= ~(IXON | IXOFF | IXANY);

    /* C_OFLAG      Output options
       OPOST        Postprocess output (not set = raw output)
       ONLCR        Map NL to CR-NL

       ONCLR ant others needs OPOST to be enabled
    */

    /* Raw ouput */
    tios.c_oflag &=~ OPOST;

    /* C_CC         Control characters
       VMIN         Minimum number of characters to read
       VTIME        Time to wait for data (tenths of seconds)

       UNIX serial interface drivers provide the ability to
       specify character and packet timeouts. Two elements of the
       c_cc array are used for timeouts: VMIN and VTIME. Timeouts
       are ignored in canonical input mode or when the NDELAY
       option is set on the file via open or fcntl.

       VMIN specifies the minimum number of characters to read. If
       it is set to 0, then the VTIME value specifies the time to
       wait for every character read. Note that this does not mean
       that a read call for N bytes will wait for N characters to
       come in. Rather, the timeout will apply to the first
       character and the read call will return the number of
       characters immediately available (up to the number you
       request).

       If VMIN is non-zero, VTIME specifies the time to wait for
       the first character read. If a character is read within the
       time given, any read will block (wait) until all VMIN
       characters are read. That is, once the first character is
       read, the serial interface driver expects to receive an
       entire packet of characters (VMIN bytes total). If no
       character is read within the time allowed, then the call to
       read returns 0. This method allows you to tell the serial
       driver you need exactly N bytes and any read call will
       return 0 or N bytes. However, the timeout only applies to
       the first character read, so if for some reason the driver
       misses one character inside the N byte packet then the read
       call could block forever waiting for additional input
       characters.

       VTIME specifies the amount of time to wait for incoming
       characters in tenths of seconds. If VTIME is set to 0 (the
       default), reads will block (wait) indefinitely unless the
       NDELAY option is set on the port with open or fcntl.
    */
    /* Unused because we use open with the NDELAY option */
    tios.c_cc[VMIN] = 0;
    tios.c_cc[VTIME] = 0;

    if (tcsetattr(ctx->s, TCSANOW, &tios) < 0) {
        return -1;
    }
#endif

    return 0;
}
int CSeries::SerOpen(int PortNo, long BaudRate, int Parity, int ByteSize)
{
	CString MsgStr;
	DCB			dcb;
	BOOL		fRetVal ;
	BYTE		i,bSet;
	DWORD		dwError;
	COMMTIMEOUTS  to;

	TCHAR DevName[10];
	wsprintf(DevName,"\\\\.\\COM%01d",(int)PortNo);

	SerClose();
	if ((m_CommPort=CreateFile(DevName , GENERIC_READ | GENERIC_WRITE  , 0  , 
		NULL , OPEN_EXISTING , NULL , NULL )) == INVALID_HANDLE_VALUE)
	{
		return -1;
	}
	for(i=0; i<5; i++)
	{
		/*设置缓冲区大小*/
		fRetVal = SetupComm(m_CommPort, MAX_BUFFER_IN ,MAX_BUFFER_OUT);
		if (fRetVal)		
		{
			break;
		}
		Sleep(100);
	}

	// purge any information in the buffer
	PurgeComm(m_CommPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );

	// set up for overlapped I/O

	GetCommTimeouts(m_CommPort, &to);
	to.ReadIntervalTimeout = 0xFFFFFFFF;
	to.ReadTotalTimeoutMultiplier =0;
	to.ReadTotalTimeoutConstant =0;
	to.WriteTotalTimeoutMultiplier =10;//10ms
	to.WriteTotalTimeoutConstant =5000;//5000ms
	SetCommTimeouts(m_CommPort, &to) ;

	// set up DCB
	dcb.DCBlength = sizeof(DCB) ;

	for(i=0; i<5; i++)
	{
		fRetVal =GetCommState(m_CommPort, &dcb);
		if (fRetVal)
		{
			break;
		}
		Sleep(100);
	}

	if (fRetVal == 0)
	{
		dwError = GetLastError();
		CloseHandle(m_CommPort);
		m_CommPort = INVALID_HANDLE_VALUE;
		return -2;
	}

	dcb.BaudRate=BaudRate;
	dcb.ByteSize=ByteSize;
	dcb.Parity = Parity;
	dcb.StopBits =ONESTOPBIT;//2009-10-29

	// setup hardware flow control

#if 2
	bSet = false;
	dcb.fOutxDsrFlow = bSet ;
	if (bSet)
		dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
	else
		dcb.fDtrControl = DTR_CONTROL_ENABLE;

	dcb.fOutxCtsFlow = bSet ;
	if (bSet)
		dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
	else
		dcb.fRtsControl = RTS_CONTROL_ENABLE;

	// setup software flow control

	bSet = false;
	dcb.fInX = dcb.fOutX = bSet ;

	dcb.XonLim = 100 ;
	dcb.XoffLim = 100 ;
	dcb.XonChar = XON;
	dcb.XoffChar = XOFF;

	dcb.fBinary = TRUE;
	if (dcb.Parity == 0)
		dcb.fParity = FALSE;
	else
		dcb.fParity = TRUE;
#else

	/**/
	dcb.fOutxCtsFlow = FALSE;				// No CTS output flow control 
	dcb.fOutxDsrFlow = FALSE;				// No DSR output flow control 
	dcb.fDtrControl = DTR_CONTROL_DISABLE; 
	// DTR flow control type 
	dcb.fDsrSensitivity = FALSE;			// DSR sensitivity 
	dcb.fTXContinueOnXoff = TRUE;			// XOFF continues Tx 
	dcb.fOutX = FALSE;						// No XON/XOFF out flow control 
	dcb.fInX = FALSE;						// No XON/XOFF in flow control 
	dcb.fErrorChar = FALSE;					// Disable error replacement 
	dcb.fNull = FALSE;						// Disable null stripping 
	dcb.fRtsControl = RTS_CONTROL_DISABLE; 
	// RTS flow control 
	dcb.fAbortOnError = FALSE;				// 当串口发生错误,并不终止串口读写
#endif
	// set up DCB
	dcb.DCBlength = sizeof( DCB );

	for(i=0; i<5; i++)
	{
		//Sleep(80);
		fRetVal = SetCommState(m_CommPort, &dcb);
		if (fRetVal)		break;
		Sleep(100);
	}
	if (fRetVal == 0)
	{
		dwError = GetLastError();
		// an error occurred, try to recover
		MsgStr.Format("<CE-%u>,Please Check ComPort", dwError);
		MessageBox(NULL, MsgStr, "SetCommState", MB_OK);
		CloseHandle(m_CommPort);
		m_CommPort = INVALID_HANDLE_VALUE;
		return -3;
	}

	GetCommState(m_CommPort, &dcb ) ;
	//	EscapeCommFunction(m_CommPort, SETDTR ) ;
	PurgeComm(m_CommPort , PURGE_TXABORT | PURGE_RXABORT |
		PURGE_TXCLEAR | PURGE_RXCLEAR ) ;

	return 0;




}