You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
9.6 KiB
302 lines
9.6 KiB
/*===================================================================== |
|
|
|
APM_PLANNER Open Source Ground Control Station |
|
|
|
(c) 2013, Bill Bonney <billbonney@communistech.com> |
|
|
|
This file is part of the APM_PLANNER project |
|
|
|
APM_PLANNER is free software: you can redistribute it and/or modify |
|
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. |
|
|
|
APM_PLANNER is distributed in the hope that it will be useful, |
|
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 |
|
along with APM_PLANNER. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
======================================================================*/ |
|
|
|
/** |
|
* @file |
|
* @brief Terminal Console display View. |
|
* |
|
* @author Bill Bonney <billbonney@communistech.com> |
|
* |
|
* Influenced from Qt examples by :- |
|
* Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com> |
|
* Copyright (C) 2012 Laszlo Papp <lpapp@kde.org> |
|
* |
|
*/ |
|
|
|
#include "SerialSettingsDialog.h" |
|
#include "terminalconsole.h" |
|
#include "ui_terminalconsole.h" |
|
#include "console.h" |
|
#include "configuration.h" |
|
|
|
#include <QDebug> |
|
#include <QSettings> |
|
#include <QStatusBar> |
|
#include <QMessageBox> |
|
#include <QVBoxLayout> |
|
#include <QComboBox> |
|
#include <qserialportinfo.h> |
|
#include <qserialport.h> |
|
|
|
TerminalConsole::TerminalConsole(QWidget *parent) : |
|
QWidget(parent), |
|
ui(new Ui::TerminalConsole), |
|
m_consoleMode(APM) |
|
{ |
|
ui->setupUi(this); |
|
|
|
// create the cosole and add it to the centralwidget |
|
m_console = new Console; |
|
m_console->setEnabled(false); |
|
|
|
m_statusBar = new QStatusBar; |
|
|
|
QLayout* layout = ui->terminalGroupBox->layout(); |
|
layout->addWidget(m_console); |
|
layout->addWidget(m_statusBar); |
|
|
|
m_serial = new QSerialPort(this); |
|
m_settingsDialog = new SettingsDialog; |
|
|
|
ui->connectButton->setEnabled(true); |
|
ui->disconnectButton->setEnabled(false); |
|
ui->settingsButton->setEnabled(true); |
|
|
|
|
|
addBaudComboBoxConfig(); |
|
fillPortsInfo(*ui->linkComboBox); |
|
|
|
loadSettings(); |
|
|
|
if (m_settings.name == "") { |
|
setLink(ui->linkComboBox->currentIndex()); |
|
} else { |
|
ui->linkComboBox->setCurrentIndex(0); |
|
} |
|
|
|
addConsoleModesComboBoxConfig(); |
|
|
|
initConnections(); |
|
} |
|
|
|
void TerminalConsole::addBaudComboBoxConfig() |
|
{ |
|
ui->consoleModeBox->addItem(QLatin1String("APM"), APM); |
|
ui->consoleModeBox->addItem(QLatin1String("PX4"), PX4); |
|
} |
|
|
|
void TerminalConsole::addConsoleModesComboBoxConfig() |
|
{ |
|
ui->baudComboBox->addItem(QLatin1String("115200"), QSerialPort::Baud115200); |
|
ui->baudComboBox->addItem(QLatin1String("57600"), QSerialPort::Baud57600); |
|
ui->baudComboBox->addItem(QLatin1String("38400"), QSerialPort::Baud38400); |
|
ui->baudComboBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); |
|
ui->baudComboBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); |
|
ui->baudComboBox->addItem(QLatin1String("9600"), QSerialPort::Baud9600); |
|
} |
|
|
|
void TerminalConsole::fillPortsInfo(QComboBox &comboxBox) |
|
{ |
|
comboxBox.clear(); |
|
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { |
|
QStringList list; |
|
list << info.portName() |
|
<< info.description() |
|
<< info.manufacturer() |
|
<< info.systemLocation() |
|
<< (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) |
|
<< (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()); |
|
|
|
comboxBox.insertItem(0,list.first(), list); |
|
qDebug() << "Inserting " << list.first(); |
|
} |
|
} |
|
|
|
TerminalConsole::~TerminalConsole() |
|
{ |
|
delete m_console; |
|
delete m_statusBar; |
|
delete m_settingsDialog; |
|
delete ui; |
|
} |
|
|
|
void TerminalConsole::openSerialPort() |
|
{ |
|
openSerialPort(m_settings); |
|
} |
|
|
|
void TerminalConsole::openSerialPort(const SerialSettings &settings) |
|
{ |
|
m_serial->setPortName(settings.name); |
|
if (m_serial->open(QIODevice::ReadWrite)) { |
|
if (m_serial->setBaudRate(settings.baudRate) |
|
&& m_serial->setDataBits(settings.dataBits) |
|
&& m_serial->setParity(settings.parity) |
|
&& m_serial->setStopBits(settings.stopBits) |
|
&& m_serial->setFlowControl(settings.flowControl)) { |
|
|
|
m_console->setEnabled(true); |
|
m_console->setLocalEchoEnabled(false); |
|
ui->connectButton->setEnabled(false); |
|
ui->disconnectButton->setEnabled(true); |
|
ui->settingsButton->setEnabled(false); |
|
m_statusBar->showMessage(tr("Connected to %1 : baud %2z") |
|
.arg(settings.name).arg(QString::number(settings.baudRate))); |
|
qDebug() << "Open Terminal Console Serial Port"; |
|
writeSettings(); // Save last successful connection |
|
|
|
sendResetCommand(); |
|
|
|
} else { |
|
m_serial->close(); |
|
QMessageBox::critical(this, tr("Error"), m_serial->errorString()); |
|
|
|
m_statusBar->showMessage(tr("Open error")); |
|
} |
|
} else { |
|
QMessageBox::critical(this, tr("Error"), m_serial->errorString()); |
|
|
|
m_statusBar->showMessage(tr("Configure error")); |
|
} |
|
} |
|
|
|
void TerminalConsole::closeSerialPort() |
|
{ |
|
m_serial->close(); |
|
m_console->setEnabled(false); |
|
ui->connectButton->setEnabled(true); |
|
ui->disconnectButton->setEnabled(false); |
|
ui->settingsButton->setEnabled(true); |
|
m_statusBar->showMessage(tr("Disconnected")); |
|
} |
|
|
|
void TerminalConsole::sendResetCommand() |
|
{ |
|
if (m_serial->isOpen()) { |
|
m_serial->setDataTerminalReady(true); |
|
m_serial->waitForBytesWritten(250); |
|
m_serial->setDataTerminalReady(false); |
|
} |
|
} |
|
|
|
void TerminalConsole::writeData(const QByteArray &data) |
|
{ |
|
// qDebug() << "writeData:" << data; |
|
m_serial->write(data); |
|
} |
|
|
|
void TerminalConsole::readData() |
|
{ |
|
QByteArray data = m_serial->readAll(); |
|
// qDebug() << "readData:" << data; |
|
m_console->putData(data); |
|
|
|
switch(m_consoleMode) |
|
{ |
|
case APM: // APM |
|
// On reset, send the break sequence and display help |
|
if (data.contains("ENTER 3")) { |
|
m_serial->write("\r\r\r"); |
|
m_serial->waitForBytesWritten(10); |
|
m_serial->write("HELP\r"); |
|
} |
|
break; |
|
case PX4: |
|
// Do nothing |
|
default: |
|
qDebug() << "Mode not yet implemented"; |
|
} |
|
|
|
} |
|
|
|
void TerminalConsole::handleError(QSerialPort::SerialPortError error) |
|
{ |
|
if (error == QSerialPort::ResourceError) { |
|
QMessageBox::critical(this, tr("Critical Error"), m_serial->errorString()); |
|
closeSerialPort(); |
|
} |
|
} |
|
|
|
void TerminalConsole::initConnections() |
|
{ |
|
// Ui Connections |
|
connect(ui->connectButton, SIGNAL(released()), this, SLOT(openSerialPort())); |
|
connect(ui->disconnectButton, SIGNAL(released()), this, SLOT(closeSerialPort())); |
|
connect(ui->settingsButton, SIGNAL(released()), m_settingsDialog, SLOT(show())); |
|
connect(ui->clearButton, SIGNAL(released()), m_console, SLOT(clear())); |
|
|
|
connect(ui->baudComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setBaudRate(int))); |
|
connect(ui->linkComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setLink(int))); |
|
// connect(ui->linkComboBox, SIGNAL()), this, SLOT(setLink(int))); |
|
|
|
// Serial Port Connections |
|
connect(m_serial, SIGNAL(error(QSerialPort::SerialPortError)), this, |
|
SLOT(handleError(QSerialPort::SerialPortError))); |
|
|
|
connect(m_serial, SIGNAL(readyRead()), this, SLOT(readData())); |
|
connect(m_console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray))); |
|
} |
|
|
|
void TerminalConsole::setBaudRate(int index) |
|
{ |
|
m_settings.baudRate = static_cast<QSerialPort::BaudRate>( |
|
ui->baudComboBox->itemData(index).toInt()); |
|
qDebug() << "Changed Baud to:" << m_settings.baudRate; |
|
|
|
} |
|
|
|
void TerminalConsole::setLink(int index) |
|
{ |
|
Q_UNUSED(index); |
|
m_settings.name = ui->linkComboBox->currentText(); |
|
qDebug() << "Changed Link to:" << m_settings.name; |
|
|
|
} |
|
|
|
void TerminalConsole::loadSettings() |
|
{ |
|
// Load defaults from settings |
|
QSettings settings(QGC::ORG_NAME, QGC::APPNAME); |
|
settings.sync(); |
|
if (settings.contains("TERMINALCONSOLE_COMM_PORT")) |
|
{ |
|
m_settings.name = settings.value("TERMINALCONSOLE_COMM_PORT").toString(); |
|
m_settings.baudRate = settings.value("TERMINALCONSOLE_COMM_BAUD").toInt(); |
|
m_settings.parity = static_cast<QSerialPort::Parity> |
|
(settings.value("TERMINALCONSOLE_COMM_PARITY").toInt()); |
|
m_settings.stopBits = static_cast<QSerialPort::StopBits> |
|
(settings.value("TERMINALCONSOLE_COMM_STOPBITS").toInt()); |
|
m_settings.dataBits = static_cast<QSerialPort::DataBits> |
|
(settings.value("TERMINALCONSOLE_COMM_DATABITS").toInt()); |
|
m_settings.flowControl = static_cast<QSerialPort::FlowControl> |
|
(settings.value("TERMINALCONSOLE_COMM_FLOW_CONTROL").toInt()); |
|
} else { |
|
// init the structure |
|
} |
|
} |
|
|
|
void TerminalConsole::writeSettings() |
|
{ |
|
// Store settings |
|
QSettings settings(QGC::ORG_NAME, QGC::APPNAME); |
|
settings.setValue("TERMINALCONSOLE_COMM_PORT", m_settings.name); |
|
settings.setValue("TERMINALCONSOLE_COMM_BAUD", m_settings.baudRate); |
|
settings.setValue("TERMINALCONSOLE_COMM_PARITY", m_settings.parity); |
|
settings.setValue("TERMINALCONSOLE_COMM_STOPBITS", m_settings.stopBits); |
|
settings.setValue("TERMINALCONSOLE_COMM_DATABITS", m_settings.dataBits); |
|
settings.setValue("TERMINALCONSOLE_COMM_FLOW_CONTROL", m_settings.flowControl); |
|
settings.sync(); |
|
} |
|
|
|
|
|
|
|
|