|
|
|
/*=====================================================================
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|