#include <win_qextserialport.h>
Inheritance diagram for Win_QextSerialPort:
Public Types | |
EventDriven | |
Polling | |
enum | QueryMode { Polling, EventDriven } |
Signals | |
void | dsrChanged (bool status) |
Public Member Functions | |
aboutToClose () | |
atEnd () | |
virtual bool | atEnd () const |
virtual BaudRateType | baudRate () const |
virtual qint64 | bytesAvailable () |
bytesToWrite () | |
virtual qint64 | bytesToWrite () const |
bytesWritten (qint64 bytes) | |
canReadLine () | |
virtual void | close () |
virtual void | construct () |
virtual DataBitsType | dataBits () const |
errorString () | |
virtual FlowType | flowControl () const |
virtual void | flush () |
getChar (char *c) | |
isOpen () | |
isReadable () | |
isSequential () | |
virtual bool | isSequential () const |
isTextModeEnabled () | |
isWritable () | |
virtual ulong | lastError () const |
virtual ulong | lineStatus (void) |
virtual bool | open (OpenMode mode) |
openMode () | |
Win_QextSerialPort & | operator= (const Win_QextSerialPort &s) |
virtual ParityType | parity () const |
peek (qint64 maxSize) | |
peek (char *data, qint64 maxSize) | |
virtual QString | portName () const |
pos () | |
putChar (char c) | |
QextSerialBase::QueryMode | queryMode () const |
read (qint64 maxSize) | |
read (char *data, qint64 maxSize) | |
readAll () | |
readLine (qint64 maxSize=0) | |
virtual qint64 | readLine (char *data, qint64 maxSize) |
readLineData (char *data, qint64 maxSize) | |
readyRead () | |
reset () | |
seek (qint64 pos) | |
virtual void | setBaudRate (BaudRateType) |
virtual void | setDataBits (DataBitsType) |
virtual void | setDtr (bool set=true) |
setErrorString (const QString &str) | |
virtual void | setFlowControl (FlowType) |
setOpenMode (OpenMode openMode) | |
virtual void | setParity (ParityType) |
virtual void | setPortName (const QString &name) |
virtual void | setQueryMode (QueryMode mode) |
virtual void | setRts (bool set=true) |
virtual void | setStopBits (StopBitsType) |
setTextModeEnabled (bool enabled) | |
virtual void | setTimeout (ulong, ulong) |
size () | |
virtual qint64 | size () const |
virtual StopBitsType | stopBits () const |
virtual void | translateError (ulong) |
virtual void | ungetChar (char c) |
waitForBytesWritten (int msecs) | |
virtual bool | waitForReadyRead (int msecs) |
Win_QextSerialPort (const QString &name, const PortSettings &settings, QextSerialBase::QueryMode mode=QextSerialBase::Polling) | |
Win_QextSerialPort (const PortSettings &settings, QextSerialBase::QueryMode mode=QextSerialBase::Polling) | |
Win_QextSerialPort (const QString &name, QextSerialBase::QueryMode mode=QextSerialBase::Polling) | |
Win_QextSerialPort (Win_QextSerialPort const &s) | |
Win_QextSerialPort () | |
write (const QByteArray &byteArray) | |
write (const char *data, qint64 maxSize) | |
virtual | ~Win_QextSerialPort () |
Protected Member Functions | |
void | monitorCommEvent () |
virtual qint64 | readData (char *data, qint64 maxSize) |
void | terminateCommWait () |
virtual qint64 | writeData (const char *data, qint64 maxSize) |
Protected Attributes | |
qint64 | _bytesToWrite |
QextSerialBase::QueryMode | _queryMode |
QReadWriteLock * | bytesToWriteLock |
ulong | lastErr |
QMutex * | mutex |
OVERLAPPED | overlap |
Win_QextSerialThread * | overlapThread |
OVERLAPPED | overlapWrite |
QString | port |
PortSettings | Settings |
HANDLE | threadStartEvent |
HANDLE | threadTerminateEvent |
COMMCONFIG | Win_CommConfig |
COMMTIMEOUTS | Win_CommTimeouts |
HANDLE | Win_Handle |
Private Member Functions | |
void | init () |
Friends | |
class | Win_QextSerialThread |
Michal Policht
enum QextSerialBase::QueryMode [inherited] |
Win_QextSerialPort::Win_QextSerialPort | ( | ) |
Default constructor. Note that the name of the device used by a Win_QextSerialPort constructed with this constructor will be determined by defined constants, or lack thereof - the default behavior is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are:
Constant Used By Naming Convention ---------- ------------- ------------------------ _TTY_WIN_ Windows COM1, COM2 _TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2 _TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0 _TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb _TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02 _TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1 _TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1 <none> Linux /dev/ttyS0, /dev/ttyS1
This constructor associates the object with the first port on the system, e.g. COM1 for Windows platforms. See the other constructor if you need a port other than the first.
00033 : 00034 QextSerialBase() 00035 { 00036 Win_Handle=INVALID_HANDLE_VALUE; 00037 init(); 00038 }
Win_QextSerialPort::Win_QextSerialPort | ( | Win_QextSerialPort const & | s | ) |
Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort&) Copy constructor.
00043 : 00044 QextSerialBase(s.port) 00045 { 00046 Win_Handle=INVALID_HANDLE_VALUE; 00047 _queryMode = s._queryMode; 00048 _bytesToWrite = s._bytesToWrite; 00049 bytesToWriteLock = new QReadWriteLock; 00050 overlapThread = new Win_QextSerialThread(this); 00051 memcpy(& overlap, & s.overlap, sizeof(OVERLAPPED)); 00052 memcpy(& overlapWrite, & s.overlapWrite, sizeof(OVERLAPPED)); 00053 setOpenMode(s.openMode()); 00054 lastErr=s.lastErr; 00055 port = s.port; 00056 Settings.FlowControl=s.Settings.FlowControl; 00057 Settings.Parity=s.Settings.Parity; 00058 Settings.DataBits=s.Settings.DataBits; 00059 Settings.StopBits=s.Settings.StopBits; 00060 Settings.BaudRate=s.Settings.BaudRate; 00061 Win_Handle=s.Win_Handle; 00062 memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG)); 00063 memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS)); 00064 if (s.overlapThread->isRunning()) 00065 overlapThread->start(); 00066 }
Win_QextSerialPort::Win_QextSerialPort | ( | const QString & | name, | |
QextSerialBase::QueryMode | mode = QextSerialBase::Polling | |||
) |
00074 : 00075 QextSerialBase(name) 00076 { 00077 Win_Handle=INVALID_HANDLE_VALUE; 00078 setQueryMode(mode); 00079 init(); 00080 }
Win_QextSerialPort::Win_QextSerialPort | ( | const PortSettings & | settings, | |
QextSerialBase::QueryMode | mode = QextSerialBase::Polling | |||
) |
00086 { 00087 Win_Handle=INVALID_HANDLE_VALUE; 00088 setBaudRate(settings.BaudRate); 00089 setDataBits(settings.DataBits); 00090 setStopBits(settings.StopBits); 00091 setParity(settings.Parity); 00092 setFlowControl(settings.FlowControl); 00093 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); 00094 setQueryMode(mode); 00095 init(); 00096 }
Win_QextSerialPort::Win_QextSerialPort | ( | const QString & | name, | |
const PortSettings & | settings, | |||
QextSerialBase::QueryMode | mode = QextSerialBase::Polling | |||
) |
00102 { 00103 Win_Handle=INVALID_HANDLE_VALUE; 00104 setPortName(name); 00105 setBaudRate(settings.BaudRate); 00106 setDataBits(settings.DataBits); 00107 setStopBits(settings.StopBits); 00108 setParity(settings.Parity); 00109 setFlowControl(settings.FlowControl); 00110 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec); 00111 setQueryMode(mode); 00112 init(); 00113 }
Win_QextSerialPort::~Win_QextSerialPort | ( | ) | [virtual] |
Standard destructor.
00131 { 00132 if (isOpen()) { 00133 close(); 00134 } 00135 CloseHandle(overlap.hEvent); 00136 delete overlapThread; 00137 delete bytesToWriteLock; 00138 }
bool QextSerialBase::atEnd | ( | ) | const [virtual, inherited] |
This function will return true if the input buffer is empty (or on error), and false otherwise. Call QextSerialBase::lastError() for error information.
00164 { 00165 if (size()) { 00166 return true; 00167 } 00168 return false; 00169 }
BaudRateType QextSerialBase::baudRate | ( | void | ) | const [virtual, inherited] |
qint64 Win_QextSerialPort::bytesAvailable | ( | ) | [virtual] |
Returns the number of bytes waiting in the port's receive queue. This function will return 0 if the port is not currently open, or -1 on error. Error information can be retrieved by calling Win_QextSerialPort::getLastError().
Implements QextSerialBase.
00287 { 00288 LOCK_MUTEX(); 00289 if (isOpen()) { 00290 DWORD Errors; 00291 COMSTAT Status; 00292 bool success=ClearCommError(Win_Handle, &Errors, &Status); 00293 translateError(Errors); 00294 if (success) { 00295 lastErr=E_NO_ERROR; 00296 UNLOCK_MUTEX(); 00297 return Status.cbInQue + QIODevice::bytesAvailable(); 00298 } 00299 UNLOCK_MUTEX(); 00300 return (unsigned int)-1; 00301 } 00302 UNLOCK_MUTEX(); 00303 return 0; 00304 }
qint64 Win_QextSerialPort::bytesToWrite | ( | ) | const [virtual] |
Return number of bytes waiting in the buffer. Currently this shows number of bytes queued within write() and before the TX_EMPTY event occured. TX_EMPTY event is created whenever last character in the system buffer was sent.
00954 { 00955 return _bytesToWrite; 00956 }
void Win_QextSerialPort::close | ( | ) | [virtual] |
Closes a serial port. This function has no effect if the serial port associated with the class is not currently open.
Implements QextSerialBase.
00233 { 00234 LOCK_MUTEX(); 00235 00236 if (isOpen()) { 00237 flush(); 00238 if (overlapThread->isRunning()) { 00239 overlapThread->stop(); 00240 if (QThread::currentThread() != overlapThread) 00241 overlapThread->wait(); 00242 } 00243 if (CloseHandle(Win_Handle)) 00244 Win_Handle = INVALID_HANDLE_VALUE; 00245 _bytesToWrite = 0; 00246 QIODevice::close(); 00247 } 00248 00249 UNLOCK_MUTEX(); 00250 }
void QextSerialBase::construct | ( | ) | [virtual, inherited] |
Common constructor function for setting up default port settings. (115200 Baud, 8N1, Hardware flow control where supported, otherwise no flow control, and 0 ms timeout).
00062 { 00063 Settings.BaudRate=BAUD115200; 00064 Settings.DataBits=DATA_8; 00065 Settings.Parity=PAR_NONE; 00066 Settings.StopBits=STOP_1; 00067 Settings.FlowControl=FLOW_HARDWARE; 00068 Settings.Timeout_Sec=0; 00069 Settings.Timeout_Millisec=0; 00070 mutex = new QMutex( QMutex::Recursive ); 00071 setOpenMode(QIODevice::NotOpen); 00072 }
DataBitsType QextSerialBase::dataBits | ( | ) | const [virtual, inherited] |
void QextSerialBase::dsrChanged | ( | bool | status | ) | [signal, inherited] |
This signal is emitted whenever dsr line has changed its state. You may use this signal to check if device is connected.
status | true when DSR signal is on, false otherwise. |
FlowType QextSerialBase::flowControl | ( | ) | const [virtual, inherited] |
Returns the type of flow control used by the port. For a list of possible values returned by this function, see the definition of the enum FlowType.
00143 { 00144 return Settings.FlowControl; 00145 }
void Win_QextSerialPort::flush | ( | ) | [virtual] |
Flushes all pending I/O to the serial port. This function has no effect if the serial port associated with the class is not currently open.
Implements QextSerialBase.
00257 { 00258 LOCK_MUTEX(); 00259 if (isOpen()) { 00260 FlushFileBuffers(Win_Handle); 00261 } 00262 UNLOCK_MUTEX(); 00263 }
void Win_QextSerialPort::init | ( | ) | [private] |
This method is a part of constructor.
00116 { 00117 _bytesToWrite = 0; 00118 overlap.Internal = 0; 00119 overlap.InternalHigh = 0; 00120 overlap.Offset = 0; 00121 overlap.OffsetHigh = 0; 00122 overlap.hEvent = CreateEvent(NULL, true, false, NULL); 00123 overlapThread = new Win_QextSerialThread(this); 00124 bytesToWriteLock = new QReadWriteLock; 00125 }
bool QextSerialBase::isSequential | ( | ) | const [virtual, inherited] |
Returns true if device is sequential, otherwise returns false. Serial port is sequential device so this function always returns true. Check QIODevice::isSequential() documentation for more information.
ulong QextSerialBase::lastError | ( | ) | const [virtual, inherited] |
Returns the code for the last error encountered by the port, or E_NO_ERROR if the last port operation was successful. Possible error codes are:
Error Explanation --------------------------- ------------------------------------------------------------- E_NO_ERROR No Error has occured E_INVALID_FD Invalid file descriptor (port was not opened correctly) E_NO_MEMORY Unable to allocate memory tables (POSIX) E_CAUGHT_NON_BLOCKED_SIGNAL Caught a non-blocked signal (POSIX) E_PORT_TIMEOUT Operation timed out (POSIX) E_INVALID_DEVICE The file opened by the port is not a character device (POSIX) E_BREAK_CONDITION The port detected a break condition E_FRAMING_ERROR The port detected a framing error (usually caused by incorrect baud rate settings) E_IO_ERROR There was an I/O error while communicating with the port E_BUFFER_OVERRUN Character buffer overrun E_RECEIVE_OVERFLOW Receive buffer overflow E_RECEIVE_PARITY_ERROR The port detected a parity error in the received data E_TRANSMIT_OVERFLOW Transmit buffer overflow E_READ_FAILED General read operation failure E_WRITE_FAILED General write operation failure
00225 { 00226 return lastErr; 00227 }
ulong Win_QextSerialPort::lineStatus | ( | void | ) | [virtual] |
returns the line status as stored by the port function. This function will retrieve the states of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned long with specific bits indicating which lines are high. The following constants should be used to examine the states of individual lines:
Mask Line ------ ---- LS_CTS CTS LS_DSR DSR LS_DCD DCD LS_RI RI
This function will return 0 if the port associated with the class is not currently open.
Implements QextSerialBase.
00925 { 00926 unsigned long Status=0, Temp=0; 00927 LOCK_MUTEX(); 00928 if (isOpen()) { 00929 GetCommModemStatus(Win_Handle, &Temp); 00930 if (Temp&MS_CTS_ON) { 00931 Status|=LS_CTS; 00932 } 00933 if (Temp&MS_DSR_ON) { 00934 Status|=LS_DSR; 00935 } 00936 if (Temp&MS_RING_ON) { 00937 Status|=LS_RI; 00938 } 00939 if (Temp&MS_RLSD_ON) { 00940 Status|=LS_DCD; 00941 } 00942 } 00943 UNLOCK_MUTEX(); 00944 return Status; 00945 }
void Win_QextSerialPort::monitorCommEvent | ( | ) | [protected] |
00959 { 00960 DWORD eventMask = 0; 00961 00962 ResetEvent(overlap.hEvent); 00963 if (!WaitCommEvent(Win_Handle, & eventMask, & overlap)) 00964 if (GetLastError() != ERROR_IO_PENDING) 00965 qCritical("WaitCommEvent error %ld\n", GetLastError()); 00966 00967 if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0) { 00968 //overlap event occured 00969 DWORD undefined; 00970 if (!GetOverlappedResult(Win_Handle, & overlap, & undefined, false)) { 00971 qWarning("Comm event overlapped error %ld", GetLastError()); 00972 return; 00973 } 00974 if (eventMask & EV_RXCHAR) { 00975 if (sender() != this) 00976 emit readyRead(); 00977 } 00978 if (eventMask & EV_TXEMPTY) { 00979 DWORD numBytes; 00980 GetOverlappedResult(Win_Handle, & overlapWrite, & numBytes, true); 00981 bytesToWriteLock->lockForWrite(); 00982 if (sender() != this) 00983 emit bytesWritten(bytesToWrite()); 00984 _bytesToWrite = 0; 00985 bytesToWriteLock->unlock(); 00986 } 00987 if (eventMask & EV_DSR) 00988 if (lineStatus() & LS_DSR) 00989 emit dsrChanged(true); 00990 else 00991 emit dsrChanged(false); 00992 } 00993 }
bool Win_QextSerialPort::open | ( | OpenMode | mode | ) | [virtual] |
Opens a serial port. Note that this function does not specify which device to open. If you need to open a device by name, see Win_QextSerialPort::open(const char*). This function has no effect if the port associated with the class is already open. The port is also configured to the current settings, as stored in the Settings structure.
Implements QextSerialBase.
00175 { 00176 unsigned long confSize = sizeof(COMMCONFIG); 00177 Win_CommConfig.dwSize = confSize; 00178 DWORD dwFlagsAndAttributes = 0; 00179 if (queryMode() == QextSerialBase::EventDriven) 00180 dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; 00181 00182 LOCK_MUTEX(); 00183 if (mode == QIODevice::NotOpen) 00184 return isOpen(); 00185 if (!isOpen()) { 00186 /*open the port*/ 00187 Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE, 00188 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL); 00189 if (Win_Handle!=INVALID_HANDLE_VALUE) { 00190 /*configure port settings*/ 00191 GetCommConfig(Win_Handle, &Win_CommConfig, &confSize); 00192 GetCommState(Win_Handle, &(Win_CommConfig.dcb)); 00193 00194 /*set up parameters*/ 00195 Win_CommConfig.dcb.fBinary=TRUE; 00196 Win_CommConfig.dcb.fInX=FALSE; 00197 Win_CommConfig.dcb.fOutX=FALSE; 00198 Win_CommConfig.dcb.fAbortOnError=FALSE; 00199 Win_CommConfig.dcb.fNull=FALSE; 00200 setBaudRate(Settings.BaudRate); 00201 setDataBits(Settings.DataBits); 00202 setStopBits(Settings.StopBits); 00203 setParity(Settings.Parity); 00204 setFlowControl(Settings.FlowControl); 00205 setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec); 00206 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00207 00208 //init event driven approach 00209 if (queryMode() == QextSerialBase::EventDriven) { 00210 if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) { 00211 qWarning("Failed to set Comm Mask. Error code: %ld", GetLastError()); 00212 UNLOCK_MUTEX(); 00213 return false; 00214 } 00215 overlapThread->start(); 00216 } 00217 QIODevice::open(mode); 00218 } 00219 } else { 00220 UNLOCK_MUTEX(); 00221 return false; 00222 } 00223 UNLOCK_MUTEX(); 00224 return isOpen(); 00225 }
Win_QextSerialPort & Win_QextSerialPort::operator= | ( | const Win_QextSerialPort & | s | ) |
overrides the = operator
00144 { 00145 setOpenMode(s.openMode()); 00146 _queryMode = s._queryMode; 00147 _bytesToWrite = s._bytesToWrite; 00148 bytesToWriteLock = new QReadWriteLock; 00149 overlapThread = new Win_QextSerialThread(this); 00150 memcpy(& overlap, & s.overlap, sizeof(OVERLAPPED)); 00151 memcpy(& overlapWrite, & s.overlapWrite, sizeof(OVERLAPPED)); 00152 lastErr=s.lastErr; 00153 port = s.port; 00154 Settings.FlowControl=s.Settings.FlowControl; 00155 Settings.Parity=s.Settings.Parity; 00156 Settings.DataBits=s.Settings.DataBits; 00157 Settings.StopBits=s.Settings.StopBits; 00158 Settings.BaudRate=s.Settings.BaudRate; 00159 Win_Handle=s.Win_Handle; 00160 memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG)); 00161 memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS)); 00162 if (s.overlapThread->isRunning()) 00163 overlapThread->start(); 00164 return *this; 00165 }
ParityType QextSerialBase::parity | ( | ) | const [virtual, inherited] |
QString QextSerialBase::portName | ( | ) | const [virtual, inherited] |
QextSerialBase::QueryMode QextSerialBase::queryMode | ( | ) | const [inline, inherited] |
qint64 Win_QextSerialPort::readData | ( | char * | data, | |
qint64 | maxSize | |||
) | [protected, virtual] |
Reads a block of data from the serial port. This function will read at most maxlen bytes from the serial port and place them in the buffer pointed to by data. Return value is the number of bytes actually read, or -1 on error.
Implements QextSerialBase.
00347 { 00348 DWORD retVal; 00349 00350 LOCK_MUTEX(); 00351 00352 retVal = 0; 00353 if (queryMode() == QextSerialBase::EventDriven) { 00354 COMSTAT Win_ComStat; 00355 DWORD Win_ErrorMask = 0; 00356 OVERLAPPED overlapRead; 00357 overlapRead.Internal = 0; 00358 overlapRead.InternalHigh = 0; 00359 overlapRead.Offset = 0; 00360 overlapRead.OffsetHigh = 0; 00361 overlapRead.hEvent = CreateEvent(NULL, true, false, NULL); 00362 ClearCommError(Win_Handle, & Win_ErrorMask, & Win_ComStat); 00363 //actually in overlapped mode maxSize acts as minSize... 00364 maxSize = qMin((qint64)Win_ComStat.cbInQue, maxSize); 00365 if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapRead)) { 00366 if (GetLastError() == ERROR_IO_PENDING) 00367 GetOverlappedResult(Win_Handle, & overlapRead, & retVal, true); 00368 else { 00369 lastErr = E_READ_FAILED; 00370 retVal = (DWORD)-1; 00371 } 00372 } 00373 CloseHandle(overlapRead.hEvent); 00374 } else if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) { 00375 lastErr = E_READ_FAILED; 00376 retVal = (DWORD)-1; 00377 } 00378 00379 UNLOCK_MUTEX(); 00380 00381 return (qint64)retVal; 00382 }
qint64 QextSerialBase::readLine | ( | char * | data, | |
qint64 | maxSize | |||
) | [virtual, inherited] |
This function will read a line of buffered input from the port, stopping when either maxSize bytes have been read, the port has no more data available, or a newline is encountered. The value returned is the length of the string that was read.
Reimplemented from QIODevice.
00178 { 00179 qint64 numBytes = bytesAvailable(); 00180 char* pData = data; 00181 00182 if (maxSize < 2) //maxSize must be larger than 1 00183 return -1; 00184 00185 /*read a byte at a time for MIN(bytesAvail, maxSize - 1) iterations, or until a newline*/ 00186 while (pData<(data+numBytes) && --maxSize) { 00187 readData(pData, 1); 00188 if (*pData++ == '\n') { 00189 break; 00190 } 00191 } 00192 *pData='\0'; 00193 00194 /*return size of data read*/ 00195 return (pData-data); 00196 }
void Win_QextSerialPort::setBaudRate | ( | BaudRateType | baudRate | ) | [virtual] |
Sets the baud rate of the serial port. Note that not all rates are applicable on all platforms. The following table shows translations of the various baud rate constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an * are speeds that are usable on both Windows and POSIX.
RATE Windows Speed POSIX Speed ----------- ------------- ----------- BAUD50 110 50 BAUD75 110 75 *BAUD110 110 110 BAUD134 110 134.5 BAUD150 110 150 BAUD200 110 200 *BAUD300 300 300 *BAUD600 600 600 *BAUD1200 1200 1200 BAUD1800 1200 1800 *BAUD2400 2400 2400 *BAUD4800 4800 4800 *BAUD9600 9600 9600 BAUD14400 14400 9600 *BAUD19200 19200 19200 *BAUD38400 38400 38400 BAUD56000 56000 38400 *BAUD57600 57600 57600 BAUD76800 57600 76800 *BAUD115200 115200 115200 BAUD128000 128000 115200 BAUD256000 256000 115200
Implements QextSerialBase.
00716 { 00717 LOCK_MUTEX(); 00718 if (Settings.BaudRate!=baudRate) { 00719 switch (baudRate) { 00720 case BAUD50: 00721 case BAUD75: 00722 case BAUD134: 00723 case BAUD150: 00724 case BAUD200: 00725 Settings.BaudRate=BAUD110; 00726 break; 00727 00728 case BAUD1800: 00729 Settings.BaudRate=BAUD1200; 00730 break; 00731 00732 case BAUD76800: 00733 Settings.BaudRate=BAUD57600; 00734 break; 00735 00736 default: 00737 Settings.BaudRate=baudRate; 00738 break; 00739 } 00740 } 00741 if (isOpen()) { 00742 switch (baudRate) { 00743 00744 /*50 baud*/ 00745 case BAUD50: 00746 TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation. Switching to 110 baud."); 00747 Win_CommConfig.dcb.BaudRate=CBR_110; 00748 break; 00749 00750 /*75 baud*/ 00751 case BAUD75: 00752 TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation. Switching to 110 baud."); 00753 Win_CommConfig.dcb.BaudRate=CBR_110; 00754 break; 00755 00756 /*110 baud*/ 00757 case BAUD110: 00758 Win_CommConfig.dcb.BaudRate=CBR_110; 00759 break; 00760 00761 /*134.5 baud*/ 00762 case BAUD134: 00763 TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation. Switching to 110 baud."); 00764 Win_CommConfig.dcb.BaudRate=CBR_110; 00765 break; 00766 00767 /*150 baud*/ 00768 case BAUD150: 00769 TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation. Switching to 110 baud."); 00770 Win_CommConfig.dcb.BaudRate=CBR_110; 00771 break; 00772 00773 /*200 baud*/ 00774 case BAUD200: 00775 TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation. Switching to 110 baud."); 00776 Win_CommConfig.dcb.BaudRate=CBR_110; 00777 break; 00778 00779 /*300 baud*/ 00780 case BAUD300: 00781 Win_CommConfig.dcb.BaudRate=CBR_300; 00782 break; 00783 00784 /*600 baud*/ 00785 case BAUD600: 00786 Win_CommConfig.dcb.BaudRate=CBR_600; 00787 break; 00788 00789 /*1200 baud*/ 00790 case BAUD1200: 00791 Win_CommConfig.dcb.BaudRate=CBR_1200; 00792 break; 00793 00794 /*1800 baud*/ 00795 case BAUD1800: 00796 TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation. Switching to 1200 baud."); 00797 Win_CommConfig.dcb.BaudRate=CBR_1200; 00798 break; 00799 00800 /*2400 baud*/ 00801 case BAUD2400: 00802 Win_CommConfig.dcb.BaudRate=CBR_2400; 00803 break; 00804 00805 /*4800 baud*/ 00806 case BAUD4800: 00807 Win_CommConfig.dcb.BaudRate=CBR_4800; 00808 break; 00809 00810 /*9600 baud*/ 00811 case BAUD9600: 00812 Win_CommConfig.dcb.BaudRate=CBR_9600; 00813 break; 00814 00815 /*14400 baud*/ 00816 case BAUD14400: 00817 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation."); 00818 Win_CommConfig.dcb.BaudRate=CBR_14400; 00819 break; 00820 00821 /*19200 baud*/ 00822 case BAUD19200: 00823 Win_CommConfig.dcb.BaudRate=CBR_19200; 00824 break; 00825 00826 /*38400 baud*/ 00827 case BAUD38400: 00828 Win_CommConfig.dcb.BaudRate=CBR_38400; 00829 break; 00830 00831 /*56000 baud*/ 00832 case BAUD56000: 00833 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation."); 00834 Win_CommConfig.dcb.BaudRate=CBR_56000; 00835 break; 00836 00837 /*57600 baud*/ 00838 case BAUD57600: 00839 Win_CommConfig.dcb.BaudRate=CBR_57600; 00840 break; 00841 00842 /*76800 baud*/ 00843 case BAUD76800: 00844 TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation. Switching to 57600 baud."); 00845 Win_CommConfig.dcb.BaudRate=CBR_57600; 00846 break; 00847 00848 /*115200 baud*/ 00849 case BAUD115200: 00850 Win_CommConfig.dcb.BaudRate=CBR_115200; 00851 break; 00852 00853 /*128000 baud*/ 00854 case BAUD128000: 00855 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation."); 00856 Win_CommConfig.dcb.BaudRate=CBR_128000; 00857 break; 00858 00859 /*256000 baud*/ 00860 case BAUD256000: 00861 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation."); 00862 Win_CommConfig.dcb.BaudRate=CBR_256000; 00863 break; 00864 } 00865 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00866 } 00867 UNLOCK_MUTEX(); 00868 }
void Win_QextSerialPort::setDataBits | ( | DataBitsType | dataBits | ) | [virtual] |
Sets the number of data bits used by the serial port. Possible values of dataBits are:
DATA_5 5 data bits DATA_6 6 data bits DATA_7 7 data bits DATA_8 8 data bits
Implements QextSerialBase.
00557 { 00558 LOCK_MUTEX(); 00559 if (Settings.DataBits!=dataBits) { 00560 if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) || 00561 (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) { 00562 } 00563 else { 00564 Settings.DataBits=dataBits; 00565 } 00566 } 00567 if (isOpen()) { 00568 switch(dataBits) { 00569 00570 /*5 data bits*/ 00571 case DATA_5: 00572 if (Settings.StopBits==STOP_2) { 00573 TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); 00574 } 00575 else { 00576 Win_CommConfig.dcb.ByteSize=5; 00577 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00578 } 00579 break; 00580 00581 /*6 data bits*/ 00582 case DATA_6: 00583 if (Settings.StopBits==STOP_1_5) { 00584 TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); 00585 } 00586 else { 00587 Win_CommConfig.dcb.ByteSize=6; 00588 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00589 } 00590 break; 00591 00592 /*7 data bits*/ 00593 case DATA_7: 00594 if (Settings.StopBits==STOP_1_5) { 00595 TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); 00596 } 00597 else { 00598 Win_CommConfig.dcb.ByteSize=7; 00599 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00600 } 00601 break; 00602 00603 /*8 data bits*/ 00604 case DATA_8: 00605 if (Settings.StopBits==STOP_1_5) { 00606 TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); 00607 } 00608 else { 00609 Win_CommConfig.dcb.ByteSize=8; 00610 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00611 } 00612 break; 00613 } 00614 } 00615 UNLOCK_MUTEX(); 00616 }
void Win_QextSerialPort::setDtr | ( | bool | set = true |
) | [virtual] |
Sets DTR line to the requested state (high by default). This function will have no effect if the port associated with the class is not currently open.
Implements QextSerialBase.
00875 { 00876 LOCK_MUTEX(); 00877 if (isOpen()) { 00878 if (set) { 00879 EscapeCommFunction(Win_Handle, SETDTR); 00880 } 00881 else { 00882 EscapeCommFunction(Win_Handle, CLRDTR); 00883 } 00884 } 00885 UNLOCK_MUTEX(); 00886 }
void Win_QextSerialPort::setFlowControl | ( | FlowType | flow | ) | [virtual] |
Sets the flow control used by the port. Possible values of flow are:
FLOW_OFF No flow control FLOW_HARDWARE Hardware (RTS/CTS) flow control FLOW_XONXOFF Software (XON/XOFF) flow control
Implements QextSerialBase.
00445 { 00446 LOCK_MUTEX(); 00447 if (Settings.FlowControl!=flow) { 00448 Settings.FlowControl=flow; 00449 } 00450 if (isOpen()) { 00451 switch(flow) { 00452 00453 /*no flow control*/ 00454 case FLOW_OFF: 00455 Win_CommConfig.dcb.fOutxCtsFlow=FALSE; 00456 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE; 00457 Win_CommConfig.dcb.fInX=FALSE; 00458 Win_CommConfig.dcb.fOutX=FALSE; 00459 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00460 break; 00461 00462 /*software (XON/XOFF) flow control*/ 00463 case FLOW_XONXOFF: 00464 Win_CommConfig.dcb.fOutxCtsFlow=FALSE; 00465 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE; 00466 Win_CommConfig.dcb.fInX=TRUE; 00467 Win_CommConfig.dcb.fOutX=TRUE; 00468 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00469 break; 00470 00471 case FLOW_HARDWARE: 00472 Win_CommConfig.dcb.fOutxCtsFlow=TRUE; 00473 Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE; 00474 Win_CommConfig.dcb.fInX=FALSE; 00475 Win_CommConfig.dcb.fOutX=FALSE; 00476 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00477 break; 00478 } 00479 } 00480 UNLOCK_MUTEX(); 00481 }
void Win_QextSerialPort::setParity | ( | ParityType | parity | ) | [virtual] |
Sets the parity associated with the serial port. The possible values of parity are:
PAR_SPACE Space Parity PAR_MARK Mark Parity PAR_NONE No Parity PAR_EVEN Even Parity PAR_ODD Odd Parity
Implements QextSerialBase.
00494 { 00495 LOCK_MUTEX(); 00496 if (Settings.Parity!=parity) { 00497 Settings.Parity=parity; 00498 } 00499 if (isOpen()) { 00500 Win_CommConfig.dcb.Parity=(unsigned char)parity; 00501 switch (parity) { 00502 00503 /*space parity*/ 00504 case PAR_SPACE: 00505 if (Settings.DataBits==DATA_8) { 00506 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems."); 00507 } 00508 Win_CommConfig.dcb.fParity=TRUE; 00509 break; 00510 00511 /*mark parity - WINDOWS ONLY*/ 00512 case PAR_MARK: 00513 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems"); 00514 Win_CommConfig.dcb.fParity=TRUE; 00515 break; 00516 00517 /*no parity*/ 00518 case PAR_NONE: 00519 Win_CommConfig.dcb.fParity=FALSE; 00520 break; 00521 00522 /*even parity*/ 00523 case PAR_EVEN: 00524 Win_CommConfig.dcb.fParity=TRUE; 00525 break; 00526 00527 /*odd parity*/ 00528 case PAR_ODD: 00529 Win_CommConfig.dcb.fParity=TRUE; 00530 break; 00531 } 00532 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00533 } 00534 UNLOCK_MUTEX(); 00535 }
void QextSerialBase::setPortName | ( | const QString & | name | ) | [virtual, inherited] |
Sets the name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0".
00084 { 00085 port = name; 00086 }
void QextSerialBase::setQueryMode | ( | QueryMode | mode | ) | [virtual, inherited] |
Set desired serial communication handling style. You may choose from polling or event driven approach. This function does nothing when port is open; to apply changes port must be reopened.
In event driven approach read() and write() functions are acting asynchronously. They return immediately and the operation is performed in the background, so they doesn't freeze the calling thread. To determine when operation is finished, QextSerialPort runs separate thread and monitors serial port events. Whenever the event occurs, adequate signal is emitted.
When polling is set, read() and write() are acting synchronously. Signals are not working in this mode and some functions may not be available. The advantage of polling is that it generates less overhead due to lack of signals emissions and it doesn't start separate thread to monitor events.
Generally event driven approach is more capable and friendly, although some applications may need as low overhead as possible and then polling comes.
mode | query mode. |
00075 { 00076 _queryMode = mechanism; 00077 }
void Win_QextSerialPort::setRts | ( | bool | set = true |
) | [virtual] |
Sets RTS line to the requested state (high by default). This function will have no effect if the port associated with the class is not currently open.
Implements QextSerialBase.
00893 { 00894 LOCK_MUTEX(); 00895 if (isOpen()) { 00896 if (set) { 00897 EscapeCommFunction(Win_Handle, SETRTS); 00898 } 00899 else { 00900 EscapeCommFunction(Win_Handle, CLRRTS); 00901 } 00902 } 00903 UNLOCK_MUTEX(); 00904 }
void Win_QextSerialPort::setStopBits | ( | StopBitsType | stopBits | ) | [virtual] |
Sets the number of stop bits used by the serial port. Possible values of stopBits are:
STOP_1 1 stop bit STOP_1_5 1.5 stop bits STOP_2 2 stop bits
Implements QextSerialBase.
00636 { 00637 LOCK_MUTEX(); 00638 if (Settings.StopBits!=stopBits) { 00639 if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || 00640 (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) { 00641 } 00642 else { 00643 Settings.StopBits=stopBits; 00644 } 00645 } 00646 if (isOpen()) { 00647 switch (stopBits) { 00648 00649 /*one stop bit*/ 00650 case STOP_1: 00651 Win_CommConfig.dcb.StopBits=ONESTOPBIT; 00652 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00653 break; 00654 00655 /*1.5 stop bits*/ 00656 case STOP_1_5: 00657 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX."); 00658 if (Settings.DataBits!=DATA_5) { 00659 TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits"); 00660 } 00661 else { 00662 Win_CommConfig.dcb.StopBits=ONE5STOPBITS; 00663 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00664 } 00665 break; 00666 00667 /*two stop bits*/ 00668 case STOP_2: 00669 if (Settings.DataBits==DATA_5) { 00670 TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits"); 00671 } 00672 else { 00673 Win_CommConfig.dcb.StopBits=TWOSTOPBITS; 00674 SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); 00675 } 00676 break; 00677 } 00678 } 00679 UNLOCK_MUTEX(); 00680 }
void Win_QextSerialPort::setTimeout | ( | ulong | sec, | |
ulong | millisec | |||
) | [virtual] |
Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
Implements QextSerialBase.
01005 { 01006 LOCK_MUTEX(); 01007 Settings.Timeout_Sec=sec; 01008 Settings.Timeout_Millisec=millisec; 01009 if(isOpen()) { 01010 Win_CommTimeouts.ReadIntervalTimeout = sec*1000+millisec; 01011 Win_CommTimeouts.ReadTotalTimeoutMultiplier = sec*1000+millisec; 01012 Win_CommTimeouts.ReadTotalTimeoutConstant = 0; 01013 Win_CommTimeouts.WriteTotalTimeoutMultiplier = sec*1000+millisec; 01014 Win_CommTimeouts.WriteTotalTimeoutConstant = 0; 01015 SetCommTimeouts(Win_Handle, &Win_CommTimeouts); 01016 } 01017 UNLOCK_MUTEX(); 01018 }
qint64 Win_QextSerialPort::size | ( | ) | const [virtual] |
This function will return the number of bytes waiting in the receive queue of the serial port. It is included primarily to provide a complete QIODevice interface, and will not record errors in the lastErr member (because it is const). This function is also not thread-safe - in multithreading situations, use Win_QextSerialPort::bytesAvailable() instead.
Implements QextSerialBase.
00272 { 00273 int availBytes; 00274 COMSTAT Win_ComStat; 00275 DWORD Win_ErrorMask=0; 00276 ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat); 00277 availBytes = Win_ComStat.cbInQue; 00278 return (qint64)availBytes; 00279 }
StopBitsType QextSerialBase::stopBits | ( | ) | const [virtual, inherited] |
void Win_QextSerialPort::terminateCommWait | ( | ) | [protected] |
void Win_QextSerialPort::translateError | ( | ulong | error | ) | [virtual] |
Translates a system-specific error code to a QextSerialPort error code. Used internally.
Implements QextSerialBase.
00310 { 00311 if (error&CE_BREAK) { 00312 lastErr=E_BREAK_CONDITION; 00313 } 00314 else if (error&CE_FRAME) { 00315 lastErr=E_FRAMING_ERROR; 00316 } 00317 else if (error&CE_IOE) { 00318 lastErr=E_IO_ERROR; 00319 } 00320 else if (error&CE_MODE) { 00321 lastErr=E_INVALID_FD; 00322 } 00323 else if (error&CE_OVERRUN) { 00324 lastErr=E_BUFFER_OVERRUN; 00325 } 00326 else if (error&CE_RXPARITY) { 00327 lastErr=E_RECEIVE_PARITY_ERROR; 00328 } 00329 else if (error&CE_RXOVER) { 00330 lastErr=E_RECEIVE_OVERFLOW; 00331 } 00332 else if (error&CE_TXFULL) { 00333 lastErr=E_TRANSMIT_OVERFLOW; 00334 } 00335 }
void Win_QextSerialPort::ungetChar | ( | char | c | ) | [virtual] |
This function is included to implement the full QIODevice interface, and currently has no purpose within this class. This function is meaningless on an unbuffered device and currently only prints a warning message to that effect.
Implements QextSerialBase.
00430 { 00431 00432 /*meaningless on unbuffered sequential device - return error and print a warning*/ 00433 TTY_WARNING("Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless"); 00434 }
bool Win_QextSerialPort::waitForReadyRead | ( | int | msecs | ) | [virtual] |
qint64 Win_QextSerialPort::writeData | ( | const char * | data, | |
qint64 | maxSize | |||
) | [protected, virtual] |
Writes a block of data to the serial port. This function will write len bytes from the buffer pointed to by data to the serial port. Return value is the number of bytes actually written, or -1 on error.
Implements QextSerialBase.
00394 { 00395 DWORD retVal; 00396 00397 LOCK_MUTEX(); 00398 00399 retVal = 0; 00400 if (queryMode() == QextSerialBase::EventDriven) { 00401 bytesToWriteLock->lockForWrite(); 00402 _bytesToWrite += maxSize; 00403 bytesToWriteLock->unlock(); 00404 overlapWrite.Internal = 0; 00405 overlapWrite.InternalHigh = 0; 00406 overlapWrite.Offset = 0; 00407 overlapWrite.OffsetHigh = 0; 00408 overlapWrite.hEvent = CreateEvent(NULL, true, false, NULL); 00409 if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapWrite)) { 00410 lastErr = E_WRITE_FAILED; 00411 retVal = (DWORD)-1; 00412 } else 00413 retVal = maxSize; 00414 } else if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) { 00415 lastErr = E_WRITE_FAILED; 00416 retVal = (DWORD)-1; 00417 } 00418 00419 UNLOCK_MUTEX(); 00420 00421 return (qint64)retVal; 00422 }
friend class Win_QextSerialThread [friend] |
qint64 Win_QextSerialPort::_bytesToWrite [protected] |
QextSerialBase::QueryMode QextSerialBase::_queryMode [protected, inherited] |
QReadWriteLock* Win_QextSerialPort::bytesToWriteLock [protected] |
ulong QextSerialBase::lastErr [protected, inherited] |
QMutex* QextSerialBase::mutex [protected, inherited] |
OVERLAPPED Win_QextSerialPort::overlap [protected] |
Win_QextSerialThread* Win_QextSerialPort::overlapThread [protected] |
OVERLAPPED Win_QextSerialPort::overlapWrite [protected] |
QString QextSerialBase::port [protected, inherited] |
PortSettings QextSerialBase::Settings [protected, inherited] |
HANDLE Win_QextSerialPort::threadStartEvent [protected] |
HANDLE Win_QextSerialPort::threadTerminateEvent [protected] |
COMMCONFIG Win_QextSerialPort::Win_CommConfig [protected] |
COMMTIMEOUTS Win_QextSerialPort::Win_CommTimeouts [protected] |
HANDLE Win_QextSerialPort::Win_Handle [protected] |