1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

OP-35 Preliminary work on the new DFU gadget. Not much to see so far.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2050 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2010-10-31 22:56:31 +00:00 committed by edouard
parent 6e0332eb10
commit dde66a3c24
8 changed files with 1023 additions and 68 deletions

View File

@ -0,0 +1,2 @@
#include "delay.h"

View File

@ -0,0 +1,13 @@
#ifndef DELAY_H
#define DELAY_H
#include <QThread>
class delay : public QThread
{
public:
static void msleep(unsigned long msecs)
{
QThread::msleep(msecs);
}
};
#endif // DELAY_H

View File

@ -0,0 +1,725 @@
#include "op_dfu.h"
#include <cmath>
#include <qwaitcondition.h>
#include <QMutex>
OP_DFU::OP_DFU(bool _debug): debug(_debug)
{
send_delay=10;
use_delay=true;
int numDevices=0;
cout<<"Please connect device now\n";
int count=0;
while(numDevices==0)
{
cout<<".";
delay::msleep(500);
numDevices = hidHandle.open(1,0x20a0,0x4117,0,0); //0xff9c,0x0001);
if(++count==10)
{
cout<<"\r";
cout<<" ";
cout<<"\r";
count=0;
}
}
if(debug)
qDebug() << numDevices << " device(s) opened";
}
bool OP_DFU::SaveByteArrayToFile(QString const & sfile, const QByteArray &array)
{
QFile file(sfile);
//QFile file("in.txt");
if (!file.open(QIODevice::WriteOnly))
{
if(debug)
qDebug()<<"Cant open file";
return false;
}
file.write(array);
file.close();
return true;
}
bool OP_DFU::enterDFU(int const &devNumber)
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::EnterDFU;//DFU Command
buf[2] = 0;//DFU Count
buf[3] = 0;//DFU Count
buf[4] = 0;//DFU Count
buf[5] = 0;//DFU Count
buf[6] = devNumber;//DFU Data0
buf[7] = 1;//DFU Data1
buf[8] = 1;//DFU Data2
buf[9] = 1;//DFU Data3
int result = hidHandle.send(0,buf, BUF_LEN, 500);
if(result<1)
return false;
if(debug)
qDebug() << result << " bytes sent";
return true;
}
bool OP_DFU::StartUpload(qint32 const & numberOfBytes, TransferTypes const & type,quint32 crc)
{
int lastPacketCount;
qint32 numberOfPackets=numberOfBytes/4/14;
int pad=(numberOfBytes-numberOfPackets*4*14)/4;
if(pad==0)
{
lastPacketCount=14;
}
else
{
++numberOfPackets;
lastPacketCount=pad;
}
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = setStartBit(OP_DFU::Upload);//DFU Command
buf[2] = numberOfPackets>>24;//DFU Count
buf[3] = numberOfPackets>>16;//DFU Count
buf[4] = numberOfPackets>>8;//DFU Count
buf[5] = numberOfPackets;//DFU Count
buf[6] = (int)type;//DFU Data0
buf[7] = lastPacketCount;//DFU Data1
buf[8] = crc>>24;
buf[9] = crc>>16;
buf[10] = crc>>8;
buf[11] = crc;
if(debug)
qDebug()<<"Number of packets:"<<numberOfPackets<<" Size of last packet:"<<lastPacketCount;
int result = hidHandle.send(0,buf, BUF_LEN, 5000);
if(debug)
qDebug() << result << " bytes sent";
if(result>0)
{
return true;
}
return false;
}
bool OP_DFU::UploadData(qint32 const & numberOfBytes, QByteArray & data)
{
int lastPacketCount;
qint32 numberOfPackets=numberOfBytes/4/14;
int pad=(numberOfBytes-numberOfPackets*4*14)/4;
if(pad==0)
{
lastPacketCount=14;
}
else
{
++numberOfPackets;
lastPacketCount=pad;
}
if(debug)
qDebug()<<"Start Uploading:"<<numberOfPackets<<"4Bytes";
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Upload;//DFU Command
int packetsize;
float percentage;
int laspercentage;
for(qint32 packetcount=0;packetcount<numberOfPackets;++packetcount)
{
percentage=(float)(packetcount+1)/numberOfPackets*100;
if(laspercentage!=(int)percentage)
printProgBar((int)percentage,"UPLOADING");
laspercentage=(int)percentage;
if(packetcount==numberOfPackets)
packetsize=lastPacketCount;
else
packetsize=14;
// qDebug()<<packetcount;
buf[2] = packetcount>>24;//DFU Count
buf[3] = packetcount>>16;//DFU Count
buf[4] = packetcount>>8;//DFU Count
buf[5] = packetcount;//DFU Count
char *pointer=data.data();
pointer=pointer+4*14*packetcount;
// qDebug()<<"Packet Number="<<packetcount<<"Data0="<<(int)data[0]<<" Data1="<<(int)data[1]<<" Data0="<<(int)data[2]<<" Data0="<<(int)data[3]<<" buf6="<<(int)buf[6]<<" buf7="<<(int)buf[7]<<" buf8="<<(int)buf[8]<<" buf9="<<(int)buf[9];
CopyWords(pointer,buf+6,packetsize*4);
// for (int y=0;y<packetsize*4;++y)
// {
// qDebug()<<y<<":"<<(int)data[packetcount*14*4+y]<<"---"<<(int)buf[6+y];
// }
// qDebug()<<" Data0="<<(int)data[0]<<" Data0="<<(int)data[1]<<" Data0="<<(int)data[2]<<" Data0="<<(int)data[3]<<" buf6="<<(int)buf[6]<<" buf7="<<(int)buf[7]<<" buf8="<<(int)buf[8]<<" buf9="<<(int)buf[9];
//delay::msleep(send_delay);
if(int ret=StatusRequest()!=OP_DFU::uploading) return false;
int result = hidHandle.send(0,buf, BUF_LEN, 5000);
// qDebug()<<"sent:"<<result;
if(result<1)
{
return false;
}
// qDebug() << "UPLOAD:"<<"Data="<<(int)buf[6]<<(int)buf[7]<<(int)buf[8]<<(int)buf[9]<<";"<<result << " bytes sent";
}
cout<<"\n";
// while(true){}
return true;
}
OP_DFU::Status OP_DFU::UploadDescription(QString & description)
{
cout<<"Starting uploading description\n";
if(description.length()%4!=0)
{
int pad=description.length()/4;
pad=(pad+1)*4;
pad=pad-description.length();
QString padding;
padding.fill(' ',pad);
description.append(padding);
}
if(!StartUpload(description.length(),OP_DFU::Descript,0))
return OP_DFU::abort;
QByteArray array=description.toAscii();
if(!UploadData(description.length(),array))
{
return OP_DFU::abort;
}
if(!EndOperation())
{
return OP_DFU::abort;
}
int ret=StatusRequest();
if(debug)
qDebug()<<"Upload description Status="<<ret;
return (OP_DFU::Status)ret;
}
QString OP_DFU::DownloadDescription(int const & numberOfChars)
{
// enterDFU(devNumber);
QByteArray arr=StartDownload(numberOfChars,Descript);
QString str(arr);
return str;
}
void OP_DFU::test()
{
char buf[BUF_LEN];
int result;
buf[0]=0x02;
buf[1]=11;
buf[2]=11;
buf[63]=333;
while(true)
{
buf[0]=0x02;
++buf[1];
++buf[2];
++buf[63];
hidHandle.send(0,buf,BUF_LEN,5000);
result = hidHandle.receive(0,buf,BUF_LEN,5000);
qDebug()<<"Result="<<result;
qDebug()<<(int)buf[0]<<":"<<(int)buf[1]<<":"<<(int)buf[2]<<":"<<(int)buf[63];
}}
QByteArray OP_DFU::StartDownload(qint32 const & numberOfBytes, TransferTypes const & type)
{
int lastPacketCount;
qint32 numberOfPackets=numberOfBytes/4/14;
int pad=(numberOfBytes-numberOfPackets*4*14)/4;
if(pad==0)
{
lastPacketCount=14;
}
else
{
++numberOfPackets;
lastPacketCount=pad;
}
QByteArray ret;
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Download_Req;//DFU Command
buf[2] = numberOfPackets>>24;//DFU Count
buf[3] = numberOfPackets>>16;//DFU Count
buf[4] = numberOfPackets>>8;//DFU Count
buf[5] = numberOfPackets;//DFU Count
buf[6] = (int)type;//DFU Data0
buf[7] = lastPacketCount;//DFU Data1
buf[8] = 1;//DFU Data2
buf[9] = 1;//DFU Data3
int result = hidHandle.send(0,buf, BUF_LEN, 500);
if(debug)
qDebug() << "StartDownload:"<<numberOfPackets<<"packets"<<" Last Packet Size="<<lastPacketCount<<" "<<result << " bytes sent";
float percentage;
int laspercentage;
for(qint32 x=0;x<numberOfPackets;++x)
{
percentage=(float)(x+1)/numberOfPackets*100;
if(laspercentage!=(int)percentage)
printProgBar((int)percentage,"DOWNLOADING");
laspercentage=(int)percentage;
// qDebug()<<"Status="<<StatusToString(StatusRequest());
result = hidHandle.receive(0,buf,BUF_LEN,5000);
if(debug)
qDebug() << result << " bytes received"<<" Count="<<x<<"-"<<(int)buf[2]<<";"<<(int)buf[3]<<";"<<(int)buf[4]<<";"<<(int)buf[5]<<" Data="<<(int)buf[6]<<";"<<(int)buf[7]<<";"<<(int)buf[8]<<";"<<(int)buf[9];
int size;
if(x==numberOfPackets-1)
size=lastPacketCount*4;
else
size=14*4;
ret.append(buf+6,size);
}
cout<<"\n";
StatusRequest();
return ret;
}
void OP_DFU::ResetDevice(void)
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Reset;//DFU Command
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 500);
}
void OP_DFU::AbortOperation(void)
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Abort_Operation;//DFU Command
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 500);
}
void OP_DFU::JumpToApp()
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::JumpFW;//DFU Command
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 500);
}
OP_DFU::Status OP_DFU::StatusRequest()
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Status_Request;//DFU Command
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 10000);
if(debug)
qDebug() << result << " bytes sent";
result = hidHandle.receive(0,buf,BUF_LEN,10000);
if(debug)
qDebug() << result << " bytes received";
if(buf[1]==OP_DFU::Status_Rep)
{
return (OP_DFU::Status)buf[6];
}
else
return OP_DFU::abort;
}
bool OP_DFU::findDevices()
{
devices.clear();
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Req_Capabilities;//DFU Command
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 5000);
if(result<1)
{
return false;
}
result = hidHandle.receive(0,buf,BUF_LEN,5000);
if(result<1)
{
return false;
}
numberOfDevices=buf[7];
RWFlags=buf[8];
RWFlags=RWFlags<<8 | buf[9];
if(buf[1]==OP_DFU::Rep_Capabilities)
{
for(int x=0;x<numberOfDevices;++x)
{
device dev;
dev.Readable=(bool)(RWFlags>>(x*2) & 1);
dev.Writable=(bool)(RWFlags>>(x*2+1) & 1);
devices.append(dev);
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Req_Capabilities;//DFU Command
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = x+1;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 5000);
result = hidHandle.receive(0,buf,BUF_LEN,5000);
devices[x].ID=buf[9];
devices[x].BL_Version=buf[7];
devices[x].SizeOfDesc=buf[8];
quint32 aux;
aux=(quint8)buf[10];
aux=aux<<8 |(quint8)buf[11];
aux=aux<<8 |(quint8)buf[12];
aux=aux<<8 |(quint8)buf[13];
devices[x].FW_CRC=aux;
aux=(quint8)buf[2];
aux=aux<<8 |(quint8)buf[3];
aux=aux<<8 |(quint8)buf[4];
aux=aux<<8 |(quint8)buf[5];
devices[x].SizeOfCode=aux;
}
if(debug)
{
qDebug()<<"Found "<<numberOfDevices;
for(int x=0;x<numberOfDevices;++x)
{
qDebug()<<"Device #"<<x+1;
qDebug()<<"Device ID="<<devices[x].ID;
qDebug()<<"Device Readable="<<devices[x].Readable;
qDebug()<<"Device Writable="<<devices[x].Writable;
qDebug()<<"Device SizeOfCode="<<devices[x].SizeOfCode;
qDebug()<<"Device SizeOfDesc="<<devices[x].SizeOfDesc;
qDebug()<<"BL Version="<<devices[x].BL_Version;
qDebug()<<"FW CRC="<<devices[x].FW_CRC;
}
}
}
return true;
}
bool OP_DFU::EndOperation()
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
buf[1] = OP_DFU::Op_END;//DFU Command
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
int result = hidHandle.send(0,buf, BUF_LEN, 5000);
// hidHandle.receive(0,buf,BUF_LEN,5000);
if(debug)
qDebug() << result << " bytes sent";
if(result>0)
return true;
return false;
}
OP_DFU::Status OP_DFU::UploadFirmware(const QString &sfile, const bool &verify,int device)
{
OP_DFU::Status ret;
cout<<"Starting Firmware Uploading...\n";
QFile file(sfile);
//QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly))
{
if(debug)
qDebug()<<"Cant open file";
return OP_DFU::abort;
}
QByteArray arr=file.readAll();
if(debug)
qDebug()<<"Bytes Loaded="<<arr.length();
if(arr.length()%4!=0)
{
int pad=arr.length()/4;
++pad;
pad=pad*4;
pad=pad-arr.length();
arr.append(QByteArray(pad,255));
}
if(devices[device].SizeOfCode<arr.length())
{
cout<<"ERROR file to big for device\n";
return OP_DFU::abort;;
}
quint32 crc=CRCFromQBArray(arr,devices[device].SizeOfCode);
cout<<"NEW FIRMWARE CRC="<<crc<<"\n";
if(!StartUpload(arr.length(),FW,crc))
{
if(debug)
{
qDebug()<<"StartUpload failed";
OP_DFU::Status ret=StatusRequest();
qDebug()<<"StartUpload returned:"<< StatusToString(ret);
}
return OP_DFU::abort;
}
cout<<"Erasing memory\n";
if(StatusRequest()==OP_DFU::abort) return OP_DFU::abort;
for(int x=0;x<3;++x)
{
OP_DFU::Status ret=StatusRequest();
if(debug)
qDebug()<<"Erase returned:"<<StatusToString(ret);
if (ret==OP_DFU::uploading)
break;
else
return OP_DFU::abort;
}
if(!UploadData(arr.length(),arr))
{
if(debug)
{
qDebug()<<"Upload failed (upload data)";
OP_DFU::Status ret=StatusRequest();
qDebug()<<"StartUpload returned:"<<StatusToString(ret);
}
return OP_DFU::abort;
}
if(!EndOperation())
{
if(debug)
{
qDebug()<<"Upload failed (end operation)";
OP_DFU::Status ret=StatusRequest();
qDebug()<<"StartUpload returned:"<<StatusToString(ret);
}
return OP_DFU::abort;
}
ret=StatusRequest();
if(ret==OP_DFU::Last_operation_Success)
{
}
else
{
return ret;
}
if(verify)
{
cout<<"Starting code verification\n";
if(arr==StartDownload(arr.length(),OP_DFU::FW))
cout<<"Verify:PASSED\n";
else
{
cout<<"Verify:FAILED\n";
return OP_DFU::abort;
}
}
else
{
return ret;
}
if(debug)
qDebug()<<"Status="<<ret;
cout<<"Firmware Uploading succeeded\n";
return ret;
}
OP_DFU::Status OP_DFU::CompareFirmware(const QString &sfile, const CompareType &type,int device)
{
cout<<"Starting Firmware Compare...\n";
QFile file(sfile);
if (!file.open(QIODevice::ReadOnly))
{
if(debug)
qDebug()<<"Cant open file";
return OP_DFU::abort;
}
QByteArray arr=file.readAll();
if(debug)
qDebug()<<"Bytes Loaded="<<arr.length();
if(arr.length()%4!=0)
{
int pad=arr.length()/4;
++pad;
pad=pad*4;
pad=pad-arr.length();
arr.append(QByteArray(pad,255));
}
if(type==OP_DFU::crccompare)
{
quint32 crc=CRCFromQBArray(arr,devices[device].SizeOfCode);
if(crc==devices[device].FW_CRC)
{
cout<<"Compare Successfull CRC MATCH!\n";
}
else
{
cout<<"Compare failed CRC DONT MATCH!\n";
}
return StatusRequest();
}
else
{
if(arr==StartDownload(arr.length(),OP_DFU::FW))
{
cout<<"Compare Successfull ALL Bytes MATCH!\n";
}
else
{
cout<<"Compare failed Bytes DONT MATCH!\n";
}
return StatusRequest();
}
}
void OP_DFU::CopyWords(char *source, char *destination, int count)
{
for (int x=0;x<count;x=x+4)
{
*(destination+x)=source[x+3];
*(destination+x+1)=source[x+2];
*(destination+x+2)=source[x+1];
*(destination+x+3)=source[x+0];
}
}
QString OP_DFU::StatusToString(OP_DFU::Status const & status)
{
switch(status)
{
case DFUidle:
return "DFUidle";
case uploading:
return "";
case wrong_packet_received:
return "wrong_packet_received";
case too_many_packets:
return "too_many_packets";
case too_few_packets:
return "too_few_packets";
case Last_operation_Success:
return "Last_operation_Success";
case downloading:
return "downloading";
case idle:
return "idle";
case Last_operation_failed:
return "Last_operation_failed";
case outsideDevCapabilities:
return "outsideDevCapabilities";
case CRC_Fail:
return "CRC check FAILED";
case failed_jump:
return "Jmp to user FW failed";
case abort:
return "abort";
case uploadingStarting:
return "Uploading Starting";
default:
return "unknown";
}
}
void OP_DFU::printProgBar( int const & percent,QString const& label){
std::string bar;
for(int i = 0; i < 50; i++){
if( i < (percent/2)){
bar.replace(i,1,"=");
}else if( i == (percent/2)){
bar.replace(i,1,">");
}else{
bar.replace(i,1," ");
}
}
std::cout<< "\r"<<label.toLatin1().data()<< "[" << bar << "] ";
std::cout.width( 3 );
std::cout<< percent << "% " << std::flush;
}
quint32 OP_DFU::CRC32WideFast(quint32 Crc, quint32 Size, quint32 *Buffer)
{
//Size = Size >> 2; // /4 Size passed in as a byte count, assumed to be a multiple of 4
while(Size--)
{
static const quint32 CrcTable[16] = { // Nibble lookup table for 0x04C11DB7 polynomial
0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };
Crc = Crc ^ *((quint32 *)Buffer); // Apply all 32-bits
Buffer += 1;
// Process 32-bits, 4 at a time, or 8 rounds
Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // Assumes 32-bit reg, masking index to 4-bits
Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // 0x04C11DB7 Polynomial used in STM32
Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
}
return(Crc);
}
quint32 OP_DFU::CRCFromQBArray(QByteArray array, quint32 Size)
{
int pad=Size-array.length();
array.append(QByteArray(pad,255));
quint32 t[Size/4];
for(int x=0;x<array.length()/4;x++)
{
quint32 aux=0;
aux=(char)array[x*4+3]&0xFF;
aux=aux<<8;
aux+=(char)array[x*4+2]&0xFF;
aux=aux<<8;
aux+=(char)array[x*4+1]&0xFF;
aux=aux<<8;
aux+=(char)array[x*4+0]&0xFF;
t[x]=aux;
}
return CRC32WideFast(0xFFFFFFFF,Size/4,(quint32*)t);
}

View File

@ -0,0 +1,139 @@
#ifndef OP_DFU_H
#define OP_DFU_H
#include <QByteArray>
#include <rawhid/pjrc_rawhid.h>
#include <QDebug>
#include <QFile>
#include <QCryptographicHash>
#include <QList>
#include <iostream>
#include "delay.h"
using namespace std;
#define BUF_LEN 64
//Command Line Options
#define DOWNLOAD "-dn" //done
#define DEVICE "-d" //done
//#define DOWNDESCRIPTION "-dd" //done
#define PROGRAMFW "-p" //done
#define PROGRAMDESC "-w" //done
#define VERIFY "-v" //done
#define COMPARECRC "-cc"
#define COMPAREALL "-ca"
#define STATUSREQUEST "-s" //done
#define LISTDEVICES "-ls" //done
#define RESET "-r"
#define JUMP "-j"
class OP_DFU
{
public:
enum TransferTypes
{
FW,
Descript
};
enum CompareType
{
crccompare,
bytetobytecompare
};
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,
Req_Capabilities,
Rep_Capabilities,
EnterDFU,
JumpFW,
Reset,
Abort_Operation,
Upload,
Op_END,
Download_Req,
Download,
Status_Request,
Status_Rep,
};
struct device
{
int ID;
quint32 FW_CRC;
int BL_Version;
int SizeOfDesc;
quint32 SizeOfCode;
bool Readable;
bool Writable;
};
void JumpToApp();
void ResetDevice(void);
bool enterDFU(int const &devNumber);
bool StartUpload(qint32 const &numberOfBytes, TransferTypes const & type,quint32 crc);
bool UploadData(qint32 const & numberOfPackets,QByteArray & data);
Status UploadDescription(QString & description);
Status UploadFirmware(const QString &sfile, const bool &verify,int device);
Status StatusRequest();
bool EndOperation();
void printProgBar( int const & percent,QString const& label);
QString DownloadDescription(int const & numberOfChars);
QByteArray StartDownload(qint32 const & numberOfBytes, TransferTypes const & type);
bool SaveByteArrayToFile(QString const & file,QByteArray const &array);
void CopyWords(char * source, char* destination, int count);
// QByteArray DownloadData(int devNumber,int numberOfPackets);
OP_DFU(bool debug);
bool findDevices();
QList<device> devices;
int numberOfDevices;
QString StatusToString(OP_DFU::Status const & status);
OP_DFU::Status CompareFirmware(const QString &sfile, const CompareType &type,int device);
quint32 CRC32WideFast(quint32 Crc, quint32 Size, quint32 *Buffer);
quint32 CRCFromQBArray(QByteArray array, quint32 Size);
void test();
int send_delay;
bool use_delay;
void AbortOperation(void);
private:
bool debug;
int RWFlags;
pjrc_rawhid hidHandle;
int setStartBit(int command){return command|0x20;}
};
#endif // OP_DFU_H

View File

@ -1,19 +1,26 @@
TEMPLATE = lib
TARGET = Uploader
include(../../openpilotgcsplugin.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(../../libs/qextserialport/qextserialport.pri)
include(../../libs/qymodem/qymodem.pri)
HEADERS += uploadergadget.h \
uploadergadgetconfiguration.h \
uploadergadgetfactory.h \
uploadergadgetoptionspage.h \
uploadergadgetwidget.h \
uploaderplugin.h
SOURCES += uploadergadget.cpp \
uploadergadgetconfiguration.cpp \
uploadergadgetfactory.cpp \
uploadergadgetoptionspage.cpp \
uploadergadgetwidget.cpp \
uploaderplugin.cpp
OTHER_FILES += Uploader.pluginspec
TEMPLATE = lib
TARGET = Uploader
include(../../openpilotgcsplugin.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(../../libs/qextserialport/qextserialport.pri)
include(../../libs/qymodem/qymodem.pri)
HEADERS += uploadergadget.h \
uploadergadgetconfiguration.h \
uploadergadgetfactory.h \
uploadergadgetoptionspage.h \
uploadergadgetwidget.h \
uploaderplugin.h \
op_dfu.h \
delay.h
SOURCES += uploadergadget.cpp \
uploadergadgetconfiguration.cpp \
uploadergadgetfactory.cpp \
uploadergadgetoptionspage.cpp \
uploadergadgetwidget.cpp \
uploaderplugin.cpp \
op_dfu.cpp \
delay.cpp
OTHER_FILES += Uploader.pluginspec
FORMS += \
uploader.ui

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UploaderWidget</class>
<widget class="QWidget" name="UploaderWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>580</width>
<height>350</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,3,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="haltButton">
<property name="toolTip">
<string>Tells the mainboard to go down
to bootloader mode.</string>
</property>
<property name="text">
<string>Halt</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="bootButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Boots the system.
Only enabled if the system is halted.</string>
</property>
<property name="text">
<string>Boot</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="toolTip">
<string>Reset the system.</string>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="boardStatus">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Running</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="systemElements">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Mainboard</string>
</attribute>
</widget>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Please connect your board through USB for firmware upload.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -28,52 +28,10 @@
UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
{
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
m_config = new Ui_UploaderWidget();
m_config->setupUi(this);
//main layout
QVBoxLayout *layout = new QVBoxLayout;
//choose file layout and widget
QHBoxLayout *FileLayout = new QHBoxLayout;
QWidget *FileWidget = new QWidget;
FileWidget->setLayout(FileLayout);
openFileNameLE=new QLineEdit();
QPushButton* loadfile = new QPushButton("Load File");
loadfile->setMaximumWidth(80);
FileLayout->addWidget(openFileNameLE);
FileLayout->addWidget(loadfile);
//send file layout and widget
QHBoxLayout *SendLayout = new QHBoxLayout;
QWidget *SendWidget = new QWidget;
SendWidget->setLayout(SendLayout);
progressBar=new QProgressBar();
progressBar->setMaximum(100);
QPushButton* sendBt = new QPushButton("Send");
sendBt->setMaximumWidth(80);
SendLayout->addWidget(progressBar);
SendLayout->addWidget(sendBt);
//status layout and widget
QHBoxLayout *StatusLayout = new QHBoxLayout;
QWidget *StatusWidget = new QWidget;
StatusWidget->setLayout(StatusLayout);
status=new QLabel();
StatusLayout->addWidget(status);
//add partial widgets to main widget
layout->addWidget(FileWidget);
layout->addWidget(SendWidget);
layout->addWidget(StatusWidget);
setLayout(layout);
//connect signals to slots
//fires when the user presses file button
connect(loadfile, SIGNAL(clicked(bool)),
this,SLOT(setOpenFileName()));
//fires when the user presses send button
connect(sendBt, SIGNAL(clicked(bool)),
this,SLOT(send()));
}
//user pressed send, send file using a new thread with qymodem library
void UploaderGadgetWidget::send()

View File

@ -28,22 +28,20 @@
#ifndef UPLOADERGADGETWIDGET_H
#define UPLOADERGADGETWIDGET_H
//#include "qmapcontrol/qmapcontrol.h"
#include "ui_uploader.h"
#include <QtGui/QWidget>
#include <qextserialport/src/qextserialport.h>
#include <qymodem/src/qymodemsend.h>
#include <QLabel>
#include <QLineEdit>
#include <QThread>
# include <QProgressBar>
#include <QProgressBar>
#include <QStringList>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QFileDialog>
#include <QMessageBox>
//using namespace qmapcontrol;
class Ui_UploaderWidget;
class UploaderGadgetWidget : public QWidget
{
@ -57,6 +55,7 @@ public:
private:
Ui_UploaderWidget *m_config;
QLineEdit* openFileNameLE;
QextSerialPort *Port;