/********************************************************************* * "COMXX:" ポートのプロパティを見る. ********************************************************************* */ void RS_printCommInfo(char *comXX) { BOOL rc; HANDLE com_handle; COMMPROP CommProp; printf("%s:",comXX); com_handle = CreateFile( comXX, /* シリアルポートの文字列 */ GENERIC_READ | GENERIC_WRITE , /* アクセスモード */ 0, NULL, /* セキュリティ属性 */ OPEN_EXISTING, /* 作成フラグ */ 0, /* 属性 */ NULL /* テンプレートのハンドル */ ); if( comHandle == INVALID_HANDLE_VALUE) { printf(" Can't Open ."); }else{ rc = GetCommProperties(com_handle,&CommProp); if(rc) { printf("TxQue=%ld,RxQue=%ld,Baud=0x%x,BaudMax=0x%x,Bits=0x%x,SubType=%x,Capa=%x " ,CommProp.dwCurrentTxQueue // バイト単位の送信バッファサイズ ,CommProp.dwCurrentRxQueue // バイト単位の受信バッファサイズ ,CommProp.dwSettableBaud // ボーレート最大値 ,CommProp.dwMaxBaud // ボーレート最大値 ,CommProp.wSettableData // DATABITS 5,6,7,8,16,16x ,CommProp.dwProvSubType // 特定プロバイダータイプ ,CommProp.dwProvCapabilities // サポートされた関数 ); } #if 1 static DCB com_dcb; memset(&com_dcb,0,sizeof(com_dcb)); com_dcb.DCBlength = sizeof(DCB); rc = GetCommState(comHandle,&com_dcb); // if(rc) { // com_dcb.BaudRate = baudrate; // com_dcb.ByteSize = 8; // com_dcb.Parity = NOPARITY; // com_dcb.StopBits = ONESTOPBIT; printf("rc=%d Baud=%ld bits=%d parity=%d stop=%d",rc ,com_dcb.BaudRate ,com_dcb.ByteSize ,com_dcb.Parity ,com_dcb.StopBits ); } #endif CloseHandle(com_handle); } printf("\n"); }
// Open the port. Returns 0 on success, or a negative error number. // Establishes default comms settings, but calls OnOpen virtual function to // change the default settings (including the port number). // DEFAULTS: COM1; 2400baud; 8 Data bits; 1 Stop Bit; No Parity; No Handshaking. int JHCommBase::Open() { char fn[10]; DCB dcb; COMMTIMEOUTS cto; COMMPROP cp; COMMSETTINGS cs; InitSettings(&cs, &dcb, &cto); OnOpen(&cs, &dcb, &cto); dcb.DCBlength = sizeof(dcb); cto.ReadIntervalTimeout = MAXDWORD; cto.ReadTotalTimeoutConstant = 0; cto.ReadTotalTimeoutMultiplier = 0; sprintf_s(fn, 10, "\\\\.\\COM%u", cs.PortNumber); hPort = CreateFileA(fn, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (hPort == INVALID_HANDLE_VALUE) { switch (GetLastError()) { case 5: return -107; default: return -100; } } if (!SetCommTimeouts(hPort, &cto)) {Close(); return -101;}; if ((cs.rxQueueSize != 0) || (cs.txQueueSize != 0)) if (!SetupComm(hPort, cs.rxQueueSize, cs.txQueueSize)) {Close(); return -102;}; if ((dcb.XoffLim == 0) || (dcb.XonLim == 0)) { if (!GetCommProperties(hPort, &cp)) cp.dwCurrentRxQueue = 0; if (cp.dwCurrentRxQueue > 0) { //If we can determine the queue size, default to 1/10th, 8/10ths, 1/10th. //Note that HighWater is measured from top of queue. dcb.XoffLim = dcb.XonLim = (short)((int)cp.dwCurrentRxQueue / 10); } else { //If we do not know the queue size, set very low defaults for safety. dcb.XoffLim = dcb.XonLim = 8; } } if (!SetCommState(hPort, &dcb)) {Close(); return -103;}; hRxEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == hRxEvent) {Close(); return -104;}; hTxEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == hTxEvent) {Close(); return -105;}; rxmode = 0; hRxThread = CreateThread(NULL, 0, RxThread, (LPVOID)this, 0, NULL); if (NULL == hRxThread) {Close(); return -106;}; sendcount = 0; //OutputDebugString("Port Opened"); return 0; }
void CSerialPort::GetProperties(COMMPROP& properties) { ASSERT(IsOpen()); if (!GetCommProperties(m_hComm, &properties)) { TRACE(_T("Failed in call to GetCommProperties\n")); AfxThrowSerialException(); } }
// Query the serial port for the maximum buffer size. vpr::Uint16 SerialPortImplWin32::getMinInputSize() const { COMMPROP lpCommProp; if ( ! GetCommProperties(mHandle, &lpCommProp) || (int) lpCommProp.dwCurrentTxQueue == 0 ) { throw IOException("Maximum buffer size is unavailable.", VPR_LOCATION); } return lpCommProp.dwCurrentTxQueue; }
/** * Initialises a serial port handle for reading and writing * * @param LPCTSTR port The name of the serial port to open. * @param HANDLE* fd The pointer to the handle which will be initialised to the open * serial port connection. * @returns int 0 on success, >0 otherwise */ int OpenPort(const LPCTSTR port, HANDLE* fd, HWND hwnd) { COMMPROP cprops; DCB dcb; COMMCONFIG config; /* Create the file descriptor handle */ if ((*fd = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE) { return 1; } if (!GetCommProperties(*fd, &cprops)) { return 2; } /* Setup the port for sending and receiving data */ if (!SetupComm(*fd, cprops.dwMaxRxQueue, cprops.dwMaxTxQueue)) { return 3; } /* Get the current DCB settings */ if (!GetCommState(*fd, &dcb)) { return 4; } config.dwSize = sizeof(COMMCONFIG); config.wVersion = 0x1; config.dcb = dcb; config.dwProviderSubType = cprops.dwProvSubType; config.dwProviderOffset = 0; config.dwProviderSize = 0; /* Show the port configuration dialog */ if (!CommConfigDialog(port, hwnd, &config)) { return 5; } /* Set the DCB to the config settings */ if (!SetCommState(*fd, &config.dcb)) { return 6; } /* Specify events to receive */ if (!SetCommMask(*fd, EV_RXCHAR | EV_TXEMPTY)) { return 7; } return 0; }
// Habilitacion y programacion del puerto serie int CComm32::OpenComm() { if (m_OnOpen) return ERROR_ALREADY_INITIALIZED; m_HPort=CreateFile(m_Name,GENERIC_READ+GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); if (m_HPort==INVALID_HANDLE_VALUE) return GetLastError(); m_OnOpen=true; if (GetFileType(m_HPort)!=FILE_TYPE_CHAR) { CloseHandle(m_HPort); return ERROR_OPEN_FAILED; } m_Read_Overlapped.hEvent=CreateEvent(NULL,true,true,NULL); if (m_Read_Overlapped.hEvent==0) { CloseAll(); return GetLastError(); } m_Write_Overlapped.hEvent=CreateEvent(NULL,true,true,NULL); if (m_Write_Overlapped.hEvent==0) { CloseAll(); return GetLastError(); } GetCommProperties(m_HPort,&m_CommProp); SetCommMask(m_HPort,m_EvtMask); SetCommTimeouts(m_HPort,&m_CommTimeOuts); GetCommModemStatus(m_HPort,&m_ModemStat); DWORD size=sizeof(COMMCONFIG); GetCommConfig(m_HPort,&m_CommConfig,&size); return 0; }
/* * Set speed/parity etc of dl0d with settings in pset * ret 0 if ok */ int diag_tty_setup(struct diag_l0_device *dl0d, const struct diag_serial_settings *pset) { HANDLE devhandle; //just to clarify code struct tty_int *wti; DCB *devstate; COMMPROP supportedprops; DCB verif_dcb; wti = (struct tty_int *)dl0d->tty_int; devhandle = wti->fd; devstate = &wti->dcb; if (devhandle == INVALID_HANDLE_VALUE) { fprintf(stderr, FLFMT "setup: something is not right\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } //optional : verify if device supports the requested settings. Testing required to see if USB->serial bridges support this ! //i.e. some l0 devices try to set 5bps which isn't supported on some devices. //For now let's just check if it supports custom baud rates. This check should be added to diag_tty_open where //it would set appropriate flags to allow _l0 devices to adapt their functionality. if (! GetCommProperties(devhandle,&supportedprops)) { fprintf(stderr, FLFMT "could not getcommproperties: %s\n",FL, diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } //simple test : only check if custom baud rates are supported, but don't abort if they aren't. Just notify user. if ( !(supportedprops.dwMaxBaud & BAUD_USER)) fprintf(stderr, FLFMT "warning : device does not support custom baud rates !\n", FL); if (diag_l0_debug & DIAG_DEBUG_IOCTL) { fprintf(stderr, FLFMT "dev %p; %dbps %d,%d,%d \n", FL, (void *)devhandle, pset->speed, pset->databits, pset->stopbits, pset->parflag); } /* * Now load the DCB with the parameters requested. */ // the DCB (devstate) has been loaded with initial values in diag_tty_open so it should already coherent. devstate->BaudRate = pset->speed; devstate->fBinary=1; // always binary mode. switch (pset->parflag) { case diag_par_n: //no parity : disable parity in the DCB devstate->fParity=0; devstate->Parity=NOPARITY; break; case diag_par_e: devstate->fParity=1; devstate->Parity=EVENPARITY; break; case diag_par_o: devstate->fParity=1; devstate->Parity=ODDPARITY; break; default: fprintf(stderr, FLFMT "bad parity setting used !\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); break; } devstate->fOutxCtsFlow=0; devstate->fOutxDsrFlow=0; //disable output flow control devstate->fDtrControl=DTR_CONTROL_DISABLE; //XXX allows to permanently set the DTR line ! devstate->fDsrSensitivity=0; //pay no attention to DSR for receiving devstate->fTXContinueOnXoff=1; //probably irrelevant ? devstate->fOutX=0; //disable Xon/Xoff tx flow ctl devstate->fInX=0; //disable XonXoff rx flow ctl devstate->fErrorChar=0; //do not replace data with bad parity devstate->fNull=0; // do not discard null bytes ! on rx devstate->fRtsControl=RTS_CONTROL_DISABLE; //XXX allows to set the RTS line! devstate->fAbortOnError=0; //do not abort transfers on error ? devstate->wReserved=0; devstate->ByteSize=pset->databits; //bits per byte switch (pset->stopbits) { case diag_stopbits_1: devstate->StopBits=ONESTOPBIT; break; case diag_stopbits_2: devstate->StopBits=TWOSTOPBITS; break; default: fprintf(stderr, FLFMT "bad stopbit setting used!)\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); break; } // DCB in devstate is now filled. if (! SetCommState(devhandle, devstate)) { fprintf(stderr, FLFMT "Could not SetCommState: %s\n",FL, diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } //to be really thorough we do another GetCommState and check that the speed was set properly. //This *may* help to detect if the serial port supports non-standard baudrates (5bps being //particularly problematic with USB->serial converters) //I see no particular reason to check all the other fields though. if (! GetCommState(devhandle, &verif_dcb)) { fprintf(stderr, FLFMT "Could not verify with GetCommState: %s\n", FL, diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } if (verif_dcb.BaudRate != pset->speed) { fprintf(stderr, FLFMT "SetCommState failed : speed is currently %u\n", FL, (unsigned int) verif_dcb.BaudRate); return diag_iseterr(DIAG_ERR_GENERAL); } return 0; } //diag_tty_setup
static int get_com_state(HANDLE fh, uart_com_state_t* com) { DCB dcb; COMMTIMEOUTS tmo; COMMPROP prop; memset(&dcb, 0, sizeof(dcb)); if (!GetCommState(fh, &dcb)) { DEBUG_ERROR("GetCommState: error %d", GetLastError()); return -1; } // input baud reate com->ibaud = from_speed(dcb.BaudRate); com->obaud = com->ibaud; // parity if (!dcb.fParity) com->parity = UART_PARITY_NONE; else { switch (dcb.Parity) { case ODDPARITY: com->parity = UART_PARITY_ODD; break; case EVENPARITY: com->parity = UART_PARITY_EVEN; break; case MARKPARITY: com->parity = UART_PARITY_MARK; break; case SPACEPARITY: com->parity = UART_PARITY_SPACE; break; case NOPARITY: com->parity = UART_PARITY_NONE; break; default: com->parity = UART_PARITY_NONE; break; } } // stop bits if (dcb.StopBits == ONESTOPBIT) com->stopb = 1; else if (dcb.StopBits == TWOSTOPBITS) com->stopb = 2; else if (dcb.StopBits == ONE5STOPBITS) com->stopb = 3; // error? else com->stopb = 0; com->csize = dcb.ByteSize; com->xonchar = dcb.XonChar; com->xoffchar = dcb.XoffChar; com->iflow = 0; if (dcb.fInX) com->iflow |= UART_SW; if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE) com->iflow |= UART_DTR; if (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE) com->iflow |= UART_RTS; com->oflow = 0; if (dcb.fOutX) com->oflow |= UART_SW; if (dcb.fOutxCtsFlow) com->oflow |= UART_CTS; if (dcb.fOutxDsrFlow) com->oflow |= UART_DSR; if (!GetCommTimeouts(fh, &tmo)) { DEBUG_ERROR("GetCommTimeouts: error %d", GetLastError()); return -1; } if (!GetCommProperties(fh, &prop)) { DEBUG_ERROR("GetCommProperties: error %d", GetLastError()); return -1; } // Hardware buffer arguments (MODERNIZE this!!!) com->bufsz = prop.dwCurrentRxQueue; // com->rxqueue = prop.dwCurrentTxQueue; ???? // com->txqueue = prop.dwCurrentTxQueue; com->buftm = tmo.ReadIntervalTimeout; return 0; }
BOOL CEnumerateSerial::EnumeratePorts() { int SPDRPlist[] = { SPDRP_DEVICEDESC, SPDRP_FRIENDLYNAME, SPDRP_MFG, SPDRP_LOCATION_INFORMATION, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, -1}; // Clear anything from previous enumerate... ResetPortList(); // Dynamically get pointers to device installation library (setupapi.dll) // in case it isn't installed... // SetupDiOpenDevRegKey // SetupDiEnumDeviceInfo // SetupDiDestroyDeviceInfoList // SetupDiGetClassDevs // SetupDiClassGuidsFromName // SetupDiGetDeviceRegistryProperty CLoadLib setupAPI(_T("SETUPAPI.DLL")); if (setupAPI == NULL) return FALSE; #define SETUPPROC(x,y) x* lpfn##x = reinterpret_cast<x*>(GetProcAddress(setupAPI,y)) SETUPPROC(SETUPDIOPENDEVREGKEY,"SetupDiOpenDevRegKey"); SETUPPROC(SETUPDIENUMDEVICEINFO, "SetupDiEnumDeviceInfo"); SETUPPROC(SETUPDIDESTROYDEVICEINFOLIST, "SetupDiDestroyDeviceInfoList"); #if defined _UNICODE SETUPPROC(SETUPDIGETCLASSDEVS, "SetupDiGetClassDevsW"); SETUPPROC(SETUPDICLASSGUIDSFROMNAME, "SetupDiClassGuidsFromNameW"); SETUPPROC(SETUPDIGETDEVICEREGISTRYPROPERTY, "SetupDiGetDeviceRegistryPropertyW"); #else SETUPPROC(SETUPDIGETCLASSDEVS, "SetupDiGetClassDevsA"); SETUPPROC(SETUPDICLASSGUIDSFROMNAME, "SetupDiClassGuidsFromNameA"); SETUPPROC(SETUPDIGETDEVICEREGISTRYPROPERTY, "SetupDiGetDeviceRegistryPropertyA"); #endif if ((lpfnSETUPDIOPENDEVREGKEY == NULL) || (lpfnSETUPDIENUMDEVICEINFO == NULL) || (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY == NULL) || (lpfnSETUPDIGETCLASSDEVS == NULL) || (lpfnSETUPDICLASSGUIDSFROMNAME == NULL) || (lpfnSETUPDIDESTROYDEVICEINFOLIST == NULL)) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } // First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName... DWORD dwGuids = 0; lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) return FALSE; // Allocate the needed memory... CHeapPtr<GUID> GuidArray; GUID *pGuids = (GUID*)GuidArray.Allocate(sizeof(GUID) * dwGuids); if (pGuids==NULL) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } // Call the function again... if (!lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), pGuids, dwGuids, &dwGuids)) return FALSE; // Now create a "device information set" which is required to enumerate all the ports... HDEVINFO hDevInfoSet = lpfnSETUPDIGETCLASSDEVS(pGuids, NULL, NULL, DIGCF_PRESENT); if (hDevInfoSet == INVALID_HANDLE_VALUE) return FALSE; // Finally do the enumeration... int nIndex = 0; SP_DEVINFO_DATA devInfo; CHeapPtr<TCHAR> tempstr(256); CSerialPortInfo *portinfo = NULL; // Enumerate the current device... devInfo.cbSize = sizeof(SP_DEVINFO_DATA); while (lpfnSETUPDIENUMDEVICEINFO(hDevInfoSet, nIndex, &devInfo)) { portinfo = NULL; // Get the registry key which stores the ports settings... HKEY hDeviceKey = lpfnSETUPDIOPENDEVREGKEY(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; // Read name of port. If formatted as "COMxx" then allocate a port slot... if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>((TCHAR*)tempstr), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ)) if (_tcslen(tempstr) > 3) if ((_tcsnicmp(tempstr, _T("COM"), 3) == 0) && IsNumber(&(tempstr[3]))) portinfo = AddPort(_ttoi(&(tempstr[3]))); // Close the key now that we are finished with it... RegCloseKey(hDeviceKey); } // If a serial port, then try getting additional useful descriptive info... if (portinfo) { for (int i=0; SPDRPlist[i]>=0; i++) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; if (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY(hDevInfoSet, &devInfo, SPDRPlist[i], &dwType, reinterpret_cast<PBYTE>((TCHAR*)tempstr), dwSize, &dwSize) && (dwType == REG_SZ)) switch (SPDRPlist[i]) { case SPDRP_MFG : portinfo->SetManufacturer(tempstr); break; case SPDRP_DEVICEDESC : portinfo->SetDeviceDesc(tempstr); break; case SPDRP_FRIENDLYNAME : portinfo->SetFriendlyName(tempstr); break; case SPDRP_LOCATION_INFORMATION : portinfo->SetLocationInfo(tempstr); break; case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME : portinfo->SetPhysLocation(tempstr); break; } } // Get COM port properties... HANDLE hPort = ::CreateFile(portinfo->GetPortDeviceName(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hPort != INVALID_HANDLE_VALUE) { COMMPROP cp; GetCommProperties(hPort, &cp); portinfo->SetCommProp(cp); TRACE ("Port %d: CommProp: maxbaud=%08x settablebaud=%08x\n",portinfo->GetPortNum(),cp.dwMaxBaud,cp.dwSettableBaud); CloseHandle(hPort); } } ++nIndex; } // Free up the "device information set" now that we are finished with it lpfnSETUPDIDESTROYDEVICEINFOLIST(hDevInfoSet); // Return the success indicator return TRUE; }
void main(int argc,char *argv[]) { HANDLE hFile; COMMPROP mp; DCB MyDcb; ULONG i; ULONG actuallyIoed; ULONG firstReadSize; ULONG secondReadSize; ULONG secondWriteSize; COMMTIMEOUTS cto; char *MyPort = "COM1"; COMSTAT stat; DWORD errors; DWORD increment = 1066; DWORD baudRate = 19200; cto.ReadIntervalTimeout = (DWORD)~0; cto.ReadTotalTimeoutMultiplier = (DWORD)0; cto.ReadTotalTimeoutConstant = (DWORD)0; cto.WriteTotalTimeoutMultiplier = (DWORD)1; cto.WriteTotalTimeoutConstant = (DWORD)1000; if (argc > 1) { MyPort = argv[1]; if (argc > 2) { sscanf(argv[2],"%d",&increment); if (argc > 3) { sscanf(argv[3],"%d",&baudRate); } } } // // Put a sequence number in each long. As an extra check // turn the high bit on. // for ( i = 0; i < MAX_CHECK; i++ ) { CheckValues[i] = i; CheckValues[i] |= 0x80000000; } if ((hFile = CreateFile( MyPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL )) == ((HANDLE)-1)) { printf("Couldn't open the port %s\n",MyPort); exit(1); } if (!GetCommState( hFile, &MyDcb )) { printf("We couldn't get the comm state\n"); exit(1); } // // Set the baud to 19200 and the data bits to 8 // (We want 8 so that we don't lose any of our data.) // MyDcb.BaudRate = baudRate; MyDcb.ByteSize = 8; if (!SetCommState( hFile, &MyDcb )) { printf("Couldn't set the baud/data for port %s\n"); exit(1); } // // All the data should be in memory, we just set a timeout // so that if we do get hung up, the reads will return. // if (!SetCommTimeouts( hFile, &cto )) { printf("Couldn't set the timeouts.\n"); exit(1); } // // Find out how many bytes are available in the RX buffer. // if (!GetCommProperties( hFile, &mp )) { printf("Couldn't get the properties for port %s\n",MyPort); exit(1); } while (mp.dwCurrentRxQueue <= (MAX_CHECK*sizeof(ULONG))) { printf("RX buffer size: %d\r",mp.dwCurrentRxQueue); // // Write out the number of bytes that the RX buffer can // hold. // // The we read in half (approximately) of those bytes. After // we read the half, we resize the buffer. We then read in // the rest of those bytes. We then check the values against // what they "should" be. // if (!WriteFile( hFile, &CheckValues[0], mp.dwCurrentRxQueue, &actuallyIoed, NULL )) { printf("\nDidn't get all of the characters written %d\n",actuallyIoed); exit(1); } if (actuallyIoed != mp.dwCurrentRxQueue) { printf("\nfirst write Timed out with IO of %d\n",actuallyIoed); exit(1); } Sleep(2); // // Call clear comm error so that we can see how many characters // are in the typeahead buffer. // if (!ClearCommError( hFile, &errors, &stat )) { printf("\nCouldn't call clear comm status after first write.\n"); exit(1); } if (stat.cbInQue != mp.dwCurrentRxQueue) { printf("\nAfter first write the typeahead buffer is incorrect %d - %x\n", stat.cbInQue,errors); exit(1); } firstReadSize = mp.dwCurrentRxQueue / 2; secondReadSize = mp.dwCurrentRxQueue - firstReadSize; if (!ReadFile( hFile, &ReadValues[0], firstReadSize, &actuallyIoed, NULL )) { printf("\nDidn't get all of the characters read %d\n",actuallyIoed); exit(1); } if (actuallyIoed != firstReadSize) { printf("\nfirst read Timed out with IO of %d\n",actuallyIoed); exit(1); } Sleep(2); // // Call clear comm error so that we can see how many characters // are in the typeahead buffer. // if (!ClearCommError( hFile, &errors, &stat )) { printf("\nCouldn't call clear comm status after first read.\n"); exit(1); } if (stat.cbInQue != secondReadSize) { printf("\nAfter first read the typeahead buffer is incorrect %d\n", stat.cbInQue); exit(1); } Sleep(100); mp.dwCurrentRxQueue += increment; if (!SetupComm( hFile, mp.dwCurrentRxQueue, mp.dwCurrentTxQueue )) { printf("\nCouldn't resize the buffer to %d\n",mp.dwCurrentRxQueue); exit(1); } Sleep(2); // // Call clear comm error so that we can see how many characters // are in the typeahead buffer. // if (!ClearCommError( hFile, &errors, &stat )) { printf("\nCouldn't call clear comm status after resize.\n"); exit(1); } if (stat.cbInQue != secondReadSize) { printf("\nAfter resize the typeahead buffer is incorrect %d\n", stat.cbInQue); exit(1); } // // It's been resized. Fill up the remaining. // secondWriteSize = mp.dwCurrentRxQueue - secondReadSize; if (!WriteFile( hFile, &CheckValues[0], secondWriteSize, &actuallyIoed, NULL )) { printf("\nDidn't write all of the chars second time %d\n",actuallyIoed); exit(1); } if (actuallyIoed != secondWriteSize) { printf("\nsecond write Timed out with IO of %d\n",actuallyIoed); exit(1); } Sleep(2); // // Call clear comm error so that we can see how many characters // are in the typeahead buffer. // if (!ClearCommError( hFile, &errors, &stat )) { printf("\nCouldn't call clear comm status after resize.\n"); exit(1); } if (stat.cbInQue != mp.dwCurrentRxQueue) { printf("\nAfter second write the typeahead buffer is incorrect %d\n", stat.cbInQue); exit(1); } // // We resized the buffer, see if we can get the rest of the // characters from the first write. // if (!ReadFile( hFile, ((PUCHAR)&ReadValues[0])+firstReadSize, secondReadSize, &actuallyIoed, NULL )) { printf("\nDidn't get all of the characters read(2) %d\n",actuallyIoed); exit(1); } if (actuallyIoed != secondReadSize) { printf("\nsecond read Timed out with IO of %d\n",actuallyIoed); exit(1); } Sleep(2); // // Call clear comm error so that we can see how many characters // are in the typeahead buffer. // if (!ClearCommError( hFile, &errors, &stat )) { printf("\nCouldn't call clear comm status after resize.\n"); exit(1); } if (stat.cbInQue != secondWriteSize) { printf("\nAfter second read the typeahead buffer is incorrect %d\n", stat.cbInQue); exit(1); } // // Now check that what we read was what we sent. // for ( i = 0; i < (((firstReadSize+secondReadSize)+(sizeof(DWORD)-1)) / sizeof(DWORD)) - 1; i++ ) { if (ReadValues[i] != CheckValues[i]) { printf("\nAt index %d - values are read %x - check %x\n", i,ReadValues[i],CheckValues[i]); exit(1); } } // // Get the chars we wrote on the second write and make // sure that they are good also. // if (!ReadFile( hFile, &ReadValues[0], secondWriteSize, &actuallyIoed, NULL )) { printf("\nDidn't get all of the characters read(3) %d\n",actuallyIoed); exit(1); } if (actuallyIoed != secondWriteSize) { printf("\nthird read Timed out with IO of %d\n",actuallyIoed); exit(1); } Sleep(2); // // Call clear comm error so that we can see how many characters // are in the typeahead buffer. // if (!ClearCommError( hFile, &errors, &stat )) { printf("\nCouldn't call clear comm status after resize.\n"); exit(1); } if (stat.cbInQue) { printf("\nAfter second read the typeahead buffer is incorrect %d\n", stat.cbInQue); exit(1); } // // Now check that what we read was what we sent. // for ( i = 0; i < ((secondWriteSize+(sizeof(DWORD)-1)) / sizeof(DWORD)) - 1; i++ ) { if (ReadValues[i] != CheckValues[i]) { printf("\nAt on read(3) index %d - values are read %x - check %x\n", i,ReadValues[i],CheckValues[i]); exit(1); } } } }
BOOL CEnumerateSerial::EnumeratePorts() { int SPDRPlist[] = { SPDRP_HARDWAREID, SPDRP_DEVICEDESC, SPDRP_FRIENDLYNAME, SPDRP_MFG, SPDRP_LOCATION_INFORMATION, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, -1}; // Clear anything from previous enumerate... ResetPortList(); // First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName... DWORD dwGuids = 0; SetupDiClassGuidsFromName(_T("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) return FALSE; // Allocate the needed memory... CHeapPtr<GUID> GuidArray; GUID *pGuids = (GUID*)GuidArray.Allocate(sizeof(GUID) * dwGuids); if (pGuids==NULL) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } // Call the function again... if (!SetupDiClassGuidsFromName(_T("Ports"), pGuids, dwGuids, &dwGuids)) return FALSE; // Now create a "device information set" which is required to enumerate all the ports... HDEVINFO hDevInfoSet = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT); if (hDevInfoSet == INVALID_HANDLE_VALUE) return FALSE; // Finally do the enumeration... int nIndex = 0; SP_DEVINFO_DATA devInfo; CHeapPtr<TCHAR> tempstr(1000); CSerialPortInfo *portinfo = NULL; // Enumerate the current device... devInfo.cbSize = sizeof(SP_DEVINFO_DATA); while (SetupDiEnumDeviceInfo(hDevInfoSet, nIndex, &devInfo)) { portinfo = NULL; // Get the registry key which stores the ports settings... HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; // Read name of port. If formatted as "COMxx" then allocate a port slot... if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>((TCHAR*)tempstr), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ)) if (_tcslen(tempstr) > 3) if ((_tcsnicmp(tempstr, _T("COM"), 3) == 0) && IsNumber(&(tempstr[3]))) portinfo = AddPort(_ttoi(&(tempstr[3]))); // Close the key now that we are finished with it... RegCloseKey(hDeviceKey); } // If a serial port, then try getting additional useful descriptive info... if (portinfo) { for (int i=0; SPDRPlist[i]>=0; i++) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRPlist[i], &dwType, reinterpret_cast<PBYTE>((TCHAR*)tempstr), dwSize, &dwSize) && ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ))) switch (SPDRPlist[i]) { case SPDRP_MFG : portinfo->SetManufacturer(tempstr); break; case SPDRP_HARDWAREID : portinfo->SetHardwareID(tempstr); break; case SPDRP_DEVICEDESC : portinfo->SetDeviceDesc(tempstr); break; case SPDRP_FRIENDLYNAME : portinfo->SetFriendlyName(tempstr); break; case SPDRP_LOCATION_INFORMATION : portinfo->SetLocationInfo(tempstr); break; case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME : portinfo->SetPhysLocation(tempstr); break; } } // Get COM port properties... HANDLE hPort = ::CreateFile(portinfo->GetPortDeviceName(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hPort != INVALID_HANDLE_VALUE) { COMMPROP cp; GetCommProperties(hPort, &cp); portinfo->SetCommProp(cp); TRACE ("Port %d: CommProp: maxbaud=%08x settablebaud=%08x\n",portinfo->GetPortNum(),cp.dwMaxBaud,cp.dwSettableBaud); CloseHandle(hPort); } } ++nIndex; } // Free up the "device information set" now that we are finished with it SetupDiDestroyDeviceInfoList(hDevInfoSet); // Return the success indicator return TRUE; }
unsigned long COMPort::getMaximumBitRate() const { COMMPROP aProp; if ( !GetCommProperties ( (HANDLE)portHandle, &aProp ) ) { } return aProp.dwMaxBaud; }
int fb_SerialOpen( FB_FILE *handle, int iPort, FB_SERIAL_OPTIONS *options, const char *pszDevice, void **ppvHandle ) { DWORD dwDefaultTxBufferSize = 16384; DWORD dwDefaultRxBufferSize = 16384; DWORD dwDesiredAccess = 0; DWORD dwShareMode = 0; char *pszDev, *p; HANDLE hDevice; int res; /* The IRQ stuff is not supported on Windows ... */ if( options->IRQNumber!=0 ) return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); res = fb_ErrorSetNum( FB_RTERROR_OK ); switch( handle->access ) { case FB_FILE_ACCESS_READ: dwDesiredAccess = GENERIC_READ; break; case FB_FILE_ACCESS_WRITE: dwDesiredAccess = GENERIC_WRITE; break; case FB_FILE_ACCESS_READWRITE: case FB_FILE_ACCESS_ANY: dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; break; } switch( handle->lock ) { case FB_FILE_LOCK_SHARED: dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; break; case FB_FILE_LOCK_READ: dwShareMode = FILE_SHARE_WRITE; break; case FB_FILE_LOCK_WRITE: dwShareMode = FILE_SHARE_READ; break; case FB_FILE_LOCK_READWRITE: break; } /* Get device name without ":" */ pszDev = calloc(strlen( pszDevice ) + 5, 1); if( iPort == 0 ) { iPort = 1; strcpy( pszDev, "COM1:" ); } else { if( iPort > 9 ) strcpy(pszDev, "\\\\.\\"); else *pszDev = '\0'; strcat(pszDev, pszDevice); p = strchr( pszDev, ':'); if( p ) *p = '\0'; } #if 0 /* FIXME: Use default COM properties by default */ COMMCONFIG cc; if( !GetDefaultCommConfig( pszDev, &cc, &dwSizeCC ) ) { } #endif /* Open device */ hDevice = CreateFileA( pszDev, dwDesiredAccess, dwShareMode, NULL, OPEN_EXISTING, 0, NULL ); free( pszDev ); if( hDevice==INVALID_HANDLE_VALUE ) return fb_ErrorSetNum( FB_RTERROR_FILENOTFOUND ); /* Set rx/tx buffer sizes */ if( res==FB_RTERROR_OK ) { COMMPROP prop; if( !GetCommProperties( hDevice, &prop ) ) { res = fb_ErrorSetNum( FB_RTERROR_NOPRIVILEDGES ); } else { if( prop.dwCurrentTxQueue ) { dwDefaultTxBufferSize = prop.dwCurrentTxQueue; } else if( prop.dwMaxTxQueue ) { dwDefaultTxBufferSize = prop.dwMaxTxQueue; } if( prop.dwCurrentRxQueue ) { dwDefaultRxBufferSize = prop.dwCurrentRxQueue; } else if( prop.dwMaxRxQueue ) { dwDefaultRxBufferSize = prop.dwMaxRxQueue; } if( options->TransmitBuffer ) dwDefaultTxBufferSize = options->TransmitBuffer; if( options->ReceiveBuffer ) dwDefaultRxBufferSize = options->ReceiveBuffer; if( !SetupComm( hDevice, dwDefaultRxBufferSize, dwDefaultTxBufferSize ) ) { res = fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); } } } /* set timeouts */ if( res==FB_RTERROR_OK ) { COMMTIMEOUTS timeouts; if( !GetCommTimeouts( hDevice, &timeouts ) ) { res = fb_ErrorSetNum( FB_RTERROR_NOPRIVILEDGES ); } else { if( options->DurationCTS!=0 ) { timeouts.ReadIntervalTimeout = options->DurationCTS; timeouts.ReadTotalTimeoutMultiplier = timeouts.ReadTotalTimeoutConstant = 0; } if( !SetCommTimeouts( hDevice, &timeouts ) ) { res = fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); } } } /* setup generic COM port configuration */ if( res==FB_RTERROR_OK ) { DCB dcb; if( !GetCommState( hDevice, &dcb ) ) { res = fb_ErrorSetNum( FB_RTERROR_NOPRIVILEDGES ); } else { dcb.BaudRate = options->uiSpeed; dcb.fBinary = !options->AddLF; /* FIXME: Windows only supports binary mode */ dcb.fParity = options->CheckParity; dcb.fOutxCtsFlow = options->DurationCTS!=0; dcb.fDtrControl = ( (options->KeepDTREnabled) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE ); /* Not sure about this one ... */ dcb.fDsrSensitivity = options->DurationDSR!=0; dcb.fOutxDsrFlow = FALSE; /* No XON/XOFF */ dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fNull = FALSE; /* Not sure about this one ... */ dcb.fRtsControl = ( ( options->SuppressRTS ) ? RTS_CONTROL_DISABLE : RTS_CONTROL_HANDSHAKE ); dcb.fAbortOnError = FALSE; dcb.ByteSize = (BYTE) options->uiDataBits; switch ( options->Parity ) { case FB_SERIAL_PARITY_NONE: dcb.Parity = NOPARITY; break; case FB_SERIAL_PARITY_EVEN: dcb.Parity = EVENPARITY; break; case FB_SERIAL_PARITY_ODD: dcb.Parity = ODDPARITY; break; case FB_SERIAL_PARITY_SPACE: dcb.Parity = SPACEPARITY; break; case FB_SERIAL_PARITY_MARK: dcb.Parity = MARKPARITY; break; } switch ( options->StopBits ) { case FB_SERIAL_STOP_BITS_1: dcb.StopBits = ONESTOPBIT; break; case FB_SERIAL_STOP_BITS_1_5: dcb.StopBits = ONE5STOPBITS; break; case FB_SERIAL_STOP_BITS_2: dcb.StopBits = TWOSTOPBITS; break; } if( !SetCommState( hDevice, &dcb ) ) { res = fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); } else { EscapeCommFunction( hDevice, SETDTR ); } } } if( !fb_hSerialCheckLines( hDevice, options ) ) { res = fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); } if( res!=FB_RTERROR_OK ) { CloseHandle( hDevice ); } else { W32_SERIAL_INFO *pInfo = calloc( 1, sizeof(W32_SERIAL_INFO) ); DBG_ASSERT( ppvHandle!=NULL ); *ppvHandle = pInfo; pInfo->hDevice = hDevice; pInfo->iPort = iPort; pInfo->pOptions = options; } return res; }
/********************************************************************* * "COMXX:" ポートのプロパティを見る. ********************************************************************* */ void RS_printCommInfo(char *comXX) { BOOL rc; HANDLE com_handle; COMMPROP CommProp; printf("%s:",comXX); com_handle = CreateFile( comXX, /* シリアルポートの文字列 */ GENERIC_READ | GENERIC_WRITE , /* アクセスモード */ 0, NULL, /* セキュリティ属性 */ OPEN_EXISTING, /* 作成フラグ */ 0, /* 属性 */ NULL /* テンプレートのハンドル */ ); if( comHandle == INVALID_HANDLE_VALUE) { printf(" Can't Open ."); }else{ rc = GetCommProperties(com_handle,&CommProp); if(rc) { #if 0 DWORD dwMaxTxQueue; // バイト単位の最大送信バッファサイズ DWORD dwMaxRxQueue; // バイト単位の最大受信バッファサイズ DWORD dwMaxBaud; // ボーレート最大値 DWORD dwProvSubType; // 特定プロバイダータイプ DWORD dwProvCapabilities; // サポートされた関数 #endif printf("TxQue=%ld,RxQue=%ld,MaxBaud=%lx" ,CommProp.dwMaxTxQueue ,CommProp.dwMaxRxQueue ,CommProp.dwMaxBaud); } #if 0 static DCB com_dcb; memset(&com_dcb,0,sizeof(com_dcb)); com_dcb.DCBlength = sizeof(DCB); rc = GetCommState(comHandle,&com_dcb); // if(rc) { // com_dcb.BaudRate = baudrate; // com_dcb.ByteSize = 8; // com_dcb.Parity = NOPARITY; // com_dcb.StopBits = ONESTOPBIT; printf("Baud=%ld bits=%d parity=%d stop=%d" ,com_dcb.BaudRate ,com_dcb.ByteSize ,com_dcb.Parity ,com_dcb.StopBits ); } #endif CloseHandle(com_handle); } printf("\n"); }