1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-06 17:46:07 +01:00
LibrePilot/ground/openpilotgcs/src/plugins/uploader/op_dfu.h
2013-09-15 23:37:20 +02:00

218 lines
5.2 KiB
C++

#ifndef OP_DFU_H
#define OP_DFU_H
#include <QByteArray>
#include <ophid/inc/ophid_hidapi.h>
#include <ophid/inc/ophid_usbmon.h>
#include <ophid/inc/ophid_usbsignal.h>
#include <QDebug>
#include <QFile>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QMetaType>
#include <QCryptographicHash>
#include <QList>
#include <QVariant>
#include <iostream>
#include "delay.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QTime>
#include <QTimer>
#include "SSP/qssp.h"
#include "SSP/port.h"
#include "SSP/qsspt.h"
using namespace std;
#define BUF_LEN 64
#define MAX_PACKET_DATA_LEN 255
#define MAX_PACKET_BUF_SIZE (1 + 1 + MAX_PACKET_DATA_LEN + 2)
namespace OP_DFU {
enum TransferTypes {
FW,
Descript
};
enum CompareType {
crccompare,
bytetobytecompare
};
Q_ENUMS(Status)
enum Status {
DFUidle, // 0
uploading, // 1
wrong_packet_received, // 2
too_many_packets, // 3
too_few_packets, // 4
Last_operation_Success, // 5
downloading, // 6
idle, // 7
Last_operation_failed, // 8
uploadingStarting, // 9
outsideDevCapabilities, // 10
CRC_Fail, // 11
failed_jump, // 12
abort // 13
};
enum Actions {
actionProgram,
actionProgramAndVerify,
actionDownload,
actionCompareAll,
actionCompareCrc,
actionListDevs,
actionStatusReq,
actionReset,
actionJump
};
enum Commands {
Reserved, // 0
Req_Capabilities, // 1
Rep_Capabilities, // 2
EnterDFU, // 3
JumpFW, // 4
Reset, // 5
Abort_Operation, // 6
Upload, // 7
Op_END, // 8
Download_Req, // 9
Download, // 10
Status_Request, // 11
Status_Rep, // 12
};
enum eBoardType {
eBoardUnkwn = 0,
eBoardMainbrd = 1,
eBoardINS,
eBoardPip = 3,
eBoardCC = 4,
eBoardRevo = 9,
};
struct device {
int ID;
quint32 FW_CRC;
int BL_Version;
int SizeOfDesc;
quint32 SizeOfCode;
bool Readable;
bool Writable;
};
class DFUObject : public QThread {
Q_OBJECT;
public:
static quint32 CRCFromQBArray(QByteArray array, quint32 Size);
// DFUObject(bool debug);
DFUObject(bool debug, bool use_serial, QString port);
~DFUObject();
// Service commands:
bool enterDFU(int const &devNumber);
bool findDevices();
int JumpToApp(bool safeboot, bool erase);
int ResetDevice(void);
OP_DFU::Status StatusRequest();
bool EndOperation();
int AbortOperation(void);
bool ready()
{
return mready;
}
// Upload (send to device) commands
OP_DFU::Status UploadDescription(QVariant description);
bool UploadFirmware(const QString &sfile, const bool &verify, int device);
// Download (get from device) commands:
// DownloadDescription is synchronous
QString DownloadDescription(int const & numberOfChars);
QByteArray DownloadDescriptionAsBA(int const & numberOfChars);
// Asynchronous firmware download: initiates fw download,
// and a downloadFinished signal is emitted when download
// if finished:
bool DownloadFirmware(QByteArray *byteArray, int device);
// Comparison functions (is this needed?)
OP_DFU::Status CompareFirmware(const QString &sfile, const CompareType &type, int device);
bool SaveByteArrayToFile(QString const & file, QByteArray const &array);
// Variables:
QList<device> devices;
int numberOfDevices;
int send_delay;
bool use_delay;
// Helper functions:
QString StatusToString(OP_DFU::Status const & status);
static quint32 CRC32WideFast(quint32 Crc, quint32 Size, quint32 *Buffer);
OP_DFU::eBoardType GetBoardType(int boardNum);
signals:
void progressUpdated(int);
void downloadFinished();
void uploadFinished(OP_DFU::Status);
void operationProgress(QString status);
private:
// Generic variables:
bool debug;
bool use_serial;
bool mready;
int RWFlags;
qsspt *serialhandle;
int sendData(void *, int);
int receiveData(void *data, int size);
uint8_t sspTxBuf[MAX_PACKET_BUF_SIZE];
uint8_t sspRxBuf[MAX_PACKET_BUF_SIZE];
port *info;
// USB Bootloader:
opHID_hidapi hidHandle;
int setStartBit(int command)
{
return command | 0x20;
}
void CopyWords(char *source, char *destination, int count);
void printProgBar(int const & percent, QString const & label);
bool StartUpload(qint32 const &numberOfBytes, TransferTypes const & type, quint32 crc);
bool UploadData(qint32 const & numberOfPackets, QByteArray & data);
// Thread management:
// Same as startDownload except that we store in an external array:
bool StartDownloadT(QByteArray *fw, qint32 const & numberOfBytes, TransferTypes const & type);
OP_DFU::Status UploadFirmwareT(const QString &sfile, const bool &verify, int device);
QMutex mutex;
OP_DFU::Commands requestedOperation;
qint32 requestSize;
OP_DFU::TransferTypes requestTransferType;
QByteArray *requestStorage;
QString requestFilename;
bool requestVerify;
int requestDevice;
protected:
void run(); // Executes the upload or download operations
};
}
Q_DECLARE_METATYPE(OP_DFU::Status)
#endif // OP_DFU_H