SerialConfigurationWindow.cc 7.71 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2
/*=====================================================================

3
QGroundControl Open Source Ground Control Station
pixhawk's avatar
pixhawk committed
4

5
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
pixhawk's avatar
pixhawk committed
6

7
This file is part of the QGROUNDCONTROL project
pixhawk's avatar
pixhawk committed
8

9
    QGROUNDCONTROL is free software: you can redistribute it and/or modify
pixhawk's avatar
pixhawk committed
10 11 12 13
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

14
    QGROUNDCONTROL is distributed in the hope that it will be useful,
pixhawk's avatar
pixhawk committed
15 16 17 18 19
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
20
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
pixhawk's avatar
pixhawk committed
21 22 23 24 25

======================================================================*/

/**
 * @file
lm's avatar
lm committed
26
 *   @brief Implementation of SerialConfigurationWindow
pixhawk's avatar
pixhawk committed
27 28 29 30 31
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include <QDir>
32
#include <QSettings>
pixhawk's avatar
pixhawk committed
33
#include <QFileInfoList>
34
#include <QDebug>
dogmaphobic's avatar
dogmaphobic committed
35 36 37 38

#ifdef __android__
#include "qserialportinfo.h"
#else
39
#include <QSerialPortInfo>
dogmaphobic's avatar
dogmaphobic committed
40
#endif
pixhawk's avatar
pixhawk committed
41

42 43
#include <SerialConfigurationWindow.h>
#include <SerialLink.h>
Bryant's avatar
Bryant committed
44

45 46 47
#ifndef USE_ANCIENT_RATES
#define USE_ANCIENT_RATES 0
#endif
pixhawk's avatar
pixhawk committed
48

49 50 51 52 53 54
SerialConfigurationWindow::SerialConfigurationWindow(SerialConfiguration *config, QWidget *parent, Qt::WindowFlags flags)
    : QWidget(parent, flags)
{
    _ui.setupUi(this);
    Q_ASSERT(config != NULL);
    _config = config;
pixhawk's avatar
pixhawk committed
55

56 57 58 59
    // Scan for serial ports. Let the user know if none were found for debugging purposes
    if (!setupPortList()) {
        qDebug() << "No serial ports found.";
    }
60

61 62
    // Set up baud rates
    _ui.baudRate->clear();
63

64 65
    // Keep track of all desired baud rates by OS. These are iterated through
    // later and added to _ui.baudRate.
66
    QStringList supportedBaudRates = SerialConfiguration::supportedBaudRates();
pixhawk's avatar
pixhawk committed
67

68 69
    // Now actually add all of our supported baud rates to the ui.
    for (int i = 0; i < supportedBaudRates.size(); ++i) {
70
        _ui.baudRate->addItem(supportedBaudRates.at(i), supportedBaudRates.at(i).toInt());
71
    }
pixhawk's avatar
pixhawk committed
72

73
    // Connect the individual user interface inputs
74 75 76 77 78 79 80 81 82
    connect(_ui.portName,           SIGNAL(currentIndexChanged(int)), this,  SLOT(setPortName(int)));
    connect(_ui.baudRate,           SIGNAL(activated(int)), this,            SLOT(setBaudRate(int)));
    connect(_ui.flowControlCheckBox,SIGNAL(toggled(bool)), this,             SLOT(enableFlowControl(bool)));
    connect(_ui.parNone,            SIGNAL(toggled(bool)), this,             SLOT(setParityNone(bool)));
    connect(_ui.parOdd,             SIGNAL(toggled(bool)), this,             SLOT(setParityOdd(bool)));
    connect(_ui.parEven,            SIGNAL(toggled(bool)), this,             SLOT(setParityEven(bool)));
    connect(_ui.dataBitsSpinBox,    SIGNAL(valueChanged(int)), this,         SLOT(setDataBits(int)));
    connect(_ui.stopBitsSpinBox,    SIGNAL(valueChanged(int)), this,         SLOT(setStopBits(int)));
    connect(_ui.advCheckBox,        SIGNAL(clicked(bool)), _ui.advGroupBox,  SLOT(setVisible(bool)));
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

    _ui.advCheckBox->setCheckable(true);
    _ui.advCheckBox->setChecked(false);
    _ui.advGroupBox->setVisible(false);

    switch(_config->parity()) {
    case QSerialPort::NoParity:
        _ui.parNone->setChecked(true);
        break;
    case QSerialPort::OddParity:
        _ui.parOdd->setChecked(true);
        break;
    case QSerialPort::EvenParity:
        _ui.parEven->setChecked(true);
        break;
    default:
        // Enforce default: no parity in link
        setParityNone(true);
        _ui.parNone->setChecked(true);
        break;
    }
pixhawk's avatar
pixhawk committed
104

105 106 107 108 109 110 111 112 113 114 115
    int idx = 0;
    _ui.flowControlCheckBox->setChecked(_config->flowControl() == QSerialPort::HardwareControl);
    idx = _ui.baudRate->findText(QString("%1").arg(_config->baud()));
    if(idx < 0) idx = _ui.baudRate->findText("57600");
    if(idx < 0) idx = 0;
    _ui.baudRate->setCurrentIndex(idx);
    _ui.dataBitsSpinBox->setValue(_config->dataBits());
    _ui.stopBitsSpinBox->setValue(_config->stopBits());
    _portCheckTimer = new QTimer(this);
    _portCheckTimer->setInterval(1000);
    connect(_portCheckTimer, SIGNAL(timeout()), this, SLOT(setupPortList()));
pixhawk's avatar
pixhawk committed
116

117 118
    // Display the widget
    setWindowTitle(tr("Serial Communication Settings"));
pixhawk's avatar
pixhawk committed
119 120
}

121 122
SerialConfigurationWindow::~SerialConfigurationWindow()
{
pixhawk's avatar
pixhawk committed
123 124 125 126 127

}

void SerialConfigurationWindow::showEvent(QShowEvent* event)
{
128
    Q_UNUSED(event);
129
    _portCheckTimer->start();
pixhawk's avatar
pixhawk committed
130 131 132 133
}

void SerialConfigurationWindow::hideEvent(QHideEvent* event)
{
134
    Q_UNUSED(event);
135
    _portCheckTimer->stop();
pixhawk's avatar
pixhawk committed
136 137
}

138
bool SerialConfigurationWindow::setupPortList()
pixhawk's avatar
pixhawk committed
139
{
140 141 142 143
    bool changed = false;
    // Iterate found ports
    QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts();
    foreach (const QSerialPortInfo &info, portList)
144
    {
145 146 147
        QString name = info.portName();
        // Append newly found port to the list
        if (_ui.portName->findText(name) < 0)
148
        {
149 150 151
            // We show the user the "short name" but store the full port name
            _ui.portName->addItem(name, QVariant(info.systemLocation()));
            changed = true;
pixhawk's avatar
pixhawk committed
152 153
        }
    }
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
    // See if configured port (if any) is present
    if(changed) {
        int idx = _ui.portName->count() - 1;
        if(!_config->portName().isEmpty()) {
            idx = _ui.portName->findData(QVariant(_config->portName()));
            if(idx < 0) {
                idx = 0;
            }
        }
        _ui.portName->setCurrentIndex(idx);
        if(_ui.portName->count() > 0) {
            _ui.portName->setEditText(_ui.portName->itemText(idx));
        }
        if(_config->portName().isEmpty()) {
            setPortName(idx);
        }
    }
    return (_ui.portName->count() > 0);
pixhawk's avatar
pixhawk committed
172 173 174 175
}

void SerialConfigurationWindow::enableFlowControl(bool flow)
{
176
    _config->setFlowControl(flow ? QSerialPort::HardwareControl : QSerialPort::NoFlowControl);
dogmaphobic's avatar
dogmaphobic committed
177 178
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
pixhawk's avatar
pixhawk committed
179 180
}

lm's avatar
lm committed
181
void SerialConfigurationWindow::setParityNone(bool accept)
pixhawk's avatar
pixhawk committed
182
{
dogmaphobic's avatar
dogmaphobic committed
183 184 185 186 187
    if (accept) {
        _config->setParity(QSerialPort::NoParity);
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
    }
pixhawk's avatar
pixhawk committed
188 189
}

lm's avatar
lm committed
190
void SerialConfigurationWindow::setParityOdd(bool accept)
pixhawk's avatar
pixhawk committed
191
{
dogmaphobic's avatar
dogmaphobic committed
192 193 194 195 196
    if (accept) {
        _config->setParity(QSerialPort::OddParity);
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
    }
pixhawk's avatar
pixhawk committed
197 198
}

lm's avatar
lm committed
199
void SerialConfigurationWindow::setParityEven(bool accept)
pixhawk's avatar
pixhawk committed
200
{
dogmaphobic's avatar
dogmaphobic committed
201 202 203 204 205
    if (accept) {
        _config->setParity(QSerialPort::EvenParity);
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
    }
pixhawk's avatar
pixhawk committed
206 207
}

208
void SerialConfigurationWindow::setPortName(int index)
pixhawk's avatar
pixhawk committed
209
{
210 211 212 213
    // Get the full port name and store it in the config
    QString pname = _ui.portName->itemData(index).toString();
    if (_config->portName() != pname) {
        _config->setPortName(pname);
dogmaphobic's avatar
dogmaphobic committed
214 215
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
pixhawk's avatar
pixhawk committed
216 217 218
    }
}

219
void SerialConfigurationWindow::setBaudRate(int index)
Bryant's avatar
Bryant committed
220
{
221 222
    int baud = _ui.baudRate->itemData(index).toInt();
    _config->setBaud(baud);
dogmaphobic's avatar
dogmaphobic committed
223 224
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
Bryant's avatar
Bryant committed
225 226
}

227
void SerialConfigurationWindow::setDataBits(int bits)
Bryant's avatar
Bryant committed
228
{
229
    _config->setDataBits(bits);
dogmaphobic's avatar
dogmaphobic committed
230 231
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
Bryant's avatar
Bryant committed
232 233
}

234
void SerialConfigurationWindow::setStopBits(int bits)
Bryant's avatar
Bryant committed
235
{
236
    _config->setStopBits(bits);
dogmaphobic's avatar
dogmaphobic committed
237 238
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
Bryant's avatar
Bryant committed
239
}