FirmwareUpgradeController.h 6.8 KB
Newer Older
1 2 3 4
/*=====================================================================
 
 QGroundControl Open Source Ground Control Station
 
5
 (c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 
 This file is part of the QGROUNDCONTROL project
 
 QGROUNDCONTROL 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.
 
 QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
 
 ======================================================================*/

/// @file
///     @author Don Gagne <don@thegagnes.com>

27 28
#ifndef FirmwareUpgradeController_H
#define FirmwareUpgradeController_H
29

30
#include "PX4FirmwareUpgradeThread.h"
31 32
#include "LinkManager.h"
#include "FirmwareImage.h"
33 34

#include <QObject>
35 36 37 38
#include <QUrl>
#include <QTimer>
#include <QNetworkAccessManager>
#include <QNetworkReply>
39 40
#include <QPixmap>
#include <QQuickItem>
41

42 43
#include "qextserialport.h"

44 45
#include <stdint.h>

46 47
// Firmware Upgrade MVC Controller for FirmwareUpgrade.qml.
class FirmwareUpgradeController : public QObject
48 49
{
    Q_OBJECT
50
    
51
public:
52 53
    FirmwareUpgradeController(void);
    
54
    /// Supported firmware types. If you modify these you will need to update the qml file as well.
55
    typedef enum {
56 57 58 59 60 61 62 63 64 65 66 67 68
        PX4StableFirmware,
        PX4BetaFirmware,
        PX4DeveloperFirmware,
        PX4CustomFirmware,
        ApmArduCopterQuadFirmware,
        ApmArduCopterX8Firmware,
        ApmArduCopterHexaFirmware,
        ApmArduCopterOctoFirmware,
        ApmArduCopterYFirmware,
        ApmArduCopterY6Firmware,
        ApmArduCopterHeliFirmware,
        ApmArduPlaneFirmware,
        ApmRoverFirmware,
69 70 71 72
    } FirmwareType_t;

    Q_ENUMS(FirmwareType_t)
    
73 74 75
    Q_PROPERTY(QString boardPort READ boardPort NOTIFY boardFound)
    Q_PROPERTY(QString boardDescription READ boardDescription NOTIFY boardFound)
    Q_PROPERTY(QString boardType MEMBER _foundBoardType NOTIFY boardFound)
76 77 78 79
    
    /// TextArea for log output
    Q_PROPERTY(QQuickItem* statusLog READ statusLog WRITE setStatusLog)
    
80 81
    /// Progress bar for you know what
    Q_PROPERTY(QQuickItem* progressBar READ progressBar WRITE setProgressBar)
82 83 84

    /// Returns true if there are active QGC connections
    Q_PROPERTY(bool qgcConnections READ qgcConnections NOTIFY qgcConnectionsChanged)
85
    
86 87
    /// Starts searching for boards on the background thread
    Q_INVOKABLE void startBoardSearch(void);
88
    
89 90
    /// Cancels whatever state the upgrade worker thread is in
    Q_INVOKABLE void cancel(void);
91
    
92 93 94 95
    /// Called when the firmware type has been selected by the user to continue the flash process.
    Q_INVOKABLE void flash(FirmwareType_t firmwareType);
    
    // Property accessors
96
    
97 98 99
    QQuickItem* progressBar(void) { return _progressBar; }
    void setProgressBar(QQuickItem* progressBar) { _progressBar = progressBar; }
    
100 101 102
    QQuickItem* statusLog(void) { return _statusLog; }
    void setStatusLog(QQuickItem* statusLog) { _statusLog = statusLog; }
    
103 104 105 106 107
    bool qgcConnections(void);
    
    QString boardPort(void) { return _foundBoardInfo.portName(); }
    QString boardDescription(void) { return _foundBoardInfo.description(); }
    
108
signals:
109 110 111 112 113 114 115
    void boardFound(void);
    void noBoardFound(void);
    void boardGone(void);
    void flashComplete(void);
    void flashCancelled(void);
    void qgcConnectionsChanged(bool connections);
    void error(void);
116
    
117 118 119 120
private slots:
    void _downloadProgress(qint64 curr, qint64 total);
    void _downloadFinished(void);
    void _downloadError(QNetworkReply::NetworkError code);
121 122 123
    void _foundBoard(bool firstAttempt, const QSerialPortInfo& portInfo, int type);
    void _noBoardFound(void);
    void _boardGone();
124
    void _foundBootloader(int bootloaderVersion, int boardID, int flashSize);
125 126
    void _error(const QString& errorString);
    void _status(const QString& statusString);
127
    void _bootloaderSyncFailed(void);
128
    void _flashComplete(void);
129
    void _updateProgress(int curr, int total);
130 131
    void _eraseStarted(void);
    void _eraseComplete(void);
132
    void _eraseProgressTick(void);
133
    void _linkDisconnected(LinkInterface* link);
134 135

private:
136
    void _getFirmwareFile(FirmwareType_t firmwareType);
137
    void _downloadFirmware(void);
138 139 140 141 142 143 144
    void _appendStatusLog(const QString& text, bool critical = false);
    void _errorCancel(const QString& msg);
    
    typedef struct {
        FirmwareType_t  firmwareType;
        const char*     downloadLocation;
    } DownloadLocationByFirmwareType_t;
145 146 147 148
    
    QString _portName;
    QString _portDescription;

149 150 151 152 153 154 155 156
    /// Information which comes back from the bootloader
    bool        _bootloaderFound;           ///< true: we have received the foundBootloader signals
    uint32_t    _bootloaderVersion;         ///< Bootloader version
    uint32_t    _bootloaderBoardID;         ///< Board ID
    uint32_t    _bootloaderBoardFlashSize;  ///< Flash size in bytes of board
    
    bool            _startFlashWhenBootloaderFound;
    FirmwareType_t  _startFlashWhenBootloaderFoundFirmwareType;
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175

    QPixmap _boardIcon;             ///< Icon used to display image of board
    
    QString _firmwareFilename;      ///< Image which we are going to flash to the board
    
    QNetworkAccessManager*  _downloadManager;       ///< Used for firmware file downloading across the internet
    QNetworkReply*          _downloadNetworkReply;  ///< Used for firmware file downloading across the internet
    
    /// @brief Thread controller which is used to run bootloader commands on seperate thread
    PX4FirmwareUpgradeThreadController* _threadController;
    
    static const int    _eraseTickMsec = 500;       ///< Progress bar update tick time for erase
    static const int    _eraseTotalMsec = 15000;    ///< Estimated amount of time erase takes
    int                 _eraseTickCount;            ///< Number of ticks for erase progress update
    QTimer              _eraseTimer;                ///< Timer used to update progress bar for erase

    static const int    _findBoardTimeoutMsec = 30000;      ///< Amount of time for user to plug in USB
    static const int    _findBootloaderTimeoutMsec = 5000;  ///< Amount time to look for bootloader
    
176
    QQuickItem*     _statusLog;         ///< Status log TextArea Qml control
177
    QQuickItem*     _progressBar;
178 179
    
    bool _searchingForBoard;    ///< true: searching for board, false: search for bootloader
180 181 182 183 184
    
    QSerialPortInfo _foundBoardInfo;
    QString         _foundBoardType;
    
    FirmwareImage*  _image;
185 186
};

187
#endif