PX4FirmwareUpgradeWorker.cc 4.17 KB
Newer Older
1 2 3
#include <QJsonDocument>
#include <QFile>

4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
#include "PX4FirmwareUpgradeWorker.h"

#include <SerialLink.h>
#include <QGC.h>

#include <QDebug>

// protocol bytes
#define INSYNC		0x12
#define EOC		0x20

// reply bytes
#define OK		0x10
#define FAILED		0x11
#define INVALID		0x13	// rev3+

// command bytes
#define NOP		0x00	// guaranteed to be discarded by the bootloader
#define GET_SYNC	0x21
#define GET_DEVICE	0x22
#define CHIP_ERASE	0x23
#define CHIP_VERIFY	0x24	// rev2 only
#define PROG_MULTI	0x27
#define READ_MULTI	0x28	// rev2 only
#define GET_CRC		0x29	// rev3+
#define REBOOT		0x30

#define INFO_BL_REV	1	// bootloader protocol revision
#define BL_REV_MIN	2	// minimum supported bootloader protocol
#define BL_REV_MAX	3	// maximum supported bootloader protocol
#define INFO_BOARD_ID	2	// board type
#define INFO_BOARD_REV	3	// board revision
#define INFO_FLASH_SIZE	4	// max firmware size in bytes

PX4FirmwareUpgradeWorker::PX4FirmwareUpgradeWorker(QObject *parent) :
    QObject(parent),
    link(NULL)
{
}

PX4FirmwareUpgradeWorker* PX4FirmwareUpgradeWorker::putWorkerInThread(QObject *parent)
{
    PX4FirmwareUpgradeWorker *worker = new PX4FirmwareUpgradeWorker;
    QThread *workerThread = new QThread(parent);

    connect(workerThread, SIGNAL(started()), worker, SLOT(startContinousScan()));
    connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
    worker->moveToThread(workerThread);

    // Starts an event loop, and emits workerThread->started()
    workerThread->start();
55
    return worker;
56 57 58
}


59
void PX4FirmwareUpgradeWorker::startContinousScan()
60
{
61 62 63 64 65 66
    exitThread = false;
    while (!exitThread) {
//        if (detect()) {
//            break;
//        }
        QGC::SLEEP::msleep(20);
67 68
    }

69 70 71 72 73
    if (exitThread) {
        link->disconnect();
        delete link;
        exit(0);
    }
74 75
}

76
void PX4FirmwareUpgradeWorker::detect()
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
{
    if (!link)
    {
        link = new SerialLink("", 921600);
        connect(link, SIGNAL(bytesReceived(LinkInterface*,QByteArray)), this, SLOT(receiveBytes(LinkInterface*,QByteArray)));
    }

    // Get a list of ports
    QVector<QString>* ports = link->getCurrentPorts();

    // Scan
    for (int i = 0; i < ports->size(); i++)
    {
        // Ignore known wrong link names

        if (ports->at(i).contains("Bluetooth")) {
93
            //continue;
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
        }

        link->setPortName(ports->at(i));
        // Open port and talk to it
        link->connect();
        char buf[2] = { GET_SYNC, EOC };
        if (!link->isConnected()) {
            continue;
        }
        // Send sync request
        insync = false;
        link->writeBytes(buf, 2);
        // Wait for response
        QGC::SLEEP::msleep(20);

        if (insync)
            emit validPortFound(ports->at(i));
            break;
    }

    //ui.portName->setCurrentIndex(ui.baudRate->findText(QString("%1").arg(this->link->getPortName())));

    // Set port

    // Load current link config

}

void PX4FirmwareUpgradeWorker::receiveBytes(LinkInterface* link, QByteArray b)
{
    for (int position = 0; position < b.size(); position++) {
        qDebug() << "BYTES";
126
        qDebug() << (char)(b[position]);
127 128 129 130
        if (((const char)b[position]) == INSYNC)
        {
            qDebug() << "SYNC";
            insync = true;
131 132 133 134
        }

        if (insync && ((const char)b[position]) == OK)
        {
135 136 137 138 139 140 141
            emit detectionStatusChanged("Found PX4 board");
        }
    }

    printf("\n");
}

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
void PX4FirmwareUpgradeWorker::loadFirmware(const QString &filename)
{
    qDebug() << __FILE__ << __LINE__ << "LOADING FW";
    QFile f(filename);
    if (f.open(QIODevice::ReadOnly))
    {
        QByteArray buf = f.readAll();
        f.close();
        firmware = QJsonDocument::fromBinaryData(buf);
        if (firmware.isNull()) {
            emit upgradeStatusChanged(tr("Failed decoding file %1").arg(filename));
        } else {
            emit upgradeStatusChanged(tr("Ready to flash %1").arg(filename));
        }
    } else {
        emit upgradeStatusChanged(tr("Failed opening file %1").arg(filename));
    }
}

void PX4FirmwareUpgradeWorker::upgrade()
162
{
163 164
    emit upgradeStatusChanged(tr("Starting firmware upgrade.."));
}
165

166 167 168
void PX4FirmwareUpgradeWorker::abort()
{
    exitThread = true;
169
}