SerialLink.cc 21.5 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 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) :
oberion's avatar
oberion committed
30
    port(NULL), m_stopp(false)
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();
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 {
oberion's avatar
oberion committed
124 125 126 127 128 129 130 131
		{
			QMutexLocker locker(&this->m_stoppMutex);
			if(this->m_stopp)
			{
				this->m_stopp = false;
				break;
			}
		}
pixhawk's avatar
pixhawk committed
132 133 134 135 136 137 138
        // 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);
    }
oberion's avatar
oberion committed
139 140 141 142 143 144 145
	if (port) {
        port->flushInBuffer();
        port->flushOutBuffer();
        port->close();
        delete port;
        port = NULL;
	}
pixhawk's avatar
pixhawk committed
146 147 148
}


149 150
void SerialLink::checkForBytes()
{
pixhawk's avatar
pixhawk committed
151
    /* Check if bytes are available */
152
    if(port && port->isOpen() && port->isWritable()) {
pixhawk's avatar
pixhawk committed
153 154 155 156
        dataMutex.lock();
        qint64 available = port->bytesAvailable();
        dataMutex.unlock();

157
        if(available > 0) {
158
            readBytes();
pixhawk's avatar
pixhawk committed
159
        }
160
    } else {
pixhawk's avatar
pixhawk committed
161 162 163 164 165
        emit disconnected();
    }

}

166 167
void SerialLink::writeBytes(const char* data, qint64 size)
{
168
    if(port && port->isOpen()) {
pixhawk's avatar
pixhawk committed
169 170
        int b = port->write(data, size);

171
        if (b > 0) {
172

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

175 176 177
            // Increase write counter
            bitsSentTotal += size * 8;

178 179 180 181 182 183 184
//            int i;
//            for (i=0; i<size; i++)
//            {
//                unsigned char v =data[i];
//                qDebug("%02x ", v);
//            }
//            qDebug("\n");
185
        } else {
186 187 188
            disconnect();
            // Error occured
            emit communicationError(this->getName(), tr("Could not send data - link %1 is disconnected!").arg(this->getName()));
189
        }
pixhawk's avatar
pixhawk committed
190 191 192 193 194 195 196 197 198
    }
}

/**
 * @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
 **/
199 200
void SerialLink::readBytes()
{
pixhawk's avatar
pixhawk committed
201
    dataMutex.lock();
202
    if(port && port->isOpen()) {
203 204
        const qint64 maxLength = 2048;
        char data[maxLength];
pixhawk's avatar
pixhawk committed
205
        qint64 numBytes = port->bytesAvailable();
James Goppert's avatar
James Goppert committed
206
        //qDebug() << "numBytes: " << numBytes;
207

208
        if(numBytes > 0) {
pixhawk's avatar
pixhawk committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
            /* 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
 **/
236 237
qint64 SerialLink::bytesAvailable()
{
238
    if (port) {
239
        return port->bytesAvailable();
240
    } else {
241 242
        return 0;
    }
pixhawk's avatar
pixhawk committed
243 244 245 246 247 248 249
}

/**
 * @brief Disconnect the connection.
 *
 * @return True if connection has been disconnected, false if connection couldn't be disconnected.
 **/
250 251
bool SerialLink::disconnect()
{
oberion's avatar
oberion committed
252 253 254 255 256 257 258 259 260
	if(this->isRunning())
	{
		{
			QMutexLocker locker(&this->m_stoppMutex);
			this->m_stopp = true;
		}
		this->wait();
	
//    if (port) {
261 262 263 264
        //#if !defined _WIN32 || !defined _WIN64
        /* Block the thread until it returns from run() */
        //#endif
//        dataMutex.lock();
oberion's avatar
oberion committed
265 266 267 268 269
//        port->flushInBuffer();
//        port->flushOutBuffer();
//        port->close();
//        delete port;
//        port = NULL;
270
//        dataMutex.unlock();
pixhawk's avatar
pixhawk committed
271

oberion's avatar
oberion committed
272 273
//        if(this->isRunning()) this->terminate(); //stop running the thread, restart it upon connect
		
274 275
        bool closed = true;
        //port->isOpen();
pixhawk's avatar
pixhawk committed
276

277 278
        emit disconnected();
        emit connected(false);
279
        return closed;
oberion's avatar
oberion committed
280 281
	}
    else {
282 283 284
        // No port, so we're disconnected
        return true;
    }
pixhawk's avatar
pixhawk committed
285 286 287 288 289 290 291 292 293 294

}

/**
 * @brief Connect the connection.
 *
 * @return True if connection has been established, false if connection couldn't be established.
 **/
bool SerialLink::connect()
{
295
    if (this->isRunning()) this->disconnect();
oberion's avatar
oberion committed
296 297 298 299
	{
		QMutexLocker locker(&this->m_stoppMutex);
		this->m_stopp = false;
	}
300
    this->start(LowPriority);
301
    return true;
pixhawk's avatar
pixhawk committed
302 303 304 305 306 307 308 309 310 311
}

/**
 * @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.
 **/
312 313
bool SerialLink::hardwareConnect()
{
314
    if(port) {
315 316 317
        port->close();
        delete port;
    }
318 319 320
    port = new QSerialPort(porthandle, portSettings);
    QObject::connect(port,SIGNAL(aboutToClose()),this,SIGNAL(disconnected()));
    port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead);
pixhawk's avatar
pixhawk committed
321 322
    connectionStartTime = MG::TIME::getGroundTimeNow();

323 324
    port->open();

pixhawk's avatar
pixhawk committed
325
    bool connectionUp = isConnected();
326
    if(connectionUp) {
pixhawk's avatar
pixhawk committed
327 328 329 330
        emit connected();
        emit connected(true);
    }

331
    //qDebug() << "CONNECTING LINK: " << __FILE__ << __LINE__ << "with settings" << port->portName() << getBaudRate() << getDataBits() << getParityType() << getStopBits();
332 333


334 335
    writeSettings();

pixhawk's avatar
pixhawk committed
336 337
    return connectionUp;
}
338 339


pixhawk's avatar
pixhawk committed
340 341 342 343 344
/**
 * @brief Check if connection is active.
 *
 * @return True if link is connected, false otherwise.
 **/
345 346
bool SerialLink::isConnected()
{
347
    if (port) {
lm's avatar
lm committed
348
        return port->isOpen();
349
    } else {
lm's avatar
lm committed
350 351
        return false;
    }
pixhawk's avatar
pixhawk committed
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
}

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

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

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


371 372
qint64 SerialLink::getNominalDataRate()
{
pixhawk's avatar
pixhawk committed
373
    qint64 dataRate = 0;
374
    switch (portSettings.baudRate()) {
375
#ifndef Q_OS_WIN
376
    case QPortSettings::BAUDR_50:
pixhawk's avatar
pixhawk committed
377 378
        dataRate = 50;
        break;
379
    case QPortSettings::BAUDR_75:
pixhawk's avatar
pixhawk committed
380 381
        dataRate = 75;
        break;
382
    case QPortSettings::BAUDR_110:
pixhawk's avatar
pixhawk committed
383 384
        dataRate = 110;
        break;
385
    case QPortSettings::BAUDR_134:
pixhawk's avatar
pixhawk committed
386 387
        dataRate = 134;
        break;
388
    case QPortSettings::BAUDR_150:
pixhawk's avatar
pixhawk committed
389 390
        dataRate = 150;
        break;
391
    case QPortSettings::BAUDR_200:
pixhawk's avatar
pixhawk committed
392 393
        dataRate = 200;
        break;
394
#endif
395
    case QPortSettings::BAUDR_300:
pixhawk's avatar
pixhawk committed
396 397
        dataRate = 300;
        break;
398
    case QPortSettings::BAUDR_600:
pixhawk's avatar
pixhawk committed
399 400
        dataRate = 600;
        break;
401
    case QPortSettings::BAUDR_1200:
pixhawk's avatar
pixhawk committed
402 403
        dataRate = 1200;
        break;
404
#ifndef Q_OS_WIN
405
    case QPortSettings::BAUDR_1800:
pixhawk's avatar
pixhawk committed
406 407
        dataRate = 1800;
        break;
408
#endif
409
    case QPortSettings::BAUDR_2400:
pixhawk's avatar
pixhawk committed
410 411
        dataRate = 2400;
        break;
412
    case QPortSettings::BAUDR_4800:
pixhawk's avatar
pixhawk committed
413 414
        dataRate = 4800;
        break;
415
    case QPortSettings::BAUDR_9600:
pixhawk's avatar
pixhawk committed
416 417
        dataRate = 9600;
        break;
418 419
#ifdef Q_OS_WIN
    case QPortSettings::BAUDR_14400:
pixhawk's avatar
pixhawk committed
420 421
        dataRate = 14400;
        break;
422 423
#endif
    case QPortSettings::BAUDR_19200:
pixhawk's avatar
pixhawk committed
424 425
        dataRate = 19200;
        break;
426
    case QPortSettings::BAUDR_38400:
pixhawk's avatar
pixhawk committed
427 428
        dataRate = 38400;
        break;
429 430
#ifdef Q_OS_WIN
    case QPortSettings::BAUDR_56000:
pixhawk's avatar
pixhawk committed
431 432
        dataRate = 56000;
        break;
433 434
#endif
    case QPortSettings::BAUDR_57600:
pixhawk's avatar
pixhawk committed
435 436
        dataRate = 57600;
        break;
437
#ifdef Q_OS_WIN_XXXX // FIXME
438
    case QPortSettings::BAUDR_76800:
pixhawk's avatar
pixhawk committed
439 440
        dataRate = 76800;
        break;
441 442
#endif
    case QPortSettings::BAUDR_115200:
pixhawk's avatar
pixhawk committed
443 444
        dataRate = 115200;
        break;
445 446 447
#ifdef Q_OS_WIN
        // Windows-specific high-end baudrates
    case QPortSettings::BAUDR_128000:
pixhawk's avatar
pixhawk committed
448 449
        dataRate = 128000;
        break;
450
    case QPortSettings::BAUDR_256000:
pixhawk's avatar
pixhawk committed
451
        dataRate = 256000;
452
    case QPortSettings::BAUDR_230400:
453
        dataRate = 230400;
454
    case QPortSettings::BAUDR_460800:
455
        dataRate = 460800;
456 457 458
#endif
        // All-OS high-speed
    case QPortSettings::BAUDR_921600:
459
        dataRate = 921600;
pixhawk's avatar
pixhawk committed
460
        break;
461 462 463 464
    case QPortSettings::BAUDR_UNKNOWN:
        default:
        // Do nothing
        break;
pixhawk's avatar
pixhawk committed
465 466 467 468
    }
    return dataRate;
}

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

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

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

486 487
qint64 SerialLink::getBitsSent()
{
pixhawk's avatar
pixhawk committed
488 489 490
    return bitsSentTotal;
}

491 492
qint64 SerialLink::getBitsReceived()
{
pixhawk's avatar
pixhawk committed
493 494 495
    return bitsReceivedTotal;
}

496 497
qint64 SerialLink::getTotalDownstream()
{
pixhawk's avatar
pixhawk committed
498 499 500 501 502
    statisticsMutex.lock();
    return bitsReceivedTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000);
    statisticsMutex.unlock();
}

503 504
qint64 SerialLink::getCurrentDownstream()
{
pixhawk's avatar
pixhawk committed
505 506 507
    return 0; // TODO
}

508 509
qint64 SerialLink::getMaxDownstream()
{
pixhawk's avatar
pixhawk committed
510 511 512
    return 0; // TODO
}

513 514
bool SerialLink::isFullDuplex()
{
pixhawk's avatar
pixhawk committed
515 516 517 518
    /* Serial connections are always half duplex */
    return false;
}

519 520
int SerialLink::getLinkQuality()
{
pixhawk's avatar
pixhawk committed
521 522 523 524
    /* This feature is not supported with this interface */
    return -1;
}

525 526
QString SerialLink::getPortName()
{
pixhawk's avatar
pixhawk committed
527 528 529
    return porthandle;
}

530 531
int SerialLink::getBaudRate()
{
pixhawk's avatar
pixhawk committed
532 533 534
    return getNominalDataRate();
}

535 536
int SerialLink::getBaudRateType()
{
537
    return portSettings.baudRate();
pixhawk's avatar
pixhawk committed
538 539
}

540 541
int SerialLink::getFlowType()
{
542
    return portSettings.flowControl();
pixhawk's avatar
pixhawk committed
543 544
}

545 546
int SerialLink::getParityType()
{
547
    return portSettings.parity();
pixhawk's avatar
pixhawk committed
548 549
}

550 551
int SerialLink::getDataBitsType()
{
552
    return portSettings.dataBits();
pixhawk's avatar
pixhawk committed
553 554
}

555 556
int SerialLink::getStopBitsType()
{
557
    return portSettings.stopBits();
pixhawk's avatar
pixhawk committed
558 559
}

560 561
int SerialLink::getDataBits()
{
562 563 564
    int ret = -1;
    switch (portSettings.dataBits()) {
    case QPortSettings::DB_5:
565 566
        ret = 5;
        break;
567
    case QPortSettings::DB_6:
568 569
        ret = 6;
        break;
570
    case QPortSettings::DB_7:
571 572
        ret = 7;
        break;
573
    case QPortSettings::DB_8:
574 575 576
        ret = 8;
        break;
    default:
577
        ret = -1;
578 579 580 581 582 583 584
        break;
    }
    return ret;
}

int SerialLink::getStopBits()
{
585 586 587 588 589 590 591 592 593 594 595 596
    int ret = -1;
        switch (portSettings.stopBits()) {
        case QPortSettings::STOP_1:
            ret = 1;
            break;
        case QPortSettings::STOP_2:
            ret = 2;
            break;
        default:
            ret = -1;
            break;
        }
597 598 599
    return ret;
}

pixhawk's avatar
pixhawk committed
600 601
bool SerialLink::setPortName(QString portName)
{
602
    if(portName.trimmed().length() > 0) {
pixhawk's avatar
pixhawk committed
603
        bool reconnect = false;
604 605 606
        if (isConnected()) reconnect = true;
        disconnect();

pixhawk's avatar
pixhawk committed
607 608 609 610 611
        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
612
        if (!this->porthandle.startsWith("\\")) {
pixhawk's avatar
pixhawk committed
613 614 615 616
            // Append \\.\ before the port handle. Additional backslashes are used for escaping.
            this->porthandle = "\\\\.\\" + this->porthandle;
        }
#endif
617

pixhawk's avatar
pixhawk committed
618 619
        if(reconnect) connect();
        return true;
620
    } else {
pixhawk's avatar
pixhawk committed
621 622 623 624 625 626 627 628 629
        return false;
    }
}


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

633 634 635 636 637 638 639
#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)
640 641
    {
        portSettings.setBaudRate((QPortSettings::BaudRate)rateIndex);
pixhawk's avatar
pixhawk committed
642 643 644 645 646 647
    }

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

648 649 650 651 652 653 654
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
655 656 657

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

pixhawk's avatar
pixhawk committed
660 661
    bool reconnect = false;
    bool accepted = true; // This is changed if none of the data rates matches
662
    if(isConnected()) {
pixhawk's avatar
pixhawk committed
663 664
        reconnect = true;
    }
665
    disconnect();
pixhawk's avatar
pixhawk committed
666

667
    switch (rate) {
668 669

#ifndef Q_OS_WIN
pixhawk's avatar
pixhawk committed
670
    case 50:
671
        portSettings.setBaudRate(QPortSettings::BAUDR_50);
pixhawk's avatar
pixhawk committed
672 673
        break;
    case 75:
674
        portSettings.setBaudRate(QPortSettings::BAUDR_75);
pixhawk's avatar
pixhawk committed
675 676
        break;
    case 110:
677
        portSettings.setBaudRate(QPortSettings::BAUDR_110);
pixhawk's avatar
pixhawk committed
678 679
        break;
    case 134:
680
        portSettings.setBaudRate(QPortSettings::BAUDR_134);
pixhawk's avatar
pixhawk committed
681 682
        break;
    case 150:
683
        portSettings.setBaudRate(QPortSettings::BAUDR_150);
pixhawk's avatar
pixhawk committed
684 685
        break;
    case 200:
686
        portSettings.setBaudRate(QPortSettings::BAUDR_200);
pixhawk's avatar
pixhawk committed
687
        break;
688
#endif
pixhawk's avatar
pixhawk committed
689
    case 300:
690
        portSettings.setBaudRate(QPortSettings::BAUDR_300);
pixhawk's avatar
pixhawk committed
691 692
        break;
    case 600:
693
        portSettings.setBaudRate(QPortSettings::BAUDR_600);
pixhawk's avatar
pixhawk committed
694 695
        break;
    case 1200:
696
        portSettings.setBaudRate(QPortSettings::BAUDR_1200);
pixhawk's avatar
pixhawk committed
697
        break;
698
#ifndef Q_OS_WIN
pixhawk's avatar
pixhawk committed
699
    case 1800:
700
        portSettings.setBaudRate(QPortSettings::BAUDR_1800);
pixhawk's avatar
pixhawk committed
701
        break;
702
#endif
pixhawk's avatar
pixhawk committed
703
    case 2400:
704
        portSettings.setBaudRate(QPortSettings::BAUDR_2400);
pixhawk's avatar
pixhawk committed
705 706
        break;
    case 4800:
707
        portSettings.setBaudRate(QPortSettings::BAUDR_4800);
pixhawk's avatar
pixhawk committed
708 709
        break;
    case 9600:
710
        portSettings.setBaudRate(QPortSettings::BAUDR_9600);
pixhawk's avatar
pixhawk committed
711
        break;
712
#ifdef Q_OS_WIN
pixhawk's avatar
pixhawk committed
713
    case 14400:
714
        portSettings.setBaudRate(QPortSettings::BAUDR_14400);
pixhawk's avatar
pixhawk committed
715
        break;
716
#endif
pixhawk's avatar
pixhawk committed
717
    case 19200:
718
        portSettings.setBaudRate(QPortSettings::BAUDR_19200);
pixhawk's avatar
pixhawk committed
719 720
        break;
    case 38400:
721
        portSettings.setBaudRate(QPortSettings::BAUDR_38400);
pixhawk's avatar
pixhawk committed
722
        break;
723
#ifdef Q_OS_WIN
pixhawk's avatar
pixhawk committed
724
    case 56000:
725
        portSettings.setBaudRate(QPortSettings::BAUDR_56000);
pixhawk's avatar
pixhawk committed
726
        break;
727
#endif
pixhawk's avatar
pixhawk committed
728
    case 57600:
729
        portSettings.setBaudRate(QPortSettings::BAUDR_57600);
pixhawk's avatar
pixhawk committed
730
        break;
731
#ifdef Q_OS_WIN_XXXX // FIXME CHECK THIS
pixhawk's avatar
pixhawk committed
732
    case 76800:
733
        portSettings.setBaudRate(QPortSettings::BAUDR_76800);
pixhawk's avatar
pixhawk committed
734
        break;
735
#endif
pixhawk's avatar
pixhawk committed
736
    case 115200:
737
        portSettings.setBaudRate(QPortSettings::BAUDR_115200);
pixhawk's avatar
pixhawk committed
738
        break;
739
#ifdef Q_OS_WIN
pixhawk's avatar
pixhawk committed
740
    case 128000:
741
        portSettings.setBaudRate(QPortSettings::BAUDR_128000);
pixhawk's avatar
pixhawk committed
742
        break;
743
    case 230400:
744
        portSettings.setBaudRate(QPortSettings::BAUDR_230400);
745
        break;
pixhawk's avatar
pixhawk committed
746
    case 256000:
747
        portSettings.setBaudRate(QPortSettings::BAUDR_256000);
pixhawk's avatar
pixhawk committed
748
        break;
749
    case 460800:
750
        portSettings.setBaudRate(QPortSettings::BAUDR_460800);
751
        break;
752
#endif
753
    case 921600:
754
        portSettings.setBaudRate(QPortSettings::BAUDR_921600);
755
        break;
pixhawk's avatar
pixhawk committed
756 757 758 759 760 761
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

762 763 764
    if(reconnect) connect();
    return accepted;

pixhawk's avatar
pixhawk committed
765 766
}

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

774
    switch (flow) {
775 776
    case (int)QPortSettings::FLOW_OFF:
        portSettings.setFlowControl(QPortSettings::FLOW_OFF);
pixhawk's avatar
pixhawk committed
777
        break;
778 779
    case (int)QPortSettings::FLOW_HARDWARE:
        portSettings.setFlowControl(QPortSettings::FLOW_HARDWARE);
pixhawk's avatar
pixhawk committed
780
        break;
781 782
    case (int)QPortSettings::FLOW_XONXOFF:
        portSettings.setFlowControl(QPortSettings::FLOW_XONXOFF);
pixhawk's avatar
pixhawk committed
783 784 785 786 787 788
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }
789

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

794 795
bool SerialLink::setParityType(int parity)
{
pixhawk's avatar
pixhawk committed
796 797
    bool reconnect = false;
    bool accepted = true;
798 799
    if (isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
800

801
    switch (parity) {
802 803
    case (int)QPortSettings::PAR_NONE:
        portSettings.setParity(QPortSettings::PAR_NONE);
pixhawk's avatar
pixhawk committed
804
        break;
805 806
    case (int)QPortSettings::PAR_ODD:
        portSettings.setParity(QPortSettings::PAR_ODD);
pixhawk's avatar
pixhawk committed
807
        break;
808 809
    case (int)QPortSettings::PAR_EVEN:
        portSettings.setParity(QPortSettings::PAR_EVEN);
pixhawk's avatar
pixhawk committed
810
        break;
811 812
    case (int)QPortSettings::PAR_SPACE:
        portSettings.setParity(QPortSettings::PAR_SPACE);
pixhawk's avatar
pixhawk committed
813 814 815 816 817 818 819
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

820
    if (reconnect) connect();
pixhawk's avatar
pixhawk committed
821 822 823
    return accepted;
}

824

825
bool SerialLink::setDataBits(int dataBits)
826
{
827
    //qDebug() << "Setting" << dataBits << "data bits";
828 829
    bool reconnect = false;
    if (isConnected()) reconnect = true;
pixhawk's avatar
pixhawk committed
830
    bool accepted = true;
831
    disconnect();
pixhawk's avatar
pixhawk committed
832

833
    switch (dataBits) {
pixhawk's avatar
pixhawk committed
834
    case 5:
835
        portSettings.setDataBits(QPortSettings::DB_5);
pixhawk's avatar
pixhawk committed
836 837
        break;
    case 6:
838
        portSettings.setDataBits(QPortSettings::DB_6);
pixhawk's avatar
pixhawk committed
839 840
        break;
    case 7:
841
        portSettings.setDataBits(QPortSettings::DB_7);
pixhawk's avatar
pixhawk committed
842 843
        break;
    case 8:
844
        portSettings.setDataBits(QPortSettings::DB_8);
pixhawk's avatar
pixhawk committed
845 846 847 848 849 850 851
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

852
    if(reconnect) connect();
pixhawk's avatar
pixhawk committed
853 854 855 856

    return accepted;
}

857
bool SerialLink::setStopBits(int stopBits)
858
{
pixhawk's avatar
pixhawk committed
859 860
    bool reconnect = false;
    bool accepted = true;
861 862
    if(isConnected()) reconnect = true;
    disconnect();
pixhawk's avatar
pixhawk committed
863

864
    switch (stopBits) {
pixhawk's avatar
pixhawk committed
865
    case 1:
866
        portSettings.setStopBits(QPortSettings::STOP_1);
pixhawk's avatar
pixhawk committed
867 868
        break;
    case 2:
869
        portSettings.setStopBits(QPortSettings::STOP_2);
pixhawk's avatar
pixhawk committed
870 871 872 873 874 875 876 877 878 879
        break;
    default:
        // If none of the above cases matches, there must be an error
        accepted = false;
        break;
    }

    if(reconnect) connect();
    return accepted;
}
880 881 882 883 884 885

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

886 887
    if (isConnected()) reconnect = true;
    disconnect();
888

889 890
    if (dataBits >= (int)QPortSettings::DB_5 && dataBits <= (int)QPortSettings::DB_8) {
        portSettings.setDataBits((QPortSettings::DataBits) dataBits);
891

892
        if(reconnect) connect();
893 894 895 896 897 898 899 900 901 902
        accepted = true;
    }

    return accepted;
}

bool SerialLink::setStopBitsType(int stopBits)
{
    bool reconnect = false;
    bool accepted = false;
903 904
    if(isConnected()) reconnect = true;
    disconnect();
905

906 907
    if (stopBits >= (int)QPortSettings::STOP_1 && stopBits <= (int)QPortSettings::STOP_2) {
        portSettings.setStopBits((QPortSettings::StopBits) stopBits);
908

909
        if(reconnect) connect();
910 911 912 913 914 915
        accepted = true;
    }

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