int open_ifport (PORTPROP *pc) { OSVERSIONINFO vinfo = { sizeof(OSVERSIONINFO) }; LARGE_INTEGER val1; BYTE cmdspi[6]; static const WORD PortsCom[] = { COM1ADR, COM2ADR, COM3ADR, COM4ADR }; static const WORD PortsLpt[] = { LPT1ADR, LPT2ADR, LPT3ADR }; char sComm[16]; DCB dcb = { sizeof(DCB), 9600, TRUE, FALSE, TRUE, FALSE, DTR_CONTROL_DISABLE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, RTS_CONTROL_DISABLE, FALSE, 0, 0, 10, 10, 8, NOPARITY, ONESTOPBIT, '\x11', '\x13', '\xFF', '\xFF', 0 }; COMMTIMEOUTS commtimeouts = { 0, 1, 100, 1, 300}; /* Check if high resolution timer is supported */ QueryPerformanceFrequency(&val1); if (val1.QuadPart == 0) { pc->Info1 = "Incompatible envilonment.\n"; return 1; } PortDly = pc->Delay; /* I/O delay for direct I/O control */ dcb.BaudRate = pc->Baud; /* Bit rate for SPI bridge */ /* Open direct I/O driver if needed */ if(GetVersionEx(&vinfo) == FALSE) { pc->Info1 = "Incompatible envilonment.\n"; return 1; } if((vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((pc->PortClass == TY_COMM)||(pc->PortClass == TY_LPT))) { if(init_driver()) { pc->Info1 = "I/O driver initialization failed.\n"; return 1; } } /* Use COM port in direct I/O */ if(pc->PortClass == TY_COMM) { if((pc->PortNum < 1)||(pc->PortNum > 4)) { pc->Info1 = "Invalid Port#.\n"; return 1; } PortBase = PortsCom[pc->PortNum - 1]; sprintf(str_info, "No COM%u(0x%X) port.\n", pc->PortNum, PortBase); pc->Info1 = str_info; if(check_comport()) { if(vinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) return 1; sprintf(sComm, "\\\\.\\COM%u", pc->PortNum); hComm = CreateFile(sComm, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hComm == INVALID_HANDLE_VALUE) return 1; if(check_comport()) return 1; } _outp(COM_IMR, 0x00); /* Mask interrupts */ pc->Info1 = NULL; PortType = TY_COMM; return 0; } /* Use COM port via API */ if(pc->PortClass == TY_VCOM) { sprintf(sComm, "\\\\.\\COM%u", pc->PortNum); hComm = CreateFile(sComm, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hComm == INVALID_HANDLE_VALUE) { sprintf(str_info, "%s could not be opened.\n", sComm); pc->Info1 = str_info; return 1; } SetCommState(hComm, &dcb); EscapeCommFunction(hComm, CLRRTS); EscapeCommFunction(hComm, CLRDTR); PortType = TY_VCOM; return 0; } /* Use SPI bridge attached on COM port */ if(pc->PortClass == TY_BRIDGE) { sprintf(sComm, "\\\\.\\COM%u", pc->PortNum); hComm = CreateFile(sComm, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hComm == INVALID_HANDLE_VALUE) { sprintf(str_info, "%s could not be opened.\n", sComm); pc->Info1 = str_info; return 1; } dcb.fOutxCtsFlow = TRUE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; SetCommState(hComm, &dcb); SetCommTimeouts(hComm, &commtimeouts); EscapeCommFunction(hComm, CLRDTR); delay_ms(10); while(read_bridge(cmdspi, sizeof(cmdspi))); cmdspi[0] = FLAG-1; cmdspi[1] = FLAG; cmdspi[2] = SPI_ENABLE; /* Enable Bridge */ cmdspi[3] = FLAG; cmdspi[4] = SPI_SETDLY; cmdspi[5] = (BYTE)PortDly; /* Set SPI delay */ send_bridge(cmdspi, 6); /* Send bridge initialization commands */ read_bridge(cmdspi, 2); /* Check if the commands are accepted */ if((cmdspi[0] != SPI_ENABLE) || (cmdspi[1] != SPI_SETDLY)) { sprintf(str_info, "No SPI bridge on the %s.\n", sComm); pc->Info1 = str_info; return 1; } PortType = TY_BRIDGE; return 0; } /* Use LPT port in direct I/O */ if(pc->PortClass == TY_LPT) { if((pc->PortNum < 1)||(pc->PortNum > 3)) { pc->Info1 = "Invalid Port#.\n"; return 1; } PortBase = PortsLpt[pc->PortNum - 1]; if(check_lptport()) { sprintf(str_info, "No LPT%u(0x%X) port.\n", pc->PortNum, PortBase); pc->Info1 = str_info; return 1; } _outp(LPT_DAT, 0x20); /* Check if the adapter is ByteBlasterMV (D5-ACK) */ if(_inp(LPT_STA) & S_ACK) { _outp(LPT_DAT, 0); if((_inp(LPT_STA) & S_ACK) == 0) { _outp(LPT_CTL, BA_ENA); pc->Info1 = "Altera ByteBlasterMV was found.\n"; PortType = TY_ALTERA; if(_inp(LPT_STA) & S_ERR) return 0; /* Check target power */ pc->Info2 = "But target power is OFF.\n"; return 1; } } _outp(LPT_DAT, 0x80); /* Check if the adapter is AVRSP (D7-PE) */ if(_inp(LPT_STA) & S_PE) { _outp(LPT_DAT, 0); if((_inp(LPT_STA) & S_PE) == 0) { _outp(LPT_DAT, B_ENA); pc->Info1 = "AVRSP adapter was found.\n"; PortType = TY_AVRSP; if(_inp(LPT_STA) & S_ERR) return 0; /* Check target power */ pc->Info2 = "But target power is OFF.\n"; return 1; } } _outp(LPT_DAT, 0x40); /* Check if the adapter is Xilinx JTAG (D6-BUSY-PE) */ if((_inp(LPT_STA) & (S_PE | S_BUSY)) == S_PE) { _outp(LPT_DAT, 0); if((_inp(LPT_STA) & (S_PE | S_BUSY)) == S_BUSY) { pc->Info1 = "Xilinx JTAG adapter was found.\n"; PortType = TY_XILINX; if(_inp(LPT_STA) & S_ERR) return 0; /* Check target power */ pc->Info2 = "But target power is OFF.\n"; return 1; } } _outp(LPT_DAT, 0x40); /* Check if the adapter is Lattice ISP (D6-PE) */ if(_inp(LPT_STA) & S_PE) { _outp(LPT_DAT, 0); if((_inp(LPT_STA) & S_PE) == 0) { pc->Info1 = "Lattice ISP adapter was found.\n"; PortType = TY_LATTICE; if(_inp(LPT_STA) & S_ERR) return 0; /* Check target power */ pc->Info2 = "But target power is OFF.\n"; return 1; } } _outp(LPT_DAT, 0x01); /* Check if the adapter is STK200 dongle (D0-PE) */ if(_inp(LPT_STA) & S_PE) { _outp(LPT_DAT, 0); if((_inp(LPT_STA) & S_PE) == 0) { pc->Info1 = "STK200 ISP dongle was found.\n"; PortType = TY_STK200; if(_inp(LPT_STA) & S_ERR) return 0; /* Check target power */ pc->Info2 = "But target power is OFF.\n"; return 1; } } sprintf(str_info, "No ISP adapter on the LPT%u.\n", pc->PortNum); pc->Info1 = str_info; return 1; } pc->Info1 = "Invalid port class.\n"; return 1; }
int UART::open(const std::string &portName, int baudRate) { UART_inner_data *pd; COMMTIMEOUTS oComTimeout; BOOL fSuccess; int ret_code = 0; // handle structure pd = (UART_inner_data *) data; if( portName.size() ) port_name = portName; if( baudRate ) baud_rate = baudRate; // open port pd->m_hCom = CreateFile( port_name.c_str(), // COM port Name GENERIC_READ | GENERIC_WRITE, // read/write flags 0, // comm devices must be opened w/exclusive-access NULL, // no security attributes OPEN_EXISTING, // COM devices must use OPEN_EXISTING 0, // no overlapped I/O NULL // hTemplate must be NULL for COM devices ); if (pd->m_hCom == INVALID_HANDLE_VALUE) { // Handle the error. dbg_pe("UART::open CreateFile failed with wrror %d.", GetLastError()); return 1; } // We will build on the current configuration, and skip setting the size // of the input and output buffers with SetupComm. fSuccess = GetCommState(pd->m_hCom, &(pd->m_oDCB)); if ( !fSuccess ) { dbg_pe("UART::open GetComState failed with error %d.", GetLastError()); ret_code = 2; goto UART_OPEN_ERR; } // Fill in the DCB switch(baud_rate) { case 110: pd->m_oDCB.BaudRate = CBR_110; break; case 300: pd->m_oDCB.BaudRate = CBR_300; break; case 600: pd->m_oDCB.BaudRate = CBR_600; break; case 1200: pd->m_oDCB.BaudRate = CBR_1200; break; case 2400: pd->m_oDCB.BaudRate = CBR_2400; break; case 4800: pd->m_oDCB.BaudRate = CBR_4800; break; case 9600: pd->m_oDCB.BaudRate = CBR_9600; break; case 14400: pd->m_oDCB.BaudRate = CBR_14400; break; case 19200: pd->m_oDCB.BaudRate = CBR_19200; break; case 38400: pd->m_oDCB.BaudRate = CBR_38400; break; case 56000: pd->m_oDCB.BaudRate = CBR_56000; break; case 57600: pd->m_oDCB.BaudRate = CBR_57600; break; case 115200: pd->m_oDCB.BaudRate = CBR_115200; break; case 128000: pd->m_oDCB.BaudRate = CBR_128000; break; case 2560000: pd->m_oDCB.BaudRate = CBR_256000; break; default: dbg_pe("UART::open Unsupport baud rate %d.", baud_rate);; ret_code = 3; goto UART_OPEN_ERR; } if( DTR_sw ) pd->m_oDCB.fDtrControl = DTR_CONTROL_DISABLE; if( RTS_sw ) pd->m_oDCB.fRtsControl = RTS_CONTROL_DISABLE; pd->m_oDCB.ByteSize = byte_size; pd->m_oDCB.Parity = parity_sw; switch( stop_bits ) { case 1: pd->m_oDCB.StopBits = ONESTOPBIT; break; case 15: pd->m_oDCB.StopBits = ONE5STOPBITS; break; case 2: pd->m_oDCB.StopBits = TWOSTOPBITS; break; } fSuccess = SetCommState(pd->m_hCom, &(pd->m_oDCB)); if (!fSuccess) { // Handle the error. dbg_pe("UART::open SetComState failed with error %d.", GetLastError()); ret_code = 4; goto UART_OPEN_ERR; } // timout options if( timeout_sw ) { fSuccess = GetCommTimeouts( pd->m_hCom, /* Handle to comm device */ &oComTimeout /* time-out values */ ); if( !fSuccess ) { dbg_pe("UART::open GetCommTimeouts failed with error %d.", GetLastError()); ret_code = 5; goto UART_OPEN_ERR; } oComTimeout.ReadIntervalTimeout = DEFAULT_READINTERVALTIMEOUT; oComTimeout.ReadTotalTimeoutMultiplier = DEFAULT_READMULTIPLIER; oComTimeout.ReadTotalTimeoutConstant = DEFAULT_READTOTALTIMEOUT; oComTimeout.WriteTotalTimeoutMultiplier = DEFAULT_WRITEMULTIPLIER; oComTimeout.WriteTotalTimeoutConstant = DEFAULT_WRITETOTALTIMEOUT; fSuccess = SetCommTimeouts( pd->m_hCom, &oComTimeout ); if( !fSuccess ) { dbg_pe("UART::open SetCommTimeouts failed with error %d.", GetLastError()); ret_code = 6; goto UART_OPEN_ERR; } } // port state goto UART_OPEN_RET; UART_OPEN_ERR: CloseHandle(pd->m_hCom); pd->m_hCom = NULL; UART_OPEN_RET: return ret_code; }
int ndiSerialComm(HANDLE serial_port, int baud, const char *mode, int handshake) { DCB comm_settings; int newbaud; switch (baud) { case 9600: newbaud = CBR_9600; break; case 14400: newbaud = CBR_14400; break; case 19200: newbaud = CBR_19200; break; case 38400: newbaud = CBR_38400; break; case 57600: newbaud = CBR_57600; break; case 115200: newbaud = CBR_115200; break; default: return -1; } GetCommState(serial_port,&comm_settings); comm_settings.BaudRate = newbaud; /* speed */ if (handshake) { /* set handshaking */ comm_settings.fOutxCtsFlow = TRUE; /* on */ comm_settings.fRtsControl = RTS_CONTROL_HANDSHAKE; } else { comm_settings.fOutxCtsFlow = FALSE; /* off */ comm_settings.fRtsControl = RTS_CONTROL_DISABLE; } if (mode[0] == '8') { /* data bits */ comm_settings.ByteSize = 8; } else if (mode[0] == '7') { comm_settings.ByteSize = 7; } else { return -1; } if (mode[1] == 'N') { /* set parity */ comm_settings.Parity = NOPARITY; } else if (mode[1] == 'O') { comm_settings.Parity = ODDPARITY; } else if (mode[1] == 'E') { comm_settings.Parity = EVENPARITY; } else { return -1; } if (mode[2] == '1') { /* set stop bits */ comm_settings.StopBits = ONESTOPBIT; } else if (mode[2] == '2') { comm_settings.StopBits = TWOSTOPBITS; } else { return -1; } SetCommState(serial_port,&comm_settings); return 0; }
int xtapi_device_create_comm_object(COMM_OBJ *commobj) { VARSTRING *varstr = NULL; DWORD varstrsize; HANDLE hCommHandle=NULL; LINECALLINFO *lcinfo = NULL; int retval; int errval = XTAPI_SUCCESS; Assert(TapiDev.connected); varstrsize = sizeof(VARSTRING) + 1024; while (1) { varstr = (VARSTRING *)realloc(varstr, varstrsize); if (!varstr) { errval = XTAPI_OUT_OF_MEMORY; goto device_create_comm_exit; } varstr->dwTotalSize = varstrsize; retval = lineGetID(0,0,TapiDev.hCall, LINECALLSELECT_CALL, varstr, "comm/datamodem"); errval = xtapi_err(retval); if (varstr->dwNeededSize > varstr->dwTotalSize) { varstrsize = varstr->dwNeededSize; } else break; } if (errval != XTAPI_SUCCESS) return errval; hCommHandle = *((LPHANDLE)((LPBYTE)varstr+varstr->dwStringOffset)); lcinfo = tapi_line_getcallinfo(TapiDev.hCall); if (!lcinfo) { errval = XTAPI_OUT_OF_MEMORY; goto device_create_comm_exit; } // Create the COMM compatible COMM_OBJ // Most COMM settings will be set by TAPI, so this is less intensive than the // COMM open connection { COMMTIMEOUTS ctimeouts; memset(commobj, 0, sizeof(COMM_OBJ)); if (GetFileType(hCommHandle) != FILE_TYPE_CHAR) { errval = XTAPI_GENERAL_ERR; goto device_create_comm_exit; } GetCommState(hCommHandle, &commobj->dcb); GetCommTimeouts(hCommHandle, &ctimeouts); commobj->handle = hCommHandle; commobj->baud = lcinfo->dwRate; // commobj->dcb.BaudRate = commobj->baud; // commobj->dcb.fBinary = 1; // commobj->dcb.fNull = 0; // commobj->dcb.ByteSize = 8; // commobj->dcb.StopBits = ONESTOPBIT; // commobj->dcb.fParity = FALSE; // commobj->dcb.Parity = NOPARITY; // commobj->dcb.XonChar = ASCII_XON; // commobj->dcb.XoffChar = ASCII_XOFF; // commobj->dcb.XonLim = 1024; // commobj->dcb.XoffLim = 1024; // commobj->dcb.EofChar = 0; // commobj->dcb.EvtChar = 0; // commobj->dcb.fOutxDsrFlow = FALSE; // commobj->dcb.fOutxCtsFlow = FALSE; // rts/cts off // commobj->dcb.fDtrControl = DTR_CONTROL_ENABLE;// dtr=on // commobj->dcb.fRtsControl = RTS_CONTROL_ENABLE; ctimeouts.ReadIntervalTimeout = 250; ctimeouts.ReadTotalTimeoutMultiplier = 0; ctimeouts.ReadTotalTimeoutConstant = 0; ctimeouts.WriteTotalTimeoutMultiplier = 0; ctimeouts.WriteTotalTimeoutConstant = 0; commobj->dcb.fAbortOnError = FALSE; SetCommTimeouts(hCommHandle, &ctimeouts); SetCommState(hCommHandle, &commobj->dcb); } memset(&commobj->rov, 0, sizeof(OVERLAPPED)); memset(&commobj->wov, 0, sizeof(OVERLAPPED)); commobj->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (commobj->rov.hEvent == NULL) { errval = XTAPI_GENERAL_ERR; goto device_create_comm_exit; } commobj->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (commobj->wov.hEvent == NULL) { CloseHandle(commobj->rov.hEvent); return 0; } commobj->hThread = NULL; commobj->threadID = (DWORD)(-1); commobj->connect = TRUE; device_create_comm_exit: if (varstr) free(varstr); if (lcinfo) free(lcinfo); return errval; }
ATMO_BOOL CAtmoDmxSerialConnection::OpenConnection() { #if defined(_ATMO_VLC_PLUGIN_) char *serdevice = m_pAtmoConfig->getSerialDevice(); if(!serdevice) return ATMO_FALSE; #else int portNummer = m_pAtmoConfig->getComport(); m_dwLastWin32Error = 0; if(portNummer < 1) return ATMO_FALSE; // make no real sense;-) #endif if(!m_dmx_channels_base) return ATMO_FALSE; CloseConnection(); #if !defined(_ATMO_VLC_PLUGIN_) char serdevice[16]; // com4294967295 sprintf(serdevice,"com%d",portNummer); #endif #if defined(WIN32) m_hComport = CreateFile(serdevice, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(m_hComport == INVALID_HANDLE_VALUE) { // we have a problem here can't open com port... somebody else may use it? // m_dwLastWin32Error = GetLastError(); return ATMO_FALSE; } /* change serial settings (Speed, stopbits etc.) */ DCB dcb; // für comport-parameter dcb.DCBlength = sizeof(DCB); GetCommState (m_hComport, &dcb); // ger current serialport settings dcb.BaudRate = 115200; // set speed dcb.ByteSize = 8; // set databits dcb.Parity = NOPARITY; // set parity dcb.StopBits = ONESTOPBIT; // set one stop bit SetCommState (m_hComport, &dcb); // apply settings #else int bconst = B115200; m_hComport = open(serdevice, O_RDWR |O_NOCTTY); if(m_hComport < 0) { return ATMO_FALSE; } struct termios tio; memset(&tio,0,sizeof(tio)); tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL); tio.c_iflag = (INPCK | BRKINT); cfsetispeed(&tio, bconst); cfsetospeed(&tio, bconst); if(!tcsetattr(m_hComport, TCSANOW, &tio)) { tcflush(m_hComport, TCIOFLUSH); } else { // can't change parms close(m_hComport); m_hComport = -1; return false; } #endif return true; }
//////////////////////////////////////////////////////////////////////////////// ///// TCommPort::OpenCommPort() ///// ///// scope: TCommPort public function. ///// purpose : Open the comm port and configure it with the current ///// settings. ///// args : void ///// returns : bool indicating success (true) or failure. ///// written : 10/31/96 by H Howe ///// remarks : Opening a comm port in windows involves getting a handle ///// to a port (comm 1 or 2), getting the current port properties, ///// and changing the properties to suit your needs. Each of the ///// steps can fail. This function bundles all of these tasks ///// into one place. ///// methods : use CreateFile as described in the win32 help file. Check ///// for errors. Then get the DCB properties. Our private DCB ///// properties are then copied into the 4 major settings. void TCommPort::OpenCommPort(void) { if(m_CommOpen) // if already open, don't bother return; // we need to get the default settings while preserving the settings // that we override. The DCB struct has 20 or so members. We override 4. // Make of copy of the settings we care about. DCB tempDCB; tempDCB.BaudRate = m_dcb.BaudRate; tempDCB.ByteSize = m_dcb.ByteSize; tempDCB.Parity = m_dcb.Parity; tempDCB.StopBits = m_dcb.StopBits; m_CommPort = "\\\\.\\" + m_CommPort; m_hCom = CreateFile(m_CommPort.c_str(), GENERIC_READ | GENERIC_WRITE, 0, /* comm devices must be opened w/exclusive-access */ NULL, /* no security attrs */ OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */ 0, /* not overlapped I/O */ NULL /* hTemplate must be NULL for comm devices */ ); // If CreateFile fails, throw an exception. CreateFile will fail if the // port is already open, or if the com port does not exist. if(m_hCom == INVALID_HANDLE_VALUE) throw ECommError(ECommError::OPEN_ERROR); // Now get the DCB properties of the port we just opened if(!GetCommState(m_hCom,&m_dcb)) { // something is hay wire, close the port and return CloseHandle(m_hCom); throw ECommError(ECommError::GETCOMMSTATE); } // dcb contains the actual port properties. Now copy our settings into this dcb m_dcb.BaudRate = tempDCB.BaudRate; m_dcb.ByteSize = tempDCB.ByteSize; m_dcb.Parity = tempDCB.Parity; m_dcb.StopBits = tempDCB.StopBits; m_dcb.fRtsControl = RTS_CONTROL_DISABLE; m_dcb.fDtrControl = DTR_CONTROL_DISABLE; m_dcb.fBinary = true; m_dcb.fParity = NOPARITY; m_dcb.fAbortOnError = false; // now we can set the properties of the port with our settings. if(!SetCommState(m_hCom,&m_dcb)) { // something is hay wire, close the port and return CloseHandle(m_hCom); throw ECommError(ECommError::SETCOMMSTATE); } // set the intial size of the transmit and receive queues. These are // not exposed to outside clients of the class either. Perhaps they should be? // I set the receive buffer to 32k, and the transmit buffer to 9k (a default). if(!SetupComm(m_hCom, 1024*32, 1024*9)) { // something is hay wire, close the port and return CloseHandle(m_hCom); throw ECommError(ECommError::SETUPCOMM); } // These values are just default values that I determined empirically. // Adjust as necessary. I don't expose these to the outside because // most people aren't sure how they work (uhhh, like me included). m_TimeOuts.ReadIntervalTimeout = 15; m_TimeOuts.ReadTotalTimeoutMultiplier = 1; m_TimeOuts.ReadTotalTimeoutConstant = 250; m_TimeOuts.WriteTotalTimeoutMultiplier = 1; m_TimeOuts.WriteTotalTimeoutConstant = 250; if(!SetCommTimeouts(m_hCom, &m_TimeOuts)) { // something is hay wire, close the port and return CloseHandle(m_hCom); throw ECommError(ECommError::SETCOMMTIMEOUTS); } // if we made it to here then success m_CommOpen = true; }
/**************************************************************************** * SetupUart() * * This function initialises the serial port and opens it ready to send and * receive data. * * The default setup is: (define in Uart.h) * COM1 9600,8,1,NOPARITY * * Usage for default setup: SetupUart(); * Or usage for specific parameters: SetupUart("COM2",2400,8,1,NOPARITY); * * Parity can be: Bitsize can be: * EVENPARITY 5 - 8 * MARKPARITY * NOPARITY * ODDPARITY * SPACEPARITY * * Will return 0 if the function fails ******************************************************************************/ int SetupUart(int ComPortNr,int baud,int Bitsize,int StopBits,int Parity) { WCHAR* Port = (WCHAR*)TEXT("COM16"); int STOPBITS; if(StopBits == 1) STOPBITS = ONESTOPBIT; // if(StopBits == 1.5) STOPBITS = ONE5STOPBITS; if(StopBits == 2) STOPBITS = TWOSTOPBITS; switch(ComPortNr){ case 1: Port = (WCHAR*) TEXT("COM1"); break; case 2: Port = (WCHAR*) TEXT("COM2"); break; case 3: Port = (WCHAR*) TEXT("COM3"); break; case 4: Port = (WCHAR*) TEXT("COM4"); break; case 5: Port = (WCHAR*) TEXT("COM5"); break; case 6: Port = (WCHAR*) TEXT("COM6"); break; case 7: Port = (WCHAR*) TEXT("COM7"); break; case 8: Port = (WCHAR*) TEXT("COM8"); break; case 9: Port = (WCHAR*) TEXT("COM9"); break; case 10: Port = (WCHAR*) TEXT("COM10"); break; case 11: Port = (WCHAR*) TEXT("COM11"); break; case 12: Port = (WCHAR*) TEXT("COM12"); break; case 13: Port = (WCHAR*) TEXT("COM13"); break; case 14: Port = (WCHAR*) TEXT("COM14"); break; case 15: Port = (WCHAR*) TEXT("COM15"); break; case 16: Port = (WCHAR*) TEXT("COM16"); break; } // Open the serial port. //hPort = CreateFile (TEXT(Port), // Name of the port //hPort = CreateFile ((const WCHAR*)Port, // Name of the port hPort = CreateFile (Port, // Name of the port GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // If it fails to open the port, return 0. if ( hPort == INVALID_HANDLE_VALUE ) { //We failed to open! return 0; } //Get the default port setting information. GetCommState (hPort, &PortDCB); // Change the settings. PortDCB.BaudRate = baud; // BAUD Rate PortDCB.ByteSize = Bitsize; // Number of bits/byte, 5-8 PortDCB.Parity = Parity; // 0-4=no,odd,even,mark,space PortDCB.StopBits = STOPBITS; // StopBits PortDCB.fNull = 0; // Allow NULL Receive bytes // Re-configure the port with the new DCB structure. if (!SetCommState (hPort, &PortDCB)) { // Could not create the read thread. CloseHandle(hPort); return 0; } // Retrieve the time-out parameters for all read and write operations // on the port. GetCommTimeouts (hPort, &CommTimeouts); memset(&CommTimeouts, 0x00, sizeof(CommTimeouts)); CommTimeouts.ReadIntervalTimeout = 10; // by³o: 10 ################# CommTimeouts.ReadTotalTimeoutConstant = 10; // by³o: 10 ################# CommTimeouts.WriteTotalTimeoutConstant = 10; // Set the time-out parameters for all read and write operations on the port. if (!SetCommTimeouts (hPort, &CommTimeouts)) { // Could not create the read thread. CloseHandle(hPort); return 0; } // Clear the port of any existing data. if(PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR)==0) { CloseHandle(hPort); return 0; } return 1; //SERIAL SETUP OK }
RS232::RS232(int comNum, int baudrate, int bytesize, int parity, int stopbit){ /*********************************************************************** //Find the com port that has been assigned to your device. /***********************************************************************/ /* res = FT_Open(0, &fthandle); if (res != FT_OK){ printf("opening failed! with error %d\n", res); return; } res = FT_GetComPortNumber(fthandle, &COMPORT); if (res != FT_OK){ printf("get com port failed %d\n", res); return; } if (COMPORT == -1){ printf("no com port installed \n"); } else{ printf("com port number is %d\n", COMPORT); } FT_Close(fthandle); */ /********************************************************/ // Open the com port assigned to your device /********************************************************/ // n = sprintf_s(COMx, "\\\\.\\COM%d", COMPORT); // myMutex = CreateMutex(NULL, TRUE, NULL); InitializeCriticalSection(&cs); memset(gStr, 0, 256); n = sprintf_s(COMx, "\\\\.\\COM%d", comNum); hCommPort = CreateFileA( COMx, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hCommPort == INVALID_HANDLE_VALUE) { printf("Help - failed to open\n"); return; } printf("Hello World!\n"); /********************************************************/ // Configure the UART interface parameters /********************************************************/ fSuccess = GetCommState(hCommPort, &dcb); if (!fSuccess) { printf("GetCommStateFailed \n", GetLastError()); return; } //set parameters. dcb.BaudRate = baudrate; dcb.ByteSize = bytesize; dcb.Parity = parity; dcb.StopBits = stopbit; fSuccess = SetCommState(hCommPort, &dcb); if (!fSuccess) { printf("SetCommStateFailed \n", GetLastError()); return; } printf("Port configured \n"); myHThread = CreateThread(NULL, 0, ThreadFunc, (LPVOID)this, CREATE_SUSPENDED, &myThreadId); }
/* SPR - was RTP_HANDLE but didn't build */ long rtp_term_aux_open(void) { HANDLE hComm; DCB dcb; /* JRT */ COMMTIMEOUTS comm_timeouts; hComm = CreateFile( RTP_TERM_AUX_COMM_PORT, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (hComm == INVALID_HANDLE_VALUE) { rtp_term_puts("Error in opening serial comm\n"); return -1; } if (!GetCommState(hComm, &dcb)) // get current DCB // Error in GetCommState return FALSE; FillMemory(&dcb, sizeof(dcb), 0); dcb.DCBlength = sizeof(dcb); if (!BuildCommDCB("baud=9600 parity=n data=8 stop=1 dtr=on rts=on", &dcb)) { // Couldn't build the DCB. Usually a problem // with the communications specification string. return FALSE; } // Update DCB rate. //dcb.BaudRate = RTP_TERM_AUX_BAUD_RATE; // Set new state. if (!SetCommState(hComm, &dcb)) { // Error in SetCommState. Possibly a problem with the communications // port handle or a problem with the DCB structure itself. } /* JRT - Get the timeout and set it appropriately */ rtp_memset(&comm_timeouts, 0x0, sizeof(comm_timeouts)); #define GET_COMM_TIMEOUTS 0 #if GET_COMM_TIMEOUTS GetCommTimeouts(hComm, &comm_timeouts); #endif if (!SetCommTimeouts(hComm, &comm_timeouts)) { char err_string[100]; int error; error = GetLastError(); rtp_sprintf(err_string, "rtp_term_aux_open: SetCommTimeouts failed, error = %d\n", error); rtp_term_puts(err_string); return (-1); } auxComm = (RTP_HANDLE) hComm; return (auxComm); }
/******************************************************************** Declaration: Call: Input: Returns: *********************************************************************/ void CommPort::OpenPort() { m_bPortReady = TRUE; // everything is OK so far m_hCom = CreateFile(m_sComPort, GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // no security OPEN_EXISTING, 0, // no overlapped I/O NULL); // null template if ((unsigned)m_hCom == HFILE_ERROR) { char *MessageBuffer = new char[50]; sprintf(MessageBuffer, "CommPort: %s failed to open.", m_sComPort); printf(MessageBuffer); throw std::runtime_error (MessageBuffer); //throw std::runtime_error ("CommPort failed to open!"); //delete [] MessageBuffer; } m_bPortReady = setBufferComm(); //SetupComm(m_hCom, XX, XX); //m_bPortReady = SetupComm(m_hCom, 128, 128); //SetBaudRate(0); m_bPortReady = GetCommState(m_hCom, &m_dcb); // Port settings are specified in a Data Communication Block (DCB). // The easiest way to initialize a DCB is to call GetCommState to fill in // its default values, override the values that you want to change and // then call SetCommState to set the values. m_dcb.BaudRate = m_BitRate; m_dcb.ByteSize = 8; m_dcb.Parity = NOPARITY; m_dcb.StopBits = ONESTOPBIT; m_dcb.fAbortOnError = TRUE; m_bPortReady = SetCommState(m_hCom, &m_dcb); // Communication timeouts are optional but can be set similarly to DCB values: m_bPortReady = GetCommTimeouts (m_hCom, &m_CommTimeouts); m_CommTimeouts.ReadIntervalTimeout = 50; m_CommTimeouts.ReadTotalTimeoutConstant = 50; m_CommTimeouts.ReadTotalTimeoutMultiplier = 10; m_CommTimeouts.WriteTotalTimeoutConstant = 50; m_CommTimeouts.WriteTotalTimeoutMultiplier = 10; m_bPortReady = SetCommTimeouts (m_hCom, &m_CommTimeouts); // If all of these API's were successful then the port is ready for use. if (m_bPortReady) { printf ("Comm Port %s open successfully.\n", m_sComPort); } else { printf ("Comm Port %s opening failed.\n", m_sComPort); } }
//---------------------------------------------------------------- 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_cflag |= CS8; tcsetattr(fd,TCSANOW,&options); bInited = true; ofLogNotice("ofSerial") << "opened " << portName << " sucessfully @ " << baud << " bps"; return true; //--------------------------------------------- #endif //--------------------------------------------- //--------------------------------------------- #ifdef 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; 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)){ ofLogError("ofSerial") << "setup(): unable to build comm dcb, (" << buf << ")"; } #else if(!BuildCommDCB(buf,&cfg.dcb)){ ofLogError("ofSerial") << "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)){ 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; //--------------------------------------------- #endif //--------------------------------------------- }
void EIO_Open(uv_work_t* req) { OpenBaton* data = static_cast<OpenBaton*>(req->data); HANDLE file = CreateFile( data->path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (file == INVALID_HANDLE_VALUE) { DWORD errorCode = GetLastError(); char temp[100]; sprintf(temp, "Opening %s", data->path); ErrorCodeToString(temp, errorCode, data->errorString); return; } bufferSize = data->bufferSize; if(bufferSize > MAX_BUFFER_SIZE) { bufferSize = MAX_BUFFER_SIZE; } DCB dcb = { 0 }; dcb.DCBlength = sizeof(DCB); if(!BuildCommDCB("9600,n,8,1", &dcb)) { ErrorCodeToString("BuildCommDCB", GetLastError(), data->errorString); return; } dcb.fBinary = true; dcb.BaudRate = data->baudRate; dcb.ByteSize = data->dataBits; switch(data->parity) { case SERIALPORT_PARITY_NONE: dcb.Parity = NOPARITY; break; case SERIALPORT_PARITY_MARK: dcb.Parity = MARKPARITY; break; case SERIALPORT_PARITY_EVEN: dcb.Parity = EVENPARITY; break; case SERIALPORT_PARITY_ODD: dcb.Parity = ODDPARITY; break; case SERIALPORT_PARITY_SPACE: dcb.Parity = SPACEPARITY; break; } switch(data->stopBits) { case SERIALPORT_STOPBITS_ONE: dcb.StopBits = ONESTOPBIT; break; case SERIALPORT_STOPBITS_ONE_FIVE: dcb.StopBits = ONE5STOPBITS; break; case SERIALPORT_STOPBITS_TWO: dcb.StopBits = TWOSTOPBITS; break; } if(!SetCommState(file, &dcb)) { ErrorCodeToString("SetCommState", GetLastError(), data->errorString); return; } // Set the com port read/write timeouts DWORD serialBitsPerByte = 8/*std data bits*/ + 1/*start bit*/; serialBitsPerByte += (data->parity == SERIALPORT_PARITY_NONE ) ? 0 : 1; serialBitsPerByte += (data->stopBits == SERIALPORT_STOPBITS_ONE) ? 1 : 2; DWORD msPerByte = (data->baudRate > 0) ? ((1000 * serialBitsPerByte + data->baudRate - 1) / data->baudRate) : 1; if (msPerByte < 1) { msPerByte = 1; } COMMTIMEOUTS commTimeouts = {0}; commTimeouts.ReadIntervalTimeout = msPerByte; // Minimize chance of concatenating of separate serial port packets on read commTimeouts.ReadTotalTimeoutMultiplier = 0; // Do not allow big read timeout when big read buffer used commTimeouts.ReadTotalTimeoutConstant = 1000; // Total read timeout (period of read loop) commTimeouts.WriteTotalTimeoutConstant = 1000; // Const part of write timeout commTimeouts.WriteTotalTimeoutMultiplier = msPerByte; // Variable part of write timeout (per byte) if(!SetCommTimeouts(file, &commTimeouts)) { ErrorCodeToString("SetCommTimeouts", GetLastError(), data->errorString); return; } // Remove garbage data in RX/TX queues PurgeComm(file, PURGE_RXCLEAR); PurgeComm(file, PURGE_TXCLEAR); data->result = (int)file; }
/** Set information specific to the serial driver device control block. * @param hc Maximus communication handle to update * @pdcb [out] The DCB we're associating with the underlying COMMHANDLE. * @returns TRUE on success. */ USHORT COMMAPI ComSetDCB(HCOMM hc, LPDCB pdcb) { return hc ? SetCommState(ComGetHandle(hc), pdcb) : FALSE; }
/** Return the current status of DCD on this line * TCP/IP Interpretation: If carrier has not been set true yet, * try and accept. If that succeeds, raise carrier. This is * analogous to a modem auto-answering and raising the DCD * signal on the serial port. * * @note This routine gets polled while Maximus is idle. * This is how we recognize that a caller is online. * * @warning We pull a super-sneaky trick here to avoid the * (normal) requirement of a listen->accept->fork * daemon. We assume that max -w is being run in * respawn mode (e.g. from inittab). When a call * comes in we fork and exit the parent, letting the * child continue along its merry way. Respawing * kicks up a new parent, and by then this process * isn't listening for inbound connections anymore. * This also makes it necessary for us to be running * in max -n0 mode, so that each max instance has * a unique node (task) number. * * @param hc Communications handle * @returns 0 when we're offline */ USHORT COMMAPI IpComIsOnline(HCOMM hc) { fd_set rfds, wfds; struct timeval tv; DCB dcb; if (!hc) return 0; if (hc->fDCD) { static byte tries = 0; int rready; tries++; tries %= 15; if (tries != 0) goto skipCheck; /* Only check once in a while */ /* "Carrier"? Let's make sure the socket is okay. */ FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(unixfd(hc), &rfds); FD_SET(unixfd(hc), &wfds); tv.tv_sec = 0; tv.tv_usec = 0; if (((rready = select(unixfd(hc) + 1, &rfds, NULL, NULL, &tv)) < 0) || (select(unixfd(hc) + 1, NULL, &wfds, NULL, &tv) < 0)) { hc->fDCD = FALSE; shutdown(unixfd(hc), 2); close(unixfd(hc)); unlink(lockpath); } if ((rready == 1) && hc->fDCD && (hc->peekHack == -1)) { unsigned char buf[1]; ssize_t i; i = read(unixfd(hc), &buf, 1); switch(i) { case 0: case -1: hc->fDCD = FALSE; shutdown(unixfd(hc), 20); close(unixfd(hc)); break; case 1: hc->peekHack = buf[0]; break; } if (hc->fDCD == FALSE) { logit("!Caller closed TCP/IP connection (Dropped Carrier)"); } } skipCheck: return hc->fDCD ? 1 : 0; } if(hc->listenfd == -1) return 0; /* No "Carrier"? See if we can accept a connection */ FD_ZERO(&rfds); FD_SET(hc->listenfd, &rfds); /* Will longish delay cause problems with console? */ tv.tv_sec = 0; tv.tv_usec = 500000; if (select(hc->listenfd + 1, &rfds, NULL, NULL, &tv) > 0) { int addrSize = sizeof(*hc->saddr_p); int fd = -1; fd = accept(hc->listenfd, (struct sockaddr *)&hc->saddr_p, &addrSize); if (fd >= 0) { FILE* f = NULL; /* Have accepted a socket. Close the bound socket and dump * the parent, so that we init can swing open a new task. * This technique probably won't cause us much grief, except * maybe on a very busy system. */ /* Set accepted descriptor and other misc com parameters */ f = fopen(lockpath, "w"); fclose(f); CommHandle_setFileHandle(hc->h, fd); hc->fDCD = TRUE; hc->listenfd = -1; memset(&dcb, 0, sizeof(dcb)); dcb.isTerminal = FALSE; dcb.fBinary = TRUE; SetCommState(ComGetHandle(hc), &dcb); ComSetBaudRate(hc, 38400, NOPARITY, 8, ONESTOPBIT); _SetTimeoutBlock(hc); hc->burstMode = TRUE; hc->burstModePending = FALSE; /* turn off nagle by default */ /* Stuff a fake LF into the input stream to try and kick max * into waking up faster. */ hc->peekHack = '\n'; } } return hc->fDCD ? 1 : 0; }
void run() { if (_arguments.count() == 1) { console.write("Usage: run [-c] <name of file to send>\n"); return; } int fileNameArgument = 1; bool comFile = false; if (_arguments[1] == "-c") { comFile = true; fileNameArgument = 2; } String data = File(_arguments[fileNameArgument], true).contents(); int l = data.length(); //// Reset the machine //{ // Stream arduinoCom = AutoStream(CreateFile( // L"COM3", // GENERIC_READ | GENERIC_WRITE, // 0, // must be opened with exclusive-access // NULL, // default security attributes // OPEN_EXISTING, // must use OPEN_EXISTING // 0, // not overlapped I/O // NULL), // hTemplate must be NULL for comm devices // String("Arduino COM port")); // DCB deviceControlBlock; // SecureZeroMemory(&deviceControlBlock, sizeof(DCB)); // IF_ZERO_THROW(GetCommState(arduinoCom, &deviceControlBlock)); // deviceControlBlock.DCBlength = sizeof(DCB); // deviceControlBlock.BaudRate = 19200; // deviceControlBlock.fBinary = TRUE; // deviceControlBlock.fParity = FALSE; // deviceControlBlock.fOutxCtsFlow = FALSE; // deviceControlBlock.fOutxDsrFlow = FALSE; // deviceControlBlock.fDtrControl = DTR_CONTROL_DISABLE; // deviceControlBlock.fDsrSensitivity = FALSE; // deviceControlBlock.fTXContinueOnXoff = TRUE; // deviceControlBlock.fOutX = TRUE; // deviceControlBlock.fInX = TRUE; // deviceControlBlock.fErrorChar = FALSE; // deviceControlBlock.fNull = FALSE; // deviceControlBlock.fRtsControl = RTS_CONTROL_DISABLE; // deviceControlBlock.fAbortOnError = TRUE; // deviceControlBlock.wReserved = 0; // deviceControlBlock.ByteSize = 8; // deviceControlBlock.Parity = NOPARITY; // deviceControlBlock.StopBits = ONESTOPBIT; // deviceControlBlock.XonChar = 17; // deviceControlBlock.XoffChar = 19; // IF_ZERO_THROW(SetCommState(arduinoCom, &deviceControlBlock)); // IF_ZERO_THROW(SetCommMask(arduinoCom, EV_RXCHAR)); // Sleep(2000); // arduinoCom.write<Byte>(0x72); // arduinoCom.write<Byte>(0x7f); // IF_ZERO_THROW(FlushFileBuffers(arduinoCom)); //} //Sleep(3000); _com = AutoStream(CreateFile( L"COM1", GENERIC_READ | GENERIC_WRITE, 0, // must be opened with exclusive-access NULL, // default security attributes OPEN_EXISTING, // must use OPEN_EXISTING 0, // not overlapped I/O NULL), // hTemplate must be NULL for comm devices String("COM port")); //IF_ZERO_THROW(SetupComm(_com, 1024, 1024)); DCB deviceControlBlock; SecureZeroMemory(&deviceControlBlock, sizeof(DCB)); IF_ZERO_THROW(GetCommState(_com, &deviceControlBlock)); deviceControlBlock.DCBlength = sizeof(DCB); deviceControlBlock.BaudRate = 115200; //57600; //115200; //38400; // deviceControlBlock.fBinary = TRUE; deviceControlBlock.fParity = FALSE; deviceControlBlock.fOutxCtsFlow = FALSE; deviceControlBlock.fOutxDsrFlow = TRUE; //deviceControlBlock.fDtrControl = DTR_CONTROL_ENABLE; deviceControlBlock.fDtrControl = DTR_CONTROL_HANDSHAKE; deviceControlBlock.fDsrSensitivity = FALSE; //TRUE; deviceControlBlock.fTXContinueOnXoff = TRUE; deviceControlBlock.fOutX = FALSE; deviceControlBlock.fInX = FALSE; deviceControlBlock.fErrorChar = FALSE; deviceControlBlock.fNull = FALSE; deviceControlBlock.fRtsControl = RTS_CONTROL_DISABLE; deviceControlBlock.fAbortOnError = TRUE; deviceControlBlock.wReserved = 0; deviceControlBlock.ByteSize = 8; deviceControlBlock.Parity = NOPARITY; deviceControlBlock.StopBits = ONESTOPBIT; deviceControlBlock.XonChar = 17; deviceControlBlock.XoffChar = 19; IF_ZERO_THROW(SetCommState(_com, &deviceControlBlock)); COMMTIMEOUTS timeOuts; SecureZeroMemory(&timeOuts, sizeof(COMMTIMEOUTS)); timeOuts.ReadIntervalTimeout = MAXDWORD; timeOuts.ReadTotalTimeoutMultiplier = 0; timeOuts.ReadTotalTimeoutConstant = 100; //MAXDWORD; IF_ZERO_THROW(SetCommTimeouts(_com, &timeOuts)); IF_ZERO_THROW(SetCommMask(_com, EV_RXCHAR)); //IF_ZERO_THROW(ClearCommBreak(_com)); //IF_ZERO_THROW(PurgeComm(_com, PURGE_RXCLEAR | PURGE_TXCLEAR)); //IF_ZERO_THROW(FlushFileBuffers(_com)); //DWORD error; //IF_ZERO_THROW(ClearCommError(_com, &error, NULL)); //_com.set(CreateFile(L"run.output", GENERIC_WRITE, 0, NULL, // CREATE_ALWAYS, 0, NULL)); // When running a .com file, we need the instruction pointer to start // at 0x100. We do this by prepending 0x100 NOP bytes at the beginning. // In DOS this area would contain the Program Segment Prefix structure. //console.write(hex(l, 8) + "\n"); _packet.allocate(0x101); Byte checksum; if (comFile) { // Send 0x100 NOPs to pad out the file so that execution starts at // the expected IP. int bytes = 0xff; _packet[0] = bytes; checksum = 0; for (int i = 0; i < bytes; ++i) { Byte d = 0x90; _packet[i + 1] = d; checksum += d; } _packet[bytes + 1] = checksum; sendPacket(); _packet[0] = 1; _packet[2] = 0x90; sendPacket(); } int p = 0; int bytes; do { bytes = min(l, 0xff); _packet[0] = bytes; checksum = 0; for (int i = 0; i < bytes; ++i) { Byte d = data[p]; ++p; _packet[i + 1] = d; checksum += d; } _packet[bytes + 1] = checksum; sendPacket(); l -= bytes; } while (bytes != 0); //IF_ZERO_THROW(FlushFileBuffers(_com)); console.write("\nUpload complete.\n"); // Dump bytes from COM port to stdout until we receive ^Z timeOuts.ReadTotalTimeoutConstant = MAXDWORD; IF_ZERO_THROW(SetCommTimeouts(_com, &timeOuts)); AppendableArray<Byte> file; do { int c = _com.read<Byte>(); if (c == 26) break; if (c == 0) { DWord l = _com.read<Byte>(); DWord m = _com.read<Byte>(); DWord h = _com.read<Byte>(); int n = l | (m << 8) | (n << 16); console.write("Transferring " + decimal(n) + " bytes.\n"); for (int i = 0; i < n; ++i) { file.append(_com.read<Byte>()); if ((i & 0xff) == 0xff) console.write("."); } console.write("Transfer complete.\n"); } console.write<Byte>(c); } while (true); console.write("Saving " + decimal(file.count()) + " bytes.\n"); if (file.count() > 0) File("retrieved.dat").save(file); }
//------------------------------------------------------------------- // Change Port Settings // static int NT_ChangePortSettings (HANDLE hPort, unsigned int Speed, t_uchar DataBits, t_uchar Parity, t_uchar StopBits) { int Error = 0; t_uchar ParityEnable = ( Parity == UART_PARITY_NONE ) ? ( FALSE ) : ( TRUE ); DCB ControlBlock; int BaudRate = 0;// { CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, // CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400, // CBR_56000, CBR_57600, CBR_115200, CBR_128000, CBR_256000 }; //Get current com port settings if ( (GetCommState( hPort, &ControlBlock )) == 0 ) //0 if fails { Error = GetLastError(); // PrintError( "NT_ChangePortSettings:", "There was ERROR:", Error ); return( Error ); }//end if //Convert Parity if ( Parity == UART_PARITY_ODD ) Parity = ODDPARITY; //1 else if ( Parity == UART_PARITY_EVEN ) Parity = EVENPARITY; //2 else Parity = NOPARITY; //0 //Convert Baud Rate switch ( Speed ) { case 4800: BaudRate = CBR_4800; break; case 9600: BaudRate = CBR_9600; break; case 115200: BaudRate = CBR_115200; break; default: BaudRate = CBR_4800; break; }//end switch //Convert Stop Bits switch ( StopBits ) { case 1: StopBits = ONESTOPBIT; break; case 2: StopBits = TWOSTOPBITS; break; default: StopBits = ONESTOPBIT; break; }//end switch //////////////////////////////////////////////////////////////////////////////////// // Change port settings //////////////////////////////////////////////////////////////////////////////////// // ControlBlock.DCBlength; // sizeof(DCB) ControlBlock.BaudRate = BaudRate; // current baud rate // ControlBlock.fBinary: 1; // binary mode, no EOF check ControlBlock.fParity = ParityEnable; // enable parity checking ControlBlock.fOutxCtsFlow = 0; // CTS output flow control ControlBlock.fOutxDsrFlow = 0; // DSR output flow control ControlBlock.fDtrControl = DTR_CONTROL_ENABLE;// DTR flow control type ControlBlock.fDsrSensitivity = 0; // DSR sensitivity ControlBlock.fTXContinueOnXoff = 0; // XOFF continues Tx ControlBlock.fOutX = 0; // XON/XOFF out flow control ControlBlock.fInX = 0; // XON/XOFF in flow control // ControlBlock.fErrorChar: 1; // enable error replacement // ControlBlock.fNull: 1; // enable null stripping ControlBlock.fRtsControl = RTS_CONTROL_ENABLE;// RTS flow control // ControlBlock.fAbortOnError:1; // abort reads/writes on error // ControlBlock.fDummy2:17; // reserved // ControlBlock.wReserved; // not currently used // ControlBlock.XonLim; // transmit XON threshold // ControlBlock.XoffLim; // transmit XOFF threshold ControlBlock.ByteSize = DataBits; // number of bits/t_uchar, 4-8 ControlBlock.Parity = Parity; // 0-4=no,odd,even,mark,space ControlBlock.StopBits = StopBits; // 0,1,2 = 1, 1.5, 2 // ControlBlock.XonChar; // Tx and Rx XON character // ControlBlock.XoffChar; // Tx and Rx XOFF character // ControlBlock.ErrorChar; // error replacement character // ControlBlock.EofChar; // end of input character // ControlBlock.EvtChar; // received event character // ControlBlock.wReserved1; // reserved; do not use //Set com port settings if ( (SetCommState( hPort, &ControlBlock )) == 0 ) // 0 if fails { Error = GetLastError(); // PrintError( "SetCommState:", "There was ERROR:", Error ); }//end if return( Error ); }//end NT_ChangePortSettings
int16_t SendCommands::Init() { int16_t failcode=0; int err; DCB dcb= {0}; dcb.DCBlength=sizeof(dcb); uint8_t portNum=6; char port_name[10] = "COMx"; // this is a 5 char string with [4]=null terminator) if ( portNum < 10 ) { // one digit port_name[3] = 48 + portNum; // ascii number } else { // two digit port number memcpy(port_name,"\\\\.\\COMxx",10); // this is a 10 char string (\\.\COMxx with [9]=null terminator) port_name[7] = 48 + (portNum / 10); // ascii number port_name[8] = 48 + (portNum % 10); // ascii number } ComFileHandle = CreateFile( "COM6", //port_name,// pointer to name of the file GENERIC_READ|GENERIC_WRITE,// access (read-write) mode 0, // share mode 0, // pointer to security descriptor OPEN_EXISTING, // how to create FILE_ATTRIBUTE_NORMAL, // if FILE_FLAG_OVERLAPPED is used, WaitCommEvent does NOT block. // FILE_FLAG_OVERLAPPED, // if FILE_FLAG_OVERLAPPED is used, WaitCommEvent does NOT block. 0 ); if( (void *)ComFileHandle == INVALID_HANDLE_VALUE) { return 1; } err = GetCommState((void *)ComFileHandle, &dcb); if (err < 0) { return 2; } /* { COMMTIMEOUTS CommTimeOuts; // Get any early notifications SetCommMask(ComFileHandle, EV_RXCHAR); // Setup device buffers SetupComm(ComFileHandle, 4096, 4096); // Purge any information in the buffer PurgeComm(ComFileHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); // Set timeouts since we are not using overlapped I/O CommTimeOuts.ReadIntervalTimeout = 0; // timeout between bytes received not used. CommTimeOuts.ReadTotalTimeoutMultiplier = 0; // not a function of num chars to read. CommTimeOuts.ReadTotalTimeoutConstant = 100; // fixed timeout in ms CommTimeOuts.WriteTotalTimeoutMultiplier = 10; // ms max for EACH byte sent CommTimeOuts.WriteTotalTimeoutConstant = 1000;// ms max for entire Write operation. SetCommTimeouts(ComFileHandle, &CommTimeOuts); } */ dcb.BaudRate= CBR_9600; dcb.Parity= NOPARITY; dcb.StopBits= ONESTOPBIT; dcb.ByteSize= 8; /* dcb.fBinary= TRUE;// binary mode, no EOF check dcb.fOutxCtsFlow= FALSE; // CTS output flow control dcb.fOutxDsrFlow= FALSE; // DSR output flow control dcb.fDtrControl= DTR_CONTROL_DISABLE; //DTR_CONTROL_ENABLE; // DTR flow control type dcb.fDsrSensitivity = FALSE; // DSR sensitivity dcb.fTXContinueOnXoff = TRUE; // XOFF continues Tx dcb.fOutX= FALSE;// XON/XOFF out flow control dcb.fInX= FALSE;// XON/XOFF in flow control dcb.fNull= FALSE;// enable null stripping dcb.fRtsControl= RTS_CONTROL_DISABLE; //RTS_CONTROL_ENABLE;// RTS flow control dcb.fAbortOnError= FALSE;// abort reads/writes on error */ err = SetCommState( ComFileHandle, &dcb); if (err < 0) { return 3; } return failcode; memset(&OverlapStruct,0,sizeof(OverlapStruct)); OverlapStruct.hEvent = CreateEvent(0, 1, 0, 0); }
BOOL DmKdInitComPort( BOOL KdModemControl ) { char ComPortName[16]; ULONG Baud; DCB LocalDcb; COMMTIMEOUTS To; DWORD mask; Baud = (ULONG)KdOptions[KDO_BAUDRATE].value; sprintf( ComPortName, "\\\\.\\com%d", (ULONG)KdOptions[KDO_PORT].value ); // // Open the device // DmKdComPort = CreateFile( (PSZ)ComPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if ( DmKdComPort == (HANDLE)-1 ) { return FALSE; } SetupComm(DmKdComPort,(DWORD)4096,(DWORD)4096); // // Create the events used by the overlapped structures for the // read and write. // ReadOverlapped.hEvent = CreateEvent( NULL, TRUE, FALSE,NULL ); if (!ReadOverlapped.hEvent) { return FALSE; } WriteOverlapped.hEvent = CreateEvent( NULL, TRUE, FALSE,NULL ); if (!WriteOverlapped.hEvent) { return FALSE; } ReadOverlapped.Offset = 0; ReadOverlapped.OffsetHigh = 0; WriteOverlapped.Offset = 0; WriteOverlapped.OffsetHigh = 0; // // Set up the Comm port.... // if (!GetCommState( DmKdComPort, &LocalDcb )) { return FALSE; } LocalDcb.BaudRate = Baud; LocalDcb.ByteSize = 8; LocalDcb.Parity = NOPARITY; LocalDcb.StopBits = ONESTOPBIT; LocalDcb.fDtrControl = DTR_CONTROL_ENABLE; LocalDcb.fRtsControl = RTS_CONTROL_ENABLE; LocalDcb.fBinary = TRUE; LocalDcb.fOutxCtsFlow = FALSE; LocalDcb.fOutxDsrFlow = FALSE; LocalDcb.fOutX = FALSE; LocalDcb.fInX = FALSE; if (!SetCommState( DmKdComPort, &LocalDcb )) { return FALSE; } // // Set the normal read and write timeout time. // The symbols are 10 millisecond intervals. // To.ReadIntervalTimeout = 0; To.ReadTotalTimeoutMultiplier = 0; To.ReadTotalTimeoutConstant = 4 * 1000; To.WriteTotalTimeoutMultiplier = 0; To.WriteTotalTimeoutConstant = 4 * 1000; if (!SetCommTimeouts( DmKdComPort, &To )) { return FALSE; } DmKdComEvent = 0; if (KdModemControl) { // // Debugger is being run over a modem. Set event to watch // carrier detect. // GetCommMask (DmKdComPort, &mask); mask = mask | EV_ERR; // | EV_RLSD; if (!SetCommMask (DmKdComPort, mask)) { return FALSE; } EventOverlapped.hEvent = CreateEvent( NULL, TRUE, FALSE,NULL ); if (!EventOverlapped.hEvent) { return FALSE; } EventOverlapped.Offset = 0; EventOverlapped.OffsetHigh = 0; DmKdComEvent = 1; // Fake an event, so modem status will be checked } InitializeCriticalSection(&csComPort); InitializeCriticalSection(&csPacket); return TRUE; }
/*! \brief win32_setup_serial_params() sets up the serial port attributes for windows platforms \param fd is the filedescriptor representing the serial port \param baud is the baud rate \param bits is the number of data bits \param parity is the enumeration describing odd, even or no parity \param stop is the number of stop bits */ G_MODULE_EXPORT void win32_setup_serial_params(gint fd, gint baud, gint bits, Parity parity, gint stop) { #ifdef __WIN32__ extern gconstpointer *global_data; Serial_Params *serial_params; serial_params = DATA_GET(global_data,"serial_params"); DCB dcb; COMMTIMEOUTS timeouts; ENTER(); if (serial_params->open == FALSE) { EXIT(); return; } ZeroMemory(&dcb, sizeof(dcb)); dcb.DCBlength = sizeof(dcb); /* Populate struct with defaults from windows */ GetCommState((HANDLE) _get_osfhandle(fd), &dcb); dcb.BaudRate = baud; dcb.ByteSize = bits; switch (parity) { case NONE: dcb.Parity = NOPARITY; dcb.fParity = FALSE; /* Disabled */ break; case ODD: dcb.Parity = ODDPARITY; dcb.fParity = TRUE; /* Enabled */ break; case EVEN: dcb.Parity = EVENPARITY; dcb.fParity = TRUE; /* Enabled */ break; } if (stop == 2) dcb.StopBits = TWOSTOPBITS; /* #defined in windows.h */ else dcb.StopBits = ONESTOPBIT; /* #defined in windows.h */ dcb.fBinary = TRUE; /* Enable binary mode */ dcb.fOutxCtsFlow = FALSE; /* don't monitor CTS line */ dcb.fOutxDsrFlow = FALSE; /* don't monitor DSR line */ dcb.fDsrSensitivity = FALSE; /* ignore Dsr line */ dcb.fDtrControl = DTR_CONTROL_DISABLE; /* Disable DTR line */ dcb.fRtsControl = RTS_CONTROL_DISABLE; /* Disable RTS line */ dcb.fOutX = FALSE; /* Disable Xoff */ dcb.fInX = FALSE; /* Disable Xin */ dcb.fErrorChar = FALSE; /* Don't replace bad chars */ dcb.fNull = FALSE; /* don't drop NULL bytes */ dcb.fAbortOnError = FALSE; /* Don't abort */ dcb.wReserved = 0; /* as per msdn */ /* Set the port properties and write the string out the port. */ if(SetCommState((HANDLE) _get_osfhandle (fd) ,&dcb) == 0) MTXDBG(CRITICAL,_("ERROR setting serial attributes\n")); /* Set timeout params in a fashion that mimics linux behavior */ GetCommTimeouts((HANDLE) _get_osfhandle (fd), &timeouts); if (DATA_GET(global_data,"serial_nonblock")) { printf("win32 serial nonblock\n"); /* Buffer? */ // SetupComm((HANDLE) _get_osfhandle (fd),128,128); /* timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 20000L/baud; timeouts.ReadTotalTimeoutConstant = 0; */ // Works, but causes deadlock in reader blocking UI //timeouts.ReadTotalTimeoutConstant = 100; /* 100ms timeout*/ //timeouts.ReadIntervalTimeout = MAXDWORD; //timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; //timeouts.WriteTotalTimeoutConstant = 0; //timeouts.WriteTotalTimeoutMultiplier = 20000L/baud; timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; } else { timeouts.ReadIntervalTimeout = 0; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 100; } SetCommTimeouts((HANDLE) _get_osfhandle (fd) ,&timeouts); // if (DATA_GET(global_data,"serial_nonblock")) // { //serial_params->rx_event = CreateEvent(0,0,0,0); //if (! SetCommMask(serial_params->comm_handle, EV_RXCHAR|EV_TXEMPTY)) // printf("Unable to set comm mask events, reason %d\n",GetLastError()); // serial_params->term_evt = CreateEvent(0,0,0,0); // serial_params->started_evt = CreateEvent(0,0,0,0); // serial_params->thread = (HANDLE)_beginthreadex(0,0,winserial_thread,(void *)serial_params,0,0); /* Wait until thread has fired up */ // tmpi = WaitForSingleObject(serial_params->started_evt, INFINITE); // g_return_if_fail(tmpi == WAIT_OBJECT_0); // CloseHandle(serial_params->started_evt); // InvalidateHandle(serial_params->started_evt); // serial_params->state = SS_Init; // } EXIT(); return; #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 //--------------------------------------------- }
/*----------------------------------------------------------------------------- FUNCTION: SetPortState( void ) PURPOSE: Sets port state based on settings from the user COMMENTS: Sets up DCB structure and calls SetCommState. Sets up new timeouts by calling SetCommTimeouts. HISTORY: Date: Author: Comment: 1/9/96 AllenD Wrote it 12/06/06 DonnMo Replaced calls to ErrorReporter() with CHECK_HR() -----------------------------------------------------------------------------*/ HRESULT RS232Connection::SetPortState() { HRESULT hr = S_OK; DCB dcb = {0}; DWORD dwLastError = 0; dcb.DCBlength = sizeof(dcb); // // get current DCB settings // if (!GetCommState(m_hCommPort, &dcb)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "GetCommState() failed within SetPortState()."); return hr; } // // update DCB rate, byte size, parity, and stop bits size // dcb.BaudRate = m_dwBaudRate; dcb.ByteSize = m_bByteSize; dcb.Parity = m_bParity; dcb.StopBits = m_bStopBits; // // update event flags // if (m_dwEventFlags & EV_RXFLAG) { dcb.EvtChar = m_chFlag; } else { dcb.EvtChar = '\0'; } dcb.EofChar = '\n'; // // update flow control settings // dcb.fDtrControl = m_fDtrControl; dcb.fRtsControl = m_fRtsControl; dcb.fOutxCtsFlow = m_fCTSOutFlow; dcb.fOutxDsrFlow = m_fDSROutFlow; dcb.fDsrSensitivity = m_fDSRInFlow; dcb.fOutX = m_fXonXoffOutFlow; dcb.fInX = m_fXonXoffInFlow; dcb.fTXContinueOnXoff = m_fTXafterXoffSent; dcb.XonChar = m_chXON; dcb.XoffChar = m_chXOFF; dcb.XonLim = m_wXONLimit; dcb.XoffLim = m_wXOFFLimit; // // DCB settings not in the user's control // dcb.fParity = TRUE; // // set new state // if (!SetCommState(m_hCommPort, &dcb)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "SetCommState() failed within SetPortState() when setting the new state."); return hr; } // // set new timeouts // if (!SetCommTimeouts(m_hCommPort, &m_timeoutsnew)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "SetCommTimeouts() failed within SetPortState() when setting the new timeouts."); return hr; } return hr; }
static int gry_open(CableHandle *h) { DCB dcb; BOOL fSuccess; COMMTIMEOUTS cto; // Open device h->priv = (void *)CreateFile(h->device, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED /*| FILE_FLAG_NO_BUFFERING*/, NULL); if (hCom == INVALID_HANDLE_VALUE) { ticables_warning("CreateFile"); return ERR_GRY_CREATEFILE; } // Setup buffer size fSuccess = SetupComm(hCom, 1024, 1024); if (!fSuccess) { ticables_warning("SetupComm"); return ERR_GRY_SETUPCOMM; } // Retrieve config structure fSuccess = GetCommState(hCom, &dcb); if (!fSuccess) { ticables_warning("GetCommState"); return ERR_GRY_GETCOMMSTATE; } // Fills the structure with config dcb.BaudRate = CBR_9600; // 9600 bauds dcb.fBinary = TRUE; // Binary mode dcb.fParity = FALSE; // Parity checking disabled dcb.fOutxCtsFlow = FALSE; // No output flow control dcb.fOutxDsrFlow = FALSE; // Idem dcb.fDtrControl = DTR_CONTROL_DISABLE; // Provide power supply dcb.fDsrSensitivity = FALSE; // ignore DSR status dcb.fOutX = FALSE; // no XON/XOFF flow control dcb.fInX = FALSE; // idem dcb.fErrorChar = FALSE; // no replacement dcb.fNull = FALSE; // don't discard null chars dcb.fRtsControl = RTS_CONTROL_ENABLE; // Provide power supply dcb.fAbortOnError = FALSE; // do not report errors dcb.ByteSize = 8; // 8 bits dcb.Parity = NOPARITY; // no parity checking dcb.StopBits = ONESTOPBIT; // 1 stop bit // Config COM port fSuccess = SetCommState(hCom, &dcb); if (!fSuccess) { ticables_warning("SetCommState"); return ERR_GRY_SETCOMMSTATE; } // Wait for GrayLink to be ready Sleep(250); // Set timeouts fSuccess = GetCommTimeouts(hCom, &cto); if (!fSuccess) { ticables_warning("GetCommTimeouts"); return ERR_GRY_GETCOMMTIMEOUT; } cto.ReadIntervalTimeout = 0; cto.ReadTotalTimeoutMultiplier = 0; cto.ReadTotalTimeoutConstant = 100 * h->timeout; cto.WriteTotalTimeoutMultiplier = 0; cto.WriteTotalTimeoutConstant = 100 * h->timeout; fSuccess = SetCommTimeouts(hCom, &cto); if (!fSuccess) { ticables_warning("SetCommTimeouts"); return ERR_GRY_SETCOMMTIMEOUT; } // Monitor receiving of chars fSuccess = SetCommMask(hCom, EV_RXCHAR); if (!fSuccess) { ticables_warning("SetCommMask"); return ERR_GRY_SETCOMMMASK; } // Flush/Dicard buffers fSuccess = PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); if (!fSuccess) { ticables_warning("PurgeComm"); return ERR_GRY_PURGECOMM; } return 0; }
Serial::Serial(char *portName) { //We're not yet connected this->connected = false; //Try to connect to the given port throuh CreateFile this->hSerial = CreateFile((LPCWSTR)portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //Check if the connection was successfull if(this->hSerial==INVALID_HANDLE_VALUE) { //If not success full display an Error if(GetLastError()==ERROR_FILE_NOT_FOUND){ //Print Error if neccessary printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName); } else { printf("ERROR!!!"); } } else { //If connected we try to set the comm parameters DCB dcbSerialParams = {0}; //Try to get the current if (!GetCommState(this->hSerial, &dcbSerialParams)) { //If impossible, show an error printf("failed to get current serial parameters!"); } else { //Define serial connection parameters for the arduino board dcbSerialParams.BaudRate=CBR_9600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY; //Set the parameters and check for their proper application if(!SetCommState(hSerial, &dcbSerialParams)) { printf("ALERT: Could not set Serial Port parameters"); } else { //If everything went fine we're connected this->connected = true; //We wait 2s as the arduino board will be reseting Sleep(ARDUINO_WAIT_TIME); } } } }
//************************************************************************************ //函 数:fSendCmd(BYTE * bufData) //功 能:打开串口 //参 数:void* pOwner----------指向父指针 // UINT portNo-----------串口号 = 1, // UINT baud-------------波特率 = 115200, // UINT parity-----------奇偶校验 = NOPARITY, // UINT databits---------数据位 = 8, // UINT stopbits---------停止位 = 1 //返 回: 打开串口是否成功 //************************************************************************************ BOOL CSeries::OpenPort(HWND hOwner,UINT portNo,UINT baud,UINT parity,UINT databits,UINT stopbits) { DCB commParam; TCHAR szPort[15]; //ASSERT(pOwner!=NULL); m_hOwner = hOwner; // 已经打开的话,直接关闭 if (m_hComm != INVALID_HANDLE_VALUE) { //关闭串口 CloseHandle (m_hComm); m_hComm = INVALID_HANDLE_VALUE; m_bOpened = FALSE; } //设置串口名 wsprintf(szPort, L"COM%d:", portNo); //打开串口 m_hComm = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, //允许读和写 0, //独占方式(共享模式) NULL, OPEN_EXISTING, //打开而不是创建(创建方式) FILE_FLAG_OVERLAPPED, NULL ); if (m_hComm == INVALID_HANDLE_VALUE) { // 无效句柄,返回。 //theMainDlg->fAddLog(_T("CreateFile 返回无效句柄\n")); return FALSE; } // 得到打开串口的当前属性参数,修改后再重新设置串口。 if (!GetCommState(m_hComm,&commParam)) { //关闭串口 CloseHandle (m_hComm); m_hComm = INVALID_HANDLE_VALUE; return FALSE; } //设置串口参数 commParam.BaudRate = baud; // 设置波特率 commParam.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE commParam.fParity = TRUE; // 支持奇偶校验 commParam.ByteSize = databits; // 数据位,范围:4-8 commParam.Parity = parity; // 校验模式 commParam.StopBits = stopbits; // 停止位 commParam.fOutxCtsFlow = FALSE; // No CTS output flow control commParam.fOutxDsrFlow = FALSE; // No DSR output flow control commParam.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type commParam.fDsrSensitivity = FALSE; // DSR sensitivity commParam.fTXContinueOnXoff = TRUE; // XOFF continues Tx commParam.fOutX = FALSE; // No XON/XOFF out flow control commParam.fInX = FALSE; // No XON/XOFF in flow control commParam.fErrorChar = FALSE; // Disable error replacement commParam.fNull = FALSE; // Disable null stripping commParam.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control commParam.fAbortOnError = FALSE; // 当串口发生错误,并不终止串口读写 //设置串口参数 if (!SetCommState(m_hComm, &commParam)) { AfxMessageBox(_T("SetCommState error")); //关闭串口 CloseHandle (m_hComm); m_hComm = INVALID_HANDLE_VALUE; return FALSE; } //设置串口读写时间 COMMTIMEOUTS CommTimeOuts; GetCommTimeouts (m_hComm, &CommTimeOuts); /* // 在整个串口的读写操作中, 存在着两种超时设置。一种是间隔超时, 一种是总超时。 这两种超时是独立存在,互不影响的。 //间隔超时>只在读操作中存在。就是ReadIntervalTimeout。 当读操作中,前后两个字符之间的时间间隔超过时,读操作就结束了。 举例来说,你一次读取8个字符,但是在你读取了第一个字符之后,在读取第二个字符时,间隔超时了,那么读操作就结束了, 这样整个操作就只读取了1个字节。 即使, 你的总时间没有超时 总超时>这里有一个公式 总的读/写超时时间 = Read(Write)TotalTimeoutMultiplier x 要读/写的字节数 + Read(Write)TotalTimeoutConstant. 这里要说明的一点,要读/写的字节数是从哪里来的。 这个是从ReadFile 或者WriteFile 函数中定义的。 在读操作时, 若当前所花读取时间已经超过了总的超时设置, 则读操作就结束了。即使, 每两个字符之间的间隔没有超时。 举例来说, 若总共读取8个字节。 间隔设置为8ms, 总超时系数为3ms,总超时常数为3ms。 则总的超时时间为3*8+3=27ms。若每个字符读取的间隔为7ms, 则这次操作总共能读取4个字符。 就结束了。因为读取第5个字符时, 已经需要35ms, 超过总超时时间了。<br><br>下面来讨论一下这几个参数的设定: 将ReadIntervalTimeout设置为MAXDWORD,将ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant设置为0, 表示读操作将立即返回存放在输入缓冲区的字符。将ReadIntervalTimeout设置为MAXDWORD,将ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant设置为MAXDWORD, 表示读操作会一直等待直到所需要读取的字节数全部接收到为止。 (大家可以把MAXDWORD 认为是永远) 将ReadIntervalTimeout设置为0, 则不使用间隔超时, 只考虑总超时设置。 //两相邻字符之间最大的延时。当读串口数据时,一旦两个字符传输的时间间隔超过该时间,读函数将返回现有的数据。设置为0表示该参数不起作用。 CommTimeOuts.ReadIntervalTimeout = 100; //读操作总的超时事件的系数。 这个变量是不能单独使用的。 必须和ReadTotalTimeoutConstant 一起使用才有效果 CommTimeOuts.ReadTotalTimeoutMultiplier = 100; //读操作总的超时时间的修正常量。 这个变量也是不能单独使用的。必须和ReadTotalTimeoutMultiplier一起使用才有效果。 CommTimeOuts.ReadTotalTimeoutConstant = 150; //写操作总的超时事件的系数。 这个变量是不能单独使用的。 必须和WriteTotalTimeoutConstant 一起使用才有效果 CommTimeOuts.WriteTotalTimeoutMultiplier = 10; //写操作总的超时时间的修正常量。 这个变量也是不能单独使用的。必须和WriteTotalTimeoutMultiplier一起使用才有效果 CommTimeOuts.WriteTotalTimeoutConstant = 100; */ CommTimeOuts.ReadIntervalTimeout = MAXWORD; CommTimeOuts.ReadTotalTimeoutMultiplier = 10; CommTimeOuts.ReadTotalTimeoutConstant = 0; CommTimeOuts.WriteTotalTimeoutMultiplier = 50; CommTimeOuts.WriteTotalTimeoutConstant = 100; if(!SetCommTimeouts( m_hComm, &CommTimeOuts )) { AfxMessageBox( _T("SetCommTimeouts") ); //关闭串口 CloseHandle (m_hComm); m_hComm = INVALID_HANDLE_VALUE; return FALSE; } //指定端口监测的事件集 SetCommMask (m_hComm, EV_RXCHAR); //分配串口设备缓冲区 SetupComm(m_hComm,1024,1024); //初始化缓冲区中的信息 PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR); m_bOpened = TRUE; return TRUE; }
bool QSerial::open( const QString &dev, int speed ) { isatend = false; #if ( defined( __linux__ ) | defined( __APPLE__ ) ) #ifdef DEBUG_SERIAL logFile = new QFile( "/tmp/qserial.log", this ); logFile->open( QIODevice::Append ); QByteArray ba = "Open file:"; ba += dev; ba += "\n"; logFile->write( ba ); #endif io_port = ::open( dev.toUtf8(), O_RDWR|O_NOCTTY|O_NONBLOCK ); if ( io_port == -1 ) { perror( "Failed to open serial" ); return false; } #if ( defined( __APPLE__ ) ) if (ioctl(io_port, TIOCEXCL)==-1) qWarning( "Failed to set exclusiv open" ); // Clear O_NONBLOCK flag. if (fcntl( io_port, F_SETFL,0)==-1) qWarning( "Failed to clear NONBLOCK flag" ); #endif tcgetattr( io_port, &oldtio ); bzero( &newtio, sizeof( newtio ) ); int s; switch( speed ) { case 4800: s = B4800; break; case 9600: s = B9600; break; case 19200: s = B19200; break; case 38400: s = B38400; break; case 57600: s = B57600; break; case 115200: s = B115200; break; default: s = B9600; break; } cfsetispeed( &newtio, s ); cfsetospeed( &newtio, s ); newtio.c_cflag |= CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNBRK | IGNPAR; newtio.c_cc[VTIME] = 10; newtio.c_cc[VMIN] = 1; tcflush( io_port, TCIFLUSH ); tcsetattr( io_port, TCSANOW, &newtio ); QIODevice::open( ReadWrite ); setupSocketNotifiers(); return true; #else fh = CreateFileA( dev.toAscii(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); // OPEN_EXISTING, FILE_ATTRIUBTE_NORMAL, NULL ); if ( fh == INVALID_HANDLE_VALUE ) { LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)"open")+40)*sizeof(TCHAR)); lasterror = ""; for( int i=0;i<(lstrlen((LPCTSTR)lpMsgBuf));i++ ) lasterror += (((LPCTSTR)lpMsgBuf)[i]); //lasterror.sprintf( "%i: open failed with err %d: %s", (lstrlen((LPCTSTR)lpMsgBuf)), (int)dw, (const char *)(LPCTSTR)lpMsgBuf ); return false; } int s; switch( speed ) { case 4800: s = CBR_4800; break; case 9600: s = CBR_9600; break; case 19200: s = CBR_19200; break; case 38400: s = CBR_38400; break; case 57600: s = CBR_57600; break; case 115200: s = CBR_115200; break; default: s = CBR_9600; break; } COMMCONFIG comcfg; if ( GetCommState(fh, &comcfg.dcb) ) { comcfg.dcb.BaudRate = s; comcfg.dcb.ByteSize = 8; comcfg.dcb.Parity = NOPARITY; comcfg.dcb.StopBits = ONESTOPBIT; comcfg.dcb.fAbortOnError = TRUE; comcfg.dcb.fOutxCtsFlow = FALSE; comcfg.dcb.fOutxDsrFlow = FALSE; comcfg.dcb.fDtrControl = DTR_CONTROL_DISABLE; comcfg.dcb.fRtsControl = RTS_CONTROL_DISABLE; comcfg.dcb.fDsrSensitivity = FALSE; comcfg.dcb.fTXContinueOnXoff = TRUE; comcfg.dcb.fOutX = FALSE; comcfg.dcb.fInX = FALSE; comcfg.dcb.fBinary = TRUE; comcfg.dcb.fParity = TRUE; SetCommState( fh, &comcfg.dcb); GetCommState( fh, &comcfg.dcb ); } QIODevice::open( ReadWrite ); setupSocketNotifiers(); return true; #endif }
int OpenComport(int comport_number, int baudrate) { if((comport_number>MAX_COMPORT_NUM)||(comport_number<0)) { printf("illegal comport number\n"); return(1); } /* ::: MODIFIED ::: [KPZ-09.01.2014] */ snprintf(comports, MAX_COMPORT_LABEL_LENGTH, "\\\\.\\COM%d", comport_number); switch(baudrate) { case 110 : strcpy(baudr, "baud=110 data=8 parity=N stop=1"); break; case 300 : strcpy(baudr, "baud=300 data=8 parity=N stop=1"); break; case 600 : strcpy(baudr, "baud=600 data=8 parity=N stop=1"); break; case 1200 : strcpy(baudr, "baud=1200 data=8 parity=N stop=1"); break; case 2400 : strcpy(baudr, "baud=2400 data=8 parity=N stop=1"); break; case 4800 : strcpy(baudr, "baud=4800 data=8 parity=N stop=1"); break; case 9600 : strcpy(baudr, "baud=9600 data=8 parity=N stop=1"); break; case 19200 : strcpy(baudr, "baud=19200 data=8 parity=N stop=1"); break; case 38400 : strcpy(baudr, "baud=38400 data=8 parity=N stop=1"); break; case 57600 : strcpy(baudr, "baud=57600 data=8 parity=N stop=1"); break; case 115200 : strcpy(baudr, "baud=115200 data=8 parity=N stop=1"); break; case 128000 : strcpy(baudr, "baud=128000 data=8 parity=N stop=1"); break; case 256000 : strcpy(baudr, "baud=256000 data=8 parity=N stop=1"); break; default : printf("invalid baudrate\n"); return(1); break; } /* ::: MODIFIED ::: [KPZ-09.01.2014] */ Cport[comport_number] = CreateFileA(comports, GENERIC_READ|GENERIC_WRITE, 0, /* no share */ NULL, /* no security */ OPEN_EXISTING, 0, /* no threads */ NULL); /* no templates */ if(Cport[comport_number]==INVALID_HANDLE_VALUE) { printf("unable to open comport\n"); return(1); } DCB port_settings; memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */ port_settings.DCBlength = sizeof(port_settings); if(!BuildCommDCBA(baudr, &port_settings)) { printf("unable to set comport dcb settings\n"); CloseHandle(Cport[comport_number]); return(1); } if(!SetCommState(Cport[comport_number], &port_settings)) { printf("unable to set comport cfg settings\n"); CloseHandle(Cport[comport_number]); return(1); } COMMTIMEOUTS Cptimeouts; Cptimeouts.ReadIntervalTimeout = MAXDWORD; Cptimeouts.ReadTotalTimeoutMultiplier = 0; Cptimeouts.ReadTotalTimeoutConstant = 0; Cptimeouts.WriteTotalTimeoutMultiplier = 0; Cptimeouts.WriteTotalTimeoutConstant = 0; if(!SetCommTimeouts(Cport[comport_number], &Cptimeouts)) { printf("unable to set comport time-out settings\n"); CloseHandle(Cport[comport_number]); return(1); } return(0); }
HANDLE ndiSerialOpen(const char *device) { static COMMTIMEOUTS default_ctmo = { MAXDWORD, MAXDWORD, TIMEOUT_PERIOD, 2, TIMEOUT_PERIOD }; HANDLE serial_port; DCB comm_settings; int i; serial_port = CreateFile(device, GENERIC_READ|GENERIC_WRITE, 0, /* not allowed to share ports */ 0, /* child-processes don't inherit handle */ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); /* no template file */ if (serial_port == INVALID_HANDLE_VALUE) { return INVALID_HANDLE_VALUE; } /* save the serial port state so that it can be restored when the serial port is closed in ndiSerialClose() */ for (i = 0; i < NDI_MAX_SAVE_STATE; i++) { if (ndi_open_handles[i] == serial_port || ndi_open_handles[i] == INVALID_HANDLE_VALUE) { ndi_open_handles[i] = serial_port; GetCommTimeouts(serial_port,&ndi_save_timeouts[i]); GetCommState(serial_port,&ndi_save_dcb[i]); break; } } if (SetupComm(serial_port,1600,1600) == FALSE) { /* set buffer size */ if (i < NDI_MAX_SAVE_STATE) { /* if we saved the state, forget the state */ ndi_open_handles[i] = INVALID_HANDLE_VALUE; } CloseHandle(serial_port); return INVALID_HANDLE_VALUE; } if (GetCommState(serial_port,&comm_settings) == FALSE) { if (i < NDI_MAX_SAVE_STATE) { /* if we saved the state, forget the state */ ndi_open_handles[i] = INVALID_HANDLE_VALUE; } CloseHandle(serial_port); return INVALID_HANDLE_VALUE; } comm_settings.fOutX = FALSE; /* no S/W handshake */ comm_settings.fInX = FALSE; comm_settings.fAbortOnError = FALSE; /* don't need to clear errors */ comm_settings.fOutxDsrFlow = FALSE; /* no modem-style flow stuff*/ comm_settings.fDtrControl = DTR_CONTROL_ENABLE; if (SetCommState(serial_port,&comm_settings) == FALSE) { if (i < NDI_MAX_SAVE_STATE) { /* if we saved the state, forget the state */ ndi_open_handles[i] = INVALID_HANDLE_VALUE; } CloseHandle(serial_port); return INVALID_HANDLE_VALUE; } if (SetCommTimeouts(serial_port,&default_ctmo) == FALSE) { SetCommState(serial_port,&comm_settings); if (i < NDI_MAX_SAVE_STATE) { /* if we saved the state, forget the state */ SetCommState(serial_port,&ndi_save_dcb[i]); ndi_open_handles[i] = INVALID_HANDLE_VALUE; } CloseHandle(serial_port); return INVALID_HANDLE_VALUE; } return serial_port; }
bool SERIAL_open(const char* portname, COMPORT* port) { // allocate COMPORT structure COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT)); if(cp == NULL) return false; cp->breakstatus=false; // open the port in NT object space (recommended by Microsoft) // allows the user to open COM10+ and custom port names. int len = strlen(portname); if(len > 240) { SetLastError(ERROR_BUFFER_OVERFLOW); free(cp); return false; } char extended_portname[256] = "\\\\.\\"; memcpy(extended_portname+4,portname,len+1); cp->porthandle = CreateFile (extended_portname, GENERIC_READ | GENERIC_WRITE, 0, // must be opened with exclusive-access NULL, // no security attributes OPEN_EXISTING, // must use OPEN_EXISTING 0, // non overlapped I/O NULL // hTemplate must be NULL for comm devices ); if (cp->porthandle == INVALID_HANDLE_VALUE) goto cleanup_error; cp->orig_dcb.DCBlength=sizeof(DCB); if(!GetCommState(cp->porthandle, &cp->orig_dcb)) { goto cleanup_error; } // configure the port for polling DCB newdcb; memcpy(&newdcb,&cp->orig_dcb,sizeof(DCB)); newdcb.fBinary=true; newdcb.fParity=true; newdcb.fOutxCtsFlow=false; newdcb.fOutxDsrFlow=false; newdcb.fDtrControl=DTR_CONTROL_DISABLE; newdcb.fDsrSensitivity=false; newdcb.fOutX=false; newdcb.fInX=false; newdcb.fErrorChar=0; newdcb.fNull=false; newdcb.fRtsControl=RTS_CONTROL_DISABLE; newdcb.fAbortOnError=false; if(!SetCommState(cp->porthandle, &newdcb)) { goto cleanup_error; } // Configure timeouts to effectively use polling COMMTIMEOUTS ct; ct.ReadIntervalTimeout = MAXDWORD; ct.ReadTotalTimeoutConstant = 0; ct.ReadTotalTimeoutMultiplier = 0; ct.WriteTotalTimeoutConstant = 0; ct.WriteTotalTimeoutMultiplier = 0; if(!SetCommTimeouts(cp->porthandle, &ct)) { goto cleanup_error; } if(!ClearCommBreak(cp->porthandle)) { // Bluetooth Bluesoleil seems to not implement it //goto cleanup_error; } DWORD errors; if(!ClearCommError(cp->porthandle, &errors, NULL)) { goto cleanup_error; } *port = cp; return true; cleanup_error: if (cp->porthandle != INVALID_HANDLE_VALUE) CloseHandle(cp->porthandle); free(cp); return false; }
bool VirtualSerialDevice::open(OpenMode mode) { Q_ASSERT(QThread::currentThread() == thread()); if (isOpen()) return true; d->portHandle = CreateFileA(windowsPortName(portName).toAscii(), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (d->portHandle == INVALID_HANDLE_VALUE) { setErrorString(tr("The port %1 could not be opened: %2"). arg(portName, winErrorMessage(GetLastError()))); return false; } DCB commState; memset(&commState, 0, sizeof(DCB)); commState.DCBlength = sizeof(DCB); bool ok = GetCommState(d->portHandle, &commState); if (ok) { commState.BaudRate = CBR_115200; commState.fBinary = TRUE; commState.fParity = FALSE; commState.fOutxCtsFlow = FALSE; commState.fOutxDsrFlow = FALSE; commState.fInX = FALSE; commState.fOutX = FALSE; commState.fNull = FALSE; commState.fAbortOnError = FALSE; commState.fDsrSensitivity = FALSE; commState.fDtrControl = DTR_CONTROL_DISABLE; commState.ByteSize = 8; commState.Parity = NOPARITY; commState.StopBits = ONESTOPBIT; ok = SetCommState(d->portHandle, &commState); } if (!ok) { qWarning("%s setting comm state", qPrintable(winErrorMessage(GetLastError()))); } // http://msdn.microsoft.com/en-us/library/aa363190(v=vs.85).aspx says this means // "the read operation is to return immediately with the bytes that have already been received, even if no bytes have been received" COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; SetCommTimeouts(d->portHandle, &timeouts); d->writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); d->writeCompleteNotifier = new QWinEventNotifier(d->writeOverlapped.hEvent, this); connect(d->writeCompleteNotifier, SIGNAL(activated(HANDLE)), this, SLOT(writeCompleted())); // This is how we implement readyRead notifications d->commEventOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); d->commEventNotifier = new QWinEventNotifier(d->commEventOverlapped.hEvent, this); connect(d->commEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(commEventOccurred())); if (!SetCommMask(d->portHandle, EV_RXCHAR)) { // What to do? qWarning("%s: Could not set comm mask, err=%d", Q_FUNC_INFO, (int)GetLastError()); } bool result = WaitCommEvent(d->portHandle, &d->commEventMask, &d->commEventOverlapped); Q_ASSERT(result == false); // Can't see how it would make sense to be anything else... (void)result; // For release build if (GetLastError() != ERROR_IO_PENDING) { setErrorString(tr("An error occurred while waiting for read notifications from %1: %2"). arg(portName, winErrorMessage(GetLastError()))); close(); return false; } ok = QIODevice::open(mode); if (!ok) close(); return ok; }
/*! \brief Open the serial port \param Device : Port name (COM1, COM2, ... for Windows ) or (/dev/ttyS0, /dev/ttyACM0, /dev/ttyUSB0 ... for linux) \param Bauds : Baud rate of the serial port. \n Supported baud rate for Windows : - 110 - 300 - 600 - 1200 - 2400 - 4800 - 9600 - 14400 - 19200 - 38400 - 56000 - 57600 - 115200 - 128000 - 256000 \n Supported baud rate for Linux :\n - 110 - 300 - 600 - 1200 - 2400 - 4800 - 9600 - 19200 - 38400 - 57600 - 115200 \return 1 success \return -1 device not found \return -2 error while opening the device \return -3 error while getting port parameters \return -4 Speed (Bauds) not recognized \return -5 error while writing port parameters \return -6 error while writing timeout parameters */ char serialib::Open(const char *Device,const unsigned int Bauds) { #if defined (_WIN32) || defined( _WIN64) // Open serial port hSerial = CreateFileA( Device,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if(hSerial==INVALID_HANDLE_VALUE) { if(GetLastError()==ERROR_FILE_NOT_FOUND) return -1; // Device not found return -2; // Error while opening the device } // Set parameters DCB dcbSerialParams = {0}; // Structure for the port parameters dcbSerialParams.DCBlength=sizeof(dcbSerialParams); if (!GetCommState(hSerial, &dcbSerialParams)) // Get the port parameters return -3; // Error while getting port parameters switch (Bauds) // Set the speed (Bauds) { case 110 : dcbSerialParams.BaudRate=CBR_110; break; case 300 : dcbSerialParams.BaudRate=CBR_300; break; case 600 : dcbSerialParams.BaudRate=CBR_600; break; case 1200 : dcbSerialParams.BaudRate=CBR_1200; break; case 2400 : dcbSerialParams.BaudRate=CBR_2400; break; case 4800 : dcbSerialParams.BaudRate=CBR_4800; break; case 9600 : dcbSerialParams.BaudRate=CBR_9600; break; case 14400 : dcbSerialParams.BaudRate=CBR_14400; break; case 19200 : dcbSerialParams.BaudRate=CBR_19200; break; case 38400 : dcbSerialParams.BaudRate=CBR_38400; break; case 56000 : dcbSerialParams.BaudRate=CBR_56000; break; case 57600 : dcbSerialParams.BaudRate=CBR_57600; break; case 115200 : dcbSerialParams.BaudRate=CBR_115200; break; case 128000 : dcbSerialParams.BaudRate=CBR_128000; break; case 256000 : dcbSerialParams.BaudRate=CBR_256000; break; default : return -4; } dcbSerialParams.ByteSize=8; // 8 bit data dcbSerialParams.StopBits=ONESTOPBIT; // One stop bit dcbSerialParams.Parity=NOPARITY; // No parity if(!SetCommState(hSerial, &dcbSerialParams)) // Write the parameters return -5; // Error while writing // Set TimeOut timeouts.ReadIntervalTimeout=0; // Set the Timeout parameters timeouts.ReadTotalTimeoutConstant=MAXDWORD; // No TimeOut timeouts.ReadTotalTimeoutMultiplier=0; timeouts.WriteTotalTimeoutConstant=MAXDWORD; timeouts.WriteTotalTimeoutMultiplier=0; if(!SetCommTimeouts(hSerial, &timeouts)) // Write the parameters return -6; // Error while writting the parameters return 1; // Opening successfull #endif #ifdef __linux__ struct termios options; // Structure with the device's options // Open device fd = open(Device, O_RDWR | O_NOCTTY | O_NDELAY); // Open port if (fd == -1) return -2; // If the device is not open, return -1 fcntl(fd, F_SETFL, FNDELAY); // Open the device in nonblocking mode // Set parameters tcgetattr(fd, &options); // Get the current options of the port bzero(&options, sizeof(options)); // Clear all the options speed_t Speed; switch (Bauds) // Set the speed (Bauds) { case 110 : Speed=B110; break; case 300 : Speed=B300; break; case 600 : Speed=B600; break; case 1200 : Speed=B1200; break; case 2400 : Speed=B2400; break; case 4800 : Speed=B4800; break; case 9600 : Speed=B9600; break; case 19200 : Speed=B19200; break; case 38400 : Speed=B38400; break; case 57600 : Speed=B57600; break; case 115200 : Speed=B115200; break; default : return -4; } cfsetispeed(&options, Speed); // Set the baud rate at 115200 bauds cfsetospeed(&options, Speed); options.c_cflag |= ( CLOCAL | CREAD | CS8); // Configure the device : 8 bits, no parity, no control options.c_iflag |= ( IGNPAR | IGNBRK ); options.c_cc[VTIME]=0; // Timer unused options.c_cc[VMIN]=0; // At least on character before satisfy reading tcsetattr(fd, TCSANOW, &options); // Activate the settings return (1); // Success #endif }