/*!
\fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits)
Sets the number of data bits used by the serial port.  Possible values of dataBits are:
\verbatim
    DATA_5      5 data bits
    DATA_6      6 data bits
    DATA_7      7 data bits
    DATA_8      8 data bits
\endverbatim

\note
This function is subject to the following restrictions:
\par
    5 data bits cannot be used with 2 stop bits.
\par
    1.5 stop bits can only be used with 5 data bits.
\par
    8 data bits cannot be used with space parity on POSIX systems.

*/
void Win_QextSerialPort::setDataBits(DataBitsType dataBits) {
    LOCK_MUTEX();
    if (Settings.DataBits!=dataBits) {
        if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
            (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) {
        }
        else {
            Settings.DataBits=dataBits;
        }
    }
    if (isOpen()) {
        switch(dataBits) {

            /*5 data bits*/
            case DATA_5:
                if (Settings.StopBits==STOP_2) {
                    TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
                }
                else {
                    Win_CommConfig.dcb.ByteSize=5;
                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                }
                break;

            /*6 data bits*/
            case DATA_6:
                if (Settings.StopBits==STOP_1_5) {
                    TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
                }
                else {
                    Win_CommConfig.dcb.ByteSize=6;
                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                }
                break;

            /*7 data bits*/
            case DATA_7:
                if (Settings.StopBits==STOP_1_5) {
                    TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
                }
                else {
                    Win_CommConfig.dcb.ByteSize=7;
                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                }
                break;

            /*8 data bits*/
            case DATA_8:
                if (Settings.StopBits==STOP_1_5) {
                    TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
                }
                else {
                    Win_CommConfig.dcb.ByteSize=8;
                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                }
                break;
        }
    }
    UNLOCK_MUTEX();
}
Example #2
0
/*!
\fn void Win_QextSerialPort::setFlowControl(FlowType flow)
Sets the flow control used by the port.  Possible values of flow are:
\verbatim
    FLOW_OFF            No flow control
    FLOW_HARDWARE       Hardware (RTS/CTS) flow control
    FLOW_XONXOFF        Software (XON/XOFF) flow control
\endverbatim
*/
void Win_QextSerialPort::setFlowControl(FlowType flow) 
{
    LOCK_MUTEX();
    if (Settings.FlowControl!=flow) 
    {
        Settings.FlowControl=flow;
    }

    if (isOpen()) 
    {
        switch(flow) 
        {
            /*no flow control*/
            case FLOW_OFF:
                {
                    m_WinCommConfig.dcb.fOutxCtsFlow=FALSE;
                    m_WinCommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
                    m_WinCommConfig.dcb.fInX=FALSE;
                    m_WinCommConfig.dcb.fOutX=FALSE;
                    SetCommConfig(m_WinHandle, &m_WinCommConfig, sizeof(COMMCONFIG));
                }
                break;

            /*software (XON/XOFF) flow control*/
            case FLOW_XONXOFF:
                {
                    m_WinCommConfig.dcb.fOutxCtsFlow=FALSE;
                    m_WinCommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
                    m_WinCommConfig.dcb.fInX=TRUE;
                    m_WinCommConfig.dcb.fOutX=TRUE;
                    SetCommConfig(m_WinHandle, &m_WinCommConfig, sizeof(COMMCONFIG));
                }
                break;

            case FLOW_HARDWARE:
                {
                    m_WinCommConfig.dcb.fOutxCtsFlow=TRUE;
                    m_WinCommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
                    m_WinCommConfig.dcb.fInX=FALSE;
                    m_WinCommConfig.dcb.fOutX=FALSE;
                    SetCommConfig(m_WinHandle, &m_WinCommConfig, sizeof(COMMCONFIG));
                }
                break;

            default:
                {
                    Assert(false);
                }
                break;
        }
    }
    UNLOCK_MUTEX();
}
/*-------------------------------------------
| Name:setRs2322
| Description:
| Parameters:
| Return Type:
| Comments:
| See:
---------------------------------------------*/
int setRs232(uart_config* config){
   COMMCONFIG commconfig;
   DWORD dwSize=sizeof(COMMCONFIG);
   char buffer[256]={0};
   sprintf(buffer,"%s: baud=%d parity=%c data=%d stop=%d",USE_COM,
           config->speed,
           config->parity,
           config->data,
           config->stop);

   if(!GetCommConfig(hCom,&commconfig,&dwSize))
      return -1;

   BuildCommDCB(buffer,&commconfig.dcb);

   //CommConfigDialog(USE_COM,NULL,&commconfig);

   if(!SetCommConfig(hCom,&commconfig,dwSize))
      return -1;

   printf("com cfg: %s\n",buffer);

   memcpy(&current_config,config,sizeof(uart_config));


   return 0;
}
/*!
\fn bool Win_QextSerialPort::open(OpenMode mode)
Opens a serial port.  Note that this function does not specify which device to open.  If you need
to open a device by name, see Win_QextSerialPort::open(const char*).  This function has no effect
if the port associated with the class is already open.  The port is also configured to the current
settings, as stored in the Settings structure.
*/
bool Win_QextSerialPort::open(OpenMode mode) {
	unsigned long confSize = sizeof(COMMCONFIG);
	Win_CommConfig.dwSize = confSize;
	DWORD dwFlagsAndAttributes = 0;
	if (queryMode() == QextSerialBase::EventDriven)
		dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;

    LOCK_MUTEX();
    if (mode == QIODevice::NotOpen)
        return isOpen();
    if (!isOpen()) {
        /*open the port*/
        Win_Handle=CreateFileA(port.toLatin1(), GENERIC_READ|GENERIC_WRITE,
                              FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
        if (Win_Handle!=INVALID_HANDLE_VALUE)
        {
            /*configure port settings*/
            GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
            GetCommState(Win_Handle, &(Win_CommConfig.dcb));

            /*set up parameters*/
            Win_CommConfig.dcb.fBinary=TRUE;
            Win_CommConfig.dcb.fInX=FALSE;
            Win_CommConfig.dcb.fOutX=FALSE;
            Win_CommConfig.dcb.fAbortOnError=FALSE;
            Win_CommConfig.dcb.fNull=FALSE;
            setBaudRate(Settings.BaudRate);
            setDataBits(Settings.DataBits);
            setStopBits(Settings.StopBits);
            setParity(Settings.Parity);
            setFlowControl(Settings.FlowControl);
            setTimeout(Settings.Timeout_Millisec);
            SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));

            //init event driven approach
			if (queryMode() == QextSerialBase::EventDriven) {
		        Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;
		        Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
		        Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
				Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
				Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
				SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
            	if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {
            		qWarning("Failed to set Comm Mask. Error code: %ld", GetLastError());
					UNLOCK_MUTEX();
            		return false;
            	}
            	overlapThread->start();
            }
			QIODevice::open(mode);
        }
    } else {
		UNLOCK_MUTEX();
    	return false;
    }
    UNLOCK_MUTEX();
    return isOpen();
}
/*!
\fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits)
Sets the number of stop bits used by the serial port.  Possible values of stopBits are:
\verbatim
    STOP_1      1 stop bit
    STOP_1_5    1.5 stop bits
    STOP_2      2 stop bits
\endverbatim

\note
This function is subject to the following restrictions:
\par
    2 stop bits cannot be used with 5 data bits.
\par
    1.5 stop bits cannot be used with 6 or more data bits.
\par
    POSIX does not support 1.5 stop bits.
*/
void Win_QextSerialPort::setStopBits(StopBitsType stopBits) {
    LOCK_MUTEX();
    if (Settings.StopBits!=stopBits) {
        if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) ||
            (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) {
        }
        else {
            Settings.StopBits=stopBits;
        }
    }
    if (isOpen()) {
        switch (stopBits) {

            /*one stop bit*/
            case STOP_1:
                Win_CommConfig.dcb.StopBits=ONESTOPBIT;
                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                break;

            /*1.5 stop bits*/
            case STOP_1_5:
                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");
                if (Settings.DataBits!=DATA_5) {
                    TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits");
                }
                else {
                    Win_CommConfig.dcb.StopBits=ONE5STOPBITS;
                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                }
                break;

            /*two stop bits*/
            case STOP_2:
                if (Settings.DataBits==DATA_5) {
                    TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
                }
                else {
                    Win_CommConfig.dcb.StopBits=TWOSTOPBITS;
                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                }
                break;
        }
    }
    UNLOCK_MUTEX();
}
/*!
Opens a serial port.  Note that this function does not specify which device to open.  If you need
to open a device by name, see QextSerialPort::open(const char*).  This function has no effect
if the port associated with the class is already open.  The port is also configured to the current
settings, as stored in the Settings structure.
*/
bool QextSerialPort::open(OpenMode mode) {
    unsigned long confSize = sizeof(COMMCONFIG);
    Win_CommConfig.dwSize = confSize;
    DWORD dwFlagsAndAttributes = 0;
    if (queryMode() == QextSerialPort::EventDriven)
        dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;

    QMutexLocker lock(mutex);
    if (mode == QIODevice::NotOpen)
        return isOpen();
    if (!isOpen()) {
        /*open the port*/
        Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE,
                              0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
        if (Win_Handle!=INVALID_HANDLE_VALUE) {
            QIODevice::open(mode);
            /*configure port settings*/
            GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
            GetCommState(Win_Handle, &(Win_CommConfig.dcb));

            /*set up parameters*/
            Win_CommConfig.dcb.fBinary=TRUE;
            Win_CommConfig.dcb.fInX=FALSE;
            Win_CommConfig.dcb.fOutX=FALSE;
            Win_CommConfig.dcb.fAbortOnError=FALSE;
            Win_CommConfig.dcb.fNull=FALSE;
            setBaudRate(Settings.BaudRate);
            setDataBits(Settings.DataBits);
            setStopBits(Settings.StopBits);
            setParity(Settings.Parity);
            setFlowControl(Settings.FlowControl);
            setTimeout(Settings.Timeout_Millisec);
            SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));

            //init event driven approach
            if (queryMode() == QextSerialPort::EventDriven) {
                Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;
                Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
                Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
                Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
                Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
                SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
                if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {
                    qWarning() << "failed to set Comm Mask. Error code:", GetLastError();
                    return false;
                }
                winEventNotifier = new QWinEventNotifier(overlap.hEvent, this);
                connect(winEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(onWinEvent(HANDLE)));
                WaitCommEvent(Win_Handle, &eventMask, &overlap);
            }
        }
    } else {
        return false;
    }
    return isOpen();
}
void CSerialPort::SetConfig(COMMCONFIG& config)
{
  ASSERT(IsOpen());

  DWORD dwSize = sizeof(COMMCONFIG);
  if (!SetCommConfig(m_hComm, &config, dwSize))
  {
    TRACE(_T("Failed in call to SetCommConfig\n"));
    AfxThrowSerialException();
  }
}
/*!
\fn void Win_QextSerialPort::setFlowControl(FlowType flow)
Sets the flow control used by the port.  Possible values of flow are:
\verbatim
    FLOW_OFF            No flow control
    FLOW_HARDWARE       Hardware (RTS/CTS) flow control
    FLOW_XONXOFF        Software (XON/XOFF) flow control
\endverbatim
*/
void Win_QextSerialPort::setFlowControl(FlowType flow) {
    LOCK_MUTEX();
    if (Settings.FlowControl!=flow) {
        Settings.FlowControl=flow;
    }
    if (1) {
        switch(flow) {

            /*no flow control*/
            case FLOW_OFF:
                Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
                Win_CommConfig.dcb.fInX=FALSE;
                Win_CommConfig.dcb.fOutX=FALSE;
                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                break;

            /*software (XON/XOFF) flow control*/
            case FLOW_XONXOFF:
                Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
                Win_CommConfig.dcb.fInX=TRUE;
                Win_CommConfig.dcb.fOutX=TRUE;
                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                break;

            case FLOW_HARDWARE:
                Win_CommConfig.dcb.fOutxCtsFlow=TRUE;
                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
                Win_CommConfig.dcb.fInX=FALSE;
                Win_CommConfig.dcb.fOutX=FALSE;
                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
                break;
        }
    }
    UNLOCK_MUTEX();
}
WindowsSimPort::WindowsSimPort(const char *port) {
	portname = NULL;

	if(NULL == port || 0 == strlen(port)) {
		return;
	}

	portname = strdup(port);

	char fullportname[512];
	_snprintf(fullportname, sizeof(fullportname), "\\\\.\\%s", portname);
	portHandle=CreateFileA(fullportname, GENERIC_READ|GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
	if (portHandle == INVALID_HANDLE_VALUE) {
		fprintf(stderr, "Invalid handle returned by CreateFileA [port \"%s\"]\n", fullportname);
		return;
	}
	COMMCONFIG Win_CommConfig;
	COMMTIMEOUTS Win_CommTimeouts;
	unsigned long confSize = sizeof(COMMCONFIG);
	Win_CommConfig.dwSize = confSize;
	GetCommConfig(portHandle, &Win_CommConfig, &confSize);
	Win_CommConfig.dcb.Parity = 0;
	Win_CommConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
	Win_CommConfig.dcb.fOutxCtsFlow = FALSE;
	Win_CommConfig.dcb.fOutxDsrFlow = FALSE;
	Win_CommConfig.dcb.fDtrControl = DTR_CONTROL_DISABLE;
	Win_CommConfig.dcb.fDsrSensitivity = FALSE;
	Win_CommConfig.dcb.fNull=FALSE;
	Win_CommConfig.dcb.fTXContinueOnXoff = FALSE;
	Win_CommConfig.dcb.fInX=FALSE;
	Win_CommConfig.dcb.fOutX=FALSE;
	Win_CommConfig.dcb.fBinary=TRUE;
	Win_CommConfig.dcb.DCBlength = sizeof(DCB);
	Win_CommConfig.dcb.BaudRate = 9600;
	Win_CommConfig.dcb.ByteSize = 8;
	Win_CommTimeouts.ReadIntervalTimeout = 50;
	Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
	Win_CommTimeouts.ReadTotalTimeoutConstant = 110;
	Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
	Win_CommTimeouts.WriteTotalTimeoutConstant = 110;
	SetCommConfig(portHandle, &Win_CommConfig, sizeof(COMMCONFIG));
	SetCommTimeouts(portHandle,&Win_CommTimeouts);

	readbuf_pos = 0;
	memset(readbuf, '\0', sizeof(readbuf));
	memset(lastread, '\0', sizeof(lastread));

	setUsable(1);
}
Example #10
0
bool setCommConfiguration(const char* device, RssconwindowsPortdata* pdata, DCB* port) {
	COMMCONFIG commConfig = {0};
	DWORD dwSize = sizeof(commConfig);
	commConfig.dwSize = dwSize;
	if (!GetDefaultCommConfig(device, &commConfig, &dwSize)) {
		fputs("Failed to get default port settings.\n", stderr);
		pdata->lastError = GetLastError();
		return false;
	}
	if (!SetCommConfig(pdata->portHandle, &commConfig, dwSize)) {
		fputs("Failed to set default port settings.\n", stderr);
		pdata->lastError = GetLastError();
		return false;
	}
	return true;
}
/*!
\fn void Win_QextSerialPort::setParity(ParityType parity)
Sets the parity associated with the serial port.  The possible values of parity are:
\verbatim
    PAR_SPACE       Space Parity
    PAR_MARK        Mark Parity
    PAR_NONE        No Parity
    PAR_EVEN        Even Parity
    PAR_ODD         Odd Parity
\endverbatim
*/
void Win_QextSerialPort::setParity(ParityType parity) {
    LOCK_MUTEX();
    if (Settings.Parity!=parity) {
        Settings.Parity=parity;
    }
    if (isOpen()) {
        Win_CommConfig.dcb.Parity=(unsigned char)parity;
        switch (parity) {

            /*space parity*/
            case PAR_SPACE:
                if (Settings.DataBits==DATA_8) {
                    TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");
                }
                Win_CommConfig.dcb.fParity=TRUE;
                break;

            /*mark parity - WINDOWS ONLY*/
            case PAR_MARK:
                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning:  Mark parity is not supported by POSIX systems");
                Win_CommConfig.dcb.fParity=TRUE;
                break;

            /*no parity*/
            case PAR_NONE:
                Win_CommConfig.dcb.fParity=FALSE;
                break;

            /*even parity*/
            case PAR_EVEN:
                Win_CommConfig.dcb.fParity=TRUE;
                break;

            /*odd parity*/
            case PAR_ODD:
                Win_CommConfig.dcb.fParity=TRUE;
                break;
        }
        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
    }
    UNLOCK_MUTEX();
}
Example #12
0
/*!
		\fn bool Win_QextSerialPort::open(OpenMode mode)
			Opens a serial port.  Note that this function does not specify which device to open.  If you need
			to open a device by name, see Win_QextSerialPort::open(const char*).  This function has no effect
			if the port associated with the class is already open.  The port is also configured to the current
			settings, as stored in the Settings structure.
*/
bool Win_QextSerialPort::open(OpenMode mode) {
	unsigned long confSize = sizeof(COMMCONFIG);
	Win_CommConfig.dwSize = confSize;
	
	LOCK_MUTEX();
	if (mode == QIODevice::NotOpen)
		return isOpen();
	if (!isOpen()) {
		/*open the port*/
		Win_Handle=CreateFileA(port.toLatin1(), GENERIC_READ|GENERIC_WRITE,
				FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
		if (Win_Handle!=INVALID_HANDLE_VALUE) {
			/*set open mode*/
			QIODevice::open(mode);
			
			/*configure port settings*/
			GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
			GetCommState(Win_Handle, &(Win_CommConfig.dcb));
			
			/*set up parameters*/
			Win_CommConfig.dcb.fBinary=TRUE;
			Win_CommConfig.dcb.fInX=FALSE;
			Win_CommConfig.dcb.fOutX=FALSE;
			Win_CommConfig.dcb.fAbortOnError=FALSE;
			Win_CommConfig.dcb.fNull=FALSE;
			setBaudRate(Settings.BaudRate);
			setDataBits(Settings.DataBits);
			setStopBits(Settings.StopBits);
			setParity(Settings.Parity);
			setFlowControl(Settings.FlowControl);
			setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
			SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
		}
	}
	UNLOCK_MUTEX();
	return isOpen();
}
static void CommPort_Init(HANDLE hComFile)
{
  if(!hComFile)
    return;
  COMMCONFIG CommConfig;
  DWORD ConfigSize = sizeof(CommConfig);
  memset(&CommConfig, 0, ConfigSize);
  GetCommConfig(hComFile, &CommConfig, &ConfigSize); 
  if(1)
  {
    CommConfig.dcb.BaudRate = CBR_57600;
    CommConfig.dcb.ByteSize = 8;
    CommConfig.dcb.Parity   = NOPARITY;
    CommConfig.dcb.StopBits = ONESTOPBIT;
    
    /*
    CommConfig.dcb.fTXContinueOnXoff = 0;
    CommConfig.dcb.fInX = 0;
    CommConfig.dcb.fOutX = 0;
    CommConfig.dcb.fOutxCtsFlow = 0;
    CommConfig.dcb.fOutxDsrFlow = 0;
    CommConfig.dcb.fDsrSensitivity = 0;
    CommConfig.dcb.fDtrControl = 0;
    CommConfig.dcb.fRtsControl = 0;*/
    /*CommConfig.dcb.StopBits = 0;
    (&CommConfig.dcb.BaudRate)[1] = 0x5091;*/
  }
  SetCommConfig(hComFile, &CommConfig, ConfigSize); 
  PurgeComm(hComFile, PURGE_TXCLEAR|PURGE_RXCLEAR);
  
  COMMTIMEOUTS Timeout;
  GetCommTimeouts(hComFile, &Timeout);
  Timeout.ReadIntervalTimeout = 1;
  Timeout.ReadTotalTimeoutMultiplier = 1;
  Timeout.ReadTotalTimeoutConstant = 1;
  SetCommTimeouts(hComFile, &Timeout);
}
static asynStatus
setOption(void *drvPvt, asynUser *pasynUser, const char *key, const char *val)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    DWORD commConfigSize = sizeof(tty->commConfig);
    BOOL ret;
    DWORD error;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
                    "%s setOption key %s val %s\n", tty->portName, key, val);
    if (tty->commHandle == INVALID_HANDLE_VALUE) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                "%s disconnected:", tty->serialDeviceName);
        return asynError;
    }

    ret = GetCommConfig(tty->commHandle, &tty->commConfig, &commConfigSize);
    if (ret == 0) {
        error = GetLastError();
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                            "%s error calling GetCommConfig %d", tty->serialDeviceName, error);
        return asynError;
    }

    if (epicsStrCaseCmp(key, "baud") == 0) {
        int baud;
        if(sscanf(val, "%d", &baud) != 1) {
            epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
                                                                "Bad number");
            return asynError;
        }
        tty->commConfig.dcb.BaudRate = baud;
    }
    else if (epicsStrCaseCmp(key, "bits") == 0) {
        int bits;
        if(sscanf(val, "%d", &bits) != 1) {
            epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
                                                                "Bad number");
            return asynError;
        }
        tty->commConfig.dcb.ByteSize = bits;
    }
    else if (epicsStrCaseCmp(key, "parity") == 0) {
        if (epicsStrCaseCmp(val, "none") == 0) {
            tty->commConfig.dcb.Parity = 0;
        }
        else if (epicsStrCaseCmp(val, "odd") == 0) {
            tty->commConfig.dcb.Parity = 1;
        }
        else if (epicsStrCaseCmp(val, "even") == 0) {
            tty->commConfig.dcb.Parity = 2;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                            "Invalid parity.");
            return asynError;
        }
    }
    else if (epicsStrCaseCmp(key, "stop") == 0) {
        if (epicsStrCaseCmp(val, "1") == 0) {
            tty->commConfig.dcb.StopBits = ONESTOPBIT;
        }
        else if (epicsStrCaseCmp(val, "2") == 0) {
            tty->commConfig.dcb.StopBits = TWOSTOPBITS;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                "Invalid number of stop bits.");
            return asynError;
        }
    }
    else if (epicsStrCaseCmp(key, "clocal") == 0) {
        if (epicsStrCaseCmp(val, "Y") == 0) {
            tty->commConfig.dcb.fOutxDsrFlow = FALSE;
            tty->commConfig.dcb.fDsrSensitivity = FALSE;
            tty->commConfig.dcb.fDtrControl = DTR_CONTROL_ENABLE;
        }
        else if (epicsStrCaseCmp(val, "N") == 0) {
            tty->commConfig.dcb.fOutxDsrFlow = TRUE;
            tty->commConfig.dcb.fDsrSensitivity = TRUE;
            tty->commConfig.dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                    "Invalid clocal value.");
            return asynError;
        }
    }
    else if (epicsStrCaseCmp(key, "crtscts") == 0) {
        if (epicsStrCaseCmp(val, "Y") == 0) {
            tty->commConfig.dcb.fOutxCtsFlow = TRUE;
            tty->commConfig.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
        }
        else if (epicsStrCaseCmp(val, "N") == 0) {
            tty->commConfig.dcb.fOutxCtsFlow = FALSE;
            tty->commConfig.dcb.fRtsControl = RTS_CONTROL_ENABLE;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                      "Invalid crtscts value.");
            return asynError;
        }
    }
    else if (epicsStrCaseCmp(key, "ixon") == 0) {
        if (epicsStrCaseCmp(val, "Y") == 0) {
            tty->commConfig.dcb.fOutX = TRUE  ;
        }
        else if (epicsStrCaseCmp(val, "N") == 0) {
            tty->commConfig.dcb.fOutX = FALSE;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                    "Invalid ixon value.");
            return asynError;
        }
    }
    else if (epicsStrCaseCmp(key, "ixany") == 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                    "Option ixany not supported on Windows");
        return asynError;       
    }
    else if (epicsStrCaseCmp(key, "ixoff") == 0) {
        if (epicsStrCaseCmp(val, "Y") == 0) {
            tty->commConfig.dcb.fInX = TRUE;
        }
        else if (epicsStrCaseCmp(val, "N") == 0) {
            tty->commConfig.dcb.fInX = FALSE;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                    "Invalid ixoff value.");
            return asynError;
        }
    }
    else if (epicsStrCaseCmp(key, "") != 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                                                "Unsupported key \"%s\"", key);
        return asynError;
    }
    ret = SetCommConfig(tty->commHandle, &tty->commConfig, commConfigSize);
    if (ret == 0) {
        error = GetLastError();
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                            "%s error calling SetCommConfig %d", tty->serialDeviceName, error);
        return asynError;
    }
    return asynSuccess;
}
Example #15
0
PORTTYPE open_port_and_set_baud_or_die(const char *name, long baud)
{
    PORTTYPE fd;
#if defined(MACOSX)
    struct termios tinfo;
    fd = open(name, O_RDWR | O_NONBLOCK);
    if (fd < 0) die("unable to open port %s\n", name);
    if (tcgetattr(fd, &tinfo) < 0) die("unable to get serial parms\n");
    cfmakeraw(&tinfo);
    if (cfsetspeed(&tinfo, baud) < 0) die("error in cfsetspeed\n");
    tinfo.c_cflag |= CLOCAL;
    if (tcsetattr(fd, TCSANOW, &tinfo) < 0) die("unable to set baud rate\n");
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
#elif defined(LINUX)
    struct termios tinfo;
    memset (&tinfo, 0, sizeof tinfo);
    struct serial_struct kernel_serial_settings;
    int r;
    fd = open(name, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0) die("unable to open port %s\n", name);
    if (tcgetattr(fd, &tinfo) < 0) die("unable to get serial parms\n");

    tinfo.c_cflag     &=  ~PARENB;            // Make 8n1
    tinfo.c_cflag     &=  ~CSTOPB;
    tinfo.c_cflag     &=  ~CSIZE;
    tinfo.c_cflag     |=  CS8;

    tinfo.c_cflag     &=  ~CRTSCTS;           // no flow control
    tinfo.c_cc[VMIN]   =  1;                  // read doesn't block
    tinfo.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
    tinfo.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines

    cfmakeraw(&tinfo);

    tcflush( fd, TCIFLUSH );

    if (cfsetspeed(&tinfo, baud) < 0) die("error in cfsetspeed\n");
    if (tcsetattr(fd, TCSANOW, &tinfo) < 0) die("unable to set baud rate\n");
    /* r = ioctl(fd, TIOCGSERIAL, &kernel_serial_settings); */
    /* if (r >= 0) { */
    /*     kernel_serial_settings.flags |= ASYNC_LOW_LATENCY; */
    /*     r = ioctl(fd, TIOCSSERIAL, &kernel_serial_settings); */
    /*     if (r >= 0) printf("set linux low latency mode\n"); */
    /* } */
#elif defined(WINDOWS)
    COMMCONFIG cfg;
    COMMTIMEOUTS timeout;
    DWORD n;
    char portname[256];
    int num;
    if (sscanf(name, "COM%d", &num) == 1) {
        sprintf(portname, "\\\\.\\COM%d", num); // Microsoft KB115831
    } else {
        strncpy(portname, name, sizeof(portname)-1);
        portname[n-1] = 0;
    }
    fd = CreateFile(portname, GENERIC_READ | GENERIC_WRITE,
        0, 0, OPEN_EXISTING, 0, NULL);
    if (fd == INVALID_HANDLE_VALUE) die("unable to open port %s\n", name);
    GetCommConfig(fd, &cfg, &n);
    //cfg.dcb.BaudRate = baud;
    cfg.dcb.BaudRate = 115200;
    cfg.dcb.fBinary = TRUE;
    cfg.dcb.fParity = FALSE;
    cfg.dcb.fOutxCtsFlow = FALSE;
    cfg.dcb.fOutxDsrFlow = FALSE;
    cfg.dcb.fOutX = FALSE;
    cfg.dcb.fInX = FALSE;
    cfg.dcb.fErrorChar = FALSE;
    cfg.dcb.fNull = FALSE;
    cfg.dcb.fRtsControl = RTS_CONTROL_ENABLE;
    cfg.dcb.fAbortOnError = FALSE;
    cfg.dcb.ByteSize = 8;
    cfg.dcb.Parity = NOPARITY;
    cfg.dcb.StopBits = ONESTOPBIT;
    cfg.dcb.fDtrControl = DTR_CONTROL_ENABLE;
    SetCommConfig(fd, &cfg, n);
    GetCommTimeouts(fd, &timeout);
    timeout.ReadIntervalTimeout = 0;
    timeout.ReadTotalTimeoutMultiplier = 0;
    timeout.ReadTotalTimeoutConstant = 1000;
    timeout.WriteTotalTimeoutConstant = 0;
    timeout.WriteTotalTimeoutMultiplier = 0;
    SetCommTimeouts(fd, &timeout);
#endif
    return fd;

}
    int ArduinoSerial::openPort(const char *portName)
    {


        _portName = std::string(portName);
        _portOpened = false;
        triedToConfigureAgain = false;
        closeSerial();
        fd = 0;
        _numberOfChannels = 1;
#if defined(__APPLE__) || defined(__linux__)
        struct termios options;

        fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY);//O_SHLOCK
        sleep(2);
        int bits;
#endif
#ifdef __APPLE__
        std::stringstream sstm;

        if (fd < 0) {
            sstm << "Unable to open " << portName << ", " << strerror(errno);
            errorString = sstm.str();
            std::cout<<"Unable to open "<<portName<<", "<<strerror(errno)<<"\n";
            return -1;
        }
        if (ioctl(fd, TIOCEXCL) == -1) {
            close(fd);
            sstm << "Unable to get exclussive access to port " << portName;;
            errorString = sstm.str();
            std::cout<<"Unable to get exclussive access to port "<<portName<<"\n";
            return -1;
        }
        if (ioctl(fd, TIOCMGET, &bits) < 0) {
            close(fd);
            sstm <<"Unable to query serial port signals on " << portName;
            errorString = sstm.str();
            std::cout<<"Unable to query serial port signals on "<<portName<<"\n";
            return -1;
        }
        bits &= ~(TIOCM_DTR | TIOCM_RTS);
        if (ioctl(fd, TIOCMSET, &bits) < 0) {
            close(fd);
            sstm <<"Unable to control serial port signals on " << portName;
            errorString = sstm.str();
            std::cout<<"Unable to control serial port signals on "<<portName<<"\n";
            return -1;
        }
        struct termios settings_orig;
        if (tcgetattr(fd, &settings_orig) < 0) {
            close(fd);
            sstm <<"Unable to access baud rate on port " << portName;
            errorString = sstm.str();
            std::cout<<"Unable to access baud rate on port "<<portName<<"\n";
            return -1;
        }
#endif
#ifdef __linux__
 // struct serial_struct kernel_serial_settings;
    struct termios settings_orig;
    //struct termios settings;
    if (fd < 0)
    {
        if (errno == EACCES)
        {
            std::cout<<"Unable to access "<< portName<< ", insufficient permission";
            // TODO: we could look at the permission bits and owner
            // to make a better message here
        }
        else if (errno == EISDIR)
        {
            std::cout<< "Unable to open " << portName <<
                     ", Object is a directory, not a serial port";
        }
        else if (errno == ENODEV || errno == ENXIO)
        {
            std::cout<< "Unable to open " << portName <<
                     ", Serial port hardware not installed";
        }
        else if (errno == ENOENT)
        {
            std::cout<< "Unable to open " << portName <<
                     ", Device name does not exist";
        }
        else
        {
            std::cout<< "Unable to open " << portName; //<<

        }
        return -1;
    }
    if (ioctl(fd, TIOCMGET, &bits) < 0)
    {
        close(fd);
        std::cout<< "Unable to query serial port signals";
        return -1;
    }
    bits &= ~(TIOCM_DTR | TIOCM_RTS);
    if (ioctl(fd, TIOCMSET, &bits) < 0)
    {
        close(fd);
        std::cout<< "Unable to control serial port signals";
        return -1;
    }
    if (tcgetattr(fd, &settings_orig) != 0)
    {
        close(fd);
        std::cout<< "Unable to query serial port settings (perhaps not a serial port)";
        return -1;
    }
    /*memset(&settings, 0, sizeof(settings));
    settings.c_iflag = IGNBRK | IGNPAR;
    settings.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
    Set_baud(baud_rate);
    if (ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings) == 0) {
    	kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
    	ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
    }
    tcflush(port_fd, TCIFLUSH);*/
#endif
#if defined(__APPLE__) || defined(__linux__)
        if (fd == -1)
        {
            std::cout<<"Can't open serial port\n";
            return -1;
        }
        fcntl(fd, F_SETFL, 0);    // clear all flags on descriptor, enable direct I/O
        tcgetattr(fd, &options);   // read serial port options
        // enable receiver, set 8 bit data, ignore control lines
        options.c_cflag |= (CLOCAL | CREAD | CS8);
        // disable parity generation and 2 stop bits
        options.c_cflag &= ~(PARENB | CSTOPB);

        //cfsetispeed(&options, B9600);
        //cfsetospeed(&options, B9600);

        cfsetispeed(&options, B230400);
        cfsetospeed(&options, B230400);

        // set the new port options
        tcsetattr(fd, TCSANOW, &options);
#endif

#ifdef _WIN32

	COMMCONFIG cfg;
	COMMTIMEOUTS timeouts;
	int got_default_cfg=0, port_num;
	char buf[1024], name_createfile[64], name_commconfig[64], *p;
	DWORD len;

	snprintf(buf, sizeof(buf), "%s", _portName.c_str());
	p = strstr(buf, "COM");
	if (p && sscanf(p + 3, "%d", &port_num) == 1) {
		printf("port_num = %d\n", port_num);
		snprintf(name_createfile, sizeof(name_createfile), "\\\\.\\COM%d", port_num);
		snprintf(name_commconfig, sizeof(name_commconfig), "COM%d", port_num);
	} else {
		snprintf(name_createfile, sizeof(name_createfile), "%s", _portName.c_str());
		snprintf(name_commconfig, sizeof(name_commconfig), "%s", _portName.c_str());
	}
	len = sizeof(COMMCONFIG);
	if (GetDefaultCommConfig(name_commconfig, &cfg, &len)) {
		// this prevents unintentionally raising DTR when opening
		// might only work on COM1 to COM9
		got_default_cfg = 1;
		memcpy(&port_cfg_orig, &cfg, sizeof(COMMCONFIG));
		cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
		cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
		SetDefaultCommConfig(name_commconfig, &cfg, sizeof(COMMCONFIG));
	} else {
		printf("error with GetDefaultCommConfig\n");
	}
	port_handle = CreateFile(name_createfile, GENERIC_READ | GENERIC_WRITE,
	   0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	if (port_handle == INVALID_HANDLE_VALUE) {
		win32_err(buf);
		//error_msg =  "Unable to open " + _portName + ", " + buf;
		return -1;
	}
	len = sizeof(COMMCONFIG);
	if (!GetCommConfig(port_handle, &port_cfg, &len)) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to read communication config on " + _portName + ", " + buf;
		return -1;
	}
	if (!got_default_cfg) {
		memcpy(&port_cfg_orig, &port_cfg, sizeof(COMMCONFIG));
	}
	// http://msdn2.microsoft.com/en-us/library/aa363188(VS.85).aspx
	port_cfg.dcb.BaudRate = 230400;
	port_cfg.dcb.fBinary = TRUE;
	port_cfg.dcb.fParity = FALSE;
	port_cfg.dcb.fOutxCtsFlow = FALSE;
	port_cfg.dcb.fOutxDsrFlow = FALSE;
	port_cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
	port_cfg.dcb.fDsrSensitivity = FALSE;
	port_cfg.dcb.fTXContinueOnXoff = TRUE;	// ???
	port_cfg.dcb.fOutX = FALSE;
	port_cfg.dcb.fInX = FALSE;
	port_cfg.dcb.fErrorChar = FALSE;
	port_cfg.dcb.fNull = FALSE;
	port_cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
	port_cfg.dcb.fAbortOnError = FALSE;
	port_cfg.dcb.ByteSize = 8;
	port_cfg.dcb.Parity = NOPARITY;
	port_cfg.dcb.StopBits = ONESTOPBIT;
	if (!SetCommConfig(port_handle, &port_cfg, sizeof(COMMCONFIG))) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to write communication config to " + name + ", " + buf;
		return -1;
	}
	if (!EscapeCommFunction(port_handle, CLRDTR | CLRRTS)) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to control serial port signals on " + name + ", " + buf;
		return -1;
	}
	// http://msdn2.microsoft.com/en-us/library/aa363190(VS.85).aspx
	// setting to all zeros means timeouts are not used
	//timeouts.ReadIntervalTimeout		= 0;
	timeouts.ReadIntervalTimeout		= MAXDWORD;
	timeouts.ReadTotalTimeoutMultiplier	= 0;
	timeouts.ReadTotalTimeoutConstant	= 0;
	timeouts.WriteTotalTimeoutMultiplier	= 0;
	timeouts.WriteTotalTimeoutConstant	= 0;
	if (!SetCommTimeouts(port_handle, &timeouts)) {
		CloseHandle(port_handle);
		win32_err(buf);
		//error_msg = "Unable to write timeout settings to " + name + ", " + buf;
		return -1;
	}

#endif // _WIN32

        circularBuffer[0] = '\n';

        cBufHead = 0;
        cBufTail = 0;

        serialCounter = 0;

        _portOpened = true;


        setNumberOfChannelsAndSamplingRate(1, maxSamplingRate());


        return fd;
    }
/*!
\fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate)
Sets the baud rate of the serial port.  Note that not all rates are applicable on
all platforms.  The following table shows translations of the various baud rate
constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
are speeds that are usable on both Windows and POSIX.
\verbatim

  RATE          Windows Speed   POSIX Speed
  -----------   -------------   -----------
   BAUD50                 110          50
   BAUD75                 110          75
  *BAUD110                110         110
   BAUD134                110         134.5
   BAUD150                110         150
   BAUD200                110         200
  *BAUD300                300         300
  *BAUD600                600         600
  *BAUD1200              1200        1200
   BAUD1800              1200        1800
  *BAUD2400              2400        2400
  *BAUD4800              4800        4800
  *BAUD9600              9600        9600
   BAUD14400            14400        9600
  *BAUD19200            19200       19200
  *BAUD38400            38400       38400
   BAUD56000            56000       38400
  *BAUD57600            57600       57600
   BAUD76800            57600       76800
  *BAUD115200          115200      115200
   BAUD128000          128000      115200
   BAUD256000          256000      115200
\endverbatim
*/
void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) {
    LOCK_MUTEX();
    if (Settings.BaudRate!=baudRate) {
        switch (baudRate) {
            case BAUD50:
            case BAUD75:
            case BAUD134:
            case BAUD150:
            case BAUD200:
                Settings.BaudRate=BAUD110;
                break;

            case BAUD1800:
                Settings.BaudRate=BAUD1200;
                break;

            case BAUD76800:
                Settings.BaudRate=BAUD57600;
                break;

            default:
                Settings.BaudRate=baudRate;
                break;
        }
    }
    if (isOpen()) {
        switch (baudRate) {

            /*50 baud*/
            case BAUD50:
                TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation.  Switching to 110 baud.");
                Win_CommConfig.dcb.BaudRate=CBR_110;
                break;

            /*75 baud*/
            case BAUD75:
                TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation.  Switching to 110 baud.");
                Win_CommConfig.dcb.BaudRate=CBR_110;
                break;

            /*110 baud*/
            case BAUD110:
                Win_CommConfig.dcb.BaudRate=CBR_110;
                break;

            /*134.5 baud*/
            case BAUD134:
                TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation.  Switching to 110 baud.");
                Win_CommConfig.dcb.BaudRate=CBR_110;
                break;

            /*150 baud*/
            case BAUD150:
                TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation.  Switching to 110 baud.");
                Win_CommConfig.dcb.BaudRate=CBR_110;
                break;

            /*200 baud*/
            case BAUD200:
                TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation.  Switching to 110 baud.");
                Win_CommConfig.dcb.BaudRate=CBR_110;
                break;

            /*300 baud*/
            case BAUD300:
                Win_CommConfig.dcb.BaudRate=CBR_300;
                break;

            /*600 baud*/
            case BAUD600:
                Win_CommConfig.dcb.BaudRate=CBR_600;
                break;

            /*1200 baud*/
            case BAUD1200:
                Win_CommConfig.dcb.BaudRate=CBR_1200;
                break;

            /*1800 baud*/
            case BAUD1800:
                TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation.  Switching to 1200 baud.");
                Win_CommConfig.dcb.BaudRate=CBR_1200;
                break;

            /*2400 baud*/
            case BAUD2400:
                Win_CommConfig.dcb.BaudRate=CBR_2400;
                break;

            /*4800 baud*/
            case BAUD4800:
                Win_CommConfig.dcb.BaudRate=CBR_4800;
                break;

            /*9600 baud*/
            case BAUD9600:
                Win_CommConfig.dcb.BaudRate=CBR_9600;
                break;

            /*14400 baud*/
            case BAUD14400:
                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation.");
                Win_CommConfig.dcb.BaudRate=CBR_14400;
                break;

            /*19200 baud*/
            case BAUD19200:
                Win_CommConfig.dcb.BaudRate=CBR_19200;
                break;

            /*38400 baud*/
            case BAUD38400:
                Win_CommConfig.dcb.BaudRate=CBR_38400;
                break;

            /*56000 baud*/
            case BAUD56000:
                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation.");
                Win_CommConfig.dcb.BaudRate=CBR_56000;
                break;

            /*57600 baud*/
            case BAUD57600:
                Win_CommConfig.dcb.BaudRate=CBR_57600;
                break;

            /*76800 baud*/
            case BAUD76800:
                TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation.  Switching to 57600 baud.");
                Win_CommConfig.dcb.BaudRate=CBR_57600;
                break;

            /*115200 baud*/
            case BAUD115200:
                Win_CommConfig.dcb.BaudRate=CBR_115200;
                break;

            /*128000 baud*/
            case BAUD128000:
                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation.");
                Win_CommConfig.dcb.BaudRate=CBR_128000;
                break;

            /*256000 baud*/
            case BAUD256000:
                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation.");
                Win_CommConfig.dcb.BaudRate=CBR_256000;
                break;
        }
        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
    }
    UNLOCK_MUTEX();
}
Example #18
0
INT_PTR CALLBACK PinCtrlDlgProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_CLOSE:
    {
        RECT rc;
        GetWindowRect(hWndDlg, &rc);
        axisx = rc.left;
        axisy = rc.top;
        hWndPinCtrl = NULL;
        EndDialog(hWndDlg, 0);
        return 0;
    }
    case WM_COMMAND:
    {
        switch(LOWORD(wParam))
        {
        case IDC_PINCTRL_OK:
            if(HIWORD(wParam) != BN_CLICKED)
                return 0;
            if(msg.hComPort == INVALID_HANDLE_VALUE)
            {
                MessageBox(hWndDlg, "没有串口设备被打开!", COMMON_NAME, MB_ICONINFORMATION);
                return 0;
            }
            cconfig.dcb.fDtrControl = dtr[ComboBox_GetCurSel(hDtr)];
            cconfig.dcb.fRtsControl = rts[ComboBox_GetCurSel(hRts)];
            if(!SetCommConfig(msg.hComPort, &cconfig, sizeof(cconfig)))
            {
                utils.msgerr("设置DTR/RTS时错误!");
                return 0;
            }
            EnableWindow(GetDlgItem(hWndDlg, IDC_PINCTRL_OK), FALSE);
            break;
        case IDC_CBO_PINCTRL_DTR:
        case IDC_CBO_PINCTRL_RTS:
            if(HIWORD(wParam) == CBN_SELENDOK)
            {
                EnableWindow(GetDlgItem(hWndDlg, IDC_PINCTRL_OK), TRUE);
                return 0;
            }
            break;
        }
        return 0;
    }
    case WM_INITDIALOG:
    {
        DWORD size = sizeof(cconfig);
        if(msg.hComPort == INVALID_HANDLE_VALUE)
        {
            utils.msgbox(MB_ICONEXCLAMATION, COMMON_NAME, "请先打开一个串口设备!");
            EndDialog(hWndDlg, 0);
            return 0;
        }
        if(!GetCommConfig(msg.hComPort, &cconfig, &size))
        {
            utils.msgerr("获取串口配置时错误");
            EndDialog(hWndDlg, 0);
            return 0;
        }
        hDtr = GetDlgItem(hWndDlg, IDC_CBO_PINCTRL_DTR);
        hRts = GetDlgItem(hWndDlg, IDC_CBO_PINCTRL_RTS);
        for(;;)
        {
            int i;
            for(i = 0; i < 3; i++)
            {
                ComboBox_AddString(hDtr, sdtr[i]);
                ComboBox_AddString(hRts, srts[i]);
            }
            ComboBox_SetCurSel(hDtr, cconfig.dcb.fDtrControl);
            ComboBox_SetCurSel(hRts, cconfig.dcb.fRtsControl);
            break;
        }
        //...
        hWndPinCtrl = hWndDlg;
        SetWindowPos(hWndDlg, 0, axisx, axisy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
        return 0;
    }
    }
    UNREFERENCED_PARAMETER(lParam);
    return 0;
}
Example #19
0
// set the baud rate
int Serial::Set_baud(int baud)
{
	if (baud <= 0) return -1;
	//printf("set_baud: %d\n", baud);
	baud_rate = baud;
	if (!port_is_open) return -1;
#if defined(LINUX)
	speed_t spd;
	switch (baud) {
		case 230400:	spd = B230400;	break;
		case 115200:	spd = B115200;	break;
		case 57600:	spd = B57600;	break;
		case 38400:	spd = B38400;	break;
		case 19200:	spd = B19200;	break;
		case 9600:	spd = B9600;	break;
		case 4800:	spd = B4800;	break;
		case 2400:	spd = B2400;	break;
		case 1800:	spd = B1800;	break;
		case 1200:	spd = B1200;	break;
		case 600:	spd = B600;	break;
		case 300:	spd = B300;	break;
		case 200:	spd = B200;	break;
		case 150:	spd = B150;	break;
		case 134:	spd = B134;	break;
		case 110:	spd = B110;	break;
		case 75:	spd = B75;	break;
		case 50:	spd = B50;	break;
		#ifdef B460800
		case 460800:	spd = B460800;	break;
		#endif
		#ifdef B500000
		case 500000:	spd = B500000;	break;
		#endif
		#ifdef B576000
		case 576000:	spd = B576000;	break;
		#endif
		#ifdef B921600
		case 921600:	spd = B921600;	break;
		#endif
		#ifdef B1000000
		case 1000000:	spd = B1000000;	break;
		#endif
		#ifdef B1152000
		case 1152000:	spd = B1152000;	break;
		#endif
		#ifdef B1500000
		case 1500000:	spd = B1500000;	break;
		#endif
		#ifdef B2000000
		case 2000000:	spd = B2000000;	break;
		#endif
		#ifdef B2500000
		case 2500000:	spd = B2500000;	break;
		#endif
		#ifdef B3000000
		case 3000000:	spd = B3000000;	break;
		#endif
		#ifdef B3500000
		case 3500000:	spd = B3500000;	break;
		#endif
		#ifdef B4000000
		case 4000000:	spd = B4000000;	break;
		#endif
		#ifdef B7200
		case 7200:	spd = B7200;	break;
		#endif
		#ifdef B14400
		case 14400:	spd = B14400;	break;
		#endif
		#ifdef B28800
		case 28800:	spd = B28800;	break;
		#endif
		#ifdef B76800
		case 76800:	spd = B76800;	break;
		#endif
		default: {
			return -1;
		}
	}
	cfsetospeed(&settings, spd);
	cfsetispeed(&settings, spd);
	if (tcsetattr(port_fd, TCSANOW, &settings) < 0) return -1;
#elif defined(MACOSX)
	cfsetospeed(&settings, (speed_t)baud);
	cfsetispeed(&settings, (speed_t)baud);
	if (tcsetattr(port_fd, TCSANOW, &settings) < 0) return -1;
#elif defined(WINDOWS)
	DWORD len = sizeof(COMMCONFIG);
	port_cfg.dcb.BaudRate = baud;
	SetCommConfig(port_handle, &port_cfg, len);
#endif
	return 0;
}
Example #20
0
int serial_open(const char *devpath, unsigned long baud, signed short timeout, bool purge)
{
#ifdef WIN32
	HANDLE hSerial = CreateFile(devpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (unlikely(hSerial == INVALID_HANDLE_VALUE))
	{
		DWORD e = GetLastError();
		switch (e) {
		case ERROR_ACCESS_DENIED:
			applog(LOG_ERR, "Do not have user privileges required to open %s", devpath);
			break;
		case ERROR_SHARING_VIOLATION:
			applog(LOG_ERR, "%s is already in use by another process", devpath);
			break;
		default:
			applog(LOG_DEBUG, "Open %s failed, GetLastError:%d", devpath, (int)e);
			break;
		}
		return -1;
	}

	// thanks to af_newbie for pointers about this
	COMMCONFIG comCfg = {0};
	comCfg.dwSize = sizeof(COMMCONFIG);
	comCfg.wVersion = 1;
	comCfg.dcb.DCBlength = sizeof(DCB);
	comCfg.dcb.BaudRate = baud;
	comCfg.dcb.fBinary = 1;
	comCfg.dcb.fDtrControl = DTR_CONTROL_ENABLE;
	comCfg.dcb.fRtsControl = RTS_CONTROL_ENABLE;
	comCfg.dcb.ByteSize = 8;

	SetCommConfig(hSerial, &comCfg, sizeof(comCfg));

	// Code must specify a valid timeout value (0 means don't timeout)
	const DWORD ctoms = (timeout * 100);
	COMMTIMEOUTS cto = {ctoms, 0, ctoms, 0, ctoms};
	SetCommTimeouts(hSerial, &cto);

	if (purge) {
		PurgeComm(hSerial, PURGE_RXABORT);
		PurgeComm(hSerial, PURGE_TXABORT);
		PurgeComm(hSerial, PURGE_RXCLEAR);
		PurgeComm(hSerial, PURGE_TXCLEAR);
	}

	return _open_osfhandle((intptr_t)hSerial, 0);
#else
	int fdDev = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY);

	if (unlikely(fdDev == -1))
	{
		if (errno == EACCES)
			applog(LOG_ERR, "Do not have user privileges required to open %s", devpath);
		else
			applog(LOG_DEBUG, "Open %s failed, errno:%d", devpath, errno);

		return -1;
	}

	struct termios my_termios;

	tcgetattr(fdDev, &my_termios);

	switch (baud) {
	case 0:
		break;
	case 19200:
		cfsetispeed(&my_termios, B19200);
		cfsetospeed(&my_termios, B19200);
		break;
	case 38400:
		cfsetispeed(&my_termios, B38400);
		cfsetospeed(&my_termios, B38400);
		break;
	case 57600:
		cfsetispeed(&my_termios, B57600);
		cfsetospeed(&my_termios, B57600);
		break;
	case 115200:
		cfsetispeed(&my_termios, B115200);
		cfsetospeed(&my_termios, B115200);
		break;
	default:
		applog(LOG_WARNING, "Unrecognized baud rate: %lu", baud);
	}

	my_termios.c_cflag &= ~(CSIZE | PARENB);
	my_termios.c_cflag |= CS8;
	my_termios.c_cflag |= CREAD;
	my_termios.c_cflag |= CLOCAL;

	my_termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK |
				ISTRIP | INLCR | IGNCR | ICRNL | IXON);
	my_termios.c_oflag &= ~OPOST;
	my_termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);

	// Code must specify a valid timeout value (0 means don't timeout)
	my_termios.c_cc[VTIME] = (cc_t)timeout;
	my_termios.c_cc[VMIN] = 0;

	tcsetattr(fdDev, TCSANOW, &my_termios);

	if (purge)
		tcflush(fdDev, TCIOFLUSH);
	return fdDev;
#endif
}
Example #21
0
bool SerialAdapter::Init()
{
	f_init=true;
	f_loop=false;
	f_start=false;

	Logger::Println("[SerialPort]	Initialize");

	string mySection="Serial";
	string str = ApplicationProperty::ReadSetupString(mySection.c_str(),"ComName","COM3");
	int fps = ApplicationProperty::ReadSetupInt(mySection.c_str(),"Fps",60);
	strcpy_s(comName,"COM3");
	ncomcfg=sizeof(comcfg);

	hPort = CreateFile(
		comName,
		GENERIC_READ,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL
		);

	if(hPort == INVALID_HANDLE_VALUE){
		Logger::Println("[SerialPort]	Error : CreateFile Fail");
		goto error;
	}

	if(!SetupComm(hPort,1024,1024)){
		Logger::Println("[SerialPort]	Error : SetupComm Fail");
		goto error;
	}

	if(!PurgeComm(hPort,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)){
		Logger::Println("[SerialPort]	Error : PurgeComm Fail");
		goto error;
	}

	GetCommConfig(hPort,&comcfg,&ncomcfg);
	if(!SetCommConfig(hPort, &comcfg,ncomcfg))
	{
		Logger::Println("[SerialPort]	Error : SetCommState Fail");
		goto error;
	}
	
	COMMTIMEOUTS timeout;
	SetupTimeout(&timeout);
	if(!SetCommTimeouts(hPort, &timeout)){
		Logger::Println("[SerialPort]	Error : SetCommTimeouts Fail");
		goto error;
	}

	unsigned int id;
	myHandle=(HANDLE)_beginthreadex(NULL,0,SerialAdapter::Launch,this,0,&id);
	if(myHandle==NULL){
		Logger::Println("[SerialPort]	Error : Thread Error");
		goto error;
	}
	return true;

error:
	f_init=false;
	return false;
}
Example #22
0
int SerialThread::openPort(QString portName,int baudrate)
{
#ifdef Q_OS_WIN32
	m_portHandle=CreateFileA(portName.toAscii(), GENERIC_READ|GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
	if (m_portHandle == INVALID_HANDLE_VALUE)
	{
		return -1;
	}
	COMMCONFIG Win_CommConfig;
	COMMTIMEOUTS Win_CommTimeouts;
	unsigned long confSize = sizeof(COMMCONFIG);
	Win_CommConfig.dwSize = confSize;
	GetCommConfig(m_portHandle, &Win_CommConfig, &confSize);
	Win_CommConfig.dcb.Parity = 1; //Odd parity
	Win_CommConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
	Win_CommConfig.dcb.fOutxCtsFlow = FALSE;
	Win_CommConfig.dcb.fOutxDsrFlow = FALSE;
	Win_CommConfig.dcb.fDtrControl = DTR_CONTROL_DISABLE;
	Win_CommConfig.dcb.fDsrSensitivity = FALSE;
	Win_CommConfig.dcb.fNull=FALSE;
	Win_CommConfig.dcb.fTXContinueOnXoff = FALSE;
	Win_CommConfig.dcb.fInX=FALSE;
	Win_CommConfig.dcb.fOutX=FALSE;
	Win_CommConfig.dcb.fBinary=TRUE;
	Win_CommConfig.dcb.DCBlength = sizeof(DCB);
	if (baudrate != -1)
	{
		Win_CommConfig.dcb.BaudRate = baudrate;
	}
	else
	{
		Win_CommConfig.dcb.BaudRate = 115200;
	}
	Win_CommConfig.dcb.ByteSize = 8;
	Win_CommTimeouts.ReadIntervalTimeout = 50;
	Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
	Win_CommTimeouts.ReadTotalTimeoutConstant = 110;
	Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
	Win_CommTimeouts.WriteTotalTimeoutConstant = 110;
	SetCommConfig(m_portHandle, &Win_CommConfig, sizeof(COMMCONFIG));
	SetCommTimeouts(m_portHandle,&Win_CommTimeouts);
	return 0;
#else

	m_portHandle = open(portName.toAscii(),O_RDWR | O_NOCTTY | O_NDELAY); //Should open the port non blocking
	if (m_portHandle < 0)
	{
		//printf("Error opening Com: %s\n",portName);
		//debug(obdLib::DEBUG_ERROR,"Error opening com port %s",portName);
		perror("Error opening COM port Low Level");
		qDebug() << "Port:" << portName;
		return -1;
	}
	//printf("Com Port Opened %i\n",portHandle);
	//debug(obdLib::DEBUG_VERBOSE,"Com Port Opened %i",portHandle);
	//fcntl(m_portHandle, F_SETFL, FASYNC); //Set it to blocking. This is required? Wtf?
	//struct termios oldtio;
	struct termios newtio;
	//bzero(&newtio,sizeof(newtio));
	tcgetattr(m_portHandle,&newtio);
	long BAUD = B115200;
	switch (baudrate)
	{
		case 38400:
			BAUD = B38400;
			break;
		case 115200:
			BAUD  = B115200;
			break;
		case 19200:
			BAUD  = B19200;
			break;
		case 9600:
			BAUD  = B9600;
			break;
		case 4800:
			BAUD  = B4800;
			break;
		default:
			BAUD = B115200;
			break;
	}  //end of switch baud_rate
	if (strspn("/dev/pts",portName.toAscii()) >= 8)
	{
		//debug(obdLib::DEBUG_WARN,"PTS Detected... disabling baud rate selection on: %s",portName);
		//printf("PTS detected... disabling baud rate selection: %s\n",portName);
		baudrate = -1;
	}
	else
	{
	}
	newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8;
	newtio.c_cflag |= CLOCAL | CREAD;
	newtio.c_cflag |= (PARENB | PARODD);
	newtio.c_cflag &= ~CRTSCTS;
	newtio.c_cflag &= ~CSTOPB;
	newtio.c_iflag=IGNBRK;
	//newtio.c_cflag |= (CLOCAL | CREAD | PARODD);
	/*newtio.c_lflag &= !(ICANON | ECHO | ECHOE | ISIG);
	newtio.c_oflag &= !(OPOST);
	newtio.c_cc[VMIN] = 0; // Min number of bytes to read
	newtio.c_cc[VTIME] = 100; //10 second read timeout*/
	newtio.c_iflag &= ~(IXON|IXOFF|IXANY);
	newtio.c_lflag=0;
	newtio.c_oflag=0;
	//newtio.c_cc[VTIME]=1;
	//newtio.c_cc[VMIN]=60;
	newtio.c_cc[VTIME]=2;
	newtio.c_cc[VMIN]=1;
	if (baudrate != -1)
	{
		if(cfsetispeed(&newtio, BAUD))
		{
			//perror("cfsetispeed");
		}

		if(cfsetospeed(&newtio, BAUD))
		{
			//perror("cfsetospeed");
		}
		//debug(obdLib::DEBUG_VERBOSE,"Setting baud rate to %i on port %s\n",baudrate,portName);
	}
	tcsetattr(m_portHandle,TCSANOW,&newtio);
	return 0;
#endif //Q_OS_WIN32
}
Example #23
0
void updateSettings(PortDescriptor *port)
{

    if (port->status != 0)
        rb_raise(rb_eException, "Can not set due to comport is not open, status: %d\n", port->status);


    if (port->toBeUpdated & T_BaudRate)
        port->commConfig.dcb.BaudRate = port->settings.BaudRate;


    if (port->toBeUpdated & T_Parity)
    {
        port->commConfig.dcb.Parity  = (BYTE) port->settings.Parity;
        port->commConfig.dcb.fParity = (port->settings.Parity == PAR_NONE) ? 0 : 1;
    }


    if (port->toBeUpdated & T_DataBits)
    {
        port->commConfig.dcb.ByteSize = (BYTE) port->settings.DataBits;
    }


    if (port->toBeUpdated & T_StopBits)
    {
        switch (port->settings.StopBits)
        {
            case STOP_1:
                port->commConfig.dcb.StopBits = ONESTOPBIT;
                break;
            case STOP_2:
                port->commConfig.dcb.StopBits = TWOSTOPBITS;
                break;
        }
    }

    if (port->toBeUpdated & T_Flow)
    {
        switch (port->settings.FlowControl)
        {
            case FLOW_OFF:
                port->commConfig.dcb.fOutxCtsFlow = 0;
                port->commConfig.dcb.fRtsControl  = RTS_CONTROL_DISABLE;
                port->commConfig.dcb.fInX         = 0;
                port->commConfig.dcb.fOutX        = 0;
                break;
            case FLOW_XONXOFF:
                port->commConfig.dcb.fOutxCtsFlow = 0;
                port->commConfig.dcb.fRtsControl  = RTS_CONTROL_DISABLE;
                port->commConfig.dcb.fInX         = 1;
                port->commConfig.dcb.fOutX        = 1;
                break;
            case FLOW_HARDWARE:
                port->commConfig.dcb.fOutxCtsFlow = 1;
                port->commConfig.dcb.fRtsControl  = RTS_CONTROL_HANDSHAKE;
                port->commConfig.dcb.fInX         = 0;
                port->commConfig.dcb.fOutX        = 0;
                break;
        }
    }

    if (port->toBeUpdated & T_TimeOut)
    {
        int millisec                             = port->settings.Timeout_Millisec;

        if (millisec == -1)
        {
            port->commTimeouts.ReadIntervalTimeout      = MAXDWORD;
            port->commTimeouts.ReadTotalTimeoutConstant = 0;
        } else
        {
            port->commTimeouts.ReadIntervalTimeout      = MAXDWORD;
            port->commTimeouts.ReadTotalTimeoutConstant = millisec;
        }
        port->commTimeouts.ReadTotalTimeoutMultiplier  = 0;
        port->commTimeouts.WriteTotalTimeoutMultiplier = millisec;
        port->commTimeouts.WriteTotalTimeoutConstant   = 0;
    }


    if (port->toBeUpdated & T_SettingsDone)
        SetCommConfig(port->fd, &port->commConfig, sizeof(COMMCONFIG));

    if ((port->toBeUpdated & T_TimeOut))
        SetCommTimeouts(port->fd, &port->commTimeouts);

    port->toBeUpdated = 0;
}
Example #24
0
/*
FUNCTION: WndProc
DATE: 12/2/2015
REVISIONS: v3 - changed all IO operations to overlapped
DESIGNER: Dylan & Allen & Thomas
PROGRAMMER: Dylan & Allen
INTERFACE: LRESULT CALLBACK WndProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
			HWND hwnd : handle to the the main window
			UINT Message : message sent from the message loop to the window
			WPARAM wParam : parameters to the message
			LPARAM lParam : parameters to the message
RETURNS: The default window procedure or 0

NOTES: Handles all button presses from the main window as well as
		events from the serial port reading thread
*/
LRESULT CALLBACK WndProc (HWND hwnd, UINT Message,
                          WPARAM wParam, LPARAM lParam) 
{

	switch (Message)
	{
	case WM_CREATE:
		break;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case ASN_ENQ:
			if (state != IDLE && state != WAIT) {
				OutputDebugString("ENQ but not idling\n");
				break;
			}
			startWriting();
			// send ENQ to the serial port and assume it never fails
			WriteFile(hComm, enq, 1, NULL, &OVERLAPPED());
			state = WENQACK;
			OutputDebugString("ENQ sent\n");
			finishWriting();
			break;
		case ASN_SET:
			startWriting();
			if (!CommConfigDialog(TEXT("com1"), hMain, &cc)) {
				return FALSE;
			}
			else {
				SetCommConfig(hComm, &cc, cc.dwSize);
				PurgeComm(hComm, PURGE_RXCLEAR);
			}
			finishWriting();
			break;
		case ASN_CON:
			OpenFileDialog();
			break;
		case ASN_CLR:
			ClearTextBoxes();
			break;
		case ASN_QUIT:
			PostQuitMessage(0);
			break;
		case ASN_HLP:
			break;
		case ASN_OPN:
			OpenFileDialog();
			break;
		case ACK_REC:
			if (state != WACK && state != WENQACK) {
				OutputDebugString("ACK received but not waiting for ACK before sending a packet\n");
				break;
			}
			if (state == WENQACK) {
				OutputDebugString("ACK received\n");
				acksReceived++;
				SetStatistics();
				if (packetBuffer[currentPacket][0] != 0) {
					OVERLAPPED overlapped = { 0 };
					overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
					startWriting();
					if (!WriteFile(hComm, packetBuffer[currentPacket++], PACKETLENGTH, NULL, &overlapped)) {
						WaitForSingleObject(overlapped.hEvent, TIMEOUT);						
					}

					OutputDebugString("Sent a packet\n");
					packetsSent++;
					SetStatistics();
					// ENQ the line to send the next packet
					// THIS SHOULD BE REPLACED BY THE APPROPRIATE PRIORTIY PROTOCOL
					/*
					if (packetBuffer[currentPacket][0] != 0) {
						WriteFile(hComm, enq, 1, NULL, NULL);
					}
					*/
					finishWriting();
				}
				OutputDebugString("Going to WACK state\n");
				state = WACK;
				break;
			}
			if (state == WACK) {
				OutputDebugString("Packet confirmed received\n");
				OutputDebugString("Going to WAIT state\n");
				state = WAIT;
				packsAcked++;
				acksReceived++;
				SetStatistics();
			}
			break;
		}
		break; // end WM_COMMAND
	case WM_CHAR:
		break;
	case WM_SIZE:
		break;
	case WM_DESTROY:	// Terminate program
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}
// This function reads the current Win_CommConfig settings and updates this
// structure with saved settings
bool Win_QextSerialPort::UpdateComConfig(void)
{
	// Question: Is it possible to change the win_commConfig settings while the port is open? - yes, but not all settings!!! Baud rate can only be changed on closed ports.
	// BUG replace global win_commConfig
	COMMCONFIG Win_CommConfig;
	COMMCONFIG readCommConfig;
	Q_ASSERT(Win_Handle!=INVALID_HANDLE_VALUE);
	LOCK_MUTEX();

	unsigned long confSize = sizeof(COMMCONFIG);
	Win_CommConfig.dwSize = confSize; // TODO: what is this?


	// read current settings
    GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
    GetCommState(Win_Handle, &(Win_CommConfig.dcb));

	/*set up default parameters*/
    Win_CommConfig.dcb.fBinary = TRUE;
    Win_CommConfig.dcb.fAbortOnError = FALSE;
    Win_CommConfig.dcb.fNull = FALSE;

    Win_CommConfig.dcb.Parity = NOPARITY;
    Win_CommConfig.dcb.StopBits = ONESTOPBIT;
    Win_CommConfig.dcb.fParity = TRUE;

    // data bit settings
    switch (Settings.DataBits)
    {
	case DATA_5:/*5 data bits*/
		if (Settings.StopBits==STOP_2) {  //BUG think about warnings
			TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
		} else {
			Win_CommConfig.dcb.ByteSize=5;
		}
		break;
	case DATA_6:/*6 data bits*/
		if (Settings.StopBits==STOP_1_5) {
			TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
		} else {
			Win_CommConfig.dcb.ByteSize=6;
		}
		break;
	case DATA_7:/*7 data bits*/
		if (Settings.StopBits==STOP_1_5) {
			TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
		} else {
			Win_CommConfig.dcb.ByteSize=7;
		}
		break;
	case DATA_8:/*8 data bits*/
		if (Settings.StopBits==STOP_1_5) {
			TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
		} else {
			Win_CommConfig.dcb.ByteSize=8;
		}
		break;
	default:
		Q_ASSERT(0); // This should never happen BUG replace by a error message
	}


  // parity settings
  switch (Settings.Parity) {
	case PAR_SPACE: /*space parity*/
		if (Settings.DataBits==DATA_8) { // BUG this assumes that data was set first
			TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");
		}
		Win_CommConfig.dcb.fParity=TRUE; // enable parity checking
		Win_CommConfig.dcb.Parity=SPACEPARITY;
		break;
	case PAR_MARK: /* mark parity - WINDOWS ONLY */
		TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning:  Mark parity is not supported by POSIX systems");
		Win_CommConfig.dcb.fParity=TRUE; // enable parity checking
		Win_CommConfig.dcb.Parity=MARKPARITY;
		break;
	case PAR_NONE: /* no parity */
		Win_CommConfig.dcb.fParity=FALSE; // disable parity checking
		Win_CommConfig.dcb.Parity=NOPARITY;
		break;
	case PAR_EVEN:/* even parity */
		Win_CommConfig.dcb.fParity=TRUE; // enable parity checking
		Win_CommConfig.dcb.Parity=EVENPARITY;
		break;
	case PAR_ODD:/* odd parity */
		Win_CommConfig.dcb.fParity=TRUE; // enable parity checking
		Win_CommConfig.dcb.Parity=ODDPARITY;
		break;
	default:
		Q_ASSERT(0); // This should never happen BUG replace by a error message
	}

  // baud settings
  switch (Settings.BaudRate) {
	case BAUD50:/*50 baud*/
		TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation.  Switching to 110 baud.");
		Win_CommConfig.dcb.BaudRate=CBR_110;
		break;
	case BAUD75:/*75 baud*/
		TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation.  Switching to 110 baud.");
		Win_CommConfig.dcb.BaudRate=CBR_110;
		break;
	case BAUD110:/*110 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_110;
		break;
	case BAUD134:		/*134.5 baud*/
		TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation.  Switching to 110 baud.");
		Win_CommConfig.dcb.BaudRate=CBR_110;
		break;
	case BAUD150:/*150 baud*/
		TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation.  Switching to 110 baud.");
		Win_CommConfig.dcb.BaudRate=CBR_110;
		break;
	case BAUD200:/*200 baud*/
		TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation.  Switching to 110 baud.");
		Win_CommConfig.dcb.BaudRate=CBR_110;
		break;
	case BAUD300:/*300 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_300;
		break;
	case BAUD600:/*600 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_600;
		break;
	case BAUD1200:/*1200 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_1200;
		break;
	case BAUD1800:/*1800 baud*/
		TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation.  Switching to 1200 baud.");
		Win_CommConfig.dcb.BaudRate=CBR_1200;
		break;
	case BAUD2400:/*2400 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_2400;
		break;
	case BAUD4800:/*4800 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_4800;
		break;
	case BAUD9600:/*9600 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_9600;
		break;
	case BAUD14400:/*14400 baud*/
		TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation.");
		Win_CommConfig.dcb.BaudRate=CBR_14400;
		break;
	case BAUD19200:/*19200 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_19200;
		break;
	case BAUD38400:/*38400 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_38400;
		break;
	case BAUD56000:/*56000 baud*/
		TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation.");
		Win_CommConfig.dcb.BaudRate=CBR_56000;
		break;
	case BAUD57600:/*57600 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_57600;
		break;
	case BAUD76800:/*76800 baud*/
		TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation.  Switching to 57600 baud.");
		Win_CommConfig.dcb.BaudRate=CBR_57600;
		break;
	case BAUD115200:/*115200 baud*/
		Win_CommConfig.dcb.BaudRate=CBR_115200;
		break;
        case BAUD128000:
		Win_CommConfig.dcb.BaudRate=CBR_128000;
		break;

        case BAUD230400:
            Win_CommConfig.dcb.BaudRate=230400;
            break;

        case BAUD250000:
            Win_CommConfig.dcb.BaudRate=250000;
            break;

        case BAUD460800:
            Win_CommConfig.dcb.BaudRate = 460800;
            break;

        case BAUD500000:
            Win_CommConfig.dcb.BaudRate = 500000;
            break;

        case BAUD614400:
            Win_CommConfig.dcb.BaudRate = 614400;
            break;

        case BAUD750000:
            Win_CommConfig.dcb.BaudRate = 750000;
            break;

        case BAUD921600:
            Win_CommConfig.dcb.BaudRate = 921600;
            break;

        case BAUD1000000:
            Win_CommConfig.dcb.BaudRate = 1000000;
            break;

        case BAUD1228800:
            Win_CommConfig.dcb.BaudRate = 1228800;
            break;

        case BAUD2457600:
            Win_CommConfig.dcb.BaudRate = 2457600;
            break;

        case BAUD3000000:
            Win_CommConfig.dcb.BaudRate = 3000000;
            break;

        case BAUD6000000:
            Win_CommConfig.dcb.BaudRate = 6000000;
            break;

        default:
            Win_CommConfig.dcb.BaudRate = (unsigned int)Settings.BaudRate;
            break;
	}

  // STOP bits
  switch (Settings.StopBits) {
	case STOP_1:/*one stop bit*/
		Win_CommConfig.dcb.StopBits=ONESTOPBIT;
		break;
	case STOP_1_5:/*1.5 stop bits*/
		TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");
		if (Settings.DataBits!=DATA_5) {
			TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits");
		} else {
			Win_CommConfig.dcb.StopBits=ONE5STOPBITS;
		}
		break;
	case STOP_2:/*two stop bits*/
		if (Settings.DataBits==DATA_5) {// BUG this assumes, that DATA was set first
			TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
		} else {
			Win_CommConfig.dcb.StopBits=TWOSTOPBITS;
		}
		break;
	default:
		Q_ASSERT(0); // This should never happen BUG replace by a error message
	}


  switch (Settings.FlowControl) {
	case FLOW_OFF:/*no flow control*/
        Win_CommConfig.dcb.fOutxCtsFlow = FALSE;
        Win_CommConfig.dcb.fOutxDsrFlow = FALSE;
        Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
		Win_CommConfig.dcb.fInX=FALSE;
		Win_CommConfig.dcb.fOutX=FALSE;
		break;
	case FLOW_XONXOFF:/*software (XON/XOFF) flow control*/
        Win_CommConfig.dcb.fOutxCtsFlow = FALSE;
        Win_CommConfig.dcb.fOutxDsrFlow = FALSE;
        Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
		Win_CommConfig.dcb.fInX=TRUE;
		Win_CommConfig.dcb.fOutX=TRUE;
		break;
	case FLOW_HARDWARE:
		Win_CommConfig.dcb.fOutxCtsFlow=TRUE;
        Win_CommConfig.dcb.fOutxDsrFlow = FALSE; // guess?
        Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
		Win_CommConfig.dcb.fInX=FALSE;
		Win_CommConfig.dcb.fOutX=FALSE;
		break;
	default:
		Q_ASSERT(0); // This should never happen BUG replace by a error message
	}

    // write configuration back
    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));

    // read current settings
    GetCommConfig(Win_Handle, &readCommConfig, &confSize);
	UNLOCK_MUTEX();

    if(Win_CommConfig.dcb.BaudRate != readCommConfig.dcb.BaudRate)
    {
        Settings.BaudRate = readCommConfig.dcb.BaudRate;
	}
	return true;
}
Example #26
0
int rlSerial::openDevice(const char *devicename, int speed, int block, int rtscts, int bits, int stopbits, int parity)
{
    int y;
#ifdef RLUNIX
  struct termios buf;

  if(fd != -1) return -1;
  fd = open(devicename, O_RDWR | O_NOCTTY | O_NDELAY);
  if(fd < 0) { return -1; }

  //signal(SIGINT, sighandler);

  if(tcgetattr(fd, &save_termios) < 0) { return -1; }
  buf = save_termios;
  buf.c_cflag = speed | CLOCAL | CREAD;
  if(rtscts   == 1)  buf.c_cflag |= CRTSCTS;
  if(bits     == 7)  buf.c_cflag |= CS7;
  else               buf.c_cflag |= CS8;
  if(stopbits == 2)  buf.c_cflag |= CSTOPB;
  if(parity == rlSerial::ODD)  buf.c_cflag |= (PARENB | PARODD);
  if(parity == rlSerial::EVEN) buf.c_cflag |= PARENB;
  buf.c_lflag = IEXTEN; //ICANON;
  buf.c_oflag     = OPOST;
  buf.c_cc[VMIN]  = 1;
  buf.c_cc[VTIME] = 0;
#ifndef PVMAC
  buf.c_line      = 0;
#endif
  buf.c_iflag     = IGNBRK | IGNPAR | IXANY;
  if(tcsetattr(fd, TCSAFLUSH, &buf) < 0) { return -1; }
  //if(tcsetattr(fd, TCSANOW, &buf) < 0) { return -1; }
  ttystate = RAW;
  ttysavefd = fd;
  if(block == 1) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
  tcflush(fd,TCIOFLUSH);
#endif

#ifdef __VMS
  // Please set com parameters at DCL level
  struct dsc$descriptor_s dsc;
  int status;

  dsc.dsc$w_length  = strlen(devicename);
  dsc.dsc$a_pointer = (char *) devicename;
  dsc.dsc$b_class   = DSC$K_CLASS_S;
  dsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  status = SYS$ASSIGN(&dsc,&vms_channel,0,0);
  if(status != SS$_NORMAL) return -1;
#endif

#ifdef RLWIN32
  DWORD ccsize;
  COMMCONFIG cc;
  //int baudrate,ret;
  //char devname[100];

  int baudrate,ret;
  //WCHAR
  wchar_t devname[100]; //={'C','O','M','1',0};

    if(strlen(devicename) > 80) return -1;
    y=0;
    while(*(devicename+y)!=0){
        devname[y]=*(devicename+y);
        y++;
    }
    devname[y]=0;
    //printf("%s",devname);        // Aenderung: allow more than 4 COM ports


  //if(strlen(devicename) > 80) return -1;
  //sprintf(devname,"\\\\.\\%s",devicename);        // Aenderung: allow more than 4 COM ports
  hdl = CreateFile(
                   devname,                       // devicename, // pointer to name of the file
                   GENERIC_READ | GENERIC_WRITE,  // access (read-write) mode
                   0,                             // share mode
                   0,                             // pointer to security attributes
                   OPEN_EXISTING,                 // how to create
                   0,                             // not overlapped I/O
                   0                              // handle to file with attributes to copy
                  );
  if(hdl == INVALID_HANDLE_VALUE)
  {
    printf("CreateFile(%s) failed\n",devicename);
    return -1;
  }

  baudrate = CBR_9600;
  if(speed == B50     ) baudrate = 50;
  if(speed == B75     ) baudrate = 75;
  if(speed == B110    ) baudrate = CBR_110;
  if(speed == B134    ) baudrate = 134;
  if(speed == B150    ) baudrate = 150;
  if(speed == B200    ) baudrate = 200;
  if(speed == B300    ) baudrate = CBR_300;
  if(speed == B600    ) baudrate = CBR_600;
  if(speed == B1200   ) baudrate = CBR_1200;
  if(speed == B1800   ) baudrate = 1800;
  if(speed == B2400   ) baudrate = CBR_2400;
  if(speed == B4800   ) baudrate = CBR_4800;
  if(speed == B9600   ) baudrate = CBR_9600;
  if(speed == B19200  ) baudrate = CBR_19200;
  if(speed == B38400  ) baudrate = CBR_38400;
  if(speed == B57600  ) baudrate = CBR_57600;
  if(speed == B115200 ) baudrate = CBR_115200;
  if(speed == B230400 ) baudrate = 230400;
  if(speed == B460800 ) baudrate = 460800;
  if(speed == B500000 ) baudrate = 500000;
  if(speed == B576000 ) baudrate = 576000;
  if(speed == B921600 ) baudrate = 921600;
  if(speed == B1000000) baudrate = 1000000;
  if(speed == B1152000) baudrate = 1152000;
  if(speed == B1500000) baudrate = 1500000;
  if(speed == B2000000) baudrate = 2000000;
  if(speed == B2500000) baudrate = 2500000;
  if(speed == B3000000) baudrate = 3000000;
  if(speed == B3500000) baudrate = 3500000;
  if(speed == B4000000) baudrate = 4000000;

  GetCommConfig(hdl,&cc,&ccsize);
  //cc.dwSize            = sizeof(cc);  // size of structure
  //cc.wVersion          = 1;           // version of structure
  //cc.wReserved         = 0;           // reserved
  //  DCB   dcb;                      // device-control block
  cc.dcb.DCBlength     = sizeof(DCB); // sizeof(DCB)
  cc.dcb.BaudRate      = baudrate;    // current baud rate
  cc.dcb.fBinary       = 1;           // binary mode, no EOF check
  cc.dcb.fParity       = 1;           // enable parity checking
  cc.dcb.fOutxCtsFlow  = 0;           // CTS output flow control
  if(rtscts == 1) cc.dcb.fOutxCtsFlow = 1;
  cc.dcb.fOutxDsrFlow  = 0;           // DSR output flow control
  cc.dcb.fDtrControl   = DTR_CONTROL_DISABLE;  // DTR flow control type
  cc.dcb.fDsrSensitivity   = 0;       // DSR sensitivity
  cc.dcb.fTXContinueOnXoff = 1;       // XOFF continues Tx
  //cc.dcb.fOutX         = 0;           // XON/XOFF out flow control
  //cc.dcb.fInX          = 0;           // XON/XOFF in flow control
  //cc.dcb.fErrorChar    = 0;           // enable error replacement
  cc.dcb.fNull         = 0;           // enable null stripping
  cc.dcb.fRtsControl   = RTS_CONTROL_DISABLE;
  if(rtscts == 1)  cc.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;  // RTS flow control
  cc.dcb.fAbortOnError = 0;           // abort reads/writes on error
  //cc.dcb.fDummy2       = 0;           // reserved
  //cc.dcb.wReserved     = 0;           // not currently used
  //cc.dcb.XonLim        = 0;           // transmit XON threshold
  //cc.dcb.XoffLim       = 0;           // transmit XOFF threshold
  cc.dcb.ByteSize      = bits;        // number of bits/byte, 4-8
  cc.dcb.Parity        = 0;           // 0-4=no,odd,even,mark,space
  if(parity == rlSerial::ODD)    cc.dcb.Parity = 1;
  if(parity == rlSerial::EVEN)   cc.dcb.Parity = 2;
  cc.dcb.StopBits      = ONESTOPBIT;  // 0,1,2 = 1, 1.5, 2
  if(stopbits==2) cc.dcb.StopBits = TWOSTOPBITS;
  //cc.dcb.XonChar       = 0;           // Tx and Rx XON character
  //cc.dcb.XoffChar      = 0;           // Tx and Rx XOFF character
  //cc.dcb.ErrorChar     = 0;           // error replacement character
  //cc.dcb.EofChar       = 0;           // end of input character
  //cc.dcb.EvtChar       = 0;           // received event character
  //cc.dcb.wReserved1    = 0;           // reserved; do not use
  cc.dwProviderSubType = PST_RS232;   // type of provider-specific data
  //cc.dwProviderOffset  = 0;           // offset of provider-specific data
  //cc.dwProviderSize    = 0;           // size of provider-specific data
  //cc.wcProviderData[0] = 0;           // provider-specific data

  ret = SetCommConfig(hdl,&cc,sizeof(cc));
  if(ret == 0)
  {
    printf("SetCommConfig ret=%d devicename=%s LastError=%d\n",ret,devicename,(int)GetLastError());
    return -1;
  }
#endif

#ifdef RM3
  RmEntryStruct    CatEntry;        /* Struktur der Deiviceinformationen              */
  int              iStatus;         /* Rckgabewert                                    */
  RmIOStatusStruct DrvSts;          /* Struktur der Rckgabewerte fr RmIO - Funktion   */
  RmBytParmStruct  PBlock;          /* Parameterstruktur fr RmIO - Funktion           */
  static UCD_BYT_PORT Ucd_byt_drv;  /* Struktur zum Setzen der UCD - Werte            */
  ushort           uTimeBd;         /* Timing - Wert der �ertragungsgeschwindigkeit   */
  uint             uMode;           /* Portsteuerungsparameter                        */
  unsigned char    cByte;           /* Byte - Parameter                               */
                                    /* Timing = 748800 / Baudrate;                    */
                                    /**************************************************/
  char byt_com[32];
                                    
  /* COM1=0x3F8 COM2=0x2F8 - Port Adresse           */
  if     (strcmp(devicename,"COM1") == 0)
  {
    strcpy(byt_com,"BYT_COM1");
    com = 0x3f8;
  }
  else if(strcmp(devicename,"COM2") == 0)
  {
    strcpy(byt_com,"BYT_COM2");
    com = 0x2f8;
  }
  else 
  {
    printf("Error: devicename=%s unknown\n",devicename);
    return -1;
  }  
  //printf("Open COM port - inside\n");

  /*
  * Device und Unit - Id auslesen
  */
  if( RmGetEntry( RM_WAIT, byt_com, &CatEntry ) != RM_OK ) /* RM_CONTINUE */
  {
    printf( "Error: %s device not found\n", byt_com);
    return -1;
  }

  device = (int) ((ushort) CatEntry.ide);
  unit   = (int) CatEntry.id;

  /*
  * Ger� reservieren
  */
  if( RmIO( BYT_RESERVE, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock ) < 0 )
  {
    printf( "Error: Unable to reserve %s device\n", byt_com);
    return -1;
  }

  /*
  * Baudrate ausrechnen
  */
  baudrate = 9600;
  if(speed == B50     ) baudrate = 50;
  if(speed == B75     ) baudrate = 75;
  if(speed == B110    ) baudrate = 110;
  if(speed == B134    ) baudrate = 134;
  if(speed == B150    ) baudrate = 150;
  if(speed == B200    ) baudrate = 200;
  if(speed == B300    ) baudrate = 300;
  if(speed == B600    ) baudrate = 600;
  if(speed == B1200   ) baudrate = 1200;
  if(speed == B1800   ) baudrate = 1800;
  if(speed == B2400   ) baudrate = 2400;
  if(speed == B4800   ) baudrate = 4800;
  if(speed == B9600   ) baudrate = 9600;
  if(speed == B19200  ) baudrate = 19200;
  if(speed == B38400  ) baudrate = 38400;
  if(speed == B57600  ) baudrate = 57600;
  if(speed == B115200 ) baudrate = 115200;
  if(speed == B230400 ) baudrate = 230400;
  if(speed == B460800 ) baudrate = 460800;
  if(speed == B500000 ) baudrate = 500000;
  if(speed == B576000 ) baudrate = 576000;
  if(speed == B921600 ) baudrate = 921600;
  if(speed == B1000000) baudrate = 1000000;
  if(speed == B1152000) baudrate = 1152000;
  if(speed == B1500000) baudrate = 1500000;
  if(speed == B2000000) baudrate = 2000000;
  if(speed == B2500000) baudrate = 2500000;
  if(speed == B3000000) baudrate = 3000000;
  if(speed == B3500000) baudrate = 3500000;
  if(speed == B4000000) baudrate = 4000000;
  uTimeBd = 748800 / baudrate;

  /*
  * Portsteuerungsparameter setzen
  */
  uMode = 0x1000 | DATA_8 | STOP_1 | NOPARITY;

  /*
  * UCD des seriellen Ports auslesen
  */
  PBlock.string = 0;
  PBlock.strlen = 0;
  PBlock.buffer = (char *)&Ucd_byt_drv;
  PBlock.timlen = sizeof(UCD_BYT_PORT);
  PBlock.status = 0;

  iStatus = RmIO( BYT_CREATE_NEW, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock );

  /*
   * Modus �dern
   */
  Ucd_byt_drv.mobyte[5] |= (ushort) (uMode & 0xFFu);

  /*
   * Timeout setzen
   */
  Ucd_byt_drv.header.timout = timeout;

  /*
   * Werte zuweisen
   */
  PBlock.string = (char*) &Ucd_byt_drv;
  PBlock.strlen = sizeof(UCD_BYT_PORT);
  PBlock.buffer = 0;
  PBlock.timlen = 0;
  PBlock.status = 0;

  iStatus = RmIO( BYT_CREATE_NEW, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock );

  /*
   * Register 0 und 1 zum Schreiben freigeben
   */
  cByte = inbyte( com + 0x03 );
  outbyte( com + 0x03, (unsigned char)(cByte | 0x80) );

  /*
   * Baudrate setzen
   */
  outbyte( com + 0x00, (ushort) LOW  (uTimeBd) );
  outbyte( com + 0x01, (ushort) HIGH (uTimeBd) );

  /*
   * Register 0 und 1 sperren
   */
  outbyte( com + 0x03, cByte );

  if( iStatus ) printf( "BYT_CREATE_NEW (set ucb): Error status = %X\n", iStatus );
#endif
  
  return 0;
}
Example #27
0
// Open a port, by name.  Return 0 on success, non-zero for error
int Serial::Open(const wxString& name)
{
	Close();
#if defined(LINUX)
	struct serial_struct kernel_serial_settings;
	int bits;
	port_fd = open(name.mb_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
	if (port_fd < 0) {
		if (errno == EACCES) {
		  error_msg = _("Unable to access ") + wxString(name,wxConvUTF8) + _(", insufficient permission");
			// TODO: we could look at the permission bits and owner
			// to make a better message here
		} else if (errno == EISDIR) {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", Object is a directory, not a serial port");
		} else if (errno == ENODEV || errno == ENXIO) {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", Serial port hardware not installed");
		} else if (errno == ENOENT) {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", Device name does not exist");
		} else {
		  error_msg = _("Unable to open ") + wxString(name,wxConvUTF8) +
		    _(", ") + wxString(strerror(errno),wxConvUTF8);
		}
		return -1;
	}
	if (ioctl(port_fd, TIOCMGET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to query serial port signals");
		return -1;
	}
	bits &= ~(TIOCM_DTR | TIOCM_RTS);
	if (ioctl(port_fd, TIOCMSET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to control serial port signals");
		return -1;
	}
	if (tcgetattr(port_fd, &settings_orig) != 0) {
		close(port_fd);
		error_msg = _("Unable to query serial port settings (perhaps not a serial port)");
		return -1;
	}
	memset(&settings, 0, sizeof(settings));
	settings.c_iflag = IGNBRK | IGNPAR;
	settings.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
	Set_baud(baud_rate);
	if (ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings) == 0) {
		kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
		ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
	}
	tcflush(port_fd, TCIFLUSH);
#elif defined(MACOSX)
	int bits;
	port_fd = open(name.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
	if (port_fd < 0) {
	  error_msg = _("Unable to open ") + name + _(", ") + strerror(errno);
		return -1;
	}
	if (ioctl(port_fd, TIOCEXCL) == -1) {
		close(port_fd);
		error_msg = _("Unable to get exclussive access to port ") + name;
		return -1;
	}
	if (ioctl(port_fd, TIOCMGET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to query serial port signals on ") + name;
		return -1;
	}
	bits &= ~(TIOCM_DTR | TIOCM_RTS);
	if (ioctl(port_fd, TIOCMSET, &bits) < 0) {
		close(port_fd);
		error_msg = _("Unable to control serial port signals on ") + name;
		return -1;
	}
	if (tcgetattr(port_fd, &settings_orig) < 0) {
		close(port_fd);
		error_msg = _("Unable to access baud rate on port ") + name;
		return -1;
	}
	memset(&settings, 0, sizeof(settings));
	settings.c_cflag = CS8 | CLOCAL | CREAD | HUPCL;
	settings.c_iflag = IGNBRK | IGNPAR;
	Set_baud(baud_rate);
	tcflush(port_fd, TCIFLUSH);
#elif defined(WINDOWS)
	COMMCONFIG cfg;
	COMMTIMEOUTS timeouts;
	int got_default_cfg=0, port_num;
	char buf[1024], name_createfile[64], name_commconfig[64], *p;
	DWORD len;

	snprintf(buf, sizeof(buf), _("%s"), name.c_str());
	p = strstr(buf, _("COM"));
	if (p && sscanf(p + 3, _("%d"), &port_num) == 1) {
	  printf(_("port_num = %d\n"), port_num);
	  snprintf(name_createfile, sizeof(name_createfile), _("\\\\.\\COM%d"), port_num);
	  snprintf(name_commconfig, sizeof(name_commconfig), _("COM%d"), port_num);
	} else {
	  snprintf(name_createfile, sizeof(name_createfile), _("%s"), name.c_str());
	  snprintf(name_commconfig, sizeof(name_commconfig), _("%s"), name.c_str());
	}
	len = sizeof(COMMCONFIG);
	if (GetDefaultCommConfig(name_commconfig, &cfg, &len)) {
		// this prevents unintentionally raising DTR when opening
		// might only work on COM1 to COM9
		got_default_cfg = 1;
		memcpy(&port_cfg_orig, &cfg, sizeof(COMMCONFIG));
		cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
		cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
		SetDefaultCommConfig(name_commconfig, &cfg, sizeof(COMMCONFIG));
	} else {
	  printf(_("error with GetDefaultCommConfig\n"));
	}
	port_handle = CreateFile(name_createfile, GENERIC_READ | GENERIC_WRITE,
	   0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	if (port_handle == INVALID_HANDLE_VALUE) {
		win32_err(buf);
		error_msg =  _("Unable to open ") + name + _(", ") + buf;
		return -1;
	}
	len = sizeof(COMMCONFIG);
	if (!GetCommConfig(port_handle, &port_cfg, &len)) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to read communication config on ") + name + _(", ") + buf;
		return -1;
	}
	if (!got_default_cfg) {
		memcpy(&port_cfg_orig, &port_cfg, sizeof(COMMCONFIG));
	}
	// http://msdn2.microsoft.com/en-us/library/aa363188(VS.85).aspx
	port_cfg.dcb.BaudRate = baud_rate;
	port_cfg.dcb.fBinary = TRUE;
	port_cfg.dcb.fParity = FALSE;
	port_cfg.dcb.fOutxCtsFlow = FALSE;
	port_cfg.dcb.fOutxDsrFlow = FALSE;
	port_cfg.dcb.fDtrControl = DTR_CONTROL_DISABLE;
	port_cfg.dcb.fDsrSensitivity = FALSE;
	port_cfg.dcb.fTXContinueOnXoff = TRUE;	// ???
	port_cfg.dcb.fOutX = FALSE;
	port_cfg.dcb.fInX = FALSE;
	port_cfg.dcb.fErrorChar = FALSE;
	port_cfg.dcb.fNull = FALSE;
	port_cfg.dcb.fRtsControl = RTS_CONTROL_DISABLE;
	port_cfg.dcb.fAbortOnError = FALSE;
	port_cfg.dcb.ByteSize = 8;
	port_cfg.dcb.Parity = NOPARITY;
	port_cfg.dcb.StopBits = ONESTOPBIT;
	if (!SetCommConfig(port_handle, &port_cfg, sizeof(COMMCONFIG))) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to write communication config to ") + name + _(", ") + buf;
		return -1;
	}
	if (!EscapeCommFunction(port_handle, CLRDTR | CLRRTS)) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to control serial port signals on ") + name + _(", ") + buf;
		return -1;
	}
	// http://msdn2.microsoft.com/en-us/library/aa363190(VS.85).aspx
	// setting to all zeros means timeouts are not used
	//timeouts.ReadIntervalTimeout		= 0;
	timeouts.ReadIntervalTimeout		= MAXDWORD;
	timeouts.ReadTotalTimeoutMultiplier	= 0;
	timeouts.ReadTotalTimeoutConstant	= 0;
	timeouts.WriteTotalTimeoutMultiplier	= 0;
	timeouts.WriteTotalTimeoutConstant	= 0;
	if (!SetCommTimeouts(port_handle, &timeouts)) {
		CloseHandle(port_handle);
		win32_err(buf);
		error_msg = _("Unable to write timeout settings to ") + name + _(", ") + buf;
		return -1;
	}
#endif
	port_name = name;
	port_is_open = 1;
	return 0;
}
/*-------------------------------------------
| Name:setRs2322
| Description:
| Parameters:
| Return Type:
| Comments:
| See:
---------------------------------------------*/
int setRs2322(uart2_config* config){
   /*
   COMMCONFIG  commconfig;
   DWORD       dwSize=sizeof(COMMCONFIG);
   char buffer[256]={0};
   sprintf(buffer,"%s: baud=%d parity=%c data=%d stop=%d",USE_COM,
      config->speed,
      config->parity,
      config->data,
      config->stop);

   if(!GetCommConfig(hCom,&commconfig,&dwSize))
      return -1;

   BuildCommDCB(buffer,&commconfig.dcb);

   //CommConfigDialog(USE_COM,NULL,&commconfig);

   if(!SetCommConfig(hCom,&commconfig,dwSize))
      return -1;

   printf("com cfg: %s\n",buffer);

   memcpy(&current_config,config,sizeof(uart2_config));
   */

   COMMCONFIG commconfig;
   DWORD dwSize=sizeof(COMMCONFIG);
   char buffer[256]={0};
   DCB dcb={0};

   COMMTIMEOUTS NewTimeouts;           // Serial port new timeouts
   COMMTIMEOUTS OldTimeouts;           // Serial port old timeouts

   sprintf(buffer,"%s: baud=%d parity=%c data=%d stop=%d",USE_COM,
           config->speed,
           config->parity,
           config->data,
           config->stop);

   if(!GetCommConfig(hCom,&commconfig,&dwSize))
      return -1;

   BuildCommDCB(buffer,&commconfig.dcb);

   //CommConfigDialog(USE_COM,NULL,&commconfig);

   if(!SetCommConfig(hCom,&commconfig,dwSize))
      return -1;

   // Get default DCB and initialize
   if(!GetCommState( hCom, &dcb))
   {
      CloseHandle( hCom );
      return -1;
   }
   else
   {
      dcb.fOutxCtsFlow = FALSE;
      dcb.fOutxDsrFlow = FALSE;
      dcb.fDtrControl = DTR_CONTROL_ENABLE;//DTR_CONTROL_DISABLE;            // DTR ON when device open (+12V) in order to power Optical link with DTR
      dcb.fRtsControl = RTS_CONTROL_ENABLE;//RTS_CONTROL_DISABLE;            // RTS OFF when device open (-12V) in order to power Optical link with RTS
      dcb.fDsrSensitivity = FALSE;
//	    dcb.fTXContinueOnXoff = false;
      dcb.fTXContinueOnXoff = TRUE;
      dcb.fNull = FALSE;
   }

   dcb.fOutX = FALSE;
   dcb.fInX = FALSE;
   dcb.fErrorChar = FALSE;
   dcb.fAbortOnError = FALSE;
   dcb.XonLim = 0;     //32;
   dcb.XoffLim = 0;     //32;
   dcb.XonChar =  40;
   dcb.XoffChar = 41;
   dcb.ErrorChar = 0;
   dcb.EofChar = 0;
   dcb.EvtChar = 0;             // '\n' is the last character of a Modbus frame ; this character will be the event for retreiving the receive buffer
   dcb.wReserved = 0;

   // Set the new state of the serial port.
   if(!SetCommState( hCom, &dcb))
   {
      CloseHandle( hCom );
      return -1;
   }

   // Save current timeouts
   GetCommTimeouts(hCom, &OldTimeouts);

   // Set new read timeout
   memcpy((void *)&NewTimeouts, (const void *)&OldTimeouts, sizeof(COMMTIMEOUTS));

   NewTimeouts.ReadIntervalTimeout = 0;
   NewTimeouts.ReadTotalTimeoutMultiplier = 0;
   NewTimeouts.ReadTotalTimeoutConstant = 0; // Timeout is expressed in milliseconds

   SetCommTimeouts (hCom, &NewTimeouts);

   //
   printf("com cfg: %s\n",buffer);

   memcpy(&current_config,config,sizeof(uart2_config));


   return 0;
}