diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/common.h b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/common.h index 28cc825b1..f0a7dfaca 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/common.h +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/common.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file common.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -23,10 +24,11 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */#ifndef COMMON_H + */ +#ifndef COMMON_H #define COMMON_H -enum decodeState_ { +enum DecodeState { decode_len1_e = 0, decode_seqNo_e, decode_data_e, @@ -34,10 +36,10 @@ enum decodeState_ { decode_crc2_e, decode_idle_e }; + enum ReceiveState { state_escaped_e = 0, state_unescaped_e }; - #endif // COMMON_H diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/main.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/main.cpp index 41891dbf9..1b142d7e3 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/main.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/main.cpp @@ -1,20 +1,51 @@ -#include -#include "../../../libs/qextserialport/src/qextserialport.h" -#include -#include +/** + ****************************************************************************** + * + * @file main.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup Uploader Serial and USB Uploader Plugin + * @{ + * @brief The USB and Serial protocol uploader plugin + *****************************************************************************/ +/* + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #include "qssp.h" #include "port.h" #include "qsspt.h" -int main(int argc, char *argv[]) -{ + +#include "../../../libs/qextserialport/src/qextserialport.h" + +#include +#include +#include + #define MAX_PACKET_DATA_LEN 255 #define MAX_PACKET_BUF_SIZE (1 + 1 + 255 + 2) +int main(int argc, char *argv[]) +{ uint8_t sspTxBuf[MAX_PACKET_BUF_SIZE]; uint8_t sspRxBuf[MAX_PACKET_BUF_SIZE]; port *info; PortSettings settings; + settings.BaudRate = BAUD57600; settings.DataBits = DATA_8; settings.FlowControl = FLOW_OFF; diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.cpp index 961baeaa8..839d0aabd 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file port.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -25,15 +26,16 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "port.h" -#include "delay.h" + +#include #include -port::port(QString name, bool debug) : debug(debug), mstatus(port::closed) + +port::port(QString name, bool debug) : mstatus(port::closed), debug(debug) { timer.start(); sport = new QSerialPort(); sport->setPortName(name); if (sport->open(QIODevice::ReadWrite)) { - sport->setReadBufferSize(0); if (sport->setBaudRate(QSerialPort::Baud57600) && sport->setDataBits(QSerialPort::Data8) && sport->setParity(QSerialPort::NoParity) @@ -41,7 +43,6 @@ port::port(QString name, bool debug) : debug(debug), mstatus(port::closed) && sport->setFlowControl(QSerialPort::NoFlowControl)) { mstatus = port::open; } - // sport->setDtr(); } else { qDebug() << sport->error(); mstatus = port::error; @@ -72,7 +73,9 @@ int16_t port::pfSerialRead(void) } rxDebugBuff.append(c[0]); } - } else { return -1; } + } else { + return -1; + } return (uint8_t)c[0]; } diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.h b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.h index 16cf65579..1edd8fc52 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.h +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/port.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file port.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -26,19 +27,28 @@ */ #ifndef PORT_H #define PORT_H -#include -#include -#include -#include -#include + #include "common.h" +#include +#include + +#include + +class QSerialPort; + class port { public: enum portstatus { open, closed, error }; + + port(QString name, bool debug); + virtual ~port(); + portstatus status(); + virtual int16_t pfSerialRead(void); // function to read a character from the serial input stream virtual void pfSerialWrite(uint8_t); // function to write a byte to be sent out the serial port virtual uint32_t pfGetTime(void); + uint8_t retryCount; // how many times have we tried to transmit the 'send' packet uint8_t maxRetryCount; // max. times to try to transmit the 'send' packet uint16_t max_retry; // Maximum number of retrys for a single transmit. @@ -54,25 +64,25 @@ public: uint8_t *rxBuf; // receive buffer. Used to store data as a packet is received. uint16_t sendSynch; // flag to indicate that we should send a synchronize packet to the host // this is required when switching from the application to the bootloader - // and vice-versa. This fixes the firwmare download timeout. - // when this flag is set to true, the next time we send a packet we will first // send a synchronize packet. + // and vice-versa. This fixes the firmware download timeout. + // when this flag is set to true, the next time we send a packet we will first + // send a synchronize packet. ReceiveState InputState; - decodeState_ DecodeState; + DecodeState DecodeState; uint16_t SendState; uint16_t crc; uint32_t RxError; uint32_t TxError; uint16_t flags; - port(QString name, bool debug); - virtual ~port(); - portstatus status(); + private: - bool debug; - QByteArray rxDebugBuff; - QByteArray txDebugBuff; portstatus mstatus; QTime timer; QSerialPort *sport; + + bool debug; + QByteArray rxDebugBuff; + QByteArray txDebugBuff; }; #endif // PORT_H diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.cpp index 66ce3588e..07f8c5167 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file qssp.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -26,12 +27,12 @@ */ #include "qssp.h" +#include #include #include #include - /** PRIVATE DEFINITIONS **/ #define SYNC 225 // Sync character used in Serial Protocol #define ESC 224 // ESC character used in Serial Protocol @@ -144,7 +145,7 @@ void qssp::ssp_Init(const PortConfig_t *const info) thisport->txSeqNo = 255; thisport->SendState = SSP_IDLE; thisport->InputState = (ReceiveState)0; - thisport->DecodeState = (decodeState_)0; + thisport->DecodeState = (DecodeState)0; thisport->TxError = 0; thisport->RxError = 0; thisport->txSeqNo = 0; @@ -174,7 +175,7 @@ int16_t qssp::ssp_SendProcess() sf_SetSendTimeout(); value = SSP_TX_WAITING; } else { - // Give up, # of trys has exceded the limit + // Give up, # of tries has exceeded the limit value = SSP_TX_TIMEOUT; CLEARBIT(thisport->flags, ACK_RECEIVED); thisport->SendState = SSP_IDLE; @@ -343,7 +344,7 @@ int16_t qssp::ssp_SendData(const uint8_t *data, const uint16_t length) } /*! - * \brief Attempts to synchronize the sequence numbers with the other end of the connectin. + * \brief Attempts to synchronize the sequence numbers with the other end of the connection. * \param thisport = which port to use * \return true = success * \return false = failed to receive an ACK to our synch request @@ -374,7 +375,7 @@ uint16_t qssp::ssp_Synchronise() packet_status = ssp_SendData(NULL, 0); #endif while (packet_status == SSP_TX_WAITING) { // we loop until we time out. - (void)ssp_ReceiveProcess(); // do the receive process + ssp_ReceiveProcess(); // do the receive process packet_status = ssp_SendProcess(); // do the send process } thisport->sendSynch = FALSE; @@ -391,7 +392,6 @@ uint16_t qssp::ssp_Synchronise() retval = FALSE; break; } - ; return retval; } @@ -417,7 +417,6 @@ void qssp::sf_SendPacket() thisport->retryCount++; } - /*! * \brief converts data to transport layer protocol packet format. * \param txbuf = buffer to use when forming the packet @@ -525,7 +524,6 @@ uint16_t qssp::sf_crc16(uint16_t crc, uint8_t data) { #ifdef SPP_USES_CRC return (crc >> 8) ^ CRC_TABLE[(crc ^ data) & 0x00FF]; - #else uint8_t cka = crc & 0xff; uint8_t ckb = (crc >> 8) & 0xff; @@ -794,6 +792,7 @@ int16_t qssp::sf_ReceivePacket() } return value; } + qssp::qssp(port *info, bool debug) : debug(debug) { thisport = info; @@ -809,12 +808,13 @@ qssp::qssp(port *info, bool debug) : debug(debug) thisport->txSeqNo = 255; thisport->SendState = SSP_IDLE; thisport->InputState = (ReceiveState)0; - thisport->DecodeState = (decodeState_)0; + thisport->DecodeState = (DecodeState)0; thisport->TxError = 0; thisport->RxError = 0; thisport->txSeqNo = 0; thisport->rxSeqNo = 0; } + void qssp::pfCallBack(uint8_t *buf, uint16_t size) { Q_UNUSED(size); diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.h b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.h index 0ffd9af47..1a7f7a8f9 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.h +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qssp.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file qssp.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -26,9 +27,12 @@ */ #ifndef QSSP_H #define QSSP_H -#include -#include "port.h" + #include "common.h" +#include "port.h" + +#include + /** LOCAL DEFINITIONS **/ #ifndef TRUE #define TRUE 1 @@ -39,6 +43,7 @@ #endif #define SPP_USES_CRC + #define SSP_TX_IDLE 0 // not expecting a ACK packet (no current transmissions in progress) #define SSP_TX_WAITING 1 // waiting for a valid ACK to arrive #define SSP_TX_TIMEOUT 2 // failed to receive a valid ACK in the timeout period, after retrying. @@ -56,7 +61,6 @@ #define SSP_RX_ACK 6 #define SSP_RX_SYNCH 7 - typedef struct { uint8_t *pbuff; uint16_t length; @@ -74,42 +78,41 @@ typedef struct { // function returns time in number of seconds that has elapsed from a given reference point } PortConfig_t; - /** Public Data **/ - /** EXTERNAL FUNCTIONS **/ class qssp { private: port *thisport; - decodeState_ DecodeState_t; - /** PRIVATE FUNCTIONS **/ + bool debug; + // static void sf_SendSynchPacket( Port_t *thisport ); - uint16_t sf_crc16(uint16_t crc, uint8_t data); + uint16_t sf_crc16(uint16_t crc, uint8_t data); void sf_write_byte(uint8_t c); void sf_SetSendTimeout(); - uint16_t sf_CheckTimeout(); + uint16_t sf_CheckTimeout(); int16_t sf_DecodeState(uint8_t c); int16_t sf_ReceiveState(uint8_t c); void sf_SendPacket(); void sf_SendAckPacket(uint8_t seqNumber); - void sf_MakePacket(uint8_t *buf, const uint8_t *pdata, uint16_t length, uint8_t seqNo); + void sf_MakePacket(uint8_t *buf, const uint8_t *pdata, uint16_t length, uint8_t seqNo); int16_t sf_ReceivePacket(); - uint16_t ssp_SendDataBlock(uint8_t *data, uint16_t length); - bool debug; + uint16_t ssp_SendDataBlock(uint8_t *data, uint16_t length); + public: - /** PUBLIC FUNCTIONS **/ - virtual void pfCallBack(uint8_t *, uint16_t); // call back function that is called when a full packet has been received + qssp(port *info, bool debug); + int16_t ssp_ReceiveProcess(); int16_t ssp_SendProcess(); uint16_t ssp_SendString(char *str); int16_t ssp_SendData(const uint8_t *data, const uint16_t length); void ssp_Init(const PortConfig_t *const info); - int16_t ssp_ReceiveByte(); + int16_t ssp_ReceiveByte(); uint16_t ssp_Synchronise(); - qssp(port *info, bool debug); + + virtual void pfCallBack(uint8_t *, uint16_t); // call back function that is called when a full packet has been received }; #endif // QSSP_H diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.cpp index 564e75805..433afa05f 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.cpp @@ -2,7 +2,8 @@ ****************************************************************************** * * @file qsspt.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -26,17 +27,26 @@ */ #include "qsspt.h" +#include + qsspt::qsspt(port *info, bool debug) : qssp(info, debug), endthread(false), datapending(false), debug(debug) {} +qsspt::~qsspt() +{ + endthread = true; + // TODO bad... + wait(1000); +} + void qsspt::run() { while (!endthread) { - receivestatus = this->ssp_ReceiveProcess(); - sendstatus = this->ssp_SendProcess(); + receivestatus = ssp_ReceiveProcess(); + sendstatus = ssp_SendProcess(); sendbufmutex.lock(); if (datapending && receivestatus == SSP_TX_IDLE) { - this->ssp_SendData(mbuf, msize); + ssp_SendData(mbuf, msize); datapending = false; } sendbufmutex.unlock(); @@ -45,13 +55,11 @@ void qsspt::run() } } } + bool qsspt::sendData(uint8_t *buf, uint16_t size) { if (debug) { - QByteArray data; - for (int i = 0; i < size; i++) { - data.append((uint8_t)buf[i]); - } + QByteArray data((const char *)buf, size); qDebug() << "SSP TX " << data.toHex(); } if (datapending) { @@ -71,21 +79,19 @@ bool qsspt::sendData(uint8_t *buf, uint16_t size) void qsspt::pfCallBack(uint8_t *buf, uint16_t size) { if (debug) { - qDebug() << "receive callback" << buf[0] << buf[1] << buf[2] << buf[3] << buf[4] << "array size=" << queue.count(); - } - QByteArray array; - for (int x = 0; x < size; x++) { - array.append(buf[x]); + qDebug() << "receive callback" << buf[0] << buf[1] << buf[2] << buf[3] << buf[4] << "queue size=" << queue.count(); } + QByteArray data((const char *)buf, size); mutex.lock(); - queue.enqueue(array); - // queue.enqueue((const char *)&buf); + queue.enqueue(data); mutex.unlock(); } + int qsspt::packets_Available() { return queue.count(); } + int qsspt::read_Packet(void *data) { mutex.lock(); @@ -101,8 +107,3 @@ int qsspt::read_Packet(void *data) mutex.unlock(); return arr.length(); } -qsspt::~qsspt() -{ - endthread = true; - wait(1000); -} diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.h b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.h index 0ec228ce6..d640f7ac0 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.h +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/qsspt.h @@ -2,7 +2,8 @@ ****************************************************************************** * * @file qsspt.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Serial and USB Uploader Plugin @@ -28,20 +29,24 @@ #define QSSPT_H #include "qssp.h" + #include #include #include #include + class qsspt : public qssp, public QThread { public: qsspt(port *info, bool debug); + ~qsspt(); + void run(); + int packets_Available(); int read_Packet(void *); - ~qsspt(); bool sendData(uint8_t *buf, uint16_t size); + private: - virtual void pfCallBack(uint8_t *, uint16_t); uint8_t *mbuf; uint16_t msize; QQueue queue; @@ -54,6 +59,8 @@ private: QWaitCondition sendwait; QMutex msendwait; bool debug; + + virtual void pfCallBack(uint8_t *, uint16_t); }; #endif // QSSPT_H diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/ssp_test.pro b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/ssp_test.pro index e0fdc09e0..65c944daa 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/ssp_test.pro +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/SSP/ssp_test.pro @@ -4,39 +4,47 @@ # #------------------------------------------------- -QT += core - -QT -= gui -DEFINES += QEXTSERIALPORT_LIBRARY -TARGET = ssp_test -CONFIG += console -CONFIG -= app_bundle - TEMPLATE = app +TARGET = ssp_test -SOURCES += main.cpp \ +QT += core +QT -= gui + +CONFIG += console +CONFIG -= app_bundle + +DEFINES += QEXTSERIALPORT_LIBRARY + +SOURCES += \ + main.cpp \ qssp.cpp \ port.cpp \ qsspt.cpp -HEADERS += ../../../libs/qextserialport/src/qextserialport.h \ - ../../../libs/qextserialport/src/qextserialenumerator.h \ - ../../../libs/qextserialport/src/qextserialport_global.h \ + +HEADERS += \ + ../../../libs/qextserialport/src/qextserialport.h \ + ../../../libs/qextserialport/src/qextserialenumerator.h \ + ../../../libs/qextserialport/src/qextserialport_global.h \ qssp.h \ port.h \ common.h \ qsspt.h -SOURCES += ../../../libs/qextserialport/src/qextserialport.cpp -unix:SOURCES += ../../../libs/qextserialport/src/posix_qextserialport.cpp -unix:!macx:SOURCES += ../../../libs/qextserialport/src/qextserialenumerator_unix.cpp +SOURCES += ../../../libs/qextserialport/src/qextserialport.cpp + +unix:SOURCES += ../../../libs/qextserialport/src/posix_qextserialport.cpp +unix:!macx:SOURCES += ../../../libs/qextserialport/src/qextserialenumerator_unix.cpp macx { - SOURCES += ../../../libs/qextserialport/src/qextserialenumerator_osx.cpp - LIBS += -framework IOKit -framework CoreFoundation + SOURCES += ../../../libs/qextserialport/src/qextserialenumerator_osx.cpp + LIBS += -framework IOKit -framework CoreFoundation } win32 { - SOURCES += ../../../libs/qextserialport/src/win_qextserialport.cpp \ -../../../libs/qextserialport/src/qextserialenumerator_win.cpp - DEFINES += WINVER=0x0501 # needed for mingw to pull in appropriate dbt business...probably a better way to do this - LIBS += -lsetupapi + SOURCES += \ + ../../../libs/qextserialport/src/win_qextserialport.cpp \ + ../../../libs/qextserialport/src/qextserialenumerator_win.cpp + + # needed for mingw to pull in appropriate dbt business...probably a better way to do this + DEFINES += WINVER=0x0501 + LIBS += -lsetupapi } diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/delay.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/delay.cpp deleted file mode 100644 index dd238f014..000000000 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/delay.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * This program 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. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "delay.h" diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/delay.h b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/delay.h deleted file mode 100644 index cc0bfa630..000000000 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/delay.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This program 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. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef DELAY_H -#define DELAY_H -#include - -class delay : public QThread { -public: - static void msleep(unsigned long msecs) - { - QThread::msleep(msecs); - } -}; -#endif // DELAY_H diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/dfu.cpp similarity index 78% rename from ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.cpp rename to ground/gcs/src/experimental/USB_UPLOAD_TOOL/dfu.cpp index f2b6071da..8d4033f1a 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/dfu.cpp @@ -1,8 +1,9 @@ /** ****************************************************************************** * - * @file op_dfu.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @file dfu.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup Uploader Uploader Plugin @@ -24,22 +25,34 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "dfu.h" -#include "op_dfu.h" +#include "SSP/port.h" +#include "SSP/qsspt.h" + +// #include +// #include +// #include + +#include +#include +#include +#include + +#include #include -#include -#include -#include -using namespace OP_DFU; +using namespace std; +using namespace DFU; DFUObject::DFUObject(bool _debug, bool _use_serial, QString portname) : debug(_debug), use_serial(_use_serial), mready(true) { - info = NULL; numberOfDevices = 0; + serialhandle = NULL; + info = NULL; - qRegisterMetaType("Status"); + qRegisterMetaType("Status"); if (use_serial) { info = new port(portname, false); @@ -54,42 +67,46 @@ DFUObject::DFUObject(bool _debug, bool _use_serial, QString portname) : mready = false; return; } - serialhandle = new qsspt(info, false); + serialhandle = new qsspt(info, false /*debug*/); int count = 0; - while ((serialhandle->ssp_Synchronise() == false) && (count < 10)) { + while (!serialhandle->ssp_Synchronise() && (count < 10)) { if (debug) { - qDebug() << "SYNC failed, resending"; + qDebug() << "SYNC failed, resending..."; } count++; } if (count == 10) { mready = false; + qDebug() << "SYNC failed"; return; } - qDebug() << "SYNC Succeded"; + serialhandle->start(); -/* } else { - mready = false; + } else { +/* + hidHandle = new opHID_hidapi(); + + mready = false; QEventLoop m_eventloop; QTimer::singleShot(200, &m_eventloop, SLOT(quit())); m_eventloop.exec(); QList devices; devices = USBMonitor::instance()->availableDevices(0x20a0, -1, -1, USBMonitor::Bootloader); if (devices.length() == 1) { - if (hidHandle.open(1, devices.first().vendorID, devices.first().productID, 0, 0) == 1) { + if (hidHandle->open(1, devices.first().vendorID, devices.first().productID, 0, 0) == 1) { mready = true; QTimer::singleShot(200, &m_eventloop, SLOT(quit())); m_eventloop.exec(); } else { - hidHandle.close(0); + hidHandle->close(0); } } else { // Wait for the board to appear on the USB bus: USBSignalFilter filter(0x20a0, -1, -1, USBMonitor::Bootloader); connect(&filter, SIGNAL(deviceDiscovered()), &m_eventloop, SLOT(quit())); for (int x = 0; x < 4; ++x) { - qDebug() << "OP_DFU trying to detect bootloader:" << x; + qDebug() << "DFU trying to detect bootloader:" << x; if (x == 0) { QTimer::singleShot(10000, &m_eventloop, SLOT(quit())); @@ -101,80 +118,39 @@ DFUObject::DFUObject(bool _debug, bool _use_serial, QString portname) : qDebug() << "Devices length: " << devices.length(); if (devices.length() == 1) { qDebug() << "Opening device"; - if (hidHandle.open(1, devices.first().vendorID, devices.first().productID, 0, 0) == 1) { + if (hidHandle->open(1, devices.first().vendorID, devices.first().productID, 0, 0) == 1) { QTimer::singleShot(200, &m_eventloop, SLOT(quit())); m_eventloop.exec(); - qDebug() << "OP_DFU detected after delay"; + qDebug() << "DFU detected after delay"; mready = true; qDebug() << "Detected"; break; } else { - hidHandle.close(0); + hidHandle->close(0); } } else { qDebug() << devices.length() << " device(s) detected, don't know what to do!"; mready = false; } } - }*/ + } + */ } } DFUObject::~DFUObject() { if (use_serial) { - if (mready) { - delete serialhandle; - delete info; + delete serialhandle; + delete info; + } else { +/* + if (hidHandle) { + hidHandle->close(0); + delete hidHandle; } - } /*else { - hidHandle.close(0); - }*/ -} - -void DFUObject::sendReset(void) -{ - qDebug() << "Requesting user mode reset"; - uint8_t aa[255] = { 0x02, 0x3E, 0x3C, 0x20, 0x75, 0x00, 0x20, 0x4F, 0x67, 0x34, 0x62, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 63 - uint8_t ba[255] = { 0x02, 0x3E, 0x3C, 0x20, 0x75, 0x00, 0x20, 0x4F, 0x67, 0x34, 0xB9, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t ca[255] = { 0x02, 0x3E, 0x3C, 0x20, 0x75, 0x00, 0x20, 0x4F, 0x67, 0x34, 0x10, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t bb[255] = { 0x02, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x8D, 0x19, 0x00, 0x00, 0x13 }; - uint8_t ab[255] = { 0x02, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x1B, 0x19, 0x00, 0x00, 0x76 }; - uint8_t cb[255] = { 0x02, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x78, 0x1C, 0x00, 0x00, 0x25 }; - // 125 - /*if (!use_serial) { - hidHandle.send(0, aa, 64, 5000); - hidHandle.send(0, ab, 64, 5000); - delay::msleep(600); - hidHandle.send(0, ba, 64, 5000); - hidHandle.send(0, bb, 64, 5000); - delay::msleep(600); - hidHandle.send(0, ca, 64, 5000); - hidHandle.send(0, cb, 64, 5000); - delay::msleep(100); - hidHandle.close(1); - } else {*/ - char a[255]; - char b[255]; - char c[255]; - memcpy(a, aa + 2, 62); - memcpy(a + 62, ab + 2, 60); - memcpy(b, ba + 2, 62); - memcpy(b + 62, bb + 2, 60); - memcpy(c, ca + 2, 62); - memcpy(c + 62, cb + 2, 60); - for (int x = 0; x < 123; ++x) { - info->pfSerialWrite(a[x]); + */ } - delay::msleep(600); - for (int x = 0; x < 123; ++x) { - info->pfSerialWrite(b[x]); - } - delay::msleep(600); - for (int x = 0; x < 123; ++x) { - info->pfSerialWrite(c[x]); - } - // } } bool DFUObject::SaveByteArrayToFile(QString const & sfile, const QByteArray &array) @@ -183,7 +159,7 @@ bool DFUObject::SaveByteArrayToFile(QString const & sfile, const QByteArray &arr if (!file.open(QIODevice::WriteOnly)) { if (debug) { - qDebug() << "Can't open file"; + qDebug() << "Can't open file" << sfile; } return false; } @@ -200,7 +176,7 @@ bool DFUObject::enterDFU(int const &devNumber) char buf[BUF_LEN]; buf[0] = 0x02; // reportID - buf[1] = OP_DFU::EnterDFU; // DFU Command + buf[1] = DFU::EnterDFU; // DFU Command buf[2] = 0; // DFU Count buf[3] = 0; // DFU Count buf[4] = 0; // DFU Count @@ -211,7 +187,6 @@ bool DFUObject::enterDFU(int const &devNumber) buf[9] = 1; // DFU Data3 int result = sendData(buf, BUF_LEN); - if (result < 1) { return false; } @@ -240,7 +215,7 @@ bool DFUObject::StartUpload(qint32 const & numberOfBytes, TransferTypes const & } char buf[BUF_LEN]; buf[0] = 0x02; // reportID - buf[1] = setStartBit(OP_DFU::Upload); // DFU Command + buf[1] = setStartBit(DFU::Upload); // DFU Command buf[2] = numberOfPackets >> 24; // DFU Count buf[3] = numberOfPackets >> 16; // DFU Count buf[4] = numberOfPackets >> 8; // DFU Count @@ -256,7 +231,7 @@ bool DFUObject::StartUpload(qint32 const & numberOfBytes, TransferTypes const & } int result = sendData(buf, BUF_LEN); - delay::msleep(1000); + QThread::msleep(1000); if (debug) { qDebug() << result << " bytes sent"; @@ -267,7 +242,6 @@ bool DFUObject::StartUpload(qint32 const & numberOfBytes, TransferTypes const & return false; } - /** Does the actual data upload to the board. Needs to be called once the board is ready to accept data following a StartUpload command, and it is erased. @@ -289,7 +263,7 @@ bool DFUObject::UploadData(qint32 const & numberOfBytes, QByteArray & data) } char buf[BUF_LEN]; buf[0] = 0x02; // reportID - buf[1] = OP_DFU::Upload; // DFU Command + buf[1] = DFU::Upload; // DFU Command int packetsize; float percentage; int laspercentage = 0; @@ -319,9 +293,9 @@ bool DFUObject::UploadData(qint32 const & numberOfBytes, QByteArray & data) // qDebug()<> (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[1] = DFU::Req_Capabilities; // DFU Command buf[2] = 0; buf[3] = 0; buf[4] = 0; @@ -722,13 +697,12 @@ bool DFUObject::findDevices() return true; } - bool DFUObject::EndOperation() { char buf[BUF_LEN]; buf[0] = 0x02; // reportID - buf[1] = OP_DFU::Op_END; // DFU Command + buf[1] = DFU::END; // DFU Command buf[2] = 0; buf[3] = 0; buf[4] = 0; @@ -748,8 +722,6 @@ bool DFUObject::EndOperation() return false; } - -// /** Starts a firmware upload (asynchronous) */ @@ -758,7 +730,7 @@ bool DFUObject::UploadFirmware(const QString &sfile, const bool &verify, int dev if (isRunning()) { return false; } - requestedOperation = OP_DFU::Upload; + requestedOperation = DFU::Upload; requestFilename = sfile; requestDevice = device; requestVerify = verify; @@ -766,9 +738,9 @@ bool DFUObject::UploadFirmware(const QString &sfile, const bool &verify, int dev return true; } -OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &verify, int device) +DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &verify, int device) { - OP_DFU::Status ret; + DFU::Status ret; if (debug) { qDebug() << "Starting Firmware Uploading..."; @@ -778,9 +750,9 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri if (!file.open(QIODevice::ReadOnly)) { if (debug) { - qDebug() << "Cant open file"; + qDebug() << "Failed to open file" << sfile; } - return OP_DFU::abort; + return DFU::abort; } QByteArray arr = file.readAll(); @@ -799,7 +771,7 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri if (debug) { qDebug() << "ERROR file to big for device"; } - return OP_DFU::abort;; + return DFU::abort;; } quint32 crc = DFUObject::CRCFromQBArray(arr, devices[device].SizeOfCode); @@ -807,7 +779,7 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri qDebug() << "NEW FIRMWARE CRC=" << crc; } - if (!StartUpload(arr.length(), OP_DFU::FW, crc)) { + if (!StartUpload(arr.length(), DFU::FW, crc)) { ret = StatusRequest(); if (debug) { qDebug() << "StartUpload failed"; @@ -816,13 +788,13 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri return ret; } - emit operationProgress(QString("Erasing, please wait...")); + emit operationProgress("Erasing, please wait..."); if (debug) { qDebug() << "Erasing memory"; } - if (StatusRequest() == OP_DFU::abort) { - return OP_DFU::abort; + if (StatusRequest() == DFU::abort) { + return DFU::abort; } // TODO: why is there a loop there? The "if" statement @@ -832,14 +804,14 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri if (debug) { qDebug() << "Erase returned: " << StatusToString(ret); } - if (ret == OP_DFU::uploading) { + if (ret == DFU::uploading) { break; } else { return ret; } } - emit operationProgress(QString("Uploading firmware")); + emit operationProgress("Uploading firmware"); if (!UploadData(arr.length(), arr)) { ret = StatusRequest(); if (debug) { @@ -857,18 +829,18 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri return ret; } ret = StatusRequest(); - if (ret != OP_DFU::Last_operation_Success) { + if (ret != DFU::Last_operation_Success) { return ret; } if (verify) { - emit operationProgress(QString("Verifying firmware")); + emit operationProgress("Verifying firmware"); cout << "Starting code verification\n"; QByteArray arr2; - StartDownloadT(&arr2, arr.length(), OP_DFU::FW); + StartDownloadT(&arr2, arr.length(), DFU::FW); if (arr != arr2) { cout << "Verify:FAILED\n"; - return OP_DFU::abort; + return DFU::abort; } } @@ -879,8 +851,7 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri return ret; } - -OP_DFU::Status DFUObject::CompareFirmware(const QString &sfile, const CompareType &type, int device) +DFU::Status DFUObject::CompareFirmware(const QString &sfile, const CompareType &type, int device) { cout << "Starting Firmware Compare...\n"; QFile file(sfile); @@ -888,7 +859,7 @@ OP_DFU::Status DFUObject::CompareFirmware(const QString &sfile, const CompareTyp if (debug) { qDebug() << "Cant open file"; } - return OP_DFU::abort; + return DFU::abort; } QByteArray arr = file.readAll(); @@ -902,7 +873,7 @@ OP_DFU::Status DFUObject::CompareFirmware(const QString &sfile, const CompareTyp pad = pad - arr.length(); arr.append(QByteArray(pad, 255)); } - if (type == OP_DFU::crccompare) { + if (type == DFU::crccompare) { quint32 crc = DFUObject::CRCFromQBArray(arr, devices[device].SizeOfCode); if (crc == devices[device].FW_CRC) { cout << "Compare Successfull CRC MATCH!\n"; @@ -912,7 +883,7 @@ OP_DFU::Status DFUObject::CompareFirmware(const QString &sfile, const CompareTyp return StatusRequest(); } else { QByteArray arr2; - StartDownloadT(&arr2, arr.length(), OP_DFU::FW); + StartDownloadT(&arr2, arr.length(), DFU::FW); if (arr == arr2) { cout << "Compare Successfull ALL Bytes MATCH!\n"; } else { @@ -931,7 +902,8 @@ void DFUObject::CopyWords(char *source, char *destination, int count) *(destination + x + 3) = source[x + 0]; } } -QString DFUObject::StatusToString(OP_DFU::Status const & status) + +QString DFUObject::StatusToString(DFU::Status const & status) { switch (status) { case DFUidle: @@ -988,11 +960,10 @@ QString DFUObject::StatusToString(OP_DFU::Status const & status) */ void DFUObject::printProgBar(int const & percent, QString const & label) { - std::string bar; - emit(progressUpdated(percent)); if (debug) { + std::string bar; for (int i = 0; i < 50; i++) { if (i < (percent / 2)) { bar.replace(i, 1, "="); @@ -1017,7 +988,8 @@ quint32 DFUObject::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 + // Nibble lookup table for 0x04C11DB7 polynomial + static const quint32 CrcTable[16] = { 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD }; @@ -1064,16 +1036,17 @@ quint32 DFUObject::CRCFromQBArray(QByteArray array, quint32 Size) return DFUObject::CRC32WideFast(0xFFFFFFFF, Size / 4, (quint32 *)t); } - /** Send data to the bootloader, either through the serial port of through the HID handle, depending on the mode we're using */ int DFUObject::sendData(void *data, int size) { - /*if (!use_serial) { - return hidHandle.send(0, data, size, 5000); - }*/ +/* + if (!use_serial) { + return hidHandle->send(0, data, size, 5000); + } + */ // Serial Mode: if (serialhandle->sendData((uint8_t *)data + 1, size - 1)) { @@ -1088,16 +1061,17 @@ int DFUObject::sendData(void *data, int size) return -1; } - /** Receive data from the bootloader, either through the serial port of through the HID handle, depending on the mode we're using */ int DFUObject::receiveData(void *data, int size) { - /*if (!use_serial) { - return hidHandle.receive(0, data, size, 10000); - }*/ +/* + if (!use_serial) { + return hidHandle->receive(0, data, size, 10000); + } + */ // Serial Mode: int x; @@ -1106,7 +1080,7 @@ int DFUObject::receiveData(void *data, int size) time.start(); while (true) { if ((x = serialhandle->read_Packet(((char *)data) + 1) != -1) || time.elapsed() > 10000) { - msleep(10); + QThread::msleep(10); if (time.elapsed() > 10000) { qDebug() << "____timeout"; } @@ -1129,9 +1103,9 @@ int DFUObject::receiveData(void *data, int size) /** Gets the type of board connected */ -OP_DFU::eBoardType DFUObject::GetBoardType(int boardNum) +DFU::eBoardType DFUObject::GetBoardType(int boardNum) { - OP_DFU::eBoardType brdType = eBoardUnkwn; + DFU::eBoardType brdType = eBoardUnkwn; // First of all, check what Board type we are talking to int board = devices[boardNum].ID; diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.h b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/dfu.h similarity index 67% rename from ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.h rename to ground/gcs/src/experimental/USB_UPLOAD_TOOL/dfu.h index ed84865ec..92b94e6be 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/op_dfu.h +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/dfu.h @@ -1,36 +1,52 @@ -#ifndef OP_DFU_H -#define OP_DFU_H +/** + ****************************************************************************** + * + * @file dfu.h + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup Uploader Uploader Plugin + * @{ + * @brief The uploader plugin + *****************************************************************************/ +/* + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef DFU_H +#define DFU_H #include -// #include -// #include -// #include -#include -#include #include #include -#include -#include -#include #include #include -#include -#include "delay.h" -#include -#include -#include -#include -#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 { +#define BUF_LEN 64 + +// serial +class port; +class qsspt; + +// usb +class opHID_hidapi; + +namespace DFU { enum TransferTypes { FW, Descript @@ -40,21 +56,6 @@ enum CompareType { crccompare, bytetobytecompare }; -// 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" -#define USE_SERIAL "-t" -#define NO_COUNTDOWN "-i" Q_ENUMS(Status) enum Status { @@ -96,7 +97,7 @@ enum Commands { Reset, // 5 Abort_Operation, // 6 Upload, // 7 - Op_END, // 8 + END, // 8 Download_Req, // 9 Download, // 10 Status_Request, // 11 @@ -114,22 +115,21 @@ enum eBoardType { }; struct device { - int ID; + quint16 ID; quint32 FW_CRC; - int BL_Version; + quint8 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); virtual ~DFUObject(); @@ -139,8 +139,7 @@ public: bool findDevices(); int JumpToApp(bool safeboot, bool erase); int ResetDevice(void); - void sendReset(void); - OP_DFU::Status StatusRequest(); + DFU::Status StatusRequest(); bool EndOperation(); int AbortOperation(void); bool ready() @@ -149,7 +148,7 @@ public: } // Upload (send to device) commands - OP_DFU::Status UploadDescription(QVariant description); + DFU::Status UploadDescription(QVariant description); bool UploadFirmware(const QString &sfile, const bool &verify, int device); // Download (get from device) commands: @@ -162,11 +161,10 @@ public: bool DownloadFirmware(QByteArray *byteArray, int device); // Comparison functions (is this needed?) - OP_DFU::Status CompareFirmware(const QString &sfile, const CompareType &type, int device); + DFU::Status CompareFirmware(const QString &sfile, const CompareType &type, int device); bool SaveByteArrayToFile(QString const & file, QByteArray const &array); - // Variables: QList devices; int numberOfDevices; @@ -174,15 +172,14 @@ public: bool use_delay; // Helper functions: - QString StatusToString(OP_DFU::Status const & status); + QString StatusToString(DFU::Status const & status); static quint32 CRC32WideFast(quint32 Crc, quint32 Size, quint32 *Buffer); - OP_DFU::eBoardType GetBoardType(int boardNum); - + DFU::eBoardType GetBoardType(int boardNum); signals: void progressUpdated(int); void downloadFinished(); - void uploadFinished(OP_DFU::Status); + void uploadFinished(DFU::Status); void operationProgress(QString status); private: @@ -191,16 +188,19 @@ private: bool use_serial; bool mready; int RWFlags; + + // Serial + port *info; qsspt *serialhandle; + + // USB + // opHID_hidapi *hidHandle; + 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; @@ -214,11 +214,11 @@ private: // 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); + DFU::Status UploadFirmwareT(const QString &sfile, const bool &verify, int device); QMutex mutex; - OP_DFU::Commands requestedOperation; + DFU::Commands requestedOperation; qint32 requestSize; - OP_DFU::TransferTypes requestTransferType; + DFU::TransferTypes requestTransferType; QByteArray *requestStorage; QString requestFilename; bool requestVerify; @@ -229,7 +229,7 @@ protected: }; } -Q_DECLARE_METATYPE(OP_DFU::Status) +Q_DECLARE_METATYPE(DFU::Status) -#endif // OP_DFU_H +#endif // DFU_H diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp index 793c6787d..35313fb10 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/main.cpp @@ -1,12 +1,66 @@ -#include +/** + ****************************************************************************** + * + * @file main.cpp + * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup Uploader Serial and USB Uploader tool + * @{ + * @brief The USB and Serial protocol uploader tool + *****************************************************************************/ +/* + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "dfu.h" + +#include +#include +#include #include -#include "op_dfu.h" #include +#include + +#include void showProgress(QString status); void progressUpdated(int percent); void usage(QTextStream *standardOutput); + QString label; + +// Command Line Options +#define DOWNLOAD "-dn" +#define DEVICE "-d" +#define DOWNDESCRIPTION "-dd" +#define PROGRAMFW "-p" +#define PROGRAMDESC "-w" +#define VERIFY "-v" +#define COMPARECRC "-cc" +#define COMPAREALL "-ca" +#define STATUSREQUEST "-s" +#define LISTDEVICES "-ls" +#define RESET "-r" +#define JUMP "-j" +#define USE_SERIAL "-t" +#define NO_COUNTDOWN "-i" +#define HELP "-?" +#define DEBUG "-debug" +#define USERMODERESET "-ur" + int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); @@ -16,20 +70,20 @@ int main(int argc, char *argv[]) bool verify; bool debug = false; // bool umodereset = false; - OP_DFU::Actions action = OP_DFU::actionNone; + DFU::Actions action = DFU::actionNone; QString file; QString serialport; QString description; int device = -1; QStringList args = QCoreApplication::arguments(); - if (args.contains("-debug")) { + if (args.contains(DEBUG)) { debug = true; } - if (args.contains("-ur")) { + if (args.contains(USERMODERESET)) { // umodereset = true; } - standardOutput << "OpenPilot serial firmware uploader tool." << endl; + standardOutput << "Serial firmware uploader tool." << endl; if (args.indexOf(PROGRAMFW) + 1 < args.length()) { file = args[args.indexOf(PROGRAMFW) + 1]; } @@ -41,7 +95,7 @@ int main(int argc, char *argv[]) device = 0; } - if (argumentCount == 0 || args.contains("-?") || !args.contains(USE_SERIAL)) { + if (argumentCount == 0 || args.contains(HELP) || !args.contains(USE_SERIAL)) { usage(&standardOutput); return -1; } else if (args.contains(PROGRAMFW)) { @@ -55,30 +109,30 @@ int main(int argc, char *argv[]) description = (args[args.indexOf(PROGRAMDESC) + 1]); } } - action = OP_DFU::actionProgram; + action = DFU::actionProgram; } else if (args.contains(COMPARECRC) || args.contains(COMPAREALL)) { // int index; if (args.contains(COMPARECRC)) { // index = args.indexOf(COMPARECRC); - action = OP_DFU::actionCompareCrc; + action = DFU::actionCompareCrc; } else { // index = args.indexOf(COMPAREALL); - action = OP_DFU::actionCompareAll; + action = DFU::actionCompareAll; } } else if (args.contains(DOWNLOAD)) { // int index; // index = args.indexOf(DOWNLOAD); - action = OP_DFU::actionDownload; + action = DFU::actionDownload; } else if (args.contains(STATUSREQUEST)) { - action = OP_DFU::actionStatusReq; + action = DFU::actionStatusReq; } else if (args.contains(RESET)) { - action = OP_DFU::actionReset; + action = DFU::actionReset; } else if (args.contains(JUMP)) { - action = OP_DFU::actionJump; + action = DFU::actionJump; } else if (args.contains(LISTDEVICES)) { - action = OP_DFU::actionListDevs; + action = DFU::actionListDevs; } - if ((file.isEmpty() || device == -1) && action != OP_DFU::actionReset && action != OP_DFU::actionStatusReq && action != OP_DFU::actionListDevs && action != OP_DFU::actionJump) { + if ((file.isEmpty() || device == -1) && action != DFU::actionReset && action != DFU::actionStatusReq && action != DFU::actionListDevs && action != DFU::actionJump) { usage(&standardOutput); return -1; } @@ -89,20 +143,19 @@ int main(int argc, char *argv[]) } } if (debug) { - qDebug() << "Action=" << (int)action << endl; - qDebug() << "File=" << file << endl; - qDebug() << "Device=" << device << endl; - qDebug() << "Action=" << action << endl; - qDebug() << "Desctription" << description << endl; - qDebug() << "Use Serial port" << use_serial << endl; + qDebug() << "Action=" << (int)action; + qDebug() << "File=" << file; + qDebug() << "Device=" << device; + qDebug() << "Action=" << action; + qDebug() << "Description" << description; + qDebug() << "Use Serial port" << use_serial; if (use_serial) { - qDebug() << "Port Name" << serialport << endl; + qDebug() << "Port Name" << serialport; } } if (use_serial) { if (args.contains(NO_COUNTDOWN)) {} else { - standardOutput << "Connect the board" << endl; - label = ""; + showProgress("Connect the board"); for (int i = 0; i < 6; i++) { progressUpdated(i * 100 / 5); QThread::msleep(500); @@ -111,11 +164,13 @@ int main(int argc, char *argv[]) standardOutput << endl << "Connect the board NOW" << endl; QThread::msleep(1000); } - ///////////////////////////////////ACTIONS START/////////////////////////////////////////////////// - OP_DFU::DFUObject dfu(debug, use_serial, serialport); - QObject::connect(&dfu, &OP_DFU::DFUObject::operationProgress, showProgress); - QObject::connect(&dfu, &OP_DFU::DFUObject::progressUpdated, progressUpdated); + ///////////////////////////////////ACTIONS START/////////////////////////////////////////////////// + + DFU::DFUObject dfu(debug, use_serial, serialport); + + QObject::connect(&dfu, &DFU::DFUObject::operationProgress, showProgress); + QObject::connect(&dfu, &DFU::DFUObject::progressUpdated, progressUpdated); if (!dfu.ready()) { return -1; @@ -126,26 +181,26 @@ int main(int argc, char *argv[]) return -1; } if (debug) { - OP_DFU::Status ret = dfu.StatusRequest(); + DFU::Status ret = dfu.StatusRequest(); qDebug() << dfu.StatusToString(ret); } - if (!(action == OP_DFU::actionStatusReq || action == OP_DFU::actionReset || action == OP_DFU::actionJump)) { + if (!(action == DFU::actionStatusReq || action == DFU::actionReset || action == DFU::actionJump)) { dfu.findDevices(); - if (action == OP_DFU::actionListDevs) { - standardOutput << "Found " << dfu.numberOfDevices << "\n" << endl; + if (action == DFU::actionListDevs) { + standardOutput << "Found " << dfu.numberOfDevices << "\n"; for (int x = 0; x < dfu.numberOfDevices; ++x) { - standardOutput << "Device #" << x << "\n" << endl; - standardOutput << "Device ID=" << dfu.devices[x].ID << "\n" << endl; - standardOutput << "Device Readable=" << dfu.devices[x].Readable << "\n" << endl; - standardOutput << "Device Writable=" << dfu.devices[x].Writable << "\n" << endl; - standardOutput << "Device SizeOfCode=" << dfu.devices[x].SizeOfCode << "\n" << endl; - standardOutput << "BL Version=" << dfu.devices[x].BL_Version << "\n" << endl; - standardOutput << "Device SizeOfDesc=" << dfu.devices[x].SizeOfDesc << "\n" << endl; + standardOutput << "Device #" << x << "\n"; + standardOutput << "Device ID=" << dfu.devices[x].ID << "\n"; + standardOutput << "Device Readable=" << dfu.devices[x].Readable << "\n"; + standardOutput << "Device Writable=" << dfu.devices[x].Writable << "\n"; + standardOutput << "Device SizeOfCode=" << dfu.devices[x].SizeOfCode << "\n"; + standardOutput << "BL Version=" << dfu.devices[x].BL_Version << "\n"; + standardOutput << "Device SizeOfDesc=" << dfu.devices[x].SizeOfDesc << "\n"; standardOutput << "FW CRC=" << dfu.devices[x].FW_CRC << "\n"; - int size = ((OP_DFU::device)dfu.devices[x]).SizeOfDesc; + int size = ((DFU::device)dfu.devices[x]).SizeOfDesc; dfu.enterDFU(x); - standardOutput << "Description:" << dfu.DownloadDescription(size).toLatin1().data() << "\n" << endl; + standardOutput << "Description:" << dfu.DownloadDescription(size).toLatin1().data() << "\n"; standardOutput << "\n"; } return 0; @@ -161,8 +216,8 @@ int main(int argc, char *argv[]) standardOutput << "Error:Could not enter DFU mode\n" << endl; return -1; } - if (action == OP_DFU::actionProgram) { - if (((OP_DFU::device)dfu.devices[device]).Writable == false) { + if (action == DFU::actionProgram) { + if (((DFU::device)dfu.devices[device]).Writable == false) { standardOutput << "ERROR device not Writable\n" << endl; return false; } @@ -177,22 +232,21 @@ int main(int argc, char *argv[]) QThread::msleep(500); } if (file.endsWith("opfw")) { - QByteArray firmware; QFile fwfile(file); if (!fwfile.open(QIODevice::ReadOnly)) { standardOutput << "Cannot open file " << file << endl; return -1; } - firmware = fwfile.readAll(); - QByteArray desc = firmware.right(100); - OP_DFU::Status status = dfu.UploadDescription(desc); - if (status != OP_DFU::Last_operation_Success) { + QByteArray firmware = fwfile.readAll(); + QByteArray desc = firmware.right(100); + DFU::Status status = dfu.UploadDescription(desc); + if (status != DFU::Last_operation_Success) { standardOutput << "Upload failed with code:" << retstatus << endl; return -1; } } else if (!description.isEmpty()) { - OP_DFU::Status status = dfu.UploadDescription(description); - if (status != OP_DFU::Last_operation_Success) { + DFU::Status status = dfu.UploadDescription(description); + if (status != DFU::Last_operation_Success) { standardOutput << "Upload failed with code:" << status << endl; return -1; } @@ -200,9 +254,9 @@ int main(int argc, char *argv[]) while (!dfu.isFinished()) { QThread::msleep(500); } - standardOutput << "Uploading Succeded!\n" << endl; - } else if (action == OP_DFU::actionDownload) { - if (((OP_DFU::device)dfu.devices[device]).Readable == false) { + standardOutput << "Uploading Succeeded!\n" << endl; + } else if (action == DFU::actionDownload) { + if (((DFU::device)dfu.devices[device]).Readable == false) { standardOutput << "ERROR device not readable\n" << endl; return false; } @@ -210,22 +264,22 @@ int main(int argc, char *argv[]) dfu.DownloadFirmware(&fw, 0); bool ret = dfu.SaveByteArrayToFile(file.toLatin1(), fw); return ret; - } else if (action == OP_DFU::actionCompareCrc) { - dfu.CompareFirmware(file.toLatin1(), OP_DFU::crccompare, device); + } else if (action == DFU::actionCompareCrc) { + dfu.CompareFirmware(file.toLatin1(), DFU::crccompare, device); return 1; - } else if (action == OP_DFU::actionCompareAll) { - if (((OP_DFU::device)dfu.devices[device]).Readable == false) { + } else if (action == DFU::actionCompareAll) { + if (((DFU::device)dfu.devices[device]).Readable == false) { standardOutput << "ERROR device not readable\n" << endl; return false; } - dfu.CompareFirmware(file.toLatin1(), OP_DFU::bytetobytecompare, device); + dfu.CompareFirmware(file.toLatin1(), DFU::bytetobytecompare, device); return 1; } - } else if (action == OP_DFU::actionStatusReq) { + } else if (action == DFU::actionStatusReq) { standardOutput << "Current device status=" << dfu.StatusToString(dfu.StatusRequest()).toLatin1().data() << "\n" << endl; - } else if (action == OP_DFU::actionReset) { + } else if (action == DFU::actionReset) { dfu.ResetDevice(); - } else if (action == OP_DFU::actionJump) { + } else if (action == DFU::actionJump) { dfu.JumpToApp(false, false); } return 0; @@ -254,10 +308,11 @@ void progressUpdated(int percent) bar.replace(i, 1, " "); } } - std::cout << "\r" << label.toLatin1().data() << "[" << bar << "] "; + std::cout << "\r" << label.toLatin1().data() << " [" << bar << "] "; std::cout.width(3); std::cout << percent << "% " << std::flush; } + void usage(QTextStream *standardOutput) { *standardOutput << "_________________________________________________________________________\n"; diff --git a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/upload.pro b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/upload.pro index 00f69b767..2316e11af 100644 --- a/ground/gcs/src/experimental/USB_UPLOAD_TOOL/upload.pro +++ b/ground/gcs/src/experimental/USB_UPLOAD_TOOL/upload.pro @@ -4,72 +4,27 @@ # #------------------------------------------------- -QT += core +TEMPLATE = app +TARGET = UploadTool -QT -= gui -QT += serialport +QT += core serialport +QT -= gui -TARGET = OPUploadTool CONFIG += console CONFIG -= app_bundle +# don't build both debug and release +CONFIG -= debug_and_release -TEMPLATE = app - -SOURCES += main.cpp \ - op_dfu.cpp \ - delay.cpp \ +SOURCES += \ + main.cpp \ + dfu.cpp \ ./SSP/qssp.cpp \ ./SSP/port.cpp \ ./SSP/qsspt.cpp \ -HEADERS += op_dfu.h \ - delay.h \ +HEADERS += \ + dfu.h \ ./SSP/qssp.h \ ./SSP/port.h \ ./SSP/common.h \ ./SSP/qsspt.h - -# win32 { -# SOURCES += ../../plugins/rawhid/pjrc_rawhid_win.cpp -# -# LIBS += -lhid \ -# -lsetupapi -#} - -#macx { -# SOURCES += ../../plugins/rawhid/pjrc_rawhid_mac.cpp -# SDK = /Developer/SDKs/MacOSX10.5.sdk -# ARCH = -mmacosx-version-min=10.5 \ -# -arch \ -# ppc \ -# -arch \ -# i386 -# LIBS += $(ARCH) \ -# -Wl,-syslibroot,$(SDK) \ -# -framework \ -# IOKit \ -# -framework \ -# CoreFoundation -#} -#linux-g++ { -# SOURCES += ../../plugins/rawhid/pjrc_rawhid_unix.cpp -# LIBS += -lusb -#} -#linux-g++-64 { -# SOURCES += ../../plugins/rawhid/pjrc_rawhid_unix.cpp -# LIBS += -lusb -#} - -#unix:SOURCES += ../../libs/qextserialport/src/posix_qextserialport.cpp -#unix:!macx:SOURCES += ../../libs/qextserialport/src/qextserialenumerator_unix.cpp -#macx { -# SOURCES += ../../libs/qextserialport/src/qextserialenumerator_osx.cpp -# LIBS += -framework IOKit -framework CoreFoundation -#} - -#win32 { -# SOURCES += ../../libs/qextserialport/src/win_qextserialport.cpp \ -#../../libs/qextserialport/src/qextserialenumerator_win.cpp -# DEFINES += WINVER=0x0501 # needed for mingw to pull in appropriate dbt business...probably a better way to do this -# LIBS += -lsetupapi -#}