Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
157 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
}