Skip to content
SerialLink.h 6.7 KiB
Newer Older
pixhawk's avatar
pixhawk committed
/*=====================================================================
pixhawk's avatar
pixhawk committed

QGroundControl Open Source Ground Control Station

(c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
pixhawk's avatar
pixhawk committed
    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.
pixhawk's avatar
pixhawk committed

    QGROUNDCONTROL is distributed in the hope that it will be useful,
pixhawk's avatar
pixhawk committed
    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.
pixhawk's avatar
pixhawk committed

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

pixhawk's avatar
pixhawk committed
======================================================================*/
pixhawk's avatar
pixhawk committed
/**
 * @file
 *   @brief Brief Description
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#ifndef SERIALLINK_H
#define SERIALLINK_H

class LinkInterface;
class SerialConfiguration;
class SerialLink;

pixhawk's avatar
pixhawk committed
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QString>
dogmaphobic's avatar
dogmaphobic committed
#ifdef __android__
#include "qserialport.h"
#else
#include <QSerialPort>
dogmaphobic's avatar
dogmaphobic committed
#endif
#include <QMetaType>
#include <QLoggingCategory>

// We use QSerialPort::SerialPortError in a signal so we must declare it as a meta type
Q_DECLARE_METATYPE(QSerialPort::SerialPortError)

#include "QGCConfig.h"
#include "LinkManager.h"

Q_DECLARE_LOGGING_CATEGORY(SerialLinkLog)

class SerialConfiguration : public LinkConfiguration
{
Don Gagne's avatar
Don Gagne committed
    Q_OBJECT

public:

    SerialConfiguration(const QString& name);
    SerialConfiguration(SerialConfiguration* copy);

    Q_PROPERTY(int      baud            READ baud               WRITE setBaud               NOTIFY baudChanged)
    Q_PROPERTY(int      dataBits        READ dataBits           WRITE setDataBits           NOTIFY dataBitsChanged)
    Q_PROPERTY(int      flowControl     READ flowControl        WRITE setFlowControl        NOTIFY flowControlChanged)
    Q_PROPERTY(int      stopBits        READ stopBits           WRITE setStopBits           NOTIFY stopBitsChanged)
    Q_PROPERTY(int      parity          READ parity             WRITE setParity             NOTIFY parityChanged)
    Q_PROPERTY(QString  portName        READ portName           WRITE setPortName           NOTIFY portNameChanged)
    Q_PROPERTY(QString  portDisplayName READ portDisplayName                                NOTIFY portDisplayNameChanged)

    int  baud()         { return _baud; }
    int  dataBits()     { return _dataBits; }
    int  flowControl()  { return _flowControl; }    ///< QSerialPort Enums
    int  stopBits()     { return _stopBits; }
    int  parity()       { return _parity; }         ///< QSerialPort Enums

    const QString portName          () { return _portName; }
    const QString portDisplayName   () { return _portDisplayName; }
    void setBaud            (int baud);
    void setDataBits        (int databits);
    void setFlowControl     (int flowControl);          ///< QSerialPort Enums
    void setStopBits        (int stopBits);
    void setParity          (int parity);               ///< QSerialPort Enums
    void setPortName        (const QString& portName);
    static QStringList supportedBaudRates();
    static QString cleanPortDisplayname(const QString name);
    LinkType    type            () { return LinkConfiguration::TypeSerial; }
    void        copyFrom        (LinkConfiguration* source);
    void        loadSettings    (QSettings& settings, const QString& root);
    void        saveSettings    (QSettings& settings, const QString& root);
    void        updateSettings  ();
    QString     settingsURL     () { return "SerialSettings.qml"; }
signals:
    void baudChanged            ();
    void dataBitsChanged        ();
    void flowControlChanged     ();
    void stopBitsChanged        ();
    void parityChanged          ();
    void portNameChanged        ();
    void portDisplayNameChanged ();

private:
    static void _initBaudRates();

private:
    int _baud;
    int _dataBits;
    int _flowControl;
    int _stopBits;
    int _parity;
    QString _portName;
    QString _portDisplayName;
pixhawk's avatar
pixhawk committed
/**
 * @brief The SerialLink class provides cross-platform access to serial links.
 * It takes care of the link management and provides a common API to higher
 * level communication layers. It is implemented as a wrapper class for a thread
 * that handles the serial communication. All methods have therefore to be thread-
 * safe.
 *
 */
class SerialLink : public LinkInterface
pixhawk's avatar
pixhawk committed
    Q_OBJECT
    friend class LinkManager;
pixhawk's avatar
pixhawk committed
public:
pixhawk's avatar
pixhawk committed

    LinkConfiguration* getLinkConfiguration();
    void    requestReset();
    bool    isConnected() const;
    qint64  getConnectionSpeed() const;
    bool    requiresUSBMavlinkStart(void) const;

    // These are left unimplemented in order to cause linker errors which indicate incorrect usage of
    // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
    bool    connect(void);
    bool    disconnect(void);
pixhawk's avatar
pixhawk committed
public slots:

pixhawk's avatar
pixhawk committed
    /**
     * @brief Write a number of bytes to the interface.
     *
     * @param data Pointer to the data byte array
     * @param size The size of the bytes array
     **/
    void writeBytes(const char* data, qint64 length);

    void linkError(QSerialPort::SerialPortError error);
pixhawk's avatar
pixhawk committed
protected:
    QSerialPort* _port;
    quint64 _bytesRead;
    int     _timeout;
    QMutex  _dataMutex;       // Mutex for reading data from _port
    QMutex  _writeMutex;      // Mutex for accessing the _transmitBuffer.

Don Gagne's avatar
Don Gagne committed
    void _readBytes(void);
pixhawk's avatar
pixhawk committed

oberion's avatar
oberion committed
private:
    // Links are only created/destroyed by LinkManager so constructor/destructor is not public
    SerialLink(SerialConfiguration* config);
    ~SerialLink();
    // From LinkInterface
    virtual bool _connect(void);
Don Gagne's avatar
Don Gagne committed
    virtual void _disconnect(void);
    // Internal methods
    void _emitLinkError(const QString& errorMsg);
    bool _hardwareConnect(QSerialPort::SerialPortError& error, QString& errorString);
    bool _isBootloader();
    void _resetConfiguration();

    // Local data
    volatile bool        _stopp;
    volatile bool        _reqReset;
    QMutex               _stoppMutex;      // Mutex for accessing _stopp
    QByteArray           _transmitBuffer;  // An internal buffer for receiving data from member functions and actually transmitting them via the serial port.
    SerialConfiguration* _config;
pixhawk's avatar
pixhawk committed

signals:
    void aboutToCloseFlag();
pixhawk's avatar
pixhawk committed

};

#endif // SERIALLINK_H