2 ******************************************************************************
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
8 * @addtogroup Uploader Uploader Plugin
10 * @brief The uploader plugin
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include <qwaitcondition.h>
32 #include <QtWidgets/QApplication>
34 using namespace OP_DFU
;
36 DFUObject::DFUObject(bool _debug
, bool _use_serial
, QString portname
) :
37 debug(_debug
), use_serial(_use_serial
), mready(true)
42 qRegisterMetaType
<OP_DFU::Status
>("Status");
45 info
= new port(portname
);
46 info
->rxBuf
= sspRxBuf
;
47 info
->rxBufSize
= MAX_PACKET_DATA_LEN
;
48 info
->txBuf
= sspTxBuf
;
49 info
->txBufSize
= MAX_PACKET_DATA_LEN
;
51 info
->timeoutLen
= 1000;
52 if (info
->status() != port::open
) {
53 cout
<< "Could not open serial port\n";
57 serialhandle
= new qsspt(info
, debug
);
60 while ((serialhandle
->ssp_Synchronise() == false) && (count
< 10)) {
62 qDebug() << "SYNC failed, resending";
70 qDebug() << "SYNC Succeded";
71 serialhandle
->start();
74 QEventLoop m_eventloop
;
75 QTimer::singleShot(200, &m_eventloop
, SLOT(quit()));
77 QList
<USBPortInfo
> devices
;
78 devices
= USBMonitor::instance()->availableDevices(0x20a0, -1, -1, USBMonitor::Bootloader
);
79 if (devices
.length() == 1) {
80 if (hidHandle
.open(1, devices
.first().vendorID
, devices
.first().productID
, 0, 0) == 1) {
82 QTimer::singleShot(200, &m_eventloop
, SLOT(quit()));
88 // Wait for the board to appear on the USB bus:
89 USBSignalFilter
filter(0x20a0, -1, -1, USBMonitor::Bootloader
);
90 connect(&filter
, SIGNAL(deviceDiscovered()), &m_eventloop
, SLOT(quit()));
91 for (int x
= 0; x
< 4; ++x
) {
92 qDebug() << "OP_DFU trying to detect bootloader:" << x
;
95 QTimer::singleShot(10000, &m_eventloop
, SLOT(quit()));
97 QTimer::singleShot(2000, &m_eventloop
, SLOT(quit()));
100 devices
= USBMonitor::instance()->availableDevices(0x20a0, -1, -1, USBMonitor::Bootloader
);
101 qDebug() << "Devices length: " << devices
.length();
102 if (devices
.length() == 1) {
103 qDebug() << "Opening device";
104 if (hidHandle
.open(1, devices
.first().vendorID
, devices
.first().productID
, 0, 0) == 1) {
105 QTimer::singleShot(200, &m_eventloop
, SLOT(quit()));
107 qDebug() << "OP_DFU detected after delay";
109 qDebug() << "Detected";
115 qDebug() << devices
.length() << " device(s) detected, don't know what to do!";
123 DFUObject::~DFUObject()
135 bool DFUObject::SaveByteArrayToFile(QString
const & sfile
, const QByteArray
&array
)
139 if (!file
.open(QIODevice::WriteOnly
)) {
141 qDebug() << "Can't open file";
151 Tells the mainboard to enter DFU Mode.
153 bool DFUObject::enterDFU(int const &devNumber
)
157 buf
[0] = 0x02; // reportID
158 buf
[1] = OP_DFU::EnterDFU
; // DFU Command
159 buf
[2] = 0; // DFU Count
160 buf
[3] = 0; // DFU Count
161 buf
[4] = 0; // DFU Count
162 buf
[5] = 0; // DFU Count
163 buf
[6] = devNumber
; // DFU Data0
164 buf
[7] = 1; // DFU Data1
165 buf
[8] = 1; // DFU Data2
166 buf
[9] = 1; // DFU Data3
168 int result
= sendData(buf
, BUF_LEN
);
173 qDebug() << "EnterDFU: " << result
<< " bytes sent";
179 Tells the board to get ready for an upload. It will in particular
180 erase the memory to make room for the data. You will have to query
181 its status to wait until erase is done before doing the actual upload.
183 bool DFUObject::StartUpload(qint32
const & numberOfBytes
, TransferTypes
const & type
, quint32 crc
)
186 qint32 numberOfPackets
= numberOfBytes
/ 4 / 14;
187 int pad
= (numberOfBytes
- numberOfPackets
* 4 * 14) / 4;
190 lastPacketCount
= 14;
193 lastPacketCount
= pad
;
196 buf
[0] = 0x02; // reportID
197 buf
[1] = setStartBit(OP_DFU::Upload
); // DFU Command
198 buf
[2] = numberOfPackets
>> 24; // DFU Count
199 buf
[3] = numberOfPackets
>> 16; // DFU Count
200 buf
[4] = numberOfPackets
>> 8; // DFU Count
201 buf
[5] = numberOfPackets
; // DFU Count
202 buf
[6] = (int)type
; // DFU Data0
203 buf
[7] = lastPacketCount
; // DFU Data1
209 qDebug() << "Number of packets:" << numberOfPackets
<< " Size of last packet:" << lastPacketCount
;
212 int result
= sendData(buf
, BUF_LEN
);
216 qDebug() << result
<< " bytes sent";
226 Does the actual data upload to the board. Needs to be called once the
227 board is ready to accept data following a StartUpload command, and it is erased.
229 bool DFUObject::UploadData(qint32
const & numberOfBytes
, QByteArray
& data
)
232 qint32 numberOfPackets
= numberOfBytes
/ 4 / 14;
233 int pad
= (numberOfBytes
- numberOfPackets
* 4 * 14) / 4;
236 lastPacketCount
= 14;
239 lastPacketCount
= pad
;
242 qDebug() << "Start Uploading:" << numberOfPackets
<< "4Bytes";
245 buf
[0] = 0x02; // reportID
246 buf
[1] = OP_DFU::Upload
; // DFU Command
249 int laspercentage
= 0;
250 for (qint32 packetcount
= 0; packetcount
< numberOfPackets
; ++packetcount
) {
251 percentage
= (float)(packetcount
+ 1) / numberOfPackets
* 100;
252 if (laspercentage
!= (int)percentage
) {
253 printProgBar((int)percentage
, "UPLOADING");
255 laspercentage
= (int)percentage
;
256 if (packetcount
== numberOfPackets
) {
257 packetsize
= lastPacketCount
;
261 // qDebug()<<packetcount;
262 buf
[2] = packetcount
>> 24; // DFU Count
263 buf
[3] = packetcount
>> 16; // DFU Count
264 buf
[4] = packetcount
>> 8; // DFU Count
265 buf
[5] = packetcount
; // DFU Count
266 char *pointer
= data
.data();
267 pointer
= pointer
+ 4 * 14 * packetcount
;
268 // 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];
269 CopyWords(pointer
, buf
+ 6, packetsize
* 4);
270 // for (int y=0;y<packetsize*4;++y)
273 // qDebug()<<y<<":"<<(int)data[packetcount*14*4+y]<<"---"<<(int)buf[6+y];
277 // 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];
278 // delay::msleep(send_delay);
280 // if(StatusRequest()!=OP_DFU::uploading) return false;
281 int result
= sendData(buf
, BUF_LEN
);
282 // qDebug()<<"sent:"<<result;
287 // qDebug() << "UPLOAD:"<<"Data="<<(int)buf[6]<<(int)buf[7]<<(int)buf[8]<<(int)buf[9]<<";"<<result << " bytes sent";
295 Sends the firmware description to the device
297 OP_DFU::Status
DFUObject::UploadDescription(QVariant desc
)
299 cout
<< "Starting uploading description\n";
302 if (desc
.type() == QVariant::String
) {
303 QString description
= desc
.toString();
304 if (description
.length() % 4 != 0) {
305 int pad
= description
.length() / 4;
307 pad
= pad
- description
.length();
309 padding
.fill(' ', pad
);
310 description
.append(padding
);
312 array
= description
.toLatin1();
313 } else if (desc
.type() == QVariant::ByteArray
) {
314 array
= desc
.toByteArray();
317 if (!StartUpload(array
.length(), OP_DFU::Descript
, 0)) {
318 return OP_DFU::abort
;
320 if (!UploadData(array
.length(), array
)) {
321 return OP_DFU::abort
;
323 if (!EndOperation()) {
324 return OP_DFU::abort
;
326 OP_DFU::Status ret
= StatusRequest();
330 qDebug() << "Upload description Status=" << StatusToString(ret
);
337 Downloads the description string for the current device.
338 You have to call enterDFU before calling this function.
340 QString
DFUObject::DownloadDescription(int const & numberOfChars
)
344 StartDownloadT(&arr
, numberOfChars
, OP_DFU::Descript
);
346 int index
= arr
.indexOf(255);
347 return QString((index
== -1) ? arr
: arr
.left(index
));
350 QByteArray
DFUObject::DownloadDescriptionAsBA(int const & numberOfChars
)
354 StartDownloadT(&arr
, numberOfChars
, OP_DFU::Descript
);
360 Starts a firmware download
361 @param firmwareArray: pointer to the location where we should store the firmware
362 @package device: the device to use for the download
364 bool DFUObject::DownloadFirmware(QByteArray
*firmwareArray
, int device
)
369 requestedOperation
= OP_DFU::Download
;
370 requestSize
= devices
[device
].SizeOfCode
;
371 requestTransferType
= OP_DFU::FW
;
372 requestStorage
= firmwareArray
;
379 Runs the upload or download operations.
381 void DFUObject::run()
383 switch (requestedOperation
) {
384 case OP_DFU::Download
:
385 StartDownloadT(requestStorage
, requestSize
, requestTransferType
);
386 emit(downloadFinished());
390 OP_DFU::Status ret
= UploadFirmwareT(requestFilename
, requestVerify
, requestDevice
);
391 emit(uploadFinished(ret
));
400 Downloads a certain number of bytes from a certain location, and stores in an array whose
401 pointer is passed as an argument
403 bool DFUObject::StartDownloadT(QByteArray
*fw
, qint32
const & numberOfBytes
, TransferTypes
const & type
)
407 // First of all, work out the number of DFU packets we should ask for:
408 qint32 numberOfPackets
= numberOfBytes
/ 4 / 14;
409 int pad
= (numberOfBytes
- numberOfPackets
* 4 * 14) / 4;
412 lastPacketCount
= 14;
415 lastPacketCount
= pad
;
420 buf
[0] = 0x02; // reportID
421 buf
[1] = OP_DFU::Download_Req
; // DFU Command
422 buf
[2] = numberOfPackets
>> 24; // DFU Count
423 buf
[3] = numberOfPackets
>> 16; // DFU Count
424 buf
[4] = numberOfPackets
>> 8; // DFU Count
425 buf
[5] = numberOfPackets
; // DFU Count
426 buf
[6] = (int)type
; // DFU Data0
427 buf
[7] = lastPacketCount
; // DFU Data1
428 buf
[8] = 1; // DFU Data2
429 buf
[9] = 1; // DFU Data3
431 int result
= sendData(buf
, BUF_LEN
);
433 qDebug() << "StartDownload:" << numberOfPackets
<< "packets" << " Last Packet Size=" << lastPacketCount
<< " " << result
<< " bytes sent";
436 int laspercentage
= 0;
438 // Now get those packets:
439 for (qint32 x
= 0; x
< numberOfPackets
; ++x
) {
441 percentage
= (float)(x
+ 1) / numberOfPackets
* 100;
442 if (laspercentage
!= (int)percentage
) {
443 printProgBar((int)percentage
, "DOWNLOADING");
445 laspercentage
= (int)percentage
;
447 result
= receiveData(buf
, BUF_LEN
);
449 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];
451 if (x
== numberOfPackets
- 1) {
452 size
= lastPacketCount
* 4;
456 fw
->append(buf
+ 6, size
);
467 int DFUObject::ResetDevice(void)
471 buf
[0] = 0x02; // reportID
472 buf
[1] = OP_DFU::Reset
; // DFU Command
482 return sendData(buf
, BUF_LEN
);
483 // return hidHandle.send(0,buf, BUF_LEN, 500);
486 int DFUObject::AbortOperation(void)
490 buf
[0] = 0x02; // reportID
491 buf
[1] = OP_DFU::Abort_Operation
; // DFU Command
501 return sendData(buf
, BUF_LEN
);
504 Starts the firmware (leaves bootloader and boots the main software)
506 int DFUObject::JumpToApp(bool safeboot
, bool erase
)
510 buf
[0] = 0x02; // reportID
511 buf
[1] = OP_DFU::JumpFW
; // DFU Command
519 /* force system to safe boot mode (hwsettings == defaults) */
527 // force data flash clear
559 return sendData(buf
, BUF_LEN
);
562 OP_DFU::Status
DFUObject::StatusRequest()
566 buf
[0] = 0x02; // reportID
567 buf
[1] = OP_DFU::Status_Request
; // DFU Command
577 int result
= sendData(buf
, BUF_LEN
);
579 qDebug() << "StatusRequest: " << result
<< " bytes sent";
581 result
= receiveData(buf
, BUF_LEN
);
583 qDebug() << "StatusRequest: " << result
<< " bytes received";
585 if (buf
[1] == OP_DFU::Status_Rep
) {
586 return (OP_DFU::Status
)buf
[6];
588 return OP_DFU::abort
;
593 Ask the bootloader for the list of devices available
595 bool DFUObject::findDevices()
599 buf
[0] = 0x02; // reportID
600 buf
[1] = OP_DFU::Req_Capabilities
; // DFU Command
610 int result
= sendData(buf
, BUF_LEN
);
615 result
= receiveData(buf
, BUF_LEN
);
620 numberOfDevices
= buf
[7];
622 RWFlags
= RWFlags
<< 8 | buf
[9];
624 if (buf
[1] == OP_DFU::Rep_Capabilities
) {
625 for (int x
= 0; x
< numberOfDevices
; ++x
) {
627 dev
.Readable
= (bool)(RWFlags
>> (x
* 2) & 1);
628 dev
.Writable
= (bool)(RWFlags
>> (x
* 2 + 1) & 1);
630 buf
[0] = 0x02; // reportID
631 buf
[1] = OP_DFU::Req_Capabilities
; // DFU Command
640 sendData(buf
, BUF_LEN
);
641 receiveData(buf
, BUF_LEN
);
642 devices
[x
].ID
= buf
[14];
643 devices
[x
].ID
= devices
[x
].ID
<< 8 | (quint8
)buf
[15];
644 devices
[x
].BL_Version
= buf
[7];
645 devices
[x
].SizeOfDesc
= buf
[8];
648 aux
= (quint8
)buf
[10];
649 aux
= aux
<< 8 | (quint8
)buf
[11];
650 aux
= aux
<< 8 | (quint8
)buf
[12];
651 aux
= aux
<< 8 | (quint8
)buf
[13];
653 devices
[x
].FW_CRC
= aux
;
656 aux
= (quint8
)buf
[2];
657 aux
= aux
<< 8 | (quint8
)buf
[3];
658 aux
= aux
<< 8 | (quint8
)buf
[4];
659 aux
= aux
<< 8 | (quint8
)buf
[5];
660 devices
[x
].SizeOfCode
= aux
;
663 qDebug() << "Found " << numberOfDevices
<< " devices";
664 for (int x
= 0; x
< numberOfDevices
; ++x
) {
665 qDebug() << "Device #" << x
+ 1;
666 qDebug() << "Device ID=" << devices
[x
].ID
;
667 qDebug() << "Device Readable=" << devices
[x
].Readable
;
668 qDebug() << "Device Writable=" << devices
[x
].Writable
;
669 qDebug() << "Device SizeOfCode=" << devices
[x
].SizeOfCode
;
670 qDebug() << "Device SizeOfDesc=" << devices
[x
].SizeOfDesc
;
671 qDebug() << "BL Version=" << devices
[x
].BL_Version
;
672 qDebug() << "FW CRC=" << devices
[x
].FW_CRC
;
680 bool DFUObject::EndOperation()
684 buf
[0] = 0x02; // reportID
685 buf
[1] = OP_DFU::Op_END
; // DFU Command
695 int result
= sendData(buf
, BUF_LEN
);
697 qDebug() << result
<< " bytes sent";
708 Starts a firmware upload (asynchronous)
710 bool DFUObject::UploadFirmware(const QString
&sfile
, const bool &verify
, int device
)
715 requestedOperation
= OP_DFU::Upload
;
716 requestFilename
= sfile
;
717 requestDevice
= device
;
718 requestVerify
= verify
;
723 OP_DFU::Status
DFUObject::UploadFirmwareT(const QString
&sfile
, const bool &verify
, int device
)
728 qDebug() << "Starting Firmware Uploading...";
733 if (!file
.open(QIODevice::ReadOnly
)) {
735 qDebug() << "Cant open file";
737 return OP_DFU::abort
;
740 QByteArray arr
= file
.readAll();
743 qDebug() << "Bytes Loaded=" << arr
.length();
745 if (arr
.length() % 4 != 0) {
746 int pad
= arr
.length() / 4;
749 pad
= pad
- arr
.length();
750 arr
.append(QByteArray(pad
, 255));
752 if (devices
[device
].SizeOfCode
< (quint32
)arr
.length()) {
754 qDebug() << "ERROR file to big for device";
756 return OP_DFU::abort
;;
759 quint32 crc
= DFUObject::CRCFromQBArray(arr
, devices
[device
].SizeOfCode
);
761 qDebug() << "NEW FIRMWARE CRC=" << crc
;
764 if (!StartUpload(arr
.length(), OP_DFU::FW
, crc
)) {
765 ret
= StatusRequest();
767 qDebug() << "StartUpload failed";
768 qDebug() << "StartUpload returned:" << StatusToString(ret
);
773 emit
operationProgress(QString("Erasing, please wait..."));
776 qDebug() << "Erasing memory";
778 if (StatusRequest() == OP_DFU::abort
) {
779 return OP_DFU::abort
;
782 // TODO: why is there a loop there? The "if" statement
783 // will cause a break or return anyway!!
784 for (int x
= 0; x
< 3; ++x
) {
785 ret
= StatusRequest();
787 qDebug() << "Erase returned: " << StatusToString(ret
);
789 if (ret
== OP_DFU::uploading
) {
796 emit
operationProgress(QString("Uploading firmware"));
797 if (!UploadData(arr
.length(), arr
)) {
798 ret
= StatusRequest();
800 qDebug() << "Upload failed (upload data)";
801 qDebug() << "UploadData returned:" << StatusToString(ret
);
805 if (!EndOperation()) {
806 ret
= StatusRequest();
808 qDebug() << "Upload failed (end operation)";
809 qDebug() << "EndOperation returned:" << StatusToString(ret
);
813 ret
= StatusRequest();
814 if (ret
!= OP_DFU::Last_operation_Success
) {
819 emit
operationProgress(QString("Verifying firmware"));
820 cout
<< "Starting code verification\n";
822 StartDownloadT(&arr2
, arr
.length(), OP_DFU::FW
);
824 cout
<< "Verify:FAILED\n";
825 return OP_DFU::abort
;
830 qDebug() << "Status=" << ret
;
832 cout
<< "Firmware Uploading succeeded\n";
837 OP_DFU::Status
DFUObject::CompareFirmware(const QString
&sfile
, const CompareType
&type
, int device
)
839 cout
<< "Starting Firmware Compare...\n";
841 if (!file
.open(QIODevice::ReadOnly
)) {
843 qDebug() << "Cant open file";
845 return OP_DFU::abort
;
847 QByteArray arr
= file
.readAll();
850 qDebug() << "Bytes Loaded=" << arr
.length();
852 if (arr
.length() % 4 != 0) {
853 int pad
= arr
.length() / 4;
856 pad
= pad
- arr
.length();
857 arr
.append(QByteArray(pad
, 255));
859 if (type
== OP_DFU::crccompare
) {
860 quint32 crc
= DFUObject::CRCFromQBArray(arr
, devices
[device
].SizeOfCode
);
861 if (crc
== devices
[device
].FW_CRC
) {
862 cout
<< "Compare Successfull CRC MATCH!\n";
864 cout
<< "Compare failed CRC DONT MATCH!\n";
866 return StatusRequest();
869 StartDownloadT(&arr2
, arr
.length(), OP_DFU::FW
);
871 cout
<< "Compare Successfull ALL Bytes MATCH!\n";
873 cout
<< "Compare failed Bytes DONT MATCH!\n";
875 return StatusRequest();
879 void DFUObject::CopyWords(char *source
, char *destination
, int count
)
881 for (int x
= 0; x
< count
; x
= x
+ 4) {
882 *(destination
+ x
) = source
[x
+ 3];
883 *(destination
+ x
+ 1) = source
[x
+ 2];
884 *(destination
+ x
+ 2) = source
[x
+ 1];
885 *(destination
+ x
+ 3) = source
[x
+ 0];
888 QString
DFUObject::StatusToString(OP_DFU::Status
const & status
)
897 case wrong_packet_received
:
898 return "wrong_packet_received";
900 case too_many_packets
:
901 return "too_many_packets";
903 case too_few_packets
:
904 return "too_few_packets";
906 case Last_operation_Success
:
907 return "Last_operation_Success";
910 return "downloading";
915 case Last_operation_failed
:
916 return "Last_operation_failed";
918 case outsideDevCapabilities
:
919 return "outsideDevCapabilities";
922 return "CRC check FAILED";
925 return "Jmp to user FW failed";
930 case uploadingStarting
:
931 return "Uploading Starting";
939 Prints a progress bar with percentage & label during an operation.
941 Also outputs to stdout if we are in debug mode.
943 void DFUObject::printProgBar(int const & percent
, QString
const & label
)
947 emit(progressUpdated(percent
));
950 for (int i
= 0; i
< 50; i
++) {
951 if (i
< (percent
/ 2)) {
952 bar
.replace(i
, 1, "=");
953 } else if (i
== (percent
/ 2)) {
954 bar
.replace(i
, 1, ">");
956 bar
.replace(i
, 1, " ");
960 std::cout
<< "\r" << label
.toLatin1().data() << "[" << bar
<< "] ";
962 std::cout
<< percent
<< "% " << std::flush
;
969 quint32
DFUObject::CRC32WideFast(quint32 Crc
, quint32 Size
, quint32
*Buffer
)
971 // Size = Size >> 2; // /4 Size passed in as a byte count, assumed to be a multiple of 4
974 static const quint32 CrcTable
[16] = { // Nibble lookup table for 0x04C11DB7 polynomial
975 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
976 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD
979 Crc
= Crc
^ *((quint32
*)Buffer
); // Apply all 32-bits
983 // Process 32-bits, 4 at a time, or 8 rounds
985 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28]; // Assumes 32-bit reg, masking index to 4-bits
986 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28]; // 0x04C11DB7 Polynomial used in STM32
987 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28];
988 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28];
989 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28];
990 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28];
991 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28];
992 Crc
= (Crc
<< 4) ^ CrcTable
[Crc
>> 28];
1001 quint32
DFUObject::CRCFromQBArray(QByteArray array
, quint32 Size
)
1003 quint32 pad
= Size
- array
.length();
1005 array
.append(QByteArray(pad
, 255));
1006 quint32
*t
= new quint32
[Size
/ 4];
1007 for (int x
= 0; x
< array
.length() / 4; x
++) {
1009 aux
= (char)array
[x
* 4 + 3] & 0xFF;
1011 aux
+= (char)array
[x
* 4 + 2] & 0xFF;
1013 aux
+= (char)array
[x
* 4 + 1] & 0xFF;
1015 aux
+= (char)array
[x
* 4 + 0] & 0xFF;
1018 quint32 ret
= DFUObject::CRC32WideFast(0xFFFFFFFF, Size
/ 4, t
);
1027 Send data to the bootloader, either through the serial port
1028 of through the HID handle, depending on the mode we're using
1030 int DFUObject::sendData(void *data
, int size
)
1033 return hidHandle
.send(0, data
, size
, 5000);
1037 if (serialhandle
->sendData((uint8_t *)data
+ 1, size
- 1)) {
1039 qDebug() << "packet sent" << "data0" << ((uint8_t *)data
+ 1)[0];
1044 qDebug() << "Serial send OVERRUN";
1051 Receive data from the bootloader, either through the serial port
1052 of through the HID handle, depending on the mode we're using
1054 int DFUObject::receiveData(void *data
, int size
)
1057 return hidHandle
.receive(0, data
, size
, 10000);
1065 if ((x
= serialhandle
->read_Packet(((char *)data
) + 1) != -1) || time
.elapsed() > 10000) {
1066 if (time
.elapsed() > 10000) {
1067 qDebug() << "____timeout";
1074 #define BOARD_ID_MB 1
1075 #define BOARD_ID_INS 2
1076 #define BOARD_ID_PIP 3
1077 #define BOARD_ID_REVO 9
1080 Gets the type of board connected
1082 OP_DFU::eBoardType
DFUObject::GetBoardType(int boardNum
)
1084 OP_DFU::eBoardType brdType
= eBoardUnkwn
;
1086 // First of all, check what Board type we are talking to
1087 int board
= devices
[boardNum
].ID
;
1089 qDebug() << "Board model: " << board
;
1090 switch (board
>> 8) {
1091 case BOARD_ID_MB
: // Mainboard family
1092 brdType
= eBoardMainbrd
;
1094 case BOARD_ID_INS
: // Inertial Nav
1095 brdType
= eBoardINS
;
1097 case BOARD_ID_PIP
: // PIP RF Modem
1098 brdType
= eBoardPip
;
1100 case BOARD_ID_REVO
: // Revo board
1101 brdType
= eBoardRevo
;