SerialLink.cc 21 KB
Newer Older
pixhawk's avatar
pixhawk committed
1
2
3
4
5
6
7
8
9
10
11
12
/*=====================================================================
======================================================================*/
/**
 * @file
 *   @brief Cross-platform support for serial ports
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include <QTimer>
#include <QDebug>
pixhawk's avatar
pixhawk committed
13
#include <QSettings>
pixhawk's avatar
pixhawk committed
14
15
16
#include <QMutexLocker>
#include "SerialLink.h"
#include "LinkManager.h"
pixhawk's avatar
pixhawk committed
17
#include "QGC.h"
pixhawk's avatar
pixhawk committed
18
#include <MG.h>
19
#include <iostream>
pixhawk's avatar
pixhawk committed
20
21
22
23
#ifdef _WIN32
#include "windows.h"
#endif

24
25
using namespace TNX;

26
//#define USE_QEXTSERIAL // this allows us to revert to old serial library during transition
pixhawk's avatar
pixhawk committed
27

28
29
SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, bool parity,
                       int dataBits, int stopBits) :
30
    port(NULL)
pixhawk's avatar
pixhawk committed
31
32
33
34
35
36
{
    // Setup settings
    this->porthandle = portname.trimmed();
#ifdef _WIN32
    // Port names above 20 need the network path format - if the port name is not already in this format
    // catch this special case
37
    if (this->porthandle.size() > 0 && !this->porthandle.startsWith("\\")) {
pixhawk's avatar
pixhawk committed
38
39
40
41
42
43
        // Append \\.\ before the port handle. Additional backslashes are used for escaping.
        this->porthandle = "\\\\.\\" + this->porthandle;
    }
#endif
    // Set unique ID and add link to the list of links
    this->id = getNextLinkId();
pixhawk's avatar
pixhawk committed
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    setBaudRate(baudRate);
    if (hardwareFlowControl)
    {
        portSettings.setFlowControl(QPortSettings::FLOW_HARDWARE);
    }
    else
    {
        portSettings.setFlowControl(QPortSettings::FLOW_OFF);
    }
    if (parity)
    {
        portSettings.setParity(QPortSettings::PAR_EVEN);
    }
    else
    {
        portSettings.setParity(QPortSettings::PAR_NONE);
    }
    setDataBits(dataBits);
    setStopBits(stopBits);
pixhawk's avatar
pixhawk committed
64
65

    // Set the port name
66
67
    if (porthandle == "")
    {
68
        name = tr("Serial Link ") + QString::number(getId());
pixhawk's avatar
pixhawk committed
69
    }
70
71
72
    else
    {
        name = portname.trimmed();
pixhawk's avatar
pixhawk committed
73
    }
lm's avatar
lm committed
74
    loadSettings();
pixhawk's avatar
pixhawk committed
75
76
77
78
79
}

SerialLink::~SerialLink()
{
    disconnect();
80
    if(port) delete port;
pixhawk's avatar
pixhawk committed
81
82
83
    port = NULL;
}

84
85
86
87
88
void SerialLink::loadSettings()
{
    // Load defaults from settings
    QSettings settings(QGC::COMPANYNAME, QGC::APPNAME);
    settings.sync();
89
    if (settings.contains("SERIALLINK_COMM_PORT")) {
90
        if (porthandle == "") setPortName(settings.value("SERIALLINK_COMM_PORT").toString());
91
92
        setBaudRateType(settings.value("SERIALLINK_COMM_BAUD").toInt());
        setParityType(settings.value("SERIALLINK_COMM_PARITY").toInt());
93
94
95
        setStopBits(settings.value("SERIALLINK_COMM_STOPBITS").toInt());
        setDataBits(settings.value("SERIALLINK_COMM_DATABITS").toInt());
        setFlowType(settings.value("SERIALLINK_COMM_FLOW_CONTROL").toInt());
96
97
98
99
100
101
102
103
104
105
    }
}

void SerialLink::writeSettings()
{
    // Store settings
    QSettings settings(QGC::COMPANYNAME, QGC::APPNAME);
    settings.setValue("SERIALLINK_COMM_PORT", this->porthandle);
    settings.setValue("SERIALLINK_COMM_BAUD", getBaudRateType());
    settings.setValue("SERIALLINK_COMM_PARITY", getParityType());
106
107
108
    settings.setValue("SERIALLINK_COMM_STOPBITS", getStopBits());
    settings.setValue("SERIALLINK_COMM_DATABITS", getDataBits());
    settings.setValue("SERIALLINK_COMM_FLOW_CONTROL", getFlowType());
109
110
111
    settings.sync();
}

pixhawk's avatar
pixhawk committed
112
113
114
115
116

/**
 * @brief Runs the thread
 *
 **/
117
118
void SerialLink::run()
{
pixhawk's avatar
pixhawk committed
119
120
121
122
    // Initialize the connection
    hardwareConnect();

    // Qt way to make clear what a while(1) loop does
123
    forever {
pixhawk's avatar
pixhawk committed
124
125
126
127
128
129
130
131
132
133
        // Check if new bytes have arrived, if yes, emit the notification signal
        checkForBytes();
        /* Serial data isn't arriving that fast normally, this saves the thread
                 * from consuming too much processing time
                 */
        MG::SLEEP::msleep(SerialLink::poll_interval);
    }
}


134
135
void SerialLink::checkForBytes()
{
pixhawk's avatar
pixhawk committed
136
    /* Check if bytes are available */
137
    if(port && port->isOpen() && port->isWritable()) {
pixhawk's avatar
pixhawk committed
138
139
140
141
        dataMutex.lock();
        qint64 available = port->bytesAvailable();
        dataMutex.unlock();

142
        if(available > 0) {
143
            readBytes();
pixhawk's avatar
pixhawk committed
144
        }
145
    } else {
pixhawk's avatar
pixhawk committed
146
147
148
149
150
        emit disconnected();
    }

}

151
152
void SerialLink::writeBytes(const char* data, qint64 size)
{
153
    if(port && port->isOpen()) {
pixhawk's avatar
pixhawk committed
154
155
        int b = port->write(data, size);

156
        if (b > 0) {
157

158
//            qDebug() << "Serial link " << this->getName() << "transmitted" << b << "bytes:";
pixhawk's avatar
pixhawk committed
159

160
161
162
            // Increase write counter
            bitsSentTotal += size * 8;

163
164
165
166
167
168
169
//            int i;
//            for (i=0; i<size; i++)
//            {
//                unsigned char v =data[i];
//                qDebug("%02x ", v);
//            }
//            qDebug("\n");
170
        } else {
171
172
173
            disconnect();
            // Error occured
            emit communicationError(this->getName(), tr("Could not send data - link %1 is disconnected!").arg(this->getName()));
174
        }
pixhawk's avatar
pixhawk committed
175
176
177
178
179
180
181
182
183
    }
}

/**
 * @brief Read a number of bytes from the interface.
 *
 * @param data Pointer to the data byte array to write the bytes to
 * @param maxLength The maximum number of bytes to write
 **/
184
185
void SerialLink::readBytes()
{
pixhawk's avatar
pixhawk committed
186
    dataMutex.lock();
187
    if(port && port->isOpen()) {
188
189
        const qint64 maxLength = 2048;
        char data[maxLength];
pixhawk's avatar
pixhawk committed
190
        qint64 numBytes = port->bytesAvailable();
James Goppert's avatar
James Goppert committed
191
        //qDebug() << "numBytes: " << numBytes;
192

193
        if(numBytes > 0) {
pixhawk's avatar
pixhawk committed
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
            /* Read as much data in buffer as possible without overflow */
            if(maxLength < numBytes) numBytes = maxLength;

            port->read(data, numBytes);
            QByteArray b(data, numBytes);
            emit bytesReceived(this, b);

            //qDebug() << "SerialLink::readBytes()" << std::hex << data;
            //            int i;
            //            for (i=0; i<numBytes; i++){
            //                unsigned int v=data[i];
            //
            //                fprintf(stderr,"%02x ", v);
            //            }
            //            fprintf(stderr,"\n");
            bitsReceivedTotal += numBytes * 8;
        }
    }
    dataMutex.unlock();
}


/**
 * @brief Get the number of bytes to read.
 *
 * @return The number of bytes to read
 **/
221
222
qint64 SerialLink::bytesAvailable()
{
223
    if (port) {
224
        return port->bytesAvailable();
225
    } else {
226
227
        return 0;
    }
pixhawk's avatar
pixhawk committed
228
229
230
231
232
233
234
}

/**
 * @brief Disconnect the connection.
 *
 * @return True if connection has been disconnected, false if connection couldn't be disconnected.
 **/
235
236
bool SerialLink::disconnect()
{
237
    if (port) {
238
239
240
241
        //#if !defined _WIN32 || !defined _WIN64
        /* Block the thread until it returns from run() */
        //#endif
//        dataMutex.lock();
242
243
        port->flushInBuffer();
        port->flushOutBuffer();
244
245
246
247
        port->close();
        delete port;
        port = NULL;
//        dataMutex.unlock();
pixhawk's avatar
pixhawk committed
248

249
        if(this->isRunning()) this->terminate(); //stop running the thread, restart it upon connect
250

251
252
        bool closed = true;
        //port->isOpen();
pixhawk's avatar
pixhawk committed
253

254
255
        emit disconnected();
        emit connected(false);
256
        return closed;
257
    } else {
258
259
260
        // No port, so we're disconnected
        return true;
    }
pixhawk's avatar
pixhawk committed
261
262
263
264
265
266
267
268
269
270

}

/**
 * @brief Connect the connection.
 *
 * @return True if connection has been established, false if connection couldn't be established.
 **/
bool SerialLink::connect()
{
271
272
    if (this->isRunning()) this->disconnect();
    this->start(LowPriority);
273
    return true;
pixhawk's avatar
pixhawk committed
274
275
276
277
278
279
280
281
282
283
}

/**
 * @brief This function is called indirectly by the connect() call.
 *
 * The connect() function starts the thread and indirectly calls this method.
 *
 * @return True if the connection could be established, false otherwise
 * @see connect() For the right function to establish the connection.
 **/
284
285
bool SerialLink::hardwareConnect()
{
286
    if(port) {
287
288
289
        port->close();
        delete port;
    }
290
291
292
    port = new QSerialPort(porthandle, portSettings);
    QObject::connect(port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected()));
    port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead);
pixhawk's avatar
pixhawk committed
293
294
    connectionStartTime = MG::TIME::getGroundTimeNow();

295
296
    port->open();

pixhawk's avatar
pixhawk committed
297
    bool connectionUp = isConnected();
298
    if(connectionUp) {
pixhawk's avatar
pixhawk committed
299
300
301
302
        emit connected();
        emit connected(true);
    }

303
    //qDebug() << "CONNECTING LINK: " << __FILE__ << __LINE__ << "with settings" << port->portName() << getBaudRate() << getDataBits() << getParityType() << getStopBits();
304
305


306
307
    writeSettings();

pixhawk's avatar
pixhawk committed
308
309
    return connectionUp;
}
310
311


pixhawk's avatar
pixhawk committed
312
313
314
315
316
/**
 * @brief Check if connection is active.
 *
 * @return True if link is connected, false otherwise.
 **/
317
318
bool SerialLink::isConnected()
{
319
    if (port) {
lm's avatar
lm committed
320
        return port->isOpen();
321
    } else {
lm's avatar
lm committed
322
323
        return false;
    }
pixhawk's avatar
pixhawk committed
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
}

int SerialLink::getId()
{
    return id;
}

QString SerialLink::getName()
{
    return name;
}

void SerialLink::setName(QString name)
{
    this->name = name;
    emit nameChanged(this->name);
}


343
344
qint64 SerialLink::getNominalDataRate()
{
pixhawk's avatar
pixhawk committed
345
    qint64 dataRate = 0;
346
    switch (portSettings.baudRate()) {
347
#ifndef Q_OS_WIN
348
    case QPortSettings::BAUDR_50:
pixhawk's avatar
pixhawk committed
349
350
        dataRate = 50;
        break;
351
    case QPortSettings::BAUDR_75:
pixhawk's avatar
pixhawk committed
352
353
        dataRate = 75;
        break;
354
    case QPortSettings::BAUDR_110:
pixhawk's avatar
pixhawk committed
355
356
        dataRate = 110;
        break;
357
    case QPortSettings::BAUDR_134:
pixhawk's avatar
pixhawk committed
358
359
        dataRate = 134;
        break;
360
    case QPortSettings::BAUDR_150:
pixhawk's avatar
pixhawk committed
361
362
        dataRate = 150;
        break;
363
    case QPortSettings::BAUDR_200:
pixhawk's avatar
pixhawk committed
364
365
        dataRate = 200;
        break;
366
#endif
367
    case QPortSettings::BAUDR_300:
pixhawk's avatar
pixhawk committed
368
369
        dataRate = 300;
        break;
370
    case QPortSettings::BAUDR_600:
pixhawk's avatar
pixhawk committed
371
372
        dataRate = 600;
        break;
373
    case QPortSettings::BAUDR_1200:
pixhawk's avatar
pixhawk committed
374
375
        dataRate = 1200;
        break;
376
#ifndef Q_OS_WIN
377
    case QPortSettings::BAUDR_1800:
pixhawk's avatar
pixhawk committed
378
379
        dataRate = 1800;
        break;
380
#endif
381
    case QPortSettings::BAUDR_2400:
pixhawk's avatar
pixhawk committed
382
383
        dataRate = 2400;
        break;
384
    case QPortSettings::BAUDR_4800:
pixhawk's avatar
pixhawk committed
385
386
        dataRate = 4800;
        break;
387
    case QPortSettings::BAUDR_9600:
pixhawk's avatar
pixhawk committed
388
389
        dataRate = 9600;
        break;
390
391
#ifdef Q_OS_WIN
    case QPortSettings::BAUDR_14400:
pixhawk's avatar
pixhawk committed
392
393
        dataRate = 14400;
        break;
394
395
#endif
    case QPortSettings::BAUDR_19200:
pixhawk's avatar
pixhawk committed
396
397
        dataRate = 19200;
        break;
398
    case QPortSettings::BAUDR_38400:
pixhawk's avatar
pixhawk committed
399
400
        dataRate = 38400;
        break;
401
402
#ifdef Q_OS_WIN
    case QPortSettings::BAUDR_56000:
pixhawk's avatar
pixhawk committed
403
404
        dataRate = 56000;
        break;
405
406
#endif
    case QPortSettings::BAUDR_57600:
pixhawk's avatar
pixhawk committed
407
408
        dataRate = 57600;
        break;
409
#ifdef Q_OS_WIN_XXXX // FIXME
410
    case QPortSettings::BAUDR_76800:
pixhawk's avatar
pixhawk committed
411
412
        dataRate = 76800;
        break;
413
414
#endif
    case QPortSettings::BAUDR_115200:
pixhawk's avatar
pixhawk committed
415
416
        dataRate = 115200;
        break;
417
418
419
#ifdef Q_OS_WIN
        // Windows-specific high-end baudrates
    case QPortSettings::BAUDR_128000:
pixhawk's avatar
pixhawk committed
420
421
        dataRate = 128000;
        break;
422
    case QPortSettings::BAUDR_256000:
pixhawk's avatar
pixhawk committed
423
        dataRate = 256000;
424
    case QPortSettings::BAUDR_230400:
425
        dataRate = 230400;
426
    case QPortSettings::BAUDR_460800:
427
        dataRate = 460800;
428
429
430
#endif
        // All-OS high-speed
    case QPortSettings::BAUDR_921600:
431
        dataRate = 921600;
pixhawk's avatar
pixhawk committed
432
        break;
433
434
435
436
    case QPortSettings::BAUDR_UNKNOWN:
        default:
        // Do nothing
        break;
pixhawk's avatar
pixhawk committed
437
438
439
440
    }
    return dataRate;
}

441
442
qint64 SerialLink::getTotalUpstream()
{
pixhawk's avatar
pixhawk committed
443
444
445
446
447
    statisticsMutex.lock();
    return bitsSentTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000);
    statisticsMutex.unlock();
}

448
449
qint64 SerialLink::getCurrentUpstream()
{
pixhawk's avatar
pixhawk committed
450
451
452
    return 0; // TODO
}

453
454
qint64 SerialLink::getMaxUpstream()
{
pixhawk's avatar
pixhawk committed
455
456
457
    return 0; // TODO
}

458
459
qint64 SerialLink::getBitsSent()
{
pixhawk's avatar
pixhawk committed
460
461
462
    return bitsSentTotal;
}

463
464
qint64 SerialLink::getBitsReceived()
{
pixhawk's avatar
pixhawk committed
465
466
467
    return bitsReceivedTotal;
}

468
469
qint64 SerialLink::getTotalDownstream()
{
pixhawk's avatar
pixhawk committed
470
471
472
473
474
    statisticsMutex.lock();
    return bitsReceivedTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000);
    statisticsMutex.unlock();
}

475
476
qint64 SerialLink::getCurrentDownstream()
{
pixhawk's avatar
pixhawk committed
477
478
479
    return 0; // TODO
}

480
481
qint64 SerialLink::getMaxDownstream()
{
pixhawk's avatar
pixhawk committed
482
483
484
    return 0; // TODO
}

485
486
bool SerialLink::isFullDuplex()
{
pixhawk's avatar
pixhawk committed
487
488
489
490
    /* Serial connections are always half duplex */
    return false;
}

491
492
int SerialLink::getLinkQuality()
{
pixhawk's avatar
pixhawk committed
493
494
495
496
    /* This feature is not supported with this interface */
    return -1;
}

497
498
QString SerialLink::getPortName()
{
pixhawk's avatar
pixhawk committed
499
500
501
    return porthandle;
}

502
503
int SerialLink::getBaudRate()
{
pixhawk's avatar
pixhawk committed
504
505
506
    return getNominalDataRate();
}

507
508
int SerialLink::getBaudRateType()
{
509
    return portSettings.baudRate();
pixhawk's avatar
pixhawk committed
510
511
}

512
513
int SerialLink::getFlowType()
{
514
    return portSettings.flowControl();
pixhawk's avatar
pixhawk committed
515
516
}

517
518
int SerialLink::getParityType()
{
519
    return portSettings.parity();
pixhawk's avatar
pixhawk committed
520
521
}

522
523
int SerialLink::getDataBitsType()
{
524
    return portSettings.dataBits();
pixhawk's avatar
pixhawk committed
525
526
}

527
528
int SerialLink::getStopBitsType()
{
529
    return portSettings.stopBits();
pixhawk's avatar
pixhawk committed
530
531
}

532
533
int SerialLink::getDataBits()
{
534
535
536
    int ret = -1;
    switch (portSettings.dataBits()) {
    case QPortSettings::DB_5:
537
538
        ret = 5;
        break;
539
    case QPortSettings::DB_6:
540
541
        ret = 6;
        break;
542
    case QPortSettings::DB_7:
543
544
        ret = 7;
        break;
545
    case QPortSettings::DB_8:
546
547
548
        ret = 8;
        break;
    default:
549
        ret = -1;
550
551
552
553
554
555
556
        break;
    }
    return ret;
}

int SerialLink::getStopBits()
{
557
558
559
560
561
562
563
564
565
566
567
568
    int ret = -1;
        switch (portSettings.stopBits()) {
        case QPortSettings::STOP_1:
            ret = 1;
            break;
        case QPortSettings::STOP_2:
            ret = 2;
            break;
        default:
            ret = -1;
            break;
        }
569
570
571
    return ret;
}

pixhawk's avatar
pixhawk committed
572
573
bool SerialLink::setPortName(QString portName)
{
574
    if(portName.trimmed().length() > 0) {
pixhawk's avatar
pixhawk committed
575
        bool reconnect = false;
576
577
578
        if (isConnected()) reconnect = true;
        disconnect();

pixhawk's avatar
pixhawk committed
579
580
581
582
583
        this->porthandle = portName.trimmed();
        setName(tr("serial port ") + portName.trimmed());
#ifdef _WIN32
        // Port names above 20 need the network path format - if the port name is not already in this format
        // catch this special case
584
        if (!this->porthandle.startsWith("\\")) {
pixhawk's avatar
pixhawk committed
585
586
587
588
            // Append \\.\ before the port handle. Additional backslashes are used for escaping.
            this->porthandle = "\\\\.\\" + this->porthandle;
        }
#endif
589

pixhawk's avatar
pixhawk committed
590
591
        if(reconnect) connect();
        return true;
592
    } else {
pixhawk's avatar
pixhawk committed
593
594
595
596
597
598
599
600
601
        return false;
    }
}


bool SerialLink::setBaudRateType(int rateIndex)
{
    bool reconnect = false;
    bool accepted = true; // This is changed if none of the data rates matches
602
603
604
    if(isConnected()) reconnect = true;
    disconnect();

605
606
607
608
609
610
611
#ifdef Q_OS_WIN
	const int minBaud = (int)QPortSettings::BAUDR_14400;
#else
	const int minBaud = (int)QPortSettings::BAUDR_50;
#endif

    if (rateIndex >= minBaud && rateIndex <= (int)QPortSettings::BAUDR_921600)
612
613
    {
        portSettings.setBaudRate((QPortSettings::BaudRate)rateIndex);
pixhawk's avatar
pixhawk committed
614
615
616
617
618
619
    }

    if(reconnect) connect();
    return accepted;
}

620
621
622
623
624
625
626
bool SerialLink::setBaudRateString(const QString& rate)
{
    bool ok;
    int intrate = rate.toInt(&ok);
    if (!ok) return false;
    return setBaudRate(intrate);
}
pixhawk's avatar
pixhawk committed
627
628
629

bool SerialLink::setBaudRate(int rate)
{
630
    //qDebug() << "BAUD RATE:" << rate;
631

pixhawk's avatar
pixhawk committed
632
633
    bool reconnect = false;
    bool accepted = true; // This is changed if none of the data rates matches
634
    if(isConnected()) {
pixhawk's avatar
pixhawk committed
635
636
        reconnect = true;
    }
637
    disconnect();
pixhawk's avatar
pixhawk committed
638

639
    switch (rate) {
640
641

#ifndef Q_OS_WIN
pixhawk's avatar
pixhawk committed
642
    case 50:
643
        portSettings.setBaudRate(QPortSettings::BAUDR_50);
pixhawk's avatar
pixhawk committed
644
645
        break;
    case 75:
646
        portSettings.setBaudRate(QPortSettings::BAUDR_75);
pixhawk's avatar
pixhawk committed
647
648
        break;
    case 110:
649
        portSettings.setBaudRate(QPortSettings::BAUDR_110);
pixhawk's avatar
pixhawk committed
650
651
        break;
    case 134:
652
        portSettings.setBaudRate(QPortSettings::BAUDR_134);
pixhawk's avatar
pixhawk committed
653
654
        break;
    case 150:
655
        portSettings.setBaudRate(QPortSettings::BAUDR_150);
pixhawk's avatar
pixhawk committed
656
657
        break;
    case 200:
658
        portSettings.setBaudRate(QPortSettings::BAUDR_200);
pixhawk's avatar
pixhawk committed
659
        break;
660
#endif
pixhawk's avatar
pixhawk committed
661
    case 300:
662
        portSettings.setBaudRate(QPortSettings::BAUDR_300);
pixhawk's avatar
pixhawk committed
663
664
        break;
    case 600:
665
        portSettings.setBaudRate(QPortSettings::BAUDR_600);
pixhawk's avatar
pixhawk committed
666
667
        break;
    case 1200:
668
        portSettings.setBaudRate(QPortSettings::BAUDR_1200);
pixhawk's avatar
pixhawk committed
669
        break;
670
#ifndef Q_OS_WIN
pixhawk's avatar
pixhawk committed
671
    case 1800:
672
        portSettings.setBaudRate(QPortSettings::BAUDR_1800);
pixhawk's avatar
pixhawk committed
673
        break;
674
#endif
pixhawk's avatar
pixhawk committed
675
    case 2400:
676
        portSettings.setBaudRate(QPortSettings::BAUDR_2400);
pixhawk's avatar
pixhawk committed
677
678
        break;
    case 4800:
679
        portSettings.setBaudRate(QPortSettings::BAUDR_4800);
pixhawk's avatar
pixhawk committed
680
681
        break;
    case 9600:
682
        portSettings.setBaudRate(QPortSettings::BAUDR_9600);
pixhawk's avatar
pixhawk committed
683
        break;
684
#ifdef Q_OS_WIN
pixhawk's avatar
pixhawk committed
685
    case 14400:
686
        portSettings.setBaudRate(QPortSettings::BAUDR_14400);
pixhawk's avatar
pixhawk committed
687
        break;
688
#endif
pixhawk's avatar
pixhawk committed
689
    case 19200:
690
        portSettings.setBaudRate(QPortSettings::BAUDR_19200);
pixhawk's avatar
pixhawk committed
691
692
        break;
    case 38400:
693
        portSettings.setBaudRate(QPortSettings::BAUDR_38400);
pixhawk's avatar
pixhawk committed
694
        break;
695
#ifdef Q_OS_WIN
pixhawk's avatar
pixhawk committed
696
    case 56000:
697
        portSettings.setBaudRate(QPortSettings::BAUDR_56000);
pixhawk's avatar
pixhawk committed
698
        break;
699
#endif
pixhawk's avatar
pixhawk committed
700
    case 57600:
701
        portSettings.setBaudRate(QPortSettings::BAUDR_57600);
pixhawk's avatar
pixhawk committed
702
        break;
703
#ifdef Q_OS_WIN_XXXX // FIXME CHECK THIS
pixhawk's avatar
pixhawk committed
704
    case 76800:
705
        portSettings.setBaudRate(QPortSettings::BAUDR_76800);
pixhawk's avatar
pixhawk committed
706
        break;
707
#endif
pixhawk's avatar
pixhawk committed
708
    case 115200:
709
        portSettings.setBaudRate(QPortSettings::BAUDR_115200);
pixhawk's avatar
pixhawk committed
710
        break;
711
#ifdef Q_OS_WIN
pixhawk's avatar
pixhawk committed
712
    case 128000:
713
        portSettings.setBaudRate(QPortSettings::BAUDR_128000);
pixhawk's avatar
pixhawk committed
714
        break;
715
    case 230400:
716
        portSettings.setBaudRate(QPortSettings::BAUDR_230400);
717
        break;
pixhawk's avatar
pixhawk committed
718
    case 256000:
719
        portSettings.setBaudRate(QPortSettings::BAUDR_256000);
pixhawk's avatar
pixhawk committed
720
        break;
721
    case 460800:
722
        portSettings.setBaudRate(QPortSettings::BAUDR_460800);
723
        break;
724
#endif
725
    case 921600:
726
        portSettings.setBaudRate(QPortSettings::BAUDR_921600);
727
        break;
pixhawk's avatar
pixhawk committed
728
729
730
731
732
733
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

734
735
736
    if(reconnect) connect();
    return accepted;

pixhawk's avatar
pixhawk committed
737
738
}

739
740
bool SerialLink::setFlowType(int flow)
{
pixhawk's avatar
pixhawk committed
741
742
    bool reconnect = false;
    bool accepted = true;
743
744
    if(isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
745

746
    switch (flow) {
747
748
    case (int)QPortSettings::FLOW_OFF:
        portSettings.setFlowControl(QPortSettings::FLOW_OFF);
pixhawk's avatar
pixhawk committed
749
        break;
750
751
    case (int)QPortSettings::FLOW_HARDWARE:
        portSettings.setFlowControl(QPortSettings::FLOW_HARDWARE);
pixhawk's avatar
pixhawk committed
752
        break;
753
754
    case (int)QPortSettings::FLOW_XONXOFF:
        portSettings.setFlowControl(QPortSettings::FLOW_XONXOFF);
pixhawk's avatar
pixhawk committed
755
756
757
758
759
760
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }
761

pixhawk's avatar
pixhawk committed
762
763
764
765
    if(reconnect) connect();
    return accepted;
}

766
767
bool SerialLink::setParityType(int parity)
{
pixhawk's avatar
pixhawk committed
768
769
    bool reconnect = false;
    bool accepted = true;
770
771
    if (isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
772

773
    switch (parity) {
774
775
    case (int)QPortSettings::PAR_NONE:
        portSettings.setParity(QPortSettings::PAR_NONE);
pixhawk's avatar
pixhawk committed
776
        break;
777
778
    case (int)QPortSettings::PAR_ODD:
        portSettings.setParity(QPortSettings::PAR_ODD);
pixhawk's avatar
pixhawk committed
779
        break;
780
781
    case (int)QPortSettings::PAR_EVEN:
        portSettings.setParity(QPortSettings::PAR_EVEN);
pixhawk's avatar
pixhawk committed
782
        break;
783
784
    case (int)QPortSettings::PAR_SPACE:
        portSettings.setParity(QPortSettings::PAR_SPACE);
pixhawk's avatar
pixhawk committed
785
786
787
788
789
790
791
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

792
    if (reconnect) connect();
pixhawk's avatar
pixhawk committed
793
794
795
    return accepted;
}

796

797
bool SerialLink::setDataBits(int dataBits)
798
{
799
    //qDebug() << "Setting" << dataBits << "data bits";
800
801
    bool reconnect = false;
    if (isConnected()) reconnect = true;
pixhawk's avatar
pixhawk committed
802
    bool accepted = true;
803
    disconnect();
pixhawk's avatar
pixhawk committed
804

805
    switch (dataBits) {
pixhawk's avatar
pixhawk committed
806
    case 5:
807
        portSettings.setDataBits(QPortSettings::DB_5);
pixhawk's avatar
pixhawk committed
808
809
        break;
    case 6:
810
        portSettings.setDataBits(QPortSettings::DB_6);
pixhawk's avatar
pixhawk committed
811
812
        break;
    case 7:
813
        portSettings.setDataBits(QPortSettings::DB_7);
pixhawk's avatar
pixhawk committed
814
815
        break;
    case 8:
816
        portSettings.setDataBits(QPortSettings::DB_8);
pixhawk's avatar
pixhawk committed
817
818
819
820
821
822
823
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

824
    if(reconnect) connect();
pixhawk's avatar
pixhawk committed
825
826
827
828

    return accepted;
}

829
bool SerialLink::setStopBits(int stopBits)
830
{
pixhawk's avatar
pixhawk committed
831
832
    bool reconnect = false;
    bool accepted = true;
833
834
    if(isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
835

836
    switch (stopBits) {
pixhawk's avatar
pixhawk committed
837
    case 1:
838
        portSettings.setStopBits(QPortSettings::STOP_1);
pixhawk's avatar
pixhawk committed
839
840
        break;
    case 2:
841
        portSettings.setStopBits(QPortSettings::STOP_2);
pixhawk's avatar
pixhawk committed
842
843
844
845
846
847
848
849
850
851
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

    if(reconnect) connect();
    return accepted;
}
852
853
854
855
856
857

bool SerialLink::setDataBitsType(int dataBits)
{
    bool reconnect = false;
    bool accepted = false;

858
859
    if (isConnected()) reconnect = true;
    disconnect();
860

861
862
    if (dataBits >= (int)QPortSettings::DB_5 && dataBits <= (int)QPortSettings::DB_8) {
        portSettings.setDataBits((QPortSettings::DataBits) dataBits);
863

864
        if(reconnect) connect();
865
866
867
868
869
870
871
872
873
874
        accepted = true;
    }

    return accepted;
}

bool SerialLink::setStopBitsType(int stopBits)
{
    bool reconnect = false;
    bool accepted = false;
875
876
    if(isConnected()) reconnect = true;
    disconnect();
877

878
879
    if (stopBits >= (int)QPortSettings::STOP_1 && stopBits <= (int)QPortSettings::STOP_2) {
        portSettings.setStopBits((QPortSettings::StopBits) stopBits);
880

881
        if(reconnect) connect();
882
883
884
885
886
887
        accepted = true;
    }

    if(reconnect) connect();
    return accepted;
}