SerialLink.cc 22.3 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>
13
#include <QSettings>
pixhawk's avatar
pixhawk committed
14 15 16
#include <QMutexLocker>
#include "SerialLink.h"
#include "LinkManager.h"
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
//#define USE_QEXTSERIAL // this allows us to revert to old serial library during transition
pixhawk's avatar
pixhawk committed
25

26 27 28
SerialLink::SerialLink(QString portname, SerialInterface::baudRateType baudrate, SerialInterface::flowType flow, SerialInterface::parityType parity,
                       SerialInterface::dataBitsType dataBits, SerialInterface::stopBitsType stopBits) :
    port(NULL)
pixhawk's avatar
pixhawk committed
29 30 31 32 33 34
{
    // 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
35
    if (this->porthandle.size() > 0 && !this->porthandle.startsWith("\\")) {
pixhawk's avatar
pixhawk committed
36 37 38 39 40 41
        // 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();
42

43 44 45 46 47 48
    this->baudrate = baudrate;
    this->flow = flow;
    this->parity = parity;
    this->dataBits = dataBits;
    this->stopBits = stopBits;
    this->timeout = 1; ///< The timeout controls how long the program flow should wait for new serial bytes. As we're polling, we don't want to wait at all.
pixhawk's avatar
pixhawk committed
49 50

    // Set the port name
51
    if (porthandle == "") {
52
        //        name = tr("serial link ") + QString::number(getId()) + tr(" (unconfigured)");
53
        name = tr("Serial Link ") + QString::number(getId());
54
    } else {
pixhawk's avatar
pixhawk committed
55 56 57 58 59 60 61 62 63 64 65 66
        name = portname.trimmed();
    }

#ifdef _WIN3232
    // Windows 32bit & 64bit serial connection
    winPort = CreateFile(porthandle,
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         0,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);
67 68
    if(winPort==INVALID_HANDLE_VALUE) {
        if(GetLastError()==ERROR_FILE_NOT_FOUND) {
pixhawk's avatar
pixhawk committed
69 70 71 72 73
            //serial port does not exist. Inform user.
        }
        //some other error occurred. Inform user.
    }
#else
lm's avatar
lm committed
74

pixhawk's avatar
pixhawk committed
75 76
#endif

lm's avatar
lm committed
77
    loadSettings();
pixhawk's avatar
pixhawk committed
78 79 80 81 82
}

SerialLink::~SerialLink()
{
    disconnect();
83
    if(port) delete port;
pixhawk's avatar
pixhawk committed
84 85 86
    port = NULL;
}

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

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());
109 110 111
    settings.setValue("SERIALLINK_COMM_STOPBITS", getStopBits());
    settings.setValue("SERIALLINK_COMM_DATABITS", getDataBits());
    settings.setValue("SERIALLINK_COMM_FLOW_CONTROL", getFlowType());
112 113 114
    settings.sync();
}

pixhawk's avatar
pixhawk committed
115 116 117 118 119

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

    // Qt way to make clear what a while(1) loop does
126
    forever {
pixhawk's avatar
pixhawk committed
127 128 129 130 131 132 133 134 135 136
        // 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);
    }
}


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

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

}

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

159
        if (b > 0) {
160

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

163 164 165
            // Increase write counter
            bitsSentTotal += size * 8;

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

/**
 * @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
 **/
187 188
void SerialLink::readBytes()
{
pixhawk's avatar
pixhawk committed
189
    dataMutex.lock();
190
    if(port && port->isOpen()) {
191 192
        const qint64 maxLength = 2048;
        char data[maxLength];
pixhawk's avatar
pixhawk committed
193
        qint64 numBytes = port->bytesAvailable();
James Goppert's avatar
James Goppert committed
194
        //qDebug() << "numBytes: " << numBytes;
195

196
        if(numBytes > 0) {
pixhawk's avatar
pixhawk committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
            /* 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
 **/
224 225
qint64 SerialLink::bytesAvailable()
{
226
    if (port) {
227
        return port->bytesAvailable();
228
    } else {
229 230
        return 0;
    }
pixhawk's avatar
pixhawk committed
231 232 233 234 235 236 237
}

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

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

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

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

}

/**
 * @brief Connect the connection.
 *
 * @return True if connection has been established, false if connection couldn't be established.
 **/
bool SerialLink::connect()
{
273
    if (!isConnected()) {
274
        qDebug() << "CONNECTING LINK: " << __FILE__ << __LINE__ << "with settings" << porthandle << baudrate << dataBits << parity << stopBits;
275
        if (!this->isRunning()) {
276
            this->start(LowPriority);
pixhawk's avatar
pixhawk committed
277 278
        }
    }
279
    return true;
pixhawk's avatar
pixhawk committed
280 281 282 283 284 285 286 287 288 289
}

/**
 * @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.
 **/
290 291
bool SerialLink::hardwareConnect()
{
292
    if(port) {
293 294 295
        port->close();
        delete port;
    }
296
#ifdef USE_QEXTSERIAL
297
    port = new SerialQextserial(porthandle, QextSerialPort::Polling);
298 299 300
#else
    port = new SerialQserial(porthandle, QIODevice::ReadWrite);
#endif
pixhawk's avatar
pixhawk committed
301 302 303 304 305 306
    QObject::connect(port, SIGNAL(aboutToClose()), this, SIGNAL(disconnected()));
    port->open(QIODevice::ReadWrite);
    port->setBaudRate(this->baudrate);
    port->setParity(this->parity);
    port->setStopBits(this->stopBits);
    port->setDataBits(this->dataBits);
307
    port->setTimeout(timeout); // Timeout of 0 ms, we don't want to wait for data, we just poll again next time
pixhawk's avatar
pixhawk committed
308 309 310 311

    connectionStartTime = MG::TIME::getGroundTimeNow();

    bool connectionUp = isConnected();
312
    if(connectionUp) {
pixhawk's avatar
pixhawk committed
313 314 315 316
        emit connected();
        emit connected(true);
    }

317 318
    writeSettings();

pixhawk's avatar
pixhawk committed
319 320
    return connectionUp;
}
321 322


pixhawk's avatar
pixhawk committed
323 324 325 326 327
/**
 * @brief Check if connection is active.
 *
 * @return True if link is connected, false otherwise.
 **/
328 329
bool SerialLink::isConnected()
{
330
    if (port) {
lm's avatar
lm committed
331
        return port->isOpen();
332
    } else {
lm's avatar
lm committed
333 334
        return false;
    }
pixhawk's avatar
pixhawk committed
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
}

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

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

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


354 355
qint64 SerialLink::getNominalDataRate()
{
pixhawk's avatar
pixhawk committed
356
    qint64 dataRate = 0;
357
    switch (baudrate) {
358
    case SerialInterface::BAUD50:
pixhawk's avatar
pixhawk committed
359 360
        dataRate = 50;
        break;
361
    case SerialInterface::BAUD75:
pixhawk's avatar
pixhawk committed
362 363
        dataRate = 75;
        break;
364
    case SerialInterface::BAUD110:
pixhawk's avatar
pixhawk committed
365 366
        dataRate = 110;
        break;
367
    case SerialInterface::BAUD134:
pixhawk's avatar
pixhawk committed
368 369
        dataRate = 134;
        break;
370
    case SerialInterface::BAUD150:
pixhawk's avatar
pixhawk committed
371 372
        dataRate = 150;
        break;
373
    case SerialInterface::BAUD200:
pixhawk's avatar
pixhawk committed
374 375
        dataRate = 200;
        break;
376
    case SerialInterface::BAUD300:
pixhawk's avatar
pixhawk committed
377 378
        dataRate = 300;
        break;
379
    case SerialInterface::BAUD600:
pixhawk's avatar
pixhawk committed
380 381
        dataRate = 600;
        break;
382
    case SerialInterface::BAUD1200:
pixhawk's avatar
pixhawk committed
383 384
        dataRate = 1200;
        break;
385
    case SerialInterface::BAUD1800:
pixhawk's avatar
pixhawk committed
386 387
        dataRate = 1800;
        break;
388
    case SerialInterface::BAUD2400:
pixhawk's avatar
pixhawk committed
389 390
        dataRate = 2400;
        break;
391
    case SerialInterface::BAUD4800:
pixhawk's avatar
pixhawk committed
392 393
        dataRate = 4800;
        break;
394
    case SerialInterface::BAUD9600:
pixhawk's avatar
pixhawk committed
395 396
        dataRate = 9600;
        break;
397
    case SerialInterface::BAUD14400:
pixhawk's avatar
pixhawk committed
398 399
        dataRate = 14400;
        break;
400
    case SerialInterface::BAUD19200:
pixhawk's avatar
pixhawk committed
401 402
        dataRate = 19200;
        break;
403
    case SerialInterface::BAUD38400:
pixhawk's avatar
pixhawk committed
404 405
        dataRate = 38400;
        break;
406
    case SerialInterface::BAUD56000:
pixhawk's avatar
pixhawk committed
407 408
        dataRate = 56000;
        break;
409
    case SerialInterface::BAUD57600:
pixhawk's avatar
pixhawk committed
410 411
        dataRate = 57600;
        break;
412
    case SerialInterface::BAUD76800:
pixhawk's avatar
pixhawk committed
413 414
        dataRate = 76800;
        break;
415
    case SerialInterface::BAUD115200:
pixhawk's avatar
pixhawk committed
416 417
        dataRate = 115200;
        break;
418
    case SerialInterface::BAUD128000:
pixhawk's avatar
pixhawk committed
419 420
        dataRate = 128000;
        break;
421
    case SerialInterface::BAUD256000:
pixhawk's avatar
pixhawk committed
422
        dataRate = 256000;
423
        // Windows-specific high-end baudrates
424
    case SerialInterface::BAUD230400:
425
        dataRate = 230400;
426
    case SerialInterface::BAUD460800:
427
        dataRate = 460800;
428
    case SerialInterface::BAUD921600:
429
        dataRate = 921600;
pixhawk's avatar
pixhawk committed
430 431 432 433 434
        break;
    }
    return dataRate;
}

435 436
qint64 SerialLink::getTotalUpstream()
{
pixhawk's avatar
pixhawk committed
437 438 439 440 441
    statisticsMutex.lock();
    return bitsSentTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000);
    statisticsMutex.unlock();
}

442 443
qint64 SerialLink::getCurrentUpstream()
{
pixhawk's avatar
pixhawk committed
444 445 446
    return 0; // TODO
}

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

452 453
qint64 SerialLink::getBitsSent()
{
pixhawk's avatar
pixhawk committed
454 455 456
    return bitsSentTotal;
}

457 458
qint64 SerialLink::getBitsReceived()
{
pixhawk's avatar
pixhawk committed
459 460 461
    return bitsReceivedTotal;
}

462 463
qint64 SerialLink::getTotalDownstream()
{
pixhawk's avatar
pixhawk committed
464 465 466 467 468
    statisticsMutex.lock();
    return bitsReceivedTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000);
    statisticsMutex.unlock();
}

469 470
qint64 SerialLink::getCurrentDownstream()
{
pixhawk's avatar
pixhawk committed
471 472 473
    return 0; // TODO
}

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

479 480
bool SerialLink::isFullDuplex()
{
pixhawk's avatar
pixhawk committed
481 482 483 484
    /* Serial connections are always half duplex */
    return false;
}

485 486
int SerialLink::getLinkQuality()
{
pixhawk's avatar
pixhawk committed
487 488 489 490
    /* This feature is not supported with this interface */
    return -1;
}

491 492
QString SerialLink::getPortName()
{
pixhawk's avatar
pixhawk committed
493 494 495
    return porthandle;
}

496 497
int SerialLink::getBaudRate()
{
pixhawk's avatar
pixhawk committed
498 499 500
    return getNominalDataRate();
}

501 502
int SerialLink::getBaudRateType()
{
pixhawk's avatar
pixhawk committed
503 504 505
    return baudrate;
}

506 507
int SerialLink::getFlowType()
{
pixhawk's avatar
pixhawk committed
508 509 510
    return flow;
}

511 512
int SerialLink::getParityType()
{
pixhawk's avatar
pixhawk committed
513 514 515
    return parity;
}

516 517
int SerialLink::getDataBitsType()
{
pixhawk's avatar
pixhawk committed
518 519 520
    return dataBits;
}

521 522
int SerialLink::getStopBitsType()
{
pixhawk's avatar
pixhawk committed
523 524 525
    return stopBits;
}

526 527 528
int SerialLink::getDataBits()
{
    int ret;
529
    switch (dataBits) {
530
    case SerialInterface::DATA_5:
531 532
        ret = 5;
        break;
533
    case SerialInterface::DATA_6:
534 535
        ret = 6;
        break;
536
    case SerialInterface::DATA_7:
537 538
        ret = 7;
        break;
539
    case SerialInterface::DATA_8:
540 541 542 543 544 545 546 547 548 549 550 551
        ret = 8;
        break;
    default:
        ret = 0;
        break;
    }
    return ret;
}

int SerialLink::getStopBits()
{
    int ret;
552
    switch (stopBits) {
553
    case SerialInterface::STOP_1:
554 555
        ret = 1;
        break;
556
    case SerialInterface::STOP_2:
557 558 559 560 561 562 563 564 565
        ret = 2;
        break;
    default:
        ret = 0;
        break;
    }
    return ret;
}

pixhawk's avatar
pixhawk committed
566 567
bool SerialLink::setPortName(QString portName)
{
568
    if(portName.trimmed().length() > 0) {
pixhawk's avatar
pixhawk committed
569
        bool reconnect = false;
570 571 572
        if (isConnected()) reconnect = true;
        disconnect();

pixhawk's avatar
pixhawk committed
573 574 575 576 577
        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
578
        if (!this->porthandle.startsWith("\\")) {
pixhawk's avatar
pixhawk committed
579 580 581 582
            // Append \\.\ before the port handle. Additional backslashes are used for escaping.
            this->porthandle = "\\\\.\\" + this->porthandle;
        }
#endif
583

pixhawk's avatar
pixhawk committed
584 585
        if(reconnect) connect();
        return true;
586
    } else {
pixhawk's avatar
pixhawk committed
587 588 589 590 591 592 593 594 595
        return false;
    }
}


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

pixhawk's avatar
pixhawk committed
599 600
    switch (rateIndex) {
    case 0:
601
        baudrate = SerialInterface::BAUD50;
pixhawk's avatar
pixhawk committed
602 603
        break;
    case 1:
604
        baudrate = SerialInterface::BAUD75;
pixhawk's avatar
pixhawk committed
605 606
        break;
    case 2:
607
        baudrate = SerialInterface::BAUD110;
pixhawk's avatar
pixhawk committed
608 609
        break;
    case 3:
610
        baudrate = SerialInterface::BAUD134;
pixhawk's avatar
pixhawk committed
611 612
        break;
    case 4:
613
        baudrate = SerialInterface::BAUD150;
pixhawk's avatar
pixhawk committed
614 615
        break;
    case 5:
616
        baudrate = SerialInterface::BAUD200;
pixhawk's avatar
pixhawk committed
617 618
        break;
    case 6:
619
        baudrate = SerialInterface::BAUD300;
pixhawk's avatar
pixhawk committed
620 621
        break;
    case 7:
622
        baudrate = SerialInterface::BAUD600;
pixhawk's avatar
pixhawk committed
623 624
        break;
    case 8:
625
        baudrate = SerialInterface::BAUD1200;
pixhawk's avatar
pixhawk committed
626 627
        break;
    case 9:
628
        baudrate = SerialInterface::BAUD1800;
pixhawk's avatar
pixhawk committed
629 630
        break;
    case 10:
631
        baudrate = SerialInterface::BAUD2400;
pixhawk's avatar
pixhawk committed
632 633
        break;
    case 11:
634
        baudrate = SerialInterface::BAUD4800;
pixhawk's avatar
pixhawk committed
635 636
        break;
    case 12:
637
        baudrate = SerialInterface::BAUD9600;
pixhawk's avatar
pixhawk committed
638 639
        break;
    case 13:
640
        baudrate = SerialInterface::BAUD14400;
pixhawk's avatar
pixhawk committed
641 642
        break;
    case 14:
643
        baudrate = SerialInterface::BAUD19200;
pixhawk's avatar
pixhawk committed
644 645
        break;
    case 15:
646
        baudrate = SerialInterface::BAUD38400;
pixhawk's avatar
pixhawk committed
647 648
        break;
    case 16:
649
        baudrate = SerialInterface::BAUD56000;
pixhawk's avatar
pixhawk committed
650 651
        break;
    case 17:
652
        baudrate = SerialInterface::BAUD57600;
pixhawk's avatar
pixhawk committed
653 654
        break;
    case 18:
655
        baudrate = SerialInterface::BAUD76800;
pixhawk's avatar
pixhawk committed
656 657
        break;
    case 19:
658
        baudrate = SerialInterface::BAUD115200;
pixhawk's avatar
pixhawk committed
659 660
        break;
    case 20:
661
        baudrate = SerialInterface::BAUD128000;
pixhawk's avatar
pixhawk committed
662 663
        break;
    case 21:
664
        baudrate = SerialInterface::BAUD230400;
665 666
        break;
    case 22:
667
        baudrate = SerialInterface::BAUD256000;
pixhawk's avatar
pixhawk committed
668
        break;
669
    case 23:
670
        baudrate = SerialInterface::BAUD460800;
671 672
        break;
    case 24:
673
        baudrate = SerialInterface::BAUD921600;
674
        break;
pixhawk's avatar
pixhawk committed
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

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



bool SerialLink::setBaudRate(int rate)
{
    bool reconnect = false;
    bool accepted = true; // This is changed if none of the data rates matches
691
    if(isConnected()) {
pixhawk's avatar
pixhawk committed
692 693
        reconnect = true;
    }
694
    disconnect();
pixhawk's avatar
pixhawk committed
695

696
    switch (rate) {
pixhawk's avatar
pixhawk committed
697
    case 50:
698
        baudrate = SerialInterface::BAUD50;
pixhawk's avatar
pixhawk committed
699 700
        break;
    case 75:
701
        baudrate = SerialInterface::BAUD75;
pixhawk's avatar
pixhawk committed
702 703
        break;
    case 110:
704
        baudrate = SerialInterface::BAUD110;
pixhawk's avatar
pixhawk committed
705 706
        break;
    case 134:
707
        baudrate = SerialInterface::BAUD134;
pixhawk's avatar
pixhawk committed
708 709
        break;
    case 150:
710
        baudrate = SerialInterface::BAUD150;
pixhawk's avatar
pixhawk committed
711 712
        break;
    case 200:
713
        baudrate = SerialInterface::BAUD200;
pixhawk's avatar
pixhawk committed
714 715
        break;
    case 300:
716
        baudrate = SerialInterface::BAUD300;
pixhawk's avatar
pixhawk committed
717 718
        break;
    case 600:
719
        baudrate = SerialInterface::BAUD600;
pixhawk's avatar
pixhawk committed
720 721
        break;
    case 1200:
722
        baudrate = SerialInterface::BAUD1200;
pixhawk's avatar
pixhawk committed
723 724
        break;
    case 1800:
725
        baudrate = SerialInterface::BAUD1800;
pixhawk's avatar
pixhawk committed
726 727
        break;
    case 2400:
728
        baudrate = SerialInterface::BAUD2400;
pixhawk's avatar
pixhawk committed
729 730
        break;
    case 4800:
731
        baudrate = SerialInterface::BAUD4800;
pixhawk's avatar
pixhawk committed
732 733
        break;
    case 9600:
734
        baudrate = SerialInterface::BAUD9600;
pixhawk's avatar
pixhawk committed
735 736
        break;
    case 14400:
737
        baudrate = SerialInterface::BAUD14400;
pixhawk's avatar
pixhawk committed
738 739
        break;
    case 19200:
740
        baudrate = SerialInterface::BAUD19200;
pixhawk's avatar
pixhawk committed
741 742
        break;
    case 38400:
743
        baudrate = SerialInterface::BAUD38400;
pixhawk's avatar
pixhawk committed
744 745
        break;
    case 56000:
746
        baudrate = SerialInterface::BAUD56000;
pixhawk's avatar
pixhawk committed
747 748
        break;
    case 57600:
749
        baudrate = SerialInterface::BAUD57600;
pixhawk's avatar
pixhawk committed
750 751
        break;
    case 76800:
752
        baudrate = SerialInterface::BAUD76800;
pixhawk's avatar
pixhawk committed
753 754
        break;
    case 115200:
755
        baudrate = SerialInterface::BAUD115200;
pixhawk's avatar
pixhawk committed
756 757
        break;
    case 128000:
758
        baudrate = SerialInterface::BAUD128000;
pixhawk's avatar
pixhawk committed
759
        break;
760
    case 230400:
761
        baudrate = SerialInterface::BAUD230400;
762
        break;
pixhawk's avatar
pixhawk committed
763
    case 256000:
764
        baudrate = SerialInterface::BAUD256000;
pixhawk's avatar
pixhawk committed
765
        break;
766
    case 460800:
767
        baudrate = SerialInterface::BAUD460800;
768 769
        break;
    case 921600:
770
        baudrate = SerialInterface::BAUD921600;
771
        break;
pixhawk's avatar
pixhawk committed
772 773 774 775 776 777
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

778 779 780
    if(reconnect) connect();
    return accepted;

pixhawk's avatar
pixhawk committed
781 782
}

783 784
bool SerialLink::setFlowType(int flow)
{
pixhawk's avatar
pixhawk committed
785 786
    bool reconnect = false;
    bool accepted = true;
787 788
    if(isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
789

790
    switch (flow) {
791 792
    case SerialInterface::FLOW_OFF:
        this->flow = SerialInterface::FLOW_OFF;
pixhawk's avatar
pixhawk committed
793
        break;
794 795
    case SerialInterface::FLOW_HARDWARE:
        this->flow = SerialInterface::FLOW_HARDWARE;
pixhawk's avatar
pixhawk committed
796
        break;
797 798
    case SerialInterface::FLOW_XONXOFF:
        this->flow = SerialInterface::FLOW_XONXOFF;
pixhawk's avatar
pixhawk committed
799 800 801 802 803 804
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }
805

pixhawk's avatar
pixhawk committed
806 807 808 809
    if(reconnect) connect();
    return accepted;
}

810 811
bool SerialLink::setParityType(int parity)
{
pixhawk's avatar
pixhawk committed
812 813
    bool reconnect = false;
    bool accepted = true;
814 815
    if (isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
816

817
    switch (parity) {
818
    case (int)PAR_NONE:
819
        this->parity = SerialInterface::PAR_NONE;
pixhawk's avatar
pixhawk committed
820
        break;
821
    case (int)PAR_ODD:
822
        this->parity = SerialInterface::PAR_ODD;
pixhawk's avatar
pixhawk committed
823
        break;
824
    case (int)PAR_EVEN:
825
        this->parity = SerialInterface::PAR_EVEN;
pixhawk's avatar
pixhawk committed
826
        break;
827
    case (int)PAR_MARK:
828
        this->parity = SerialInterface::PAR_MARK;
pixhawk's avatar
pixhawk committed
829
        break;
830
    case (int)PAR_SPACE:
831
        this->parity = SerialInterface::PAR_SPACE;
pixhawk's avatar
pixhawk committed
832 833 834 835 836 837 838
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

839
    if (reconnect) connect();
pixhawk's avatar
pixhawk committed
840 841 842
    return accepted;
}

843

844
bool SerialLink::setDataBits(int dataBits)
845
{
846 847
    bool reconnect = false;
    if (isConnected()) reconnect = true;
pixhawk's avatar
pixhawk committed
848
    bool accepted = true;
849
    disconnect();
pixhawk's avatar
pixhawk committed
850

851
    switch (dataBits) {
pixhawk's avatar
pixhawk committed
852
    case 5:
853
        this->dataBits = SerialInterface::DATA_5;
pixhawk's avatar
pixhawk committed
854 855
        break;
    case 6:
856
        this->dataBits = SerialInterface::DATA_6;
pixhawk's avatar
pixhawk committed
857 858
        break;
    case 7:
859
        this->dataBits = SerialInterface::DATA_7;
pixhawk's avatar
pixhawk committed
860 861
        break;
    case 8:
862
        this->dataBits = SerialInterface::DATA_8;
pixhawk's avatar
pixhawk committed
863 864 865 866 867 868 869
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

870
    if(reconnect) connect();
pixhawk's avatar
pixhawk committed
871 872 873 874

    return accepted;
}

875
bool SerialLink::setStopBits(int stopBits)
876
{
pixhawk's avatar
pixhawk committed
877 878
    bool reconnect = false;
    bool accepted = true;
879 880
    if(isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
881

882
    switch (stopBits) {
pixhawk's avatar
pixhawk committed
883
    case 1:
884
        this->stopBits = SerialInterface::STOP_1;
pixhawk's avatar
pixhawk committed
885 886
        break;
    case 2:
887
        this->stopBits = SerialInterface::STOP_2;
pixhawk's avatar
pixhawk committed
888 889 890 891 892 893 894 895 896 897
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

    if(reconnect) connect();
    return accepted;
}
898 899 900 901 902 903

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

904 905
    if (isConnected()) reconnect = true;
    disconnect();
906

907
    if (dataBits >= (int)SerialInterface::DATA_5 && dataBits <= (int)SerialInterface::DATA_8) {
908
        this->dataBits = (SerialInterface::dataBitsType) dataBits;
909

910
        if(reconnect) connect();
911 912 913 914 915 916 917 918 919 920
        accepted = true;
    }

    return accepted;
}

bool SerialLink::setStopBitsType(int stopBits)
{
    bool reconnect = false;
    bool accepted = false;
921 922
    if(isConnected()) reconnect = true;
    disconnect();
923

924 925
    if (stopBits >= (int)SerialInterface::STOP_1 && dataBits <= (int)SerialInterface::STOP_2) {
        SerialInterface::stopBitsType newBits = (SerialInterface::stopBitsType) stopBits;
926 927 928 929 930 931 932 933

        port->setStopBits(newBits);
        accepted = true;
    }

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