source: projects/punch-card/punch-card-editor/src/libs/qextserialport/win_qextserialport.cpp @ 53

Last change on this file since 53 was 53, checked in by sven, 14 years ago

Punch Card Editor, ongoing development

  • Extended new Deck interface, expanding the undo framework
  • Implemented editor changes via undo framework
  • revised the menu and toolbar actions and structure (now dynamic construction at deck load time), implemented undo viewer
  • Started implementation of device driver framework in menu
  • Embedded the Qextserialport library (http://qextserialport.sourceforge.net/)
  • Started the Documation M200 Client device driver (well, just created the directory structure and qmake project file infrastructure)
  • At the current state, the complete project compiles :-)

Statistics: About 3500 Lines of code (without libqextserialport)

-- sven @ workstation

  • Property svn:executable set to *
File size: 29.6 KB
Line 
1/*!
2\class Win_QextSerialPort
3\version 1.0.0
4\author Stefan Sander
5
6A cross-platform serial port class.
7This class encapsulates the Windows portion of QextSerialPort.  The user will be notified of
8errors and possible portability conflicts at run-time by default - this behavior can be turned
9off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off
10portability warnings) in the project.  Note that defining _TTY_NOWARN_ also defines
11_TTY_NOWARN_PORT_.
12
13\note
14On Windows NT/2000/XP this class uses Win32 serial port functions by default.  The user may
15select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can
16make 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()
25Default constructor.  Note that the name of the device used by a Win_QextSerialPort constructed
26with this constructor will be determined by #defined constants, or lack thereof - the default
27behavior is the same as _TTY_LINUX_.  Possible naming conventions and their associated constants
28are:
29
30\verbatim
31
32Constant         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
44This constructor associates the object with the first port on the system, e.g. COM1 for Windows
45platforms.  See the other constructor if you need a port other than the first.
46*/
47Win_QextSerialPort::Win_QextSerialPort():QextSerialBase() {
48    Win_Handle=INVALID_HANDLE_VALUE;
49}
50
51/*!Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort&)
52Copy constructor.
53*/
54Win_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)
71Constructs a serial port attached to the port specified by devName.
72devName is the name of the device, which is windowsystem-specific,
73e.g."COM2" or "/dev/ttyS0".
74*/
75Win_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)
81Constructs a port with default name and specified settings.
82*/
83Win_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)
95Constructs a port with specified name and settings.
96*/
97Win_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()
110Standard destructor.
111*/
112Win_QextSerialPort::~Win_QextSerialPort() {
113    if (isOpen()) {
114        close();
115    }
116}
117
118/*!
119\fn Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s)
120overrides the = operator
121*/
122Win_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)
139Opens a serial port.  Note that this function does not specify which device to open.  If you need
140to open a device by name, see Win_QextSerialPort::open(const char*).  This function has no effect
141if the port associated with the class is already open.  The port is also configured to the current
142settings, as stored in the Settings structure.
143*/
144bool 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()
184Closes a serial port.  This function has no effect if the serial port associated with the class
185is not currently open.
186*/
187void 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()
196Flushes all pending I/O to the serial port.  This function has no effect if the serial port
197associated with the class is not currently open.
198*/
199void 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
209This function will return the number of bytes waiting in the receive queue of the serial port.
210It is included primarily to provide a complete QIODevice interface, and will not record errors
211in the lastErr member (because it is const).  This function is also not thread-safe - in
212multithreading situations, use Win_QextSerialPort::bytesAvailable() instead.
213*/
214qint64 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()
225Returns the number of bytes waiting in the port's receive queue.  This function will return 0 if
226the port is not currently open, or -1 on error.  Error information can be retrieved by calling
227Win_QextSerialPort::getLastError().
228*/
229qint64 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)
250Translates a system-specific error code to a QextSerialPort error code.  Used internally.
251*/
252void 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)
281Reads a block of data from the serial port.  This function will read at most maxlen bytes from
282the serial port and place them in the buffer pointed to by data.  Return value is the number of
283bytes actually read, or -1 on error.
284
285\warning before calling this function ensure that serial port associated with this class
286is currently open (use isOpen() function to check if port is open).
287*/
288qint64 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)
312Writes a block of data to the serial port.  This function will write len bytes
313from the buffer pointed to by data to the serial port.  Return value is the number
314of bytes actually written, or -1 on error.
315
316\warning before calling this function ensure that serial port associated with this class
317is currently open (use isOpen() function to check if port is open).
318*/
319qint64 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)
339This function is included to implement the full QIODevice interface, and currently has no
340purpose within this class.  This function is meaningless on an unbuffered device and currently
341only prints a warning message to that effect.
342*/
343void 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)
351Sets 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*/
358void 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)
398Sets 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*/
407void 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)
452Sets 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
461This 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*/
470void 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)
533Sets 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
541This 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*/
549void 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)
597Sets the baud rate of the serial port.  Note that not all rates are applicable on
598all platforms.  The following table shows translations of the various baud rate
599constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
600are 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*/
629void 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)
785Sets DTR line to the requested state (high by default).  This function will have no effect if
786the port associated with the class is not currently open.
787*/
788void 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)
803Sets RTS line to the requested state (high by default).  This function will have no effect if
804the port associated with the class is not currently open.
805*/
806void 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)
821returns the line status as stored by the port function.  This function will retrieve the states
822of the following lines: DCD, CTS, DSR, and RI.  On POSIX systems, the following additional lines
823can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD.  The value returned is an unsigned
824long with specific bits indicating which lines are high.  The following constants should be used
825to examine the states of individual lines:
826
827\verbatim
828Mask        Line
829------      ----
830LS_CTS      CTS
831LS_DSR      DSR
832LS_DCD      DCD
833LS_RI       RI
834\endverbatim
835
836This function will return 0 if the port associated with the class is not currently open.
837*/
838ulong 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);
862Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
863*/
864void 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}
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License