uploadFirmware.cpp
2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// SPDX-License-Identifier: GPL-2.0+
#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <QTemporaryFile>
#include <libusb-1.0/libusb.h>
#include <memory>
#include "ezusb.h"
#include "uploadFirmware.h"
#include "usbdevice.h"
#include "utils/printutils.h"
#include "dsomodel.h"
#define TR(str) QCoreApplication::translate("UploadFirmware", str)
bool UploadFirmware::startUpload(USBDevice *device) {
if (device->isConnected() || !device->needsFirmware()) return false;
// Open device
libusb_device_handle *handle;
int errorCode = libusb_open(device->getRawDevice(), &handle);
if (errorCode != LIBUSB_SUCCESS) {
handle = nullptr;
errorMessage = TR("Couldn't open device: %1").arg(libUsbErrorString(errorCode));
return false;
}
// Write firmware from resources to temp files
QFile firmwareRes(
QString(":/firmware/%1-firmware.hex").arg(QString::fromStdString(device->getModel()->firmwareToken)));
auto temp_firmware_path = std::unique_ptr<QTemporaryFile>(QTemporaryFile::createNativeFile(firmwareRes));
if (!temp_firmware_path) return false;
temp_firmware_path->open();
QFile loaderRes(QString(":/firmware/%1-loader.hex").arg(QString::fromStdString(device->getModel()->firmwareToken)));
auto temp_loader_path = std::unique_ptr<QTemporaryFile>(QTemporaryFile::createNativeFile(loaderRes));
if (!temp_loader_path) return false;
temp_loader_path->open();
/* We need to claim the first interface */
libusb_set_auto_detach_kernel_driver(handle, 1);
int status = libusb_claim_interface(handle, 0);
if (status != LIBUSB_SUCCESS) {
errorMessage = TR("libusb_claim_interface() failed: %1").arg(libusb_error_name(status));
libusb_close(handle);
return false;
}
// Write loader
status = ezusb_load_ram(handle, temp_loader_path->fileName().toUtf8().constData(), FX_TYPE_FX2, 0);
if (status != LIBUSB_SUCCESS) {
errorMessage = TR("Writing the loader firmware failed: %1").arg(libusb_error_name(status));
libusb_release_interface(handle, 0);
libusb_close(handle);
return false;
}
// Write firmware
status = ezusb_load_ram(handle, temp_firmware_path->fileName().toUtf8().constData(), FX_TYPE_FX2, 1);
if (status != LIBUSB_SUCCESS) {
errorMessage = TR("Writing the main firmware failed: %1").arg(libusb_error_name(status));
libusb_release_interface(handle, 0);
libusb_close(handle);
return false;
}
libusb_release_interface(handle, 0);
libusb_close(handle);
return status == LIBUSB_SUCCESS;
}
const QString &UploadFirmware::getErrorMessage() const { return errorMessage; }