/*===================================================================== APM_PLANNER Open Source Ground Control Station (c) 2013, Bill Bonney 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 . ======================================================================*/ /** * @file * @brief Terminal Console display View. * * @author Bill Bonney * * Influenced from Qt examples by :- * Copyright (C) 2012 Denis Shienkov * Copyright (C) 2012 Laszlo Papp * */ #include "SerialSettingsDialog.h" #include "terminalconsole.h" #include "ui_terminalconsole.h" #include "console.h" #include "QGCConfig.h" #include #include #include #include #include #include #include #include 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( 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 (settings.value("TERMINALCONSOLE_COMM_PARITY").toInt()); m_settings.stopBits = static_cast (settings.value("TERMINALCONSOLE_COMM_STOPBITS").toInt()); m_settings.dataBits = static_cast (settings.value("TERMINALCONSOLE_COMM_DATABITS").toInt()); m_settings.flowControl = static_cast (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(); }