diff --git a/Software/PC_Application/Application b/Software/PC_Application/Application index 7a9407d..8a1ce8c 100755 Binary files a/Software/PC_Application/Application and b/Software/PC_Application/Application differ diff --git a/Software/PC_Application/Device/device.cpp b/Software/PC_Application/Device/device.cpp index a09dd93..fe5c30d 100644 --- a/Software/PC_Application/Device/device.cpp +++ b/Software/PC_Application/Device/device.cpp @@ -181,15 +181,15 @@ bool Device::SendCommandWithoutPayload(Protocol::PacketType type) } } -std::vector Device::GetDevices() +std::set Device::GetDevices() { - std::vector serials; + std::set serials; libusb_context *ctx; libusb_init(&ctx); SearchDevices([&serials](libusb_device_handle *, QString serial) -> bool { - serials.push_back(serial); + serials.insert(serial); return true; }, ctx); diff --git a/Software/PC_Application/Device/device.h b/Software/PC_Application/Device/device.h index c94fef3..fa68b4e 100644 --- a/Software/PC_Application/Device/device.h +++ b/Software/PC_Application/Device/device.h @@ -7,6 +7,7 @@ #include #include #include +#include Q_DECLARE_METATYPE(Protocol::Datapoint); Q_DECLARE_METATYPE(Protocol::ManualStatus); @@ -50,7 +51,7 @@ public: bool SendFirmwareChunk(Protocol::FirmwarePacket &fw); bool SendCommandWithoutPayload(Protocol::PacketType type); // Returns serial numbers of all connected devices - static std::vector GetDevices(); + static std::set GetDevices(); QString serial() const; Protocol::DeviceInfo getLastInfo() const; QString getLastDeviceInfoString(); diff --git a/Software/PC_Application/Device/firmwareupdatedialog.cpp b/Software/PC_Application/Device/firmwareupdatedialog.cpp index e1b020b..6c0751d 100644 --- a/Software/PC_Application/Device/firmwareupdatedialog.cpp +++ b/Software/PC_Application/Device/firmwareupdatedialog.cpp @@ -2,7 +2,7 @@ #include "ui_firmwareupdatedialog.h" #include -FirmwareUpdateDialog::FirmwareUpdateDialog(Device &dev, QWidget *parent) : +FirmwareUpdateDialog::FirmwareUpdateDialog(Device *&dev, QWidget *parent) : QDialog(parent), ui(new Ui::FirmwareUpdateDialog), dev(dev), @@ -13,10 +13,7 @@ FirmwareUpdateDialog::FirmwareUpdateDialog(Device &dev, QWidget *parent) : ui->setupUi(this); ui->bFile->setIcon(this->style()->standardPixmap(QStyle::SP_FileDialogStart)); ui->bStart->setIcon(this->style()->standardPixmap(QStyle::SP_MediaPlay)); - timer.setSingleShot(true); - connect(&timer, &QTimer::timeout, [=](){ - abortWithError("Response timed out"); - }); + connect(&timer, &QTimer::timeout, this, &FirmwareUpdateDialog::timerCallback); } FirmwareUpdateDialog::~FirmwareUpdateDialog() @@ -62,7 +59,8 @@ void FirmwareUpdateDialog::on_bStart_clicked() } state = State::ErasingFLASH; addStatus("Erasing device memory..."); - dev.SendCommandWithoutPayload(Protocol::PacketType::ClearFlash); + dev->SendCommandWithoutPayload(Protocol::PacketType::ClearFlash); + timer.setSingleShot(true); timer.start(10000); } @@ -84,6 +82,22 @@ void FirmwareUpdateDialog::abortWithError(QString error) state = State::Idle; } +void FirmwareUpdateDialog::timerCallback() +{ + if(state != State::WaitingForReboot) { + abortWithError("Response timed out"); + } else { + // Currently waiting for the reboot, check device list + auto devices = Device::GetDevices(); + if(devices.find(serialnumber) != devices.end()) { + // the device rebooted and is available again + dev = new Device(serialnumber); + addStatus("...device reattached, update complete"); + timer.stop(); + } + } +} + void FirmwareUpdateDialog::receivedAck() { switch(state) { @@ -105,7 +119,7 @@ void FirmwareUpdateDialog::receivedAck() // complete file transferred addStatus("Triggering device update..."); state = State::TriggeringUpdate; - dev.SendCommandWithoutPayload(Protocol::PacketType::PerformFirmwareUpdate); + dev->SendCommandWithoutPayload(Protocol::PacketType::PerformFirmwareUpdate); timer.start(5000); } sendNextFirmwareChunk(); @@ -113,8 +127,14 @@ void FirmwareUpdateDialog::receivedAck() break; case State::TriggeringUpdate: addStatus("Rebooting device..."); - // TODO delete current device and listen for reconnect - state = State::Idle; + serialnumber = dev->serial(); + delete dev; + dev = nullptr; + state = State::WaitingForReboot; + timer.setSingleShot(false); + timer.start(1000); + break; + default: break; } } @@ -124,5 +144,5 @@ void FirmwareUpdateDialog::sendNextFirmwareChunk() Protocol::FirmwarePacket fw; fw.address = transferredBytes; file->read((char*) &fw.data, Protocol::FirmwareChunkSize); - dev.SendFirmwareChunk(fw); + dev->SendFirmwareChunk(fw); } diff --git a/Software/PC_Application/Device/firmwareupdatedialog.h b/Software/PC_Application/Device/firmwareupdatedialog.h index 9016a85..8f0978a 100644 --- a/Software/PC_Application/Device/firmwareupdatedialog.h +++ b/Software/PC_Application/Device/firmwareupdatedialog.h @@ -15,13 +15,20 @@ class FirmwareUpdateDialog : public QDialog Q_OBJECT public: - explicit FirmwareUpdateDialog(Device &dev, QWidget *parent = nullptr); + /* + * Depending on the result of the firmware update, the device pointer will be modified: + * - In case of user-aborted firmware update, the device pointer will be unchanged + * - If the update fails during transmission of firmware data, the device pointer will be unchanged + * - If the update fails during device reboot, the device pointer is set to zero and the device deleted + * - If the update succeeds, the device pointer will be set to the new device instance + */ + explicit FirmwareUpdateDialog(Device *&dev, QWidget *parent = nullptr); ~FirmwareUpdateDialog(); private slots: void on_bFile_clicked(); - void on_bStart_clicked(); + void timerCallback(); private: void addStatus(QString line); @@ -29,7 +36,7 @@ private: void receivedAck(); void sendNextFirmwareChunk(); Ui::FirmwareUpdateDialog *ui; - Device &dev; + Device *&dev; QFile *file; QTimer timer; @@ -38,9 +45,11 @@ private: ErasingFLASH, TransferringData, TriggeringUpdate, + WaitingForReboot, }; State state; unsigned int transferredBytes; + QString serialnumber; }; #endif // FIRMWAREUPDATEDIALOG_H diff --git a/Software/PC_Application/vna.cpp b/Software/PC_Application/vna.cpp index 2916f9b..8e6965c 100644 --- a/Software/PC_Application/vna.cpp +++ b/Software/PC_Application/vna.cpp @@ -109,7 +109,7 @@ VNA::VNA(QWidget *parent) }); connect(ui->actionFirmware_Update, &QAction::triggered, [=](){ if(device) { - auto fw_update = new FirmwareUpdateDialog(*device); + auto fw_update = new FirmwareUpdateDialog(device); fw_update->exec(); } });