/*------------------------------------------- | 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(¤t_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(); }
/*! 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::GetConfig(COMMCONFIG& config) { ASSERT(IsOpen()); DWORD dwSize = sizeof(COMMCONFIG); if (!GetCommConfig(m_hComm, &config, &dwSize)) { TRACE(_T("Failed in call to GetCommConfig\n")); AfxThrowSerialException(); } }
VALUE openIO(VALUE self) { PortDescriptor *port = NULL; Data_Get_Struct(self, PortDescriptor, port); if (port->status == 0) return INT2FIX(port->status); DWORD conf_length = sizeof(COMMCONFIG); port->commConfig.dwSize = conf_length; DWORD threading = 0; port->fd = CreateFileA(port->settings.ComPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, threading, NULL); if (port->fd == INVALID_HANDLE_VALUE) { port->status = 1; rb_raise(rb_eException, "Unable to open comport: %s\n", port->settings.ComPort); } else { port->status = 0; rb_iv_set(self, "@open", INT2FIX(port->status)); GetCommConfig(port->fd, &port->commConfig, &conf_length); GetCommState(port->fd, &(port->commConfig.dcb)); port->commConfig.dcb.fBinary = 1; port->commConfig.dcb.fInX = 0; port->commConfig.dcb.fOutX = 0; port->commConfig.dcb.fAbortOnError = 0; port->commConfig.dcb.fNull = 0; port->commConfig.dcb.fDtrControl = 1; port->toBeUpdated = T_ALL; setSettings(self); } return INT2FIX(port->status); }
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); }
/*----------------------------------------------------------------------------- - FUNCTION: ConfPort - - DATE: September 20th, 2013 - - REVISIONS: VincentLau - Edited parameters to take in an opened port name - 2013/11/15 - - DESIGNER: Vincent Lau - - PROGRAMMER: Vincent Lau - - INTERFACE: bool ConfigurePort (HWND* lphwnd, LPTSTR* lpszOpenedPort) - - PARAMETERS: HWND* lphwnd - Pointer to the main window's handle - LPTSTR lpszOpenedPort - Name of the serial port that is connected - - RETURNS: TRUE - if the configuration was successful - FALSE - if a configuration error occured or the dialog was canceled - - NOTES: Brings up the Win32 COMMCONFIG dialog for the user to adjust any - settings for communication. Will also set the state of the comm - device and get+set the default timeouts for the specified port. - -----------------------------------------------------------------------------*/ BOOL ConfPort (HWND* lphwnd, LPTSTR lpszOpenedPort) { COMMCONFIG cc; COMMTIMEOUTS comTimeout; cc.dwSize = sizeof (COMMCONFIG); cc.wVersion = 0x100; // Get defaults GetCommConfig (hComm, &cc, &cc.dwSize); // Allow user to change settings from this config dialog if (!CommConfigDialog (lpszOpenedPort, *lphwnd, &cc)) return FALSE; PurgeComm(hComm, PURGE_RXCLEAR | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXABORT); return TRUE; }
bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode) { Q_Q(QextSerialPort); DWORD confSize = sizeof(COMMCONFIG); commConfig.dwSize = confSize; DWORD dwFlagsAndAttributes = 0; if (queryMode == QextSerialPort::EventDriven) dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; /*open the port*/ handle = CreateFileW((wchar_t *)fullPortNameWin(port).utf16(), GENERIC_READ|GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, dwFlagsAndAttributes, nullptr); if (handle != INVALID_HANDLE_VALUE) { q->setOpenMode(mode); /*configure port settings*/ GetCommConfig(handle, &commConfig, &confSize); GetCommState(handle, &(commConfig.dcb)); /*set up parameters*/ commConfig.dcb.fBinary = TRUE; commConfig.dcb.fInX = FALSE; commConfig.dcb.fOutX = FALSE; commConfig.dcb.fAbortOnError = FALSE; commConfig.dcb.fNull = FALSE; /* Dtr default to true. See Issue 122*/ commConfig.dcb.fDtrControl = TRUE; /*flush all settings*/ settingsDirtyFlags = DFE_ALL; updatePortSettings(); //init event driven approach if (queryMode == QextSerialPort::EventDriven) { if (!SetCommMask(handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) { QESP_WARNING()<<"failed to set Comm Mask. Error code:"<<GetLastError(); return false; } winEventNotifier = new QWinEventNotifier(overlap.hEvent, q); qRegisterMetaType<HANDLE>("HANDLE"); q->connect(winEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onWinEvent(HANDLE)), Qt::DirectConnection); WaitCommEvent(handle, &eventMask, &overlap); } return true; } return false; }
// Habilitacion y programacion del puerto serie int CComm32::OpenComm() { if (m_OnOpen) return ERROR_ALREADY_INITIALIZED; m_HPort=CreateFile(m_Name,GENERIC_READ+GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); if (m_HPort==INVALID_HANDLE_VALUE) return GetLastError(); m_OnOpen=true; if (GetFileType(m_HPort)!=FILE_TYPE_CHAR) { CloseHandle(m_HPort); return ERROR_OPEN_FAILED; } m_Read_Overlapped.hEvent=CreateEvent(NULL,true,true,NULL); if (m_Read_Overlapped.hEvent==0) { CloseAll(); return GetLastError(); } m_Write_Overlapped.hEvent=CreateEvent(NULL,true,true,NULL); if (m_Write_Overlapped.hEvent==0) { CloseAll(); return GetLastError(); } GetCommProperties(m_HPort,&m_CommProp); SetCommMask(m_HPort,m_EvtMask); SetCommTimeouts(m_HPort,&m_CommTimeOuts); GetCommModemStatus(m_HPort,&m_ModemStat); DWORD size=sizeof(COMMCONFIG); GetCommConfig(m_HPort,&m_CommConfig,&size); return 0; }
/*! \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; }
LRESULT CALLBACK WndProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { int response; HDC hdc; PAINTSTRUCT paintstruct; static unsigned k = 0; switch (Message) { case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_COM1: cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; GetCommConfig (hComm, &cc, &cc.dwSize); if (!CommConfigDialog (lpszCommName, hwnd, &cc)) break; break; case IDM_COM2: cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; GetCommConfig (hComm, &cc, &cc.dwSize); if (!CommConfigDialog (lpszCommName, hwnd, &cc)) break; break; } break; case WM_RBUTTONDOWN: // Process right button response = MessageBox (hwnd, "Press One:", "Right Button", MB_ABORTRETRYIGNORE); switch (response) { case IDABORT: MessageBox (hwnd, "", "Abort", MB_OK); break; case IDRETRY: MessageBox (hwnd, "", "Retry", MB_OK); break; case IDIGNORE: MessageBox (hwnd, "", "Ignore", MB_OK); break; } break; case WM_LBUTTONDOWN: // Process left button response = MessageBox (hwnd, "Conitnue?", "Left Button", MB_ICONHAND | MB_YESNO); switch (response) { case IDYES: MessageBox (hwnd, "Press Button", "Yes", MB_OK); break; case IDNO: MessageBox (hwnd, "Press Button", "No", MB_OK); break; } break; case WM_CHAR: // Process keystroke hdc = GetDC (hwnd); // get device context sprintf (str, "%c", (char) wParam); // Convert char to string TextOut (hdc, 10*k, 0, str, strlen (str)); // output character k++; // increment the screen x-coordinate ReleaseDC (hwnd, hdc); // Release device context break; case WM_PAINT: // Process a repaint message hdc = BeginPaint (hwnd, &paintstruct); // Acquire DC TextOut (hdc, 0, 0, str, strlen (str)); // output character EndPaint (hwnd, &paintstruct); // Release DC break; case WM_DESTROY: // Terminate program PostQuitMessage (0); break; default: return DefWindowProc (hwnd, Message, wParam, lParam); } return 0; }
__bool CSerialPort::open() { char buf[64]; DCB dcb; COMMTIMEOUTS tout; if(INVALID_HANDLE_VALUE != m_hFile){ return __true; } sprintf(buf, "\\\\.\\COM%d", m_iPortNo); m_hFile = CreateFile( buf, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); utils_trace( "COM %d opened as 0x%08x\n", m_iPortNo, m_hFile ); if(INVALID_HANDLE_VALUE==m_hFile){ return __false; } get_config_string(); if( !setup_dcb(m_Setting, &dcb) ){ close(); utils_trace( "COM%d, error in setting string : %s, code %d\n", m_iPortNo, m_Setting, GetLastError() ); return __false; } if( !SetCommState(m_hFile, &dcb) ){ utils_error( "COM%d, SetCommState failed with %d.\n", m_iPortNo, GetLastError() ); close(); } utils_trace( "Ok, COM%d setting applied : '%s'\n", m_iPortNo, m_Setting ); if( !GetCommTimeouts(m_hFile, &tout) ){ close(); utils_trace( "COM%d, Error in GetCommTimeouts, Code %d.\n", m_iPortNo, GetLastError() ); return __false; } tout.ReadIntervalTimeout = MAXDWORD; tout.ReadTotalTimeoutMultiplier = 0; tout.ReadTotalTimeoutConstant = 0; tout.WriteTotalTimeoutMultiplier = 10; tout.WriteTotalTimeoutConstant = 0; if(!SetCommTimeouts(m_hFile, &tout)){ utils_trace( "COM%d, Error in SetCommTimeouts, Code %d.\n", m_iPortNo, GetLastError() ); close(); return __false; } m_OverlappedEvent = new CEvent(0, TRUE, FALSE); if(!m_OverlappedEvent || !m_OverlappedEvent->Handle()){ utils_trace( "COM%d, error %d creating overlapped event.\n", m_iPortNo, GetLastError() ); close(); return __false; } if( !PurgeComm( m_hFile, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ){ utils_error( "COM%d, Warning : PurgeComm failed with %d\n", m_iPortNo, GetLastError() ); } COMMCONFIG cfg; DWORD size; cfg.dwSize = size = sizeof(cfg); if( !GetCommConfig(m_hFile, &cfg, &size) ){ utils_error( "Warning : GetCommConfig failed with %d\n", GetLastError() ); }else{ utils_trace( "COM%d setting is : '%d,%c,%d,%d(%08x)'\n", m_iPortNo, cfg.dcb.BaudRate, Parity(&cfg.dcb), cfg.dcb.ByteSize, Stopbits(cfg.dcb.StopBits), *((DWORD*)&cfg.dcb + 2) ); } return __true; }
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 }
//---------------------------------------------------------------- bool ofSerial::setup(string portName, int baud){ bInited = false; #if defined( TARGET_OSX ) || defined( TARGET_LINUX ) //lets account for the name being passed in instead of the device path if(portName.size() > 5 && portName.substr(0, 5) != "/dev/"){ portName = "/dev/" + portName; } ofLogNotice("ofSerial") << "opening " << portName << " @ " << baud << " bps"; fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd == -1){ ofLogError("ofSerial") << "unable to open " << portName; return false; } struct termios options; tcgetattr(fd, &oldoptions); options = oldoptions; switch(baud){ case 300: cfsetispeed(&options, B300); cfsetospeed(&options, B300); break; case 1200: cfsetispeed(&options, B1200); cfsetospeed(&options, B1200); break; case 2400: cfsetispeed(&options, B2400); cfsetospeed(&options, B2400); break; case 4800: cfsetispeed(&options, B4800); cfsetospeed(&options, B4800); break; case 9600: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); break; case 14400: cfsetispeed(&options, B14400); cfsetospeed(&options, B14400); break; case 19200: cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); break; case 28800: cfsetispeed(&options, B28800); cfsetospeed(&options, B28800); break; case 38400: cfsetispeed(&options, B38400); cfsetospeed(&options, B38400); break; case 57600: cfsetispeed(&options, B57600); cfsetospeed(&options, B57600); break; case 115200: cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); break; case 230400: cfsetispeed(&options, B230400); cfsetospeed(&options, B230400); break; default: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); ofLogError("ofSerial") << "setup(): cannot set " << baud << " bps, setting to 9600"; break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_iflag &= (tcflag_t) ~(INLCR | IGNCR | ICRNL | IGNBRK); options.c_oflag &= (tcflag_t) ~(OPOST); options.c_cflag |= CS8; tcsetattr(fd, TCSANOW, &options); bInited = true; ofLogNotice("ofSerial") << "opened " << portName << " sucessfully @ " << baud << " bps"; return true; #elif defined( TARGET_WIN32 ) char pn[sizeof(portName)]; int num; if(sscanf(portName.c_str(), "COM%d", &num) == 1){ // Microsoft KB115831 a.k.a if COM > COM9 you have to use a different // syntax sprintf(pn, "\\\\.\\COM%d", num); } else { strncpy(pn, (const char *)portName.c_str(), sizeof(portName)-1); } // open the serial port: // "COM4", etc... hComm = CreateFileA(pn, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if(hComm == INVALID_HANDLE_VALUE){ ofLogError("ofSerial") << "setup(): unable to open " << portName; return false; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; WCHAR buf[80]; cfgSize = sizeof(cfg); GetCommConfig(hComm, &cfg, &cfgSize); int bps = baud; swprintf(buf, L"baud=%d parity=N data=8 stop=1", bps); if(!BuildCommDCBW(buf, &cfg.dcb)){ ofLogError("ofSerial") << "setup(): unable to build comm dcb, (" << buf << ")"; } // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm, &cfg.dcb)){ ofLogError("ofSerial") << "setup(): couldn't set comm state: " << cfg.dcb.BaudRate << " bps, xio " << cfg.dcb.fInX << "/" << cfg.dcb.fOutX; } //ofLogNotice("ofSerial") << "bps=" << cfg.dcb.BaudRate << ", xio=" << cfg.dcb.fInX << "/" << cfg.dcb.fOutX; // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm, &oldTimeout); tOut = oldTimeout; // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout = MAXDWORD; tOut.ReadTotalTimeoutMultiplier = 0; tOut.ReadTotalTimeoutConstant = 0; SetCommTimeouts(hComm, &tOut); bInited = true; return true; #else ofLogError("ofSerial") << "not implemented in this platform"; return false; #endif }
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; }
//---------------------------------------------------------------- bool ofSerial::setup(std::string portName, int baud){ std::cout << "setup serial" << "\r\n"; bInited = false; char pn[sizeof(portName)]; int num; if (sscanf(portName.c_str(), "COM%d", &num) == 1) { // Microsoft KB115831 a.k.a if COM > COM9 you have to use a different // syntax sprintf(pn, "\\\\.\\COM%d", num); } else { strncpy(pn, (const char *)portName.c_str(), sizeof(portName)-1); } // open the serial port: // "COM4", etc... hComm=CreateFileA(pn,GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ std::cout << "setup(): unable to open " << portName << "\r\n"; return false; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); #if (_MSC_VER) // microsoft visual studio // msvc doesn't like BuildCommDCB, //so we need to use this version: BuildCommDCBA if(!BuildCommDCBA(buf,&cfg.dcb)){ std::cout << "setup(): unable to build comm dcb, (" << buf << ")" << "\r\n"; } #else if(!BuildCommDCB(buf,&cfg.dcb)){ std::cout << "setup(): unable to build comm dcb, (" << buf << ")" << "\r\n"; } #endif // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm,&cfg.dcb)){ std::cout << "setup(): couldn't set comm state: " << cfg.dcb.BaudRate << " bps, xio " << cfg.dcb.fInX << "/" << cfg.dcb.fOutX << "\r\n"; } //std::cout << "bps=" << cfg.dcb.BaudRate << ", xio=" << cfg.dcb.fInX << "/" << cfg.dcb.fOutX << "\r\n"; // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&oldTimeout); tOut = oldTimeout; // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; return true; }
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; }
//---------------------------------------------------------------- bool ofSerial::setup(std::string portName, int baud){ bInited = false; //--------------------------------------------- #if defined( TARGET_OSX ) || defined( TARGET_LINUX ) //--------------------------------------------- //lets account for the name being passed in instead of the device path if( portName.size() > 5 && portName.substr(0, 5) != "/dev/" ){ portName = "/dev/" + portName; } ofLog(OF_LOG_NOTICE,"ofSerialInit: opening port %s @ %d bps", portName.c_str(), baud); fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd == -1){ ofLog(OF_LOG_ERROR,"ofSerial: unable to open port %s", portName.c_str()); return false; } struct termios options; tcgetattr(fd,&oldoptions); options = oldoptions; switch(baud){ case 300: cfsetispeed(&options,B300); cfsetospeed(&options,B300); break; case 1200: cfsetispeed(&options,B1200); cfsetospeed(&options,B1200); break; case 2400: cfsetispeed(&options,B2400); cfsetospeed(&options,B2400); break; case 4800: cfsetispeed(&options,B4800); cfsetospeed(&options,B4800); break; case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; case 14400: cfsetispeed(&options,B14400); cfsetospeed(&options,B14400); break; case 19200: cfsetispeed(&options,B19200); cfsetospeed(&options,B19200); break; case 28800: cfsetispeed(&options,B28800); cfsetospeed(&options,B28800); break; case 38400: cfsetispeed(&options,B38400); cfsetospeed(&options,B38400); break; case 57600: cfsetispeed(&options,B57600); cfsetospeed(&options,B57600); break; case 115200: cfsetispeed(&options,B115200); cfsetospeed(&options,B115200); break; default: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); ofLog(OF_LOG_ERROR,"ofSerialInit: cannot set %i baud setting baud to 9600", baud); break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; ofLog(OF_LOG_NOTICE,"sucess in opening serial connection"); return true; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- // open the serial port: // "COM4", etc... hComm=CreateFileA(portName.c_str(),GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ ofLog(OF_LOG_ERROR,"ofSerial: unable to open port"); return false; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; sprintf_s(buf,80,"baud=%d parity=N data=8 stop=1",bps); #if (_MSC_VER) // microsoft visual studio // msvc doesn't like BuildCommDCB, //so we need to use this version: BuildCommDCBA if(!BuildCommDCBA(buf,&cfg.dcb)){ ofLog(OF_LOG_ERROR,"ofSerial: unable to build comm dcb; (%s)",buf); } #else if(!BuildCommDCB(buf,&cfg.dcb)){ ofLog(OF_LOG_ERROR,"ofSerial: Can't build comm dcb; %s",buf); } #endif // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm,&cfg.dcb)){ ofLog(OF_LOG_ERROR,"ofSerial: Can't set comm state"); } //ofLog(OF_LOG_NOTICE,buf,"bps=%d, xio=%d/%d",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX); // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&oldTimeout); tOut = oldTimeout; // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; return true; //--------------------------------------------- #endif //--------------------------------------------- }
/* * asynOption methods */ static asynStatus getOption(void *drvPvt, asynUser *pasynUser, const char *key, char *val, int valSize) { ttyController_t *tty = (ttyController_t *)drvPvt; DWORD commConfigSize = sizeof(tty->commConfig); BOOL ret; DWORD error; int l; assert(tty); 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) { l = epicsSnprintf(val, valSize, "%d", tty->commConfig.dcb.BaudRate); } else if (epicsStrCaseCmp(key, "bits") == 0) { l = epicsSnprintf(val, valSize, "%d", tty->commConfig.dcb.ByteSize); } else if (epicsStrCaseCmp(key, "parity") == 0) { switch (tty->commConfig.dcb.Parity) { case 0: l = epicsSnprintf(val, valSize, "none"); break; case 1: l = epicsSnprintf(val, valSize, "odd"); break; case 2: l = epicsSnprintf(val, valSize, "even"); break; } } else if (epicsStrCaseCmp(key, "stop") == 0) { l = epicsSnprintf(val, valSize, "%d", (tty->commConfig.dcb.StopBits == 2) ? 2 : 1); } else if (epicsStrCaseCmp(key, "clocal") == 0) { l = epicsSnprintf(val, valSize, "%c", (tty->commConfig.dcb.fOutxDsrFlow == TRUE) ? 'N' : 'Y'); } else if (epicsStrCaseCmp(key, "crtscts") == 0) { l = epicsSnprintf(val, valSize, "%c", (tty->commConfig.dcb.fOutxCtsFlow == TRUE) ? 'Y' : 'N'); } else if (epicsStrCaseCmp(key, "ixon") == 0) { l = epicsSnprintf(val, valSize, "%c", (tty->commConfig.dcb.fOutX == TRUE) ? 'Y' : 'N'); } else if (epicsStrCaseCmp(key, "ixany") == 0) { l = epicsSnprintf(val, valSize, "%c", 'N'); } else if (epicsStrCaseCmp(key, "ixoff") == 0) { l = epicsSnprintf(val, valSize, "%c", (tty->commConfig.dcb.fInX == TRUE) ? 'Y' : 'N'); } else { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Unsupported key \"%s\"", key); return asynError; } if (l >= valSize) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Value buffer for key '%s' is too small.", key); return asynError; } asynPrint(tty->pasynUser, ASYN_TRACEIO_DRIVER, "%s getOption, key=%s, val=%s\n", tty->serialDeviceName, key, val); return asynSuccess; }
//---------------------------------------------------------------- bool ofSerial::setup(int deviceNumber, int baud){ int deviceCount = 0; string str = ""; string device = ""; bool deviceFound = false; //--------------------------------------------- #if defined( TARGET_OSX ) || defined( TARGET_LINUX ) //--------------------------------------------- //---------------------------------------------------- //We will find serial devices by listing the directory DIR *dir; struct dirent *entry; dir = opendir("/dev"); if (dir == NULL){ ofLog(OF_LOG_ERROR,"ofSerial: error listing devices in /dev"); } while ((entry = readdir(dir)) != NULL){ str = (char *)entry->d_name; #ifdef TARGET_OSX //if( str.substr(0,3) == "cu." || str.substr(0,4) == "tty." ){ if( str.find("cu.usbserial") == 0 || str.find("tty.usbserial") == 0 ){ #else if( str.substr(0,4) == "ttyS" || str.substr(0,6) == "ttyUSB" || str.substr(0,3) == "rfc" ){ #endif if(deviceCount == deviceNumber){ device = "/dev/"+str; deviceFound = true; ofLog(OF_LOG_NOTICE,"ofSerial device %i - /dev/%s <--selected", deviceCount, str.c_str()); }else ofLog(OF_LOG_NOTICE,"ofSerial device %i - /dev/%s", deviceCount, str.c_str()); deviceCount++; } } if(deviceFound){ return setup(device, baud); }else{ ofLog(OF_LOG_ERROR,"ofSerial: could not find device %i - only %i devices found", deviceNumber, deviceCount); return false; } //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- enumerateWin32Ports(); if (deviceNumber < nPorts){ device = portNamesShort[deviceNumber]; deviceFound = true; } if(deviceFound){ return setup(device, baud); }else{ ofLog(OF_LOG_ERROR,"ofSerial: could not find device %i - only %i devices found", deviceNumber, nPorts); return false; } //--------------------------------------------- #endif //--------------------------------------------- } //---------------------------------------------------------------- bool ofSerial::setup(string portName, int baud){ bInited = false; //--------------------------------------------- #if defined( TARGET_OSX ) || defined( TARGET_LINUX ) //--------------------------------------------- ofLog(OF_LOG_NOTICE,"ofSerialInit: opening port %s @ %d bps", portName.c_str(), baud); fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd == -1){ ofLog(OF_LOG_ERROR,"ofSerial: unable to open port"); return false; } struct termios options; tcgetattr(fd,&oldoptions); options = oldoptions; switch(baud){ case 300: cfsetispeed(&options,B300); cfsetospeed(&options,B300); break; case 1200: cfsetispeed(&options,B1200); cfsetospeed(&options,B1200); break; case 2400: cfsetispeed(&options,B2400); cfsetospeed(&options,B2400); break; case 4800: cfsetispeed(&options,B4800); cfsetospeed(&options,B4800); break; case 9600: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); break; case 14400: cfsetispeed(&options,B14400); cfsetospeed(&options,B14400); break; case 19200: cfsetispeed(&options,B19200); cfsetospeed(&options,B19200); break; case 28800: cfsetispeed(&options,B28800); cfsetospeed(&options,B28800); break; case 38400: cfsetispeed(&options,B38400); cfsetospeed(&options,B38400); break; case 57600: cfsetispeed(&options,B57600); cfsetospeed(&options,B57600); break; case 115200: cfsetispeed(&options,B115200); cfsetospeed(&options,B115200); break; default: cfsetispeed(&options,B9600); cfsetospeed(&options,B9600); ofLog(OF_LOG_ERROR,"ofSerialInit: cannot set %i baud setting baud to 9600\n", baud); break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; ofLog(OF_LOG_NOTICE,"sucess in opening serial connection"); return true; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef TARGET_WIN32 //--------------------------------------------- // open the serial port: // "COM4", etc... hComm=CreateFileA(portName.c_str(),GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE){ ofLog(OF_LOG_ERROR,"ofSerial: unable to open port"); return false; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); #if (_MSC_VER) // microsoft visual studio // msvc doesn't like BuildCommDCB, //so we need to use this version: BuildCommDCBA if(!BuildCommDCBA(buf,&cfg.dcb)){ ofLog(OF_LOG_ERROR,"ofSerial: unable to build comm dcb; (%s)",buf); } #else if(!BuildCommDCB(buf,&cfg.dcb)){ ofLog(OF_LOG_ERROR,"ofSerial: Can't build comm dcb; %s",buf); } #endif // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm,&cfg.dcb)){ ofLog(OF_LOG_ERROR,"ofSerial: Can't set comm state"); } //ofLog(OF_LOG_NOTICE,buf,"bps=%d, xio=%d/%d",cfg.dcb.BaudRate,cfg.dcb.fOutX,cfg.dcb.fInX); // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&oldTimeout); tOut = oldTimeout; // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; return true; //--------------------------------------------- #endif //--------------------------------------------- }
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; }
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; }
//---------------------------------------------------------------- bool Serial::setup(string portName, int baud) { close(); //--------------------------------------------- #if defined( KINSKI_MAC ) || defined( KINSKI_LINUX ) //--------------------------------------------- //lets account for the name being passed in instead of the device path if( portName.size() > 5 && portName.substr(0, 5) != "/dev/" ) { portName = "/dev/" + portName; } LOG_DEBUG << "opening " << portName << " @ " << baud << " bps"; m_handle = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); if(m_handle == -1) { LOG_ERROR << "unable to open " << portName; return false; } struct termios options; tcgetattr(m_handle, &m_old_options); options = m_old_options; switch(baud) { case 300: cfsetispeed(&options, B300); cfsetospeed(&options, B300); break; case 1200: cfsetispeed(&options, B1200); cfsetospeed(&options, B1200); break; case 2400: cfsetispeed(&options, B2400); cfsetospeed(&options, B2400); break; case 4800: cfsetispeed(&options, B4800); cfsetospeed(&options, B4800); break; case 9600: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); break; #ifndef KINSKI_LINUX case 14400: cfsetispeed(&options, B14400); cfsetospeed(&options, B14400); break; case 28800: cfsetispeed(&options, B28800); cfsetospeed(&options, B28800); break; #endif case 19200: cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); break; case 38400: cfsetispeed(&options, B38400); cfsetospeed(&options, B38400); break; case 57600: cfsetispeed(&options, B57600); cfsetospeed(&options, B57600); break; case 115200: cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); break; case 230400: cfsetispeed(&options, B230400); cfsetospeed(&options, B230400); break; default: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); LOG_ERROR << "setup(): cannot set " << baud << " bps, setting to 9600"; break; } options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(m_handle,TCSANOW,&options); bInited = true; LOG_DEBUG << "opened " << portName << "sucessfully @ " << baud << " bps"; return true; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef KINSKI_MSW //--------------------------------------------- char pn[sizeof(portName)]; int num; if (sscanf(portName.c_str(), "COM%d", &num) == 1) { // Microsoft KB115831 a.k.a if COM > COM9 you have to use a different // syntax sprintf(pn, "\\\\.\\COM%d", num); } else { strncpy(pn, (const char *)portName.c_str(), sizeof(portName)-1); } // open the serial port: // "COM4", etc... hComm=CreateFileA(pn,GENERIC_READ|GENERIC_WRITE,0,0, OPEN_EXISTING,0,0); if(hComm==INVALID_HANDLE_VALUE) { LOG_ERROR << "setup(): unable to open " << portName; return false; } // now try the settings: COMMCONFIG cfg; DWORD cfgSize; char buf[80]; cfgSize=sizeof(cfg); GetCommConfig(hComm,&cfg,&cfgSize); int bps = baud; sprintf(buf,"baud=%d parity=N data=8 stop=1",bps); #if (_MSC_VER) // microsoft visual studio // msvc doesn't like BuildCommDCB, //so we need to use this version: BuildCommDCBA if(!BuildCommDCBA(buf,&cfg.dcb)) { LOG_ERROR << "setup(): unable to build comm dcb, (" << buf << ")"; } #else if(!BuildCommDCB(buf,&cfg.dcb)) { LOG_ERROR << "setup(): unable to build comm dcb, (" << buf << ")"; } #endif // Set baudrate and bits etc. // Note that BuildCommDCB() clears XON/XOFF and hardware control by default if(!SetCommState(hComm,&cfg.dcb)) { LOG_ERROR << "setup(): couldn't set comm state: " << cfg.dcb.BaudRate << " bps, xio " << cfg.dcb.fInX << "/" << cfg.dcb.fOutX;; } //ofLogNotice("Serial") << "bps=" << cfg.dcb.BaudRate << ", xio=" << cfg.dcb.fInX << "/" << cfg.dcb.fOutX; // Set communication timeouts (NT) COMMTIMEOUTS tOut; GetCommTimeouts(hComm,&oldTimeout); tOut = oldTimeout; // Make timeout so that: // - return immediately with buffered characters tOut.ReadIntervalTimeout=MAXDWORD; tOut.ReadTotalTimeoutMultiplier=0; tOut.ReadTotalTimeoutConstant=0; SetCommTimeouts(hComm,&tOut); bInited = true; return true; //--------------------------------------------- #endif //--------------------------------------------- }
/*------------------------------------------------------------------------------ -- FUNCTION: Connect -- -- DATE: Oct 16, 2010 -- -- REVISIONS: Nov 6, 2010 - Added initialization of rfid scanner and printing -- headers for token display. -- -- DESIGNER: Dean Morin -- -- PROGRAMMER: Dean Morin -- -- INTERFACE: Connect(HWND hWnd) -- hWnd - the handle to the window -- -- RETURNS: True if the serial connection was succefully made. -- -- NOTES: -- Opens a serial port connection, displaying appropriate dialogue -- messages for failed connections. If successful, it sets comm -- settings and creates a read thread. It then enables/disables -- the appropriate menu choices. ------------------------------------------------------------------------------*/ BOOL Connect(HWND hWnd) { PWNDDATA pwd = {0}; COMMTIMEOUTS timeOut = {0}; DWORD dwThreadid = 0; DWORD i = 0; COMMCONFIG cc = {0}; pwd = (PWNDDATA) GetWindowLongPtr(hWnd, 0); // open serial port pwd->hPort = CreateFile(pwd->lpszCommName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (pwd->hPort == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) { DISPLAY_ERROR("Serial port does not exist"); } else { DISPLAY_ERROR("Error opening port"); } return FALSE; } pwd->bConnected = TRUE; cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 1; GetCommConfig(pwd->hPort, &cc, &cc.dwSize); if (!CommConfigDialog(pwd->lpszCommName, hWnd, &cc)) { DISPLAY_ERROR("The comm settings dialogue failed.\nThis port may not exist"); } // set timeouts for the port if (!GetCommTimeouts(pwd->hPort, &timeOut)) { DISPLAY_ERROR("Error retrieving comm timeouts"); return FALSE; } timeOut.ReadIntervalTimeout = MAXDWORD; timeOut.ReadTotalTimeoutConstant = 0; timeOut.ReadTotalTimeoutMultiplier = 0; timeOut.WriteTotalTimeoutMultiplier = 0; timeOut.WriteTotalTimeoutConstant = 0; if (!SetCommTimeouts(pwd->hPort, &timeOut)) { DISPLAY_ERROR("Could not set comm timeouts"); return FALSE; } if (!SetCommState(pwd->hPort, &cc.dcb)) { DISPLAY_ERROR("Could not set comm state"); return FALSE; } // create thread for reading pwd->hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PortIOThreadProc, hWnd, 0, &dwThreadid); if (pwd->hThread == INVALID_HANDLE_VALUE) { DISPLAY_ERROR("Error creating read thread"); return FALSE; } if (!EscapeCommFunction(pwd->hPort, SETRTS)) { DISPLAY_ERROR("Error sending RTS signal"); } if (!EscapeCommFunction(pwd->hPort, SETDTR)) { DISPLAY_ERROR("Error sending DTR signal"); } CUR_FG_COLOR = 7; CUR_BG_COLOR = 0; CUR_STYLE = 0; BRIGHTNESS = 0; // enable/disable appropriate menu choices EnableMenuItem(GetMenu(hWnd), IDM_DISCONNECT, MF_ENABLED); EnableMenuItem(GetMenu(hWnd), IDM_CONNECT, MF_GRAYED); EnableMenuItem(GetMenu(hWnd), IDM_COMMSET, MF_GRAYED); for (i = 0; i < NO_OF_PORTS; i++) { EnableMenuItem(GetMenu(hWnd), IDM_COM1 + i, MF_GRAYED); } return TRUE; }
// 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; }
// 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; }
/* FUNCTION: CreateUI DATE: 12/2/2015 REVISIONS: v1 DESIGNER: Dylan PROGRAMMER: Dylan INTERFACE: BOOL CreateUI(HINSTANCE hInst) HINSTANCE hInst : instance on to which the UI elements are created RETURNS: TRUE if all the UI elements are created, FALSE otherwise NOTES: It is the caller's responsibility to ensure that this function is called at the appropriate time (i.e. when UI elements can be created). */ BOOL CreateUI(HINSTANCE hInst) { WNDCLASSEX Wcl; enq[0] = ENQ; ack[0] = ACK; if ((hComm = CreateFile(TEXT("COM1"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE) { OutputDebugString("Failed to open COM port\n"); } else { } // create the main window class Wcl.cbSize = sizeof(WNDCLASSEX); Wcl.style = CS_HREDRAW | CS_VREDRAW; Wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon Wcl.hIconSm = NULL; // use small version of large icon Wcl.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor style Wcl.lpfnWndProc = WndProc; Wcl.hInstance = hInst; Wcl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //white background Wcl.lpszClassName = Name; Wcl.lpszMenuName = TEXT("ASN4MENU"); // The menu Class Wcl.cbClsExtra = 0; // no extra memory needed Wcl.cbWndExtra = 0; if (!RegisterClassEx(&Wcl)) { OutputDebugString("Failed to register Wcl"); return FALSE; } // show ui hMain = CreateWindow(Name, Name, WS_OVERLAPPEDWINDOW, 10, 10, 800, 600, NULL, NULL, hInst, NULL); if (!(hBtnConnect = CreateWindow("BUTTON", "Send File", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, BTN_XSTART, BTN_YSTART, BTN_WIDTH, BTN_HEIGHT, hMain, (HMENU)ASN_OPN, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hBtnQuit = CreateWindow("BUTTON", "Quit", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, BTN_XSTART, BTN_YSTART + BTN_HEIGHT + BTN_BUFFER, BTN_WIDTH, BTN_HEIGHT, hMain, (HMENU)ASN_QUIT, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hSend = CreateWindow("EDIT", "Sent File", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE, 0, 0, 400, 250, hMain, (HMENU)NULL, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hSendEnq = CreateWindow("BUTTON", "Send ENQ", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, BTN_XSTART, BTN_YSTART + (BTN_HEIGHT + BTN_BUFFER) * 2, BTN_WIDTH, BTN_HEIGHT, hMain, (HMENU)ASN_ENQ, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hReceive = CreateWindow("EDIT", "Received File", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 250, 400, 250, hMain, (HMENU)NULL, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hStats = CreateWindow("STATIC", "Statistics", WS_VISIBLE | WS_CHILD | WS_BORDER, BTN_XSTART + BTN_WIDTH + BTN_BUFFER, BTN_YSTART, 200, 200, hMain, (HMENU)NULL, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; if (!GetCommConfig(hComm, &cc, &cc.dwSize)) { OutputDebugString("Could not get CommConfig\n"); return FALSE; } if ((hThrd = CreateThread(NULL, 0, ReadFromPort, (LPVOID)hComm, 0, &threadId)) == NULL) { //failure OutputDebugString("Failed to start read thread\n"); } else { OutputDebugString("Thread created\n"); } SetStatistics(); return TRUE; }
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; }