Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
158 KeyOz 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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE,
154
                                FILE_SHARE_READ|FILE_SHARE_WRITE, 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.dcb));
162
 
163
                        /*set up parameters*/
164
                        Win_CommConfig.dcb.fBinary=TRUE;
165
                        Win_CommConfig.dcb.fInX=FALSE;
166
                        Win_CommConfig.dcb.fOutX=FALSE;
167
                        Win_CommConfig.dcb.fAbortOnError=FALSE;
168
                        Win_CommConfig.dcb.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
                }
177
        }
178
        UNLOCK_MUTEX();
179
        return isOpen();
180
}
181
 
182
/*!
183
                \fn void Win_QextSerialPort::close()
184
                        Closes a serial port.  This function has no effect if the serial port associated with the class
185
                        is not currently open.
186
*/
187
void Win_QextSerialPort::close() {
188
        LOCK_MUTEX();
189
        CloseHandle(Win_Handle);
190
        QIODevice::close();
191
        UNLOCK_MUTEX();
192
}
193
 
194
/*!
195
                \fn void Win_QextSerialPort::flush()
196
                        Flushes all pending I/O to the serial port.  This function has no effect if the serial port
197
                        associated with the class is not currently open.
198
*/
199
void Win_QextSerialPort::flush() {
200
        LOCK_MUTEX();
201
        if (isOpen()) {
202
                FlushFileBuffers(Win_Handle);
203
        }
204
        UNLOCK_MUTEX();
205
}
206
 
207
/*!
208
                \fn qint64 Win_QextSerialPort::size() const
209
This function will return the number of bytes waiting in the receive queue of the serial port.
210
                It is included primarily to provide a complete QIODevice interface, and will not record errors
211
                in the lastErr member (because it is const).  This function is also not thread-safe - in
212
                multithreading situations, use Win_QextSerialPort::bytesAvailable() instead.
213
*/
214
qint64 Win_QextSerialPort::size() const {
215
        int availBytes;
216
        COMSTAT Win_ComStat;
217
        DWORD Win_ErrorMask=0;
218
        ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
219
        availBytes = Win_ComStat.cbInQue;
220
        return (qint64)availBytes;
221
}
222
 
223
/*!
224
                \fn qint64 Win_QextSerialPort::bytesAvailable()
225
                        Returns the number of bytes waiting in the port's receive queue.  This function will return 0 if
226
                        the port is not currently open, or -1 on error.  Error information can be retrieved by calling
227
                        Win_QextSerialPort::getLastError().
228
*/
229
qint64 Win_QextSerialPort::bytesAvailable() {
230
        LOCK_MUTEX();
231
        if (isOpen()) {
232
                DWORD Errors;
233
                COMSTAT Status;
234
                bool success=ClearCommError(Win_Handle, &Errors, &Status);
235
                translateError(Errors);
236
                if (success) {
237
                        lastErr=E_NO_ERROR;
238
                        UNLOCK_MUTEX();
239
                        return Status.cbInQue + QIODevice::bytesAvailable();
240
                }
241
                UNLOCK_MUTEX();
242
                return (unsigned int)-1;
243
        }
244
        UNLOCK_MUTEX();
245
        return 0;
246
}
247
 
248
/*!
249
                \fn void Win_QextSerialPort::translateError(ulong error)
250
                        Translates a system-specific error code to a QextSerialPort error code.  Used internally.
251
*/
252
void Win_QextSerialPort::translateError(ulong error) {
253
        if (error&CE_BREAK) {
254
                lastErr=E_BREAK_CONDITION;
255
        }
256
        else if (error&CE_FRAME) {
257
                lastErr=E_FRAMING_ERROR;
258
        }
259
        else if (error&CE_IOE) {
260
                lastErr=E_IO_ERROR;
261
        }
262
        else if (error&CE_MODE) {
263
                lastErr=E_INVALID_FD;
264
        }
265
        else if (error&CE_OVERRUN) {
266
                lastErr=E_BUFFER_OVERRUN;
267
        }
268
        else if (error&CE_RXPARITY) {
269
                lastErr=E_RECEIVE_PARITY_ERROR;
270
        }
271
        else if (error&CE_RXOVER) {
272
                lastErr=E_RECEIVE_OVERFLOW;
273
        }
274
        else if (error&CE_TXFULL) {
275
                lastErr=E_TRANSMIT_OVERFLOW;
276
        }
277
}
278
 
279
/*!
280
                \fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
281
                        Reads a block of data from the serial port.  This function will read at most maxlen bytes from
282
                        the serial port and place them in the buffer pointed to by data.  Return value is the number of
283
                        bytes actually read, or -1 on error.
284
 
285
\warning before calling this function ensure that serial port associated with this class
286
                is currently open (use isOpen() function to check if port is open).
287
*/
288
qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
289
{
290
        LOCK_MUTEX();
291
        int retVal=0;
292
        COMSTAT Win_ComStat;
293
        DWORD Win_BytesRead=0;
294
        DWORD Win_ErrorMask=0;
295
        ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
296
        if (Win_ComStat.cbInQue &&
297
                        (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesRead, NULL)
298
                        || Win_BytesRead==0)) {
299
                                lastErr=E_READ_FAILED;
300
                retVal=-1;
301
        }
302
        else {
303
                retVal=((int)Win_BytesRead);
304
        }
305
        UNLOCK_MUTEX();
306
 
307
        return retVal;
308
}
309
 
310
/*!
311
                \fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
312
                        Writes a block of data to the serial port.  This function will write len bytes
313
                        from the buffer pointed to by data to the serial port.  Return value is the number
314
                        of bytes actually written, or -1 on error.
315
 
316
\warning before calling this function ensure that serial port associated with this class
317
                is currently open (use isOpen() function to check if port is open).
318
*/
319
qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
320
{
321
        LOCK_MUTEX();
322
        int retVal=0;
323
        DWORD Win_BytesWritten;
324
        if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesWritten, NULL)) {
325
                lastErr=E_WRITE_FAILED;
326
                retVal=-1;
327
        }
328
        else {
329
                retVal=((int)Win_BytesWritten);
330
        }
331
        UNLOCK_MUTEX();
332
 
333
        flush();
334
        return retVal;
335
}
336
 
337
/*!
338
                \fn void Win_QextSerialPort::ungetChar(char c)
339
                        This function is included to implement the full QIODevice interface, and currently has no
340
                        purpose within this class.  This function is meaningless on an unbuffered device and currently
341
                        only prints a warning message to that effect.
342
*/
343
void Win_QextSerialPort::ungetChar(char c) {
344
 
345
        /*meaningless on unbuffered sequential device - return error and print a warning*/
346
        TTY_WARNING("Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
347
}
348
 
349
/*!
350
                \fn void Win_QextSerialPort::setFlowControl(FlowType flow)
351
                        Sets the flow control used by the port.  Possible values of flow are:
352
\verbatim
353
                FLOW_OFF            No flow control
354
                FLOW_HARDWARE       Hardware (RTS/CTS) flow control
355
                FLOW_XONXOFF        Software (XON/XOFF) flow control
356
                \endverbatim
357
*/
358
void Win_QextSerialPort::setFlowControl(FlowType flow) {
359
        LOCK_MUTEX();
360
        if (Settings.FlowControl!=flow) {
361
                Settings.FlowControl=flow;
362
        }
363
        if (isOpen()) {
364
                switch(flow) {
365
 
366
                                /*no flow control*/
367
                        case FLOW_OFF:
368
                                Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
369
                                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
370
                                Win_CommConfig.dcb.fInX=FALSE;
371
                                Win_CommConfig.dcb.fOutX=FALSE;
372
                                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
373
                                break;
374
 
375
                                /*software (XON/XOFF) flow control*/
376
                        case FLOW_XONXOFF:
377
                                Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
378
                                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
379
                                Win_CommConfig.dcb.fInX=TRUE;
380
                                Win_CommConfig.dcb.fOutX=TRUE;
381
                                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
382
                                break;
383
 
384
                        case FLOW_HARDWARE:
385
                                Win_CommConfig.dcb.fOutxCtsFlow=TRUE;
386
                                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
387
                                Win_CommConfig.dcb.fInX=FALSE;
388
                                Win_CommConfig.dcb.fOutX=FALSE;
389
                                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
390
                                break;
391
                }
392
        }
393
        UNLOCK_MUTEX();
394
}
395
 
396
/*!
397
                \fn void Win_QextSerialPort::setParity(ParityType parity)
398
                        Sets the parity associated with the serial port.  The possible values of parity are:
399
\verbatim
400
                PAR_SPACE       Space Parity
401
                PAR_MARK        Mark Parity
402
                PAR_NONE        No Parity
403
                PAR_EVEN        Even Parity
404
                PAR_ODD         Odd Parity
405
                \endverbatim
406
*/
407
void Win_QextSerialPort::setParity(ParityType parity) {
408
        LOCK_MUTEX();
409
        if (Settings.Parity!=parity) {
410
                Settings.Parity=parity;
411
        }
412
        if (isOpen()) {
413
                Win_CommConfig.dcb.Parity=(unsigned char)parity;
414
                switch (parity) {
415
 
416
                                /*space parity*/
417
                        case PAR_SPACE:
418
                                if (Settings.DataBits==DATA_8) {
419
                                        TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");
420
                                }
421
                                Win_CommConfig.dcb.fParity=TRUE;
422
                                break;
423
 
424
                                /*mark parity - WINDOWS ONLY*/
425
                        case PAR_MARK:
426
                                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning:  Mark parity is not supported by POSIX systems");
427
                                Win_CommConfig.dcb.fParity=TRUE;
428
                                break;
429
 
430
                                /*no parity*/
431
                        case PAR_NONE:
432
                                Win_CommConfig.dcb.fParity=FALSE;
433
                                break;
434
 
435
                                /*even parity*/
436
                        case PAR_EVEN:
437
                                Win_CommConfig.dcb.fParity=TRUE;
438
                                break;
439
 
440
                                /*odd parity*/
441
                        case PAR_ODD:
442
                                Win_CommConfig.dcb.fParity=TRUE;
443
                                break;
444
                        }
445
                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
446
        }
447
        UNLOCK_MUTEX();
448
}
449
 
450
/*!
451
                \fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits)
452
                        Sets the number of data bits used by the serial port.  Possible values of dataBits are:
453
\verbatim
454
                DATA_5      5 data bits
455
                DATA_6      6 data bits
456
                DATA_7      7 data bits
457
                DATA_8      8 data bits
458
                \endverbatim
459
 
460
\note
461
                This function is subject to the following restrictions:
462
\par
463
                5 data bits cannot be used with 2 stop bits.
464
                \par
465
                1.5 stop bits can only be used with 5 data bits.
466
                \par
467
                8 data bits cannot be used with space parity on POSIX systems.
468
 
469
*/
470
void Win_QextSerialPort::setDataBits(DataBitsType dataBits) {
471
        LOCK_MUTEX();
472
        if (Settings.DataBits!=dataBits) {
473
                if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
474
                                (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) {
475
                                }
476
                else {
477
                        Settings.DataBits=dataBits;
478
                }
479
        }
480
        if (isOpen()) {
481
                switch(dataBits) {
482
 
483
                                /*5 data bits*/
484
                        case DATA_5:
485
                                if (Settings.StopBits==STOP_2) {
486
                                        TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
487
                                }
488
                                else {
489
                                        Win_CommConfig.dcb.ByteSize=5;
490
                                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
491
                                }
492
                                break;
493
 
494
                                /*6 data bits*/
495
                        case DATA_6:
496
                                if (Settings.StopBits==STOP_1_5) {
497
                                        TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
498
                                }
499
                                else {
500
                                        Win_CommConfig.dcb.ByteSize=6;
501
                                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
502
                                }
503
                                break;
504
 
505
                                /*7 data bits*/
506
                        case DATA_7:
507
                                if (Settings.StopBits==STOP_1_5) {
508
                                        TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
509
                                }
510
                                else {
511
                                        Win_CommConfig.dcb.ByteSize=7;
512
                                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
513
                                }
514
                                break;
515
 
516
                                /*8 data bits*/
517
                        case DATA_8:
518
                                if (Settings.StopBits==STOP_1_5) {
519
                                        TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
520
                                }
521
                                else {
522
                                        Win_CommConfig.dcb.ByteSize=8;
523
                                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
524
                                }
525
                                break;
526
                        }
527
        }
528
        UNLOCK_MUTEX();
529
}
530
 
531
/*!
532
                \fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits)
533
                        Sets the number of stop bits used by the serial port.  Possible values of stopBits are:
534
\verbatim
535
                STOP_1      1 stop bit
536
                STOP_1_5    1.5 stop bits
537
                STOP_2      2 stop bits
538
                \endverbatim
539
 
540
\note
541
                This function is subject to the following restrictions:
542
\par
543
                2 stop bits cannot be used with 5 data bits.
544
                \par
545
                1.5 stop bits cannot be used with 6 or more data bits.
546
                \par
547
                POSIX does not support 1.5 stop bits.
548
*/
549
void Win_QextSerialPort::setStopBits(StopBitsType stopBits) {
550
        LOCK_MUTEX();
551
        if (Settings.StopBits!=stopBits) {
552
                if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) ||
553
                                (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) {
554
                                }
555
                else {
556
                        Settings.StopBits=stopBits;
557
                }
558
        }
559
        if (isOpen()) {
560
                switch (stopBits) {
561
 
562
                                /*one stop bit*/
563
                        case STOP_1:
564
                                Win_CommConfig.dcb.StopBits=ONESTOPBIT;
565
                                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
566
                                break;
567
 
568
                                /*1.5 stop bits*/
569
                        case STOP_1_5:
570
                                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");
571
                                if (Settings.DataBits!=DATA_5) {
572
                                        TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits");
573
                                }
574
                                else {
575
                                        Win_CommConfig.dcb.StopBits=ONE5STOPBITS;
576
                                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
577
                                }
578
                                break;
579
 
580
                                /*two stop bits*/
581
                        case STOP_2:
582
                                if (Settings.DataBits==DATA_5) {
583
                                        TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
584
                                }
585
                                else {
586
                                        Win_CommConfig.dcb.StopBits=TWOSTOPBITS;
587
                                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
588
                                }
589
                                break;
590
                        }
591
        }
592
        UNLOCK_MUTEX();
593
}
594
 
595
/*!
596
                \fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate)
597
                        Sets the baud rate of the serial port.  Note that not all rates are applicable on
598
                        all platforms.  The following table shows translations of the various baud rate
599
                        constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
600
                        are speeds that are usable on both Windows and POSIX.
601
                        \verbatim
602
 
603
RATE          Windows Speed   POSIX Speed
604
                -----------   -------------   -----------
605
                BAUD50                 110          50
606
                BAUD75                 110          75
607
                *BAUD110                110         110
608
                BAUD134                110         134.5
609
                BAUD150                110         150
610
                BAUD200                110         200
611
                *BAUD300                300         300
612
                *BAUD600                600         600
613
                *BAUD1200              1200        1200
614
                BAUD1800              1200        1800
615
                *BAUD2400              2400        2400
616
                *BAUD4800              4800        4800
617
                *BAUD9600              9600        9600
618
                BAUD14400            14400        9600
619
                *BAUD19200            19200       19200
620
                *BAUD38400            38400       38400
621
                BAUD56000            56000       38400
622
                *BAUD57600            57600       57600
623
                BAUD76800            57600       76800
624
                *BAUD115200          115200      115200
625
                BAUD128000          128000      115200
626
                BAUD256000          256000      115200
627
                \endverbatim
628
*/
629
void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) {
630
        LOCK_MUTEX();
631
        if (Settings.BaudRate!=baudRate) {
632
                switch (baudRate) {
633
                        case BAUD50:
634
                        case BAUD75:
635
                        case BAUD134:
636
                        case BAUD150:
637
                        case BAUD200:
638
                                Settings.BaudRate=BAUD110;
639
                                break;
640
 
641
                        case BAUD1800:
642
                                Settings.BaudRate=BAUD1200;
643
                                break;
644
 
645
                        case BAUD76800:
646
                                Settings.BaudRate=BAUD57600;
647
                                break;
648
 
649
                        default:
650
                                Settings.BaudRate=baudRate;
651
                                break;
652
                        }
653
        }
654
        if (isOpen()) {
655
                switch (baudRate) {
656
 
657
                                /*50 baud*/
658
                        case BAUD50:
659
                                TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation.  Switching to 110 baud.");
660
                                Win_CommConfig.dcb.BaudRate=CBR_110;
661
                                break;
662
 
663
                                /*75 baud*/
664
                        case BAUD75:
665
                                TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation.  Switching to 110 baud.");
666
                                Win_CommConfig.dcb.BaudRate=CBR_110;
667
                                break;
668
 
669
                                /*110 baud*/
670
                        case BAUD110:
671
                                Win_CommConfig.dcb.BaudRate=CBR_110;
672
                                break;
673
 
674
                                /*134.5 baud*/
675
                        case BAUD134:
676
                                TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation.  Switching to 110 baud.");
677
                                Win_CommConfig.dcb.BaudRate=CBR_110;
678
                                break;
679
 
680
                                /*150 baud*/
681
                        case BAUD150:
682
                                TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation.  Switching to 110 baud.");
683
                                Win_CommConfig.dcb.BaudRate=CBR_110;
684
                                break;
685
 
686
                                /*200 baud*/
687
                        case BAUD200:
688
                                TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation.  Switching to 110 baud.");
689
                                Win_CommConfig.dcb.BaudRate=CBR_110;
690
                                break;
691
 
692
                                /*300 baud*/
693
                        case BAUD300:
694
                                Win_CommConfig.dcb.BaudRate=CBR_300;
695
                                break;
696
 
697
                                /*600 baud*/
698
                        case BAUD600:
699
                                Win_CommConfig.dcb.BaudRate=CBR_600;
700
                                break;
701
 
702
                                /*1200 baud*/
703
                        case BAUD1200:
704
                                Win_CommConfig.dcb.BaudRate=CBR_1200;
705
                                break;
706
 
707
                                /*1800 baud*/
708
                        case BAUD1800:
709
                                TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation.  Switching to 1200 baud.");
710
                                Win_CommConfig.dcb.BaudRate=CBR_1200;
711
                                break;
712
 
713
                                /*2400 baud*/
714
                        case BAUD2400:
715
                                Win_CommConfig.dcb.BaudRate=CBR_2400;
716
                                break;
717
 
718
                                /*4800 baud*/
719
                        case BAUD4800:
720
                                Win_CommConfig.dcb.BaudRate=CBR_4800;
721
                                break;
722
 
723
                                /*9600 baud*/
724
                        case BAUD9600:
725
                                Win_CommConfig.dcb.BaudRate=CBR_9600;
726
                                break;
727
 
728
                                /*14400 baud*/
729
                        case BAUD14400:
730
                                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation.");
731
                                Win_CommConfig.dcb.BaudRate=CBR_14400;
732
                                break;
733
 
734
                                /*19200 baud*/
735
                        case BAUD19200:
736
                                Win_CommConfig.dcb.BaudRate=CBR_19200;
737
                                break;
738
 
739
                                /*38400 baud*/
740
                        case BAUD38400:
741
                                Win_CommConfig.dcb.BaudRate=CBR_38400;
742
                                break;
743
 
744
                                /*56000 baud*/
745
                        case BAUD56000:
746
                                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation.");
747
                                Win_CommConfig.dcb.BaudRate=CBR_56000;
748
                                break;
749
 
750
                                /*57600 baud*/
751
                        case BAUD57600:
752
                                Win_CommConfig.dcb.BaudRate=CBR_57600;
753
                                break;
754
 
755
                                /*76800 baud*/
756
                        case BAUD76800:
757
                                TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation.  Switching to 57600 baud.");
758
                                Win_CommConfig.dcb.BaudRate=CBR_57600;
759
                                break;
760
 
761
                                /*115200 baud*/
762
                        case BAUD115200:
763
                                Win_CommConfig.dcb.BaudRate=CBR_115200;
764
                                break;
765
 
766
                                /*128000 baud*/
767
                        case BAUD128000:
768
                                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation.");
769
                                Win_CommConfig.dcb.BaudRate=CBR_128000;
770
                                break;
771
 
772
                                /*256000 baud*/
773
                        case BAUD256000:
774
                                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation.");
775
                                Win_CommConfig.dcb.BaudRate=CBR_256000;
776
                                break;
777
                        }
778
                        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
779
        }
780
        UNLOCK_MUTEX();
781
}
782
 
783
/*!
784
                \fn void Win_QextSerialPort::setDtr(bool set)
785
                        Sets DTR line to the requested state (high by default).  This function will have no effect if
786
                        the port associated with the class is not currently open.
787
*/
788
void Win_QextSerialPort::setDtr(bool set) {
789
        LOCK_MUTEX();
790
        if (isOpen()) {
791
                if (set) {
792
                        EscapeCommFunction(Win_Handle, SETDTR);
793
                }
794
                else {
795
                        EscapeCommFunction(Win_Handle, CLRDTR);
796
                }
797
        }
798
        UNLOCK_MUTEX();
799
}
800
 
801
/*!
802
                \fn void Win_QextSerialPort::setRts(bool set)
803
                        Sets RTS line to the requested state (high by default).  This function will have no effect if
804
                        the port associated with the class is not currently open.
805
*/
806
void Win_QextSerialPort::setRts(bool set) {
807
        LOCK_MUTEX();
808
        if (isOpen()) {
809
                if (set) {
810
                        EscapeCommFunction(Win_Handle, SETRTS);
811
                }
812
                else {
813
                        EscapeCommFunction(Win_Handle, CLRRTS);
814
                }
815
        }
816
        UNLOCK_MUTEX();
817
}
818
 
819
/*!
820
                \fn ulong Win_QextSerialPort::lineStatus(void)
821
                        returns the line status as stored by the port function.  This function will retrieve the states
822
                        of the following lines: DCD, CTS, DSR, and RI.  On POSIX systems, the following additional lines
823
                        can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD.  The value returned is an unsigned
824
                        long with specific bits indicating which lines are high.  The following constants should be used
825
                        to examine the states of individual lines:
826
 
827
\verbatim
828
                Mask        Line
829
                ------      ----
830
                LS_CTS      CTS
831
                LS_DSR      DSR
832
                LS_DCD      DCD
833
                LS_RI       RI
834
                \endverbatim
835
 
836
This function will return 0 if the port associated with the class is not currently open.
837
*/
838
ulong Win_QextSerialPort::lineStatus(void) {
839
        unsigned long Status=0, Temp=0;
840
        LOCK_MUTEX();
841
        if (isOpen()) {
842
                GetCommModemStatus(Win_Handle, &Temp);
843
                if (Temp&MS_CTS_ON) {
844
                        Status|=LS_CTS;
845
                }
846
                if (Temp&MS_DSR_ON) {
847
                        Status|=LS_DSR;
848
                }
849
                if (Temp&MS_RING_ON) {
850
                        Status|=LS_RI;
851
                }
852
                if (Temp&MS_RLSD_ON) {
853
                        Status|=LS_DCD;
854
                }
855
        }
856
        UNLOCK_MUTEX();
857
        return Status;
858
}
859
 
860
/*!
861
                \fn void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec);
862
Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
863
*/
864
void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec) {
865
        LOCK_MUTEX();
866
        Settings.Timeout_Sec=sec;
867
        Settings.Timeout_Millisec=millisec;
868
        if(isOpen()) {
869
                Win_CommTimeouts.ReadIntervalTimeout = sec*1000+millisec;
870
                Win_CommTimeouts.ReadTotalTimeoutMultiplier = sec*1000+millisec;
871
                Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
872
                Win_CommTimeouts.WriteTotalTimeoutMultiplier = sec*1000+millisec;
873
                Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
874
                SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
875
        }
876
        UNLOCK_MUTEX();
877
}