1 /*!
2 \class Win_QextSerialPort
3 \version 1.0.0
4 \author Stefan Sander
5
6 A cross-platform serial port class.
7 This class encapsulates the Windows portion of QextSerialPort. The user will be notified of
8 errors and possible portability conflicts at run-time by default - this behavior can be turned
9 off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off
10 portability warnings) in the project. Note that defining _TTY_NOWARN_ also defines
11 _TTY_NOWARN_PORT_.
12
13 \note
14 On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may
15 select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can
16 make no guarantees as to the quality of POSIX support under NT/2000 however.
17
18 */
19
20 #include <stdio.h>
21 #include "win_qextserialport.h"
22
23 /*!
24 \fn Win_QextSerialPort::Win_QextSerialPort()
25 Default constructor. Note that the name of the device used by a Win_QextSerialPort constructed
26 with this constructor will be determined by #defined constants, or lack thereof - the default
27 behavior is the same as _TTY_LINUX_. Possible naming conventions and their associated constants
28 are:
29
30 \verbatim
31
32 Constant Used By Naming Convention
33 ---------- ------------- ------------------------
34 _TTY_WIN_ Windows COM1, COM2
35 _TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2
36 _TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0
37 _TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb
38 _TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02
39 _TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1
40 _TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1
41 <none> Linux /dev/ttyS0, /dev/ttyS1
42 \endverbatim
43
44 This constructor associates the object with the first port on the system, e.g. COM1 for Windows
45 platforms. See the other constructor if you need a port other than the first.
46 */
Win_QextSerialPort()47 Win_QextSerialPort::Win_QextSerialPort():QextSerialBase() {
48 Win_Handle=INVALID_HANDLE_VALUE;
49 }
50
51 /*!Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort&)
52 Copy constructor.
53 */
Win_QextSerialPort(const Win_QextSerialPort & s)54 Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort& s):QextSerialBase(s.port) {
55 Win_Handle=INVALID_HANDLE_VALUE;
56 setOpenMode(s.openMode());
57 lastErr=s.lastErr;
58 port = s.port;
59 Settings.FlowControl=s.Settings.FlowControl;
60 Settings.Parity=s.Settings.Parity;
61 Settings.DataBits=s.Settings.DataBits;
62 Settings.StopBits=s.Settings.StopBits;
63 Settings.BaudRate=s.Settings.BaudRate;
64 Win_Handle=s.Win_Handle;
65 memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));
66 memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
67 }
68
69 /*!
70 \fn Win_QextSerialPort::Win_QextSerialPort(const QString & name)
71 Constructs a serial port attached to the port specified by devName.
72 devName is the name of the device, which is windowsystem-specific,
73 e.g."COM2" or "/dev/ttyS0".
74 */
Win_QextSerialPort(const QString & name)75 Win_QextSerialPort::Win_QextSerialPort(const QString & name):QextSerialBase(name) {
76 Win_Handle=INVALID_HANDLE_VALUE;
77 }
78
79 /*!
80 \fn Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings)
81 Constructs a port with default name and specified settings.
82 */
Win_QextSerialPort(const PortSettings & settings)83 Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings) {
84 Win_Handle=INVALID_HANDLE_VALUE;
85 setBaudRate(settings.BaudRate);
86 setDataBits(settings.DataBits);
87 setStopBits(settings.StopBits);
88 setParity(settings.Parity);
89 setFlowControl(settings.FlowControl);
90 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
91 }
92
93 /*!
94 \fn Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings)
95 Constructs a port with specified name and settings.
96 */
Win_QextSerialPort(const QString & name,const PortSettings & settings)97 Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings) {
98 Win_Handle=INVALID_HANDLE_VALUE;
99 setPortName(name);
100 setBaudRate(settings.BaudRate);
101 setDataBits(settings.DataBits);
102 setStopBits(settings.StopBits);
103 setParity(settings.Parity);
104 setFlowControl(settings.FlowControl);
105 setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
106 }
107
108 /*!
109 \fn Win_QextSerialPort::~Win_QextSerialPort()
110 Standard destructor.
111 */
~Win_QextSerialPort()112 Win_QextSerialPort::~Win_QextSerialPort() {
113 if (isOpen()) {
114 close();
115 }
116 }
117
118 /*!
119 \fn Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s)
120 overrides the = operator
121 */
operator =(const Win_QextSerialPort & s)122 Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s) {
123 setOpenMode(s.openMode());
124 lastErr=s.lastErr;
125 port = s.port;
126 Settings.FlowControl=s.Settings.FlowControl;
127 Settings.Parity=s.Settings.Parity;
128 Settings.DataBits=s.Settings.DataBits;
129 Settings.StopBits=s.Settings.StopBits;
130 Settings.BaudRate=s.Settings.BaudRate;
131 Win_Handle=s.Win_Handle;
132 memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));
133 memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
134 return *this;
135 }
136
137 /*!
138 \fn bool Win_QextSerialPort::open(OpenMode mode)
139 Opens a serial port. Note that this function does not specify which device to open. If you need
140 to open a device by name, see Win_QextSerialPort::open(const char*). This function has no effect
141 if the port associated with the class is already open. The port is also configured to the current
142 settings, as stored in the Settings structure.
143 */
open(OpenMode mode)144 bool Win_QextSerialPort::open(OpenMode mode) {
145 //unsigned long confSize = sizeof(COMMCONFIG);
146 //Win_CommConfig.dwSize = confSize;
147
148 LOCK_MUTEX();
149 if (mode == QIODevice::NotOpen)
150 return isOpen();
151 if (!isOpen()) {
152 /*open the port*/
153 Win_Handle=CreateFileW((LPCWSTR)port.utf16(), GENERIC_READ|GENERIC_WRITE,
154 0, NULL, OPEN_EXISTING, 0, NULL);
155 if (Win_Handle!=INVALID_HANDLE_VALUE) {
156 /*set open mode*/
157 QIODevice::open(mode);
158
159 /*configure port settings*/
160 //GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
161 GetCommState(Win_Handle, &(Win_CommConfig));
162
163 /*set up parameters*/
164 Win_CommConfig.fBinary=TRUE;
165 Win_CommConfig.fInX=FALSE;
166 Win_CommConfig.fOutX=FALSE;
167 Win_CommConfig.fAbortOnError=FALSE;
168 Win_CommConfig.fNull=FALSE;
169 setBaudRate(Settings.BaudRate);
170 setDataBits(Settings.DataBits);
171 setStopBits(Settings.StopBits);
172 setParity(Settings.Parity);
173 setFlowControl(Settings.FlowControl);
174 setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
175 //SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
176 SetCommState(Win_Handle, &Win_CommConfig);
177 } else {
178 qDebug("Device handle failed with error : %d\n", (int)GetLastError());
179 }
180 }
181 UNLOCK_MUTEX();
182 return isOpen();
183 }
184
185 /*!
186 \fn void Win_QextSerialPort::close()
187 Closes a serial port. This function has no effect if the serial port associated with the class
188 is not currently open.
189 */
close()190 void Win_QextSerialPort::close() {
191 LOCK_MUTEX();
192 CloseHandle(Win_Handle);
193 QIODevice::close();
194 UNLOCK_MUTEX();
195 }
196
197 /*!
198 \fn void Win_QextSerialPort::flush()
199 Flushes all pending I/O to the serial port. This function has no effect if the serial port
200 associated with the class is not currently open.
201 */
flush()202 void Win_QextSerialPort::flush() {
203 LOCK_MUTEX();
204 if (isOpen()) {
205 FlushFileBuffers(Win_Handle);
206 }
207 UNLOCK_MUTEX();
208 }
209
210 /*!
211 \fn qint64 Win_QextSerialPort::size() const
212 This function will return the number of bytes waiting in the receive queue of the serial port.
213 It is included primarily to provide a complete QIODevice interface, and will not record errors
214 in the lastErr member (because it is const). This function is also not thread-safe - in
215 multithreading situations, use Win_QextSerialPort::bytesAvailable() instead.
216 */
size() const217 qint64 Win_QextSerialPort::size() const {
218 int availBytes;
219 COMSTAT Win_ComStat;
220 DWORD Win_ErrorMask=0;
221 ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
222 availBytes = Win_ComStat.cbInQue;
223 return (qint64)availBytes;
224 }
225
226 /*!
227 \fn qint64 Win_QextSerialPort::bytesAvailable()
228 Returns the number of bytes waiting in the port's receive queue. This function will return 0 if
229 the port is not currently open, or -1 on error. Error information can be retrieved by calling
230 Win_QextSerialPort::getLastError().
231 */
bytesAvailable()232 qint64 Win_QextSerialPort::bytesAvailable() {
233 LOCK_MUTEX();
234 if (isOpen()) {
235 DWORD Errors;
236 COMSTAT Status;
237 bool success=ClearCommError(Win_Handle, &Errors, &Status);
238 translateError(Errors);
239 if (success) {
240 lastErr=E_NO_ERROR;
241 UNLOCK_MUTEX();
242 return Status.cbInQue + QIODevice::bytesAvailable();
243 }
244 UNLOCK_MUTEX();
245 return (int)-1;
246 }
247 UNLOCK_MUTEX();
248 return 0;
249 }
250
251 /*!
252 \fn void Win_QextSerialPort::translateError(ulong error)
253 Translates a system-specific error code to a QextSerialPort error code. Used internally.
254 */
translateError(ulong error)255 void Win_QextSerialPort::translateError(ulong error) {
256 if (error&CE_BREAK) {
257 lastErr=E_BREAK_CONDITION;
258 }
259 else if (error&CE_FRAME) {
260 lastErr=E_FRAMING_ERROR;
261 }
262 else if (error&CE_IOE) {
263 lastErr=E_IO_ERROR;
264 }
265 else if (error&CE_MODE) {
266 lastErr=E_INVALID_FD;
267 }
268 else if (error&CE_OVERRUN) {
269 lastErr=E_BUFFER_OVERRUN;
270 }
271 else if (error&CE_RXPARITY) {
272 lastErr=E_RECEIVE_PARITY_ERROR;
273 }
274 else if (error&CE_RXOVER) {
275 lastErr=E_RECEIVE_OVERFLOW;
276 }
277 else if (error&CE_TXFULL) {
278 lastErr=E_TRANSMIT_OVERFLOW;
279 }
280 }
281
282 /*!
283 \fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
284 Reads a block of data from the serial port. This function will read at most maxlen bytes from
285 the serial port and place them in the buffer pointed to by data. Return value is the number of
286 bytes actually read, or -1 on error.
287
288 \warning before calling this function ensure that serial port associated with this class
289 is currently open (use isOpen() function to check if port is open).
290 */
readData(char * data,qint64 maxSize)291 qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
292 {
293 LOCK_MUTEX();
294 int retVal=0;
295 COMSTAT Win_ComStat;
296 DWORD Win_BytesRead=0;
297 DWORD Win_ErrorMask=0;
298 ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
299 if (Win_ComStat.cbInQue &&
300 (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesRead, NULL)
301 || Win_BytesRead==0)) {
302 lastErr=E_READ_FAILED;
303 retVal=-1;
304 }
305 else {
306 retVal=((int)Win_BytesRead);
307 }
308 UNLOCK_MUTEX();
309
310 return retVal;
311 }
312
313 /*!
314 \fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
315 Writes a block of data to the serial port. This function will write len bytes
316 from the buffer pointed to by data to the serial port. Return value is the number
317 of bytes actually written, or -1 on error.
318
319 \warning before calling this function ensure that serial port associated with this class
320 is currently open (use isOpen() function to check if port is open).
321 */
writeData(const char * data,qint64 maxSize)322 qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
323 {
324 LOCK_MUTEX();
325 int retVal=0;
326 DWORD Win_BytesWritten;
327 if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesWritten, NULL)) {
328 lastErr=E_WRITE_FAILED;
329 retVal=-1;
330 }
331 else {
332 retVal=((int)Win_BytesWritten);
333 }
334 UNLOCK_MUTEX();
335
336 flush();
337 return retVal;
338 }
339
340 /*!
341 \fn void Win_QextSerialPort::ungetChar(char c)
342 This function is included to implement the full QIODevice interface, and currently has no
343 purpose within this class. This function is meaningless on an unbuffered device and currently
344 only prints a warning message to that effect.
345 */
ungetChar(char c)346 void Win_QextSerialPort::ungetChar(char c) {
347 Q_UNUSED(c);
348 /*meaningless on unbuffered sequential device - return error and print a warning*/
349 TTY_WARNING("Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
350 }
351
352 /*!
353 \fn void Win_QextSerialPort::setFlowControl(FlowType flow)
354 Sets the flow control used by the port. Possible values of flow are:
355 \verbatim
356 FLOW_OFF No flow control
357 FLOW_HARDWARE Hardware (RTS/CTS) flow control
358 FLOW_XONXOFF Software (XON/XOFF) flow control
359 \endverbatim
360 */
setFlowControl(FlowType flow)361 void Win_QextSerialPort::setFlowControl(FlowType flow) {
362 LOCK_MUTEX();
363 if (Settings.FlowControl!=flow) {
364 Settings.FlowControl=flow;
365 }
366 if (isOpen()) {
367 switch(flow) {
368
369 /*no flow control*/
370 case FLOW_OFF:
371 Win_CommConfig.fOutxCtsFlow=FALSE;
372 Win_CommConfig.fRtsControl=RTS_CONTROL_DISABLE;
373 Win_CommConfig.fInX=FALSE;
374 Win_CommConfig.fOutX=FALSE;
375 SetCommState(Win_Handle, &Win_CommConfig);
376 break;
377
378 /*software (XON/XOFF) flow control*/
379 case FLOW_XONXOFF:
380 Win_CommConfig.fOutxCtsFlow=FALSE;
381 Win_CommConfig.fRtsControl=RTS_CONTROL_DISABLE;
382 Win_CommConfig.fInX=TRUE;
383 Win_CommConfig.fOutX=TRUE;
384 SetCommState(Win_Handle, &Win_CommConfig);
385 break;
386
387 case FLOW_HARDWARE:
388 Win_CommConfig.fOutxCtsFlow=TRUE;
389 Win_CommConfig.fRtsControl=RTS_CONTROL_HANDSHAKE;
390 Win_CommConfig.fInX=FALSE;
391 Win_CommConfig.fOutX=FALSE;
392 SetCommState(Win_Handle, &Win_CommConfig);
393 break;
394 }
395 }
396 UNLOCK_MUTEX();
397 }
398
399 /*!
400 \fn void Win_QextSerialPort::setParity(ParityType parity)
401 Sets the parity associated with the serial port. The possible values of parity are:
402 \verbatim
403 PAR_SPACE Space Parity
404 PAR_MARK Mark Parity
405 PAR_NONE No Parity
406 PAR_EVEN Even Parity
407 PAR_ODD Odd Parity
408 \endverbatim
409 */
setParity(ParityType parity)410 void Win_QextSerialPort::setParity(ParityType parity) {
411 LOCK_MUTEX();
412 if (Settings.Parity!=parity) {
413 Settings.Parity=parity;
414 }
415 if (isOpen()) {
416 Win_CommConfig.Parity=(unsigned char)parity;
417 switch (parity) {
418
419 /*space parity*/
420 case PAR_SPACE:
421 if (Settings.DataBits==DATA_8) {
422 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");
423 }
424 Win_CommConfig.fParity=TRUE;
425 break;
426
427 /*mark parity - WINDOWS ONLY*/
428 case PAR_MARK:
429 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems");
430 Win_CommConfig.fParity=TRUE;
431 break;
432
433 /*no parity*/
434 case PAR_NONE:
435 Win_CommConfig.fParity=FALSE;
436 break;
437
438 /*even parity*/
439 case PAR_EVEN:
440 Win_CommConfig.fParity=TRUE;
441 break;
442
443 /*odd parity*/
444 case PAR_ODD:
445 Win_CommConfig.fParity=TRUE;
446 break;
447 }
448 SetCommState(Win_Handle, &Win_CommConfig);
449 }
450 UNLOCK_MUTEX();
451 }
452
453 /*!
454 \fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits)
455 Sets the number of data bits used by the serial port. Possible values of dataBits are:
456 \verbatim
457 DATA_5 5 data bits
458 DATA_6 6 data bits
459 DATA_7 7 data bits
460 DATA_8 8 data bits
461 \endverbatim
462
463 \note
464 This function is subject to the following restrictions:
465 \par
466 5 data bits cannot be used with 2 stop bits.
467 \par
468 1.5 stop bits can only be used with 5 data bits.
469 \par
470 8 data bits cannot be used with space parity on POSIX systems.
471
472 */
setDataBits(DataBitsType dataBits)473 void Win_QextSerialPort::setDataBits(DataBitsType dataBits) {
474 LOCK_MUTEX();
475 if (Settings.DataBits!=dataBits) {
476 if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
477 (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) {
478 }
479 else {
480 Settings.DataBits=dataBits;
481 }
482 }
483 if (isOpen()) {
484 switch(dataBits) {
485
486 /*5 data bits*/
487 case DATA_5:
488 if (Settings.StopBits==STOP_2) {
489 TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
490 }
491 else {
492 Win_CommConfig.ByteSize=5;
493 SetCommState(Win_Handle, &Win_CommConfig);
494 }
495 break;
496
497 /*6 data bits*/
498 case DATA_6:
499 if (Settings.StopBits==STOP_1_5) {
500 TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
501 }
502 else {
503 Win_CommConfig.ByteSize=6;
504 SetCommState(Win_Handle, &Win_CommConfig);
505 }
506 break;
507
508 /*7 data bits*/
509 case DATA_7:
510 if (Settings.StopBits==STOP_1_5) {
511 TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
512 }
513 else {
514 Win_CommConfig.ByteSize=7;
515 SetCommState(Win_Handle, &Win_CommConfig);
516 }
517 break;
518
519 /*8 data bits*/
520 case DATA_8:
521 if (Settings.StopBits==STOP_1_5) {
522 TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
523 }
524 else {
525 Win_CommConfig.ByteSize=8;
526 SetCommState(Win_Handle, &Win_CommConfig);
527 }
528 break;
529 }
530 }
531 UNLOCK_MUTEX();
532 }
533
534 /*!
535 \fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits)
536 Sets the number of stop bits used by the serial port. Possible values of stopBits are:
537 \verbatim
538 STOP_1 1 stop bit
539 STOP_1_5 1.5 stop bits
540 STOP_2 2 stop bits
541 \endverbatim
542
543 \note
544 This function is subject to the following restrictions:
545 \par
546 2 stop bits cannot be used with 5 data bits.
547 \par
548 1.5 stop bits cannot be used with 6 or more data bits.
549 \par
550 POSIX does not support 1.5 stop bits.
551 */
setStopBits(StopBitsType stopBits)552 void Win_QextSerialPort::setStopBits(StopBitsType stopBits) {
553 LOCK_MUTEX();
554 if (Settings.StopBits!=stopBits) {
555 if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) ||
556 (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) {
557 }
558 else {
559 Settings.StopBits=stopBits;
560 }
561 }
562 if (isOpen()) {
563 switch (stopBits) {
564
565 /*one stop bit*/
566 case STOP_1:
567 Win_CommConfig.StopBits=ONESTOPBIT;
568 SetCommState(Win_Handle, &Win_CommConfig);
569 break;
570
571 /*1.5 stop bits*/
572 case STOP_1_5:
573 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");
574 if (Settings.DataBits!=DATA_5) {
575 TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits");
576 }
577 else {
578 Win_CommConfig.StopBits=ONE5STOPBITS;
579 SetCommState(Win_Handle, &Win_CommConfig);
580 }
581 break;
582
583 /*two stop bits*/
584 case STOP_2:
585 if (Settings.DataBits==DATA_5) {
586 TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
587 }
588 else {
589 Win_CommConfig.StopBits=TWOSTOPBITS;
590 SetCommState(Win_Handle, &Win_CommConfig);
591 }
592 break;
593 }
594 }
595 UNLOCK_MUTEX();
596 }
597
598 /*!
599 \fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate)
600 Sets the baud rate of the serial port. Note that not all rates are applicable on
601 all platforms. The following table shows translations of the various baud rate
602 constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an *
603 are speeds that are usable on both Windows and POSIX.
604 \verbatim
605
606 RATE Windows Speed POSIX Speed
607 ----------- ------------- -----------
608 BAUD50 110 50
609 BAUD75 110 75
610 *BAUD110 110 110
611 BAUD134 110 134.5
612 BAUD150 110 150
613 BAUD200 110 200
614 *BAUD300 300 300
615 *BAUD600 600 600
616 *BAUD1200 1200 1200
617 BAUD1800 1200 1800
618 *BAUD2400 2400 2400
619 *BAUD4800 4800 4800
620 *BAUD9600 9600 9600
621 BAUD14400 14400 9600
622 *BAUD19200 19200 19200
623 *BAUD38400 38400 38400
624 BAUD56000 56000 38400
625 *BAUD57600 57600 57600
626 BAUD76800 57600 76800
627 *BAUD115200 115200 115200
628 BAUD128000 128000 115200
629 BAUD256000 256000 115200
630 \endverbatim
631 */
setBaudRate(BaudRateType baudRate)632 void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) {
633 LOCK_MUTEX();
634 if (Settings.BaudRate!=baudRate) {
635 switch (baudRate) {
636 case BAUD50:
637 case BAUD75:
638 case BAUD134:
639 case BAUD150:
640 case BAUD200:
641 Settings.BaudRate=BAUD110;
642 break;
643
644 case BAUD1800:
645 Settings.BaudRate=BAUD1200;
646 break;
647
648 case BAUD76800:
649 Settings.BaudRate=BAUD57600;
650 break;
651
652 default:
653 Settings.BaudRate=baudRate;
654 break;
655 }
656 }
657 if (isOpen()) {
658 switch (baudRate) {
659
660 /*50 baud*/
661 case BAUD50:
662 TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation. Switching to 110 baud.");
663 Win_CommConfig.BaudRate=CBR_110;
664 break;
665
666 /*75 baud*/
667 case BAUD75:
668 TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation. Switching to 110 baud.");
669 Win_CommConfig.BaudRate=CBR_110;
670 break;
671
672 /*110 baud*/
673 case BAUD110:
674 Win_CommConfig.BaudRate=CBR_110;
675 break;
676
677 /*134.5 baud*/
678 case BAUD134:
679 TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation. Switching to 110 baud.");
680 Win_CommConfig.BaudRate=CBR_110;
681 break;
682
683 /*150 baud*/
684 case BAUD150:
685 TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation. Switching to 110 baud.");
686 Win_CommConfig.BaudRate=CBR_110;
687 break;
688
689 /*200 baud*/
690 case BAUD200:
691 TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation. Switching to 110 baud.");
692 Win_CommConfig.BaudRate=CBR_110;
693 break;
694
695 /*300 baud*/
696 case BAUD300:
697 Win_CommConfig.BaudRate=CBR_300;
698 break;
699
700 /*600 baud*/
701 case BAUD600:
702 Win_CommConfig.BaudRate=CBR_600;
703 break;
704
705 /*1200 baud*/
706 case BAUD1200:
707 Win_CommConfig.BaudRate=CBR_1200;
708 break;
709
710 /*1800 baud*/
711 case BAUD1800:
712 TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation. Switching to 1200 baud.");
713 Win_CommConfig.BaudRate=CBR_1200;
714 break;
715
716 /*2400 baud*/
717 case BAUD2400:
718 Win_CommConfig.BaudRate=CBR_2400;
719 break;
720
721 /*4800 baud*/
722 case BAUD4800:
723 Win_CommConfig.BaudRate=CBR_4800;
724 break;
725
726 /*9600 baud*/
727 case BAUD9600:
728 Win_CommConfig.BaudRate=CBR_9600;
729 break;
730
731 /*14400 baud*/
732 case BAUD14400:
733 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation.");
734 Win_CommConfig.BaudRate=CBR_14400;
735 break;
736
737 /*19200 baud*/
738 case BAUD19200:
739 Win_CommConfig.BaudRate=CBR_19200;
740 break;
741
742 /*38400 baud*/
743 case BAUD38400:
744 Win_CommConfig.BaudRate=CBR_38400;
745 break;
746
747 /*56000 baud*/
748 case BAUD56000:
749 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation.");
750 Win_CommConfig.BaudRate=CBR_56000;
751 break;
752
753 /*57600 baud*/
754 case BAUD57600:
755 Win_CommConfig.BaudRate=CBR_57600;
756 break;
757
758 /*76800 baud*/
759 case BAUD76800:
760 TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation. Switching to 57600 baud.");
761 Win_CommConfig.BaudRate=CBR_57600;
762 break;
763
764 /*115200 baud*/
765 case BAUD115200:
766 Win_CommConfig.BaudRate=CBR_115200;
767 break;
768
769 /*128000 baud*/
770 case BAUD128000:
771 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation.");
772 Win_CommConfig.BaudRate=CBR_128000;
773 break;
774
775 /*256000 baud*/
776 case BAUD256000:
777 TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation.");
778 Win_CommConfig.BaudRate=CBR_256000;
779 break;
780 }
781 SetCommState(Win_Handle, &Win_CommConfig);
782 }
783 UNLOCK_MUTEX();
784 }
785
786 /*!
787 \fn void Win_QextSerialPort::setDtr(bool set)
788 Sets DTR line to the requested state (high by default). This function will have no effect if
789 the port associated with the class is not currently open.
790 */
setDtr(bool set)791 void Win_QextSerialPort::setDtr(bool set) {
792 LOCK_MUTEX();
793 if (isOpen()) {
794 if (set) {
795 EscapeCommFunction(Win_Handle, SETDTR);
796 }
797 else {
798 EscapeCommFunction(Win_Handle, CLRDTR);
799 }
800 }
801 UNLOCK_MUTEX();
802 }
803
804 /*!
805 \fn void Win_QextSerialPort::setRts(bool set)
806 Sets RTS line to the requested state (high by default). This function will have no effect if
807 the port associated with the class is not currently open.
808 */
setRts(bool set)809 void Win_QextSerialPort::setRts(bool set) {
810 LOCK_MUTEX();
811 if (isOpen()) {
812 if (set) {
813 EscapeCommFunction(Win_Handle, SETRTS);
814 }
815 else {
816 EscapeCommFunction(Win_Handle, CLRRTS);
817 }
818 }
819 UNLOCK_MUTEX();
820 }
821
822 /*!
823 \fn ulong Win_QextSerialPort::lineStatus(void)
824 returns the line status as stored by the port function. This function will retrieve the states
825 of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines
826 can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned
827 long with specific bits indicating which lines are high. The following constants should be used
828 to examine the states of individual lines:
829
830 \verbatim
831 Mask Line
832 ------ ----
833 LS_CTS CTS
834 LS_DSR DSR
835 LS_DCD DCD
836 LS_RI RI
837 \endverbatim
838
839 This function will return 0 if the port associated with the class is not currently open.
840 */
lineStatus(void)841 ulong Win_QextSerialPort::lineStatus(void) {
842 unsigned long Status=0, Temp=0;
843 LOCK_MUTEX();
844 if (isOpen()) {
845 GetCommModemStatus(Win_Handle, &Temp);
846 if (Temp&MS_CTS_ON) {
847 Status|=LS_CTS;
848 }
849 if (Temp&MS_DSR_ON) {
850 Status|=LS_DSR;
851 }
852 if (Temp&MS_RING_ON) {
853 Status|=LS_RI;
854 }
855 if (Temp&MS_RLSD_ON) {
856 Status|=LS_DCD;
857 }
858 }
859 UNLOCK_MUTEX();
860 return Status;
861 }
862
863 /*!
864 \fn void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec);
865 Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
866 */
setTimeout(ulong sec,ulong millisec)867 void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec) {
868 LOCK_MUTEX();
869 Settings.Timeout_Sec=sec;
870 Settings.Timeout_Millisec=millisec;
871 if(isOpen()) {
872 Win_CommTimeouts.ReadIntervalTimeout = sec*1000+millisec;
873 Win_CommTimeouts.ReadTotalTimeoutMultiplier = sec*1000+millisec;
874 Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
875 Win_CommTimeouts.WriteTotalTimeoutMultiplier = sec*1000+millisec;
876 Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
877 SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
878 }
879 UNLOCK_MUTEX();
880 }
881