void MdiChild::writeEeprom() // write to Tx { QString tempFile = generateProcessUniqueTempFileName("temp.bin"); saveFile(tempFile, false); if(!QFileInfo(tempFile).exists()) { QMessageBox::critical(this, tr("Error"), tr("Cannot write temporary file!")); return; } FlashEEpromDialog *cd = new FlashEEpromDialog(this, tempFile); cd->exec(); }
void FlashFirmwareDialog::on_burnButton_clicked() { g.flashDir(QFileInfo(fwName).dir().absolutePath()); g.profile[g.id()].fwName(fwName); g.checkHardwareCompatibility(ui->checkHardwareCompatibility->isChecked()); g.backupOnFlash(ui->backupEEprom->isChecked()); qDebug() << "FlashFirmwareDialog: flashing" << fwName; if (imageSource != FIRMWARE) { // load the splash image const QPixmap * pixmap = ui->splash->pixmap(); QImage image; if (pixmap) { image = pixmap->toImage().scaled(ui->splash->width(), ui->splash->height()); } if (image.isNull()) { QMessageBox::critical(this, tr("Warning"), tr("Splash image not found")); return; } // write the customized firmware QString tempFile; if (getFileType(fwName) == FILE_TYPE_HEX) tempFile = generateProcessUniqueTempFileName("flash.hex"); else tempFile = generateProcessUniqueTempFileName("flash.bin"); qDebug() << "FlashFirmwareDialog: patching" << fwName << "with custom splash screen and saving to" << tempFile; FirmwareInterface firmware(fwName); firmware.setSplash(image); if (firmware.save(tempFile) <= 0) { QMessageBox::critical(this, tr("Warning"), tr("Cannot save customized firmware")); return; } startFlash(tempFile); } else { startFlash(fwName); } }
QStringList getSambaArgs(const QString &tcl) { QStringList result; QString tclFilename = generateProcessUniqueTempFileName("temp.tcl"); if (QFile::exists(tclFilename)) { qunlink(tclFilename); } QFile tclFile(tclFilename); if (!tclFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::warning(NULL, QObject::tr("Error"), QObject::tr("Cannot write file %1:\n%2.").arg(tclFilename).arg(tclFile.errorString())); return result; } QTextStream outputStream(&tclFile); outputStream << tcl; burnConfigDialog bcd; result << bcd.getSambaPort() << bcd.getArmMCU() << tclFilename ; return result; }
void MdiChild::writeEeprom() // write to Tx { bool backupEnable=true; QString backupPath=((MainWindow *)this->parent())->getBackupPath(); if (backupPath.isEmpty()) { backupEnable=false; } QString stickCal=g.profile[g.id()].stickPotCalib(); burnConfigDialog bcd; QString tempFile = generateProcessUniqueTempFileName("temp.bin"); saveFile(tempFile, false); if(!QFileInfo(tempFile).exists()) { QMessageBox::critical(this,tr("Error"), tr("Cannot write temporary file!")); return; } bool backup=false; burnDialog *cd = new burnDialog(this, 1, &tempFile, &backup,strippedName(curFile)); cd->exec(); if (!tempFile.isEmpty()) { if (backup) { if (backupEnable) { QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss")+".bin"; if (!((MainWindow *)this->parent())->readEepromFromRadio(backupFile, tr("Backup EEPROM From Radio"))) return; } int oldrev=((MainWindow *)this->parent())->getEpromVersion(tempFile); QString tempFlash = generateProcessUniqueTempFileName("flash.bin"); if (!((MainWindow *)this->parent())->readFirmwareFromRadio(tempFlash)) return; QString restoreFile = generateProcessUniqueTempFileName("compat.bin"); if (!((MainWindow *)this->parent())->convertEEPROM(tempFile, restoreFile, tempFlash)) { int ret = QMessageBox::question(this, tr("Error"), tr("Cannot check eeprom compatibility! Continue anyway?"), QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::No) return; } else { int rev=((MainWindow *)this->parent())->getEpromVersion(restoreFile); if ((rev/100)!=(oldrev/100)) { QMessageBox::warning(this,tr("Warning"), tr("Firmware in radio is of a different family of eeprom written, check file and preferences!")); } if (rev<oldrev) { QMessageBox::warning(this,tr("Warning"), tr("Firmware in flash is outdated, please upgrade!")); } tempFile=restoreFile; } qunlink(tempFlash); } else { if (backupEnable) { QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin"; if (!((MainWindow *)this->parent())->readEepromFromRadio(backupFile, tr("Backup EEPROM From Radio"))) return; } } if (!((MainWindow *)this->parent())->writeEepromToRadio(tempFile, tr("Write EEPROM To Radio"))) return; } }
void FlashFirmwareDialog::startFlash(const QString &filename) { bool backup = g.backupOnFlash(); close(); ProgressDialog progressDialog(this, tr("Write Firmware to Radio"), CompanionIcon("write_flash.png")); // check hardware compatibility if requested if (g.checkHardwareCompatibility()) { QString tempFirmware = generateProcessUniqueTempFileName("flash-check.bin"); if (!readFirmware(tempFirmware, progressDialog.progress())) { QMessageBox::warning(this, tr("Firmware check failed"), tr("Could not check firmware from radio")); return; } FirmwareInterface previousFirmware(tempFirmware); qunlink(tempFirmware); FirmwareInterface newFirmware(filename); qDebug() << "startFlash: checking firmware compatibility between " << tempFirmware << "and" << filename; if (!newFirmware.isHardwareCompatible(previousFirmware)) { QMessageBox::warning(this, tr("Firmware check failed"), tr("New firmware is not compatible with the one currently installed!")); if (isTempFileName(filename)) { qDebug() << "startFlash: removing temporary file" << filename; qunlink(filename); } return; } } // backup if requested bool result = true; QString backupFilename; QString backupPath; if (backup) { backupPath = g.profile[g.id()].pBackupDir(); if (backupPath.isEmpty()) { backupPath=g.backupDir(); } backupFilename = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin"; result = readEeprom(backupFilename, progressDialog.progress()); sleep(2); } // flash result = (result && writeFirmware(filename, progressDialog.progress())); // restore if backup requested if (backup && result) { sleep(2); QString restoreFilename = generateProcessUniqueTempFileName("restore.bin"); if (!convertEEprom(backupFilename, restoreFilename, filename)) { QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used")); restoreFilename = backupFilename; } if (!writeEeprom(restoreFilename, progressDialog.progress())) { QMessageBox::warning(this, tr("Restore failed"), tr("Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1").arg(backupFilename)); } } progressDialog.progress()->setInfo(tr("Flashing done")); progressDialog.exec(); if (isTempFileName(filename)) { qDebug() << "startFlash: removing temporary file" << filename; qunlink(filename); } }
void resetAvrdudeFuses(bool eepromProtect, ProgressWidget *progress) { //fuses //avrdude -c usbasp -p m64 -U lfuse:w:<0x0E>:m //avrdude -c usbasp -p m64 -U hfuse:w:<0x89>:m 0x81 for eeprom protection //avrdude -c usbasp -p m64 -U efuse:w:<0xFF>:m burnConfigDialog bcd; QMessageBox::StandardButton ret = QMessageBox::No; ret = QMessageBox::warning(NULL, QObject::tr("Companion"), QObject::tr("<b><u>WARNING!</u></b><br>This will reset the fuses of %1 to the factory settings.<br>" "Writing fuses can mess up your radio.<br>Do this only if you are sure they are wrong!<br>" "Are you sure you want to continue?").arg(bcd.getMCU()), QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::Yes) { QStringList args = bcd.getAvrdudeArgs(); QStringList str; if (bcd.getMCU() == "m2560") { args << "-B8"; QString erStr = eepromProtect ? "hfuse:w:0x11:m" : "hfuse:w:0x19:m"; str << "-U" << "lfuse:w:0xD7:m" << "-U" << erStr << "-U" << "efuse:w:0xFC:m"; //use hfuse = 0x81 to prevent eeprom being erased with every flashing } else { QString lfuses; QString tempFile = generateProcessUniqueTempFileName("ftemp.bin"); QStringList argread; argread << "-c" << bcd.getProgrammer() << "-p" << bcd.getMCU() << args <<"-U" << "lfuse:r:"+tempFile+":r"; FlashProcess flashProcess(bcd.getAVRDUDE(), argread, progress); flashProcess.run(); QFile file(tempFile); if (file.exists() && file.size()==1) { file.open(QIODevice::ReadOnly); char bin_flash[1]; file.read(bin_flash, 1); if (bin_flash[0]==0x0E) { lfuses = "lfuse:w:0x0E:m"; } else { lfuses = "lfuse:w:0x3F:m"; } file.close(); qunlink(tempFile); } else { lfuses = "lfuse:w:0x3F:m"; } QString erStr = eepromProtect ? "hfuse:w:0x81:m" : "hfuse:w:0x89:m"; str << "-U" << lfuses << "-U" << erStr << "-U" << "efuse:w:0xFF:m"; //use hfuse = 0x81 to prevent eeprom being erased with every flashing } QStringList arguments; if (bcd.getMCU() == "m2560") { arguments << "-c" << bcd.getProgrammer() << "-p" << bcd.getMCU() << args << "-u" << str; } else { arguments << "-c" << bcd.getProgrammer() << "-p" << bcd.getMCU() << args << "-B" << "100" << "-u" << str; } FlashProcess flashProcess(bcd.getAVRDUDE(), arguments, progress); flashProcess.run(); } }
void burnConfigDialog::restFuses(bool eeProtect) { //fuses //avrdude -c usbasp -p m64 -U lfuse:w:<0x0E>:m //avrdude -c usbasp -p m64 -U hfuse:w:<0x89>:m 0x81 for eeprom protection //avrdude -c usbasp -p m64 -U efuse:w:<0xFF>:m QMessageBox::StandardButton ret = QMessageBox::No; ret = QMessageBox::warning(this, tr("Companion"), tr("<b><u>WARNING!</u></b><br>This will reset the fuses of %1 to the factory settings.<br>Writing fuses can mess up your radio.<br>Do this only if you are sure they are wrong!<br>Are you sure you want to continue?").arg(avrMCU), QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::Yes) { QStringList args = avrArgs; if(!avrPort.isEmpty()) args << "-P" << avrPort; QStringList str; if (avrMCU=="m2560") { args << "-B8"; QString erStr = eeProtect ? "hfuse:w:0x11:m" : "hfuse:w:0x19:m"; str << "-U" << "lfuse:w:0xD7:m" << "-U" << erStr << "-U" << "efuse:w:0xFC:m"; //use hfuse = 0x81 to prevent eeprom being erased with every flashing } else { QString lfuses; QString tempFile = generateProcessUniqueTempFileName("ftemp.bin"); QStringList argread; argread << "-c" << avrProgrammer << "-p" << avrMCU << args <<"-U" << "lfuse:r:"+tempFile+":r" ; avrOutputDialog *ad = new avrOutputDialog(this, avrLoc, argread, "Reset Fuses",AVR_DIALOG_CLOSE_IF_SUCCESSFUL,FALSE); ad->setWindowIcon(CompanionIcon("fuses.png")); ad->exec(); delete ad; QFile file(tempFile); if (file.exists() && file.size()==1) { file.open(QIODevice::ReadOnly); char bin_flash[1]; file.read(bin_flash, 1); if (bin_flash[0]==0x0E) { lfuses="lfuse:w:0x0E:m"; } else { lfuses="lfuse:w:0x3F:m"; } file.close(); qunlink(tempFile); } else { lfuses="lfuse:w:0x3F:m"; } QString erStr = eeProtect ? "hfuse:w:0x81:m" : "hfuse:w:0x89:m"; str << "-U" << lfuses << "-U" << erStr << "-U" << "efuse:w:0xFF:m"; //use hfuse = 0x81 to prevent eeprom being erased with every flashing } QStringList arguments; if (avrMCU=="m2560") { arguments << "-c" << avrProgrammer << "-p" << avrMCU << args << "-u" << str; } else { arguments << "-c" << avrProgrammer << "-p" << avrMCU << args << "-B" << "100" << "-u" << str; } avrOutputDialog *ad = new avrOutputDialog(this, avrLoc, arguments, "Reset Fuses",AVR_DIALOG_KEEP_OPEN,TRUE); ad->setWindowIcon(CompanionIcon("fuses.png")); ad->show(); delete ad; } }
void LogsDialog::exportToGoogleEarth() { // filter data points QList<QStringList> dataPoints = filterGePoints(csvlog); int n = dataPoints.count(); // number of points to export if (n==0) return; int latcol=0, longcol=0, altcol=0, speedcol=0; QSet<int> nondataCols; for (int i=1; i<dataPoints.at(0).count(); i++) { // Long,Lat,Course,GPS Speed,GPS Alt if (dataPoints.at(0).at(i).contains("Long")) { longcol = i; nondataCols << i; } if (dataPoints.at(0).at(i).contains("Lat")) { latcol = i; nondataCols << i; } if (dataPoints.at(0).at(i).contains("GPS Alt") || dataPoints.at(0).at(i).contains("GAlt")) { altcol = i; nondataCols << i; } if (dataPoints.at(0).at(i).contains("GPS Speed")) { speedcol = i; nondataCols << i; } } if (longcol==0 || latcol==0) { return; } QString geIconFilename = generateProcessUniqueTempFileName("track0.png"); if (QFile::exists(geIconFilename)) { QFile::remove(geIconFilename); } QFile::copy(":/images/track0.png", geIconFilename); QString geFilename = generateProcessUniqueTempFileName("flight.kml"); if (QFile::exists(geFilename)) { QFile::remove(geFilename); } QFile geFile(geFilename); if (!geFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::warning(this, tr("Error"), tr("Cannot write file %1:\n%2.") .arg(geFilename) .arg(geFile.errorString())); return; } QTextStream outputStream(&geFile); // file header outputStream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">\n"; outputStream << "\t<Document>\n\t\t<name>" << logFilename << "</name>\n"; outputStream << "\t\t<Style id=\"multiTrack_n\">\n\t\t\t<IconStyle>\n\t\t\t\t<Icon>\n\t\t\t\t\t<href>file://" << geIconFilename << "</href>\n\t\t\t\t</Icon>\n\t\t\t</IconStyle>\n\t\t\t<LineStyle>\n\t\t\t\t<color>991081f4</color>\n\t\t\t\t<width>6</width>\n\t\t\t</LineStyle>\n\t\t</Style>\n"; outputStream << "\t\t<Style id=\"multiTrack_h\">\n\t\t\t<IconStyle>\n\t\t\t\t<scale>0</scale>\n\t\t\t\t<Icon>\n\t\t\t\t\t<href>file://" << geIconFilename << "</href>\n\t\t\t\t</Icon>\n\t\t\t</IconStyle>\n\t\t\t<LineStyle>\n\t\t\t\t<color>991081f4</color>\n\t\t\t\t<width>8</width>\n\t\t\t</LineStyle>\n\t\t</Style>\n"; outputStream << "\t\t<StyleMap id=\"multiTrack\">\n\t\t\t<Pair>\n\t\t\t\t<key>normal</key>\n\t\t\t\t<styleUrl>#multiTrack_n</styleUrl>\n\t\t\t</Pair>\n\t\t\t<Pair>\n\t\t\t\t<key>highlight</key>\n\t\t\t\t<styleUrl>#multiTrack_h</styleUrl>\n\t\t\t</Pair>\n\t\t</StyleMap>\n"; outputStream << "\t\t<Style id=\"lineStyle\">\n\t\t\t<LineStyle>\n\t\t\t\t<color>991081f4</color>\n\t\t\t\t<width>6</width>\n\t\t\t</LineStyle>\n\t\t</Style>\n"; outputStream << "\t\t<Schema id=\"schema\">\n"; outputStream << "\t\t\t<gx:SimpleArrayField name=\"GPSSpeed\" type=\"float\">\n\t\t\t\t<displayName>GPS Speed</displayName>\n\t\t\t</gx:SimpleArrayField>\n"; // declare additional fields for (int i=0; i<dataPoints.at(0).count()-2; i++) { if (ui->FieldsTW->item(0,i)->isSelected() && !nondataCols.contains(i+2)) { QString origName = dataPoints.at(0).at(i+2); QString safeName = origName; safeName.replace(" ","_"); outputStream << "\t\t\t<gx:SimpleArrayField name=\""<< safeName <<"\" "; outputStream << "type=\"string\""; // additional fields have fixed type: string outputStream << ">\n\t\t\t\t<displayName>" << origName << "</displayName>\n\t\t\t</gx:SimpleArrayField>\n"; } } QString planeName; if (logFilename.indexOf("-")>0) { planeName=logFilename.left(logFilename.indexOf("-")); } else { planeName=logFilename; } outputStream << "\t\t</Schema>\n"; outputStream << "\t\t<Folder>\n\t\t\t<name>Log Data</name>\n\t\t\t<Placemark>\n\t\t\t\t<name>" << planeName << "</name>"; outputStream << "\n\t\t\t\t<styleUrl>#multiTrack</styleUrl>"; outputStream << "\n\t\t\t\t<gx:Track>\n"; outputStream << "\n\t\t\t\t\t<altitudeMode>absolute</altitudeMode>\n"; // time data points for (int i=1; i<n; i++) { QString tstamp=dataPoints.at(i).at(0)+QString("T")+dataPoints.at(i).at(1)+QString("Z"); outputStream << "\t\t\t\t\t<when>"<< tstamp <<"</when>\n"; } // coordinate data points for (int i=1; i<n; i++) { QString latitude = dataPoints.at(i).at(latcol).trimmed(); QString longitude = dataPoints.at(i).at(longcol).trimmed(); int altitude = altcol ? dataPoints.at(i).at(altcol).toFloat() : 0; latitude.sprintf("%3.8f", toDecimalCoordinate(latitude)); longitude.sprintf("%3.8f", toDecimalCoordinate(longitude)); outputStream << "\t\t\t\t\t<gx:coord>" << longitude << " " << latitude << " " << altitude << " </gx:coord>\n" ; } // additional data for data points outputStream << "\t\t\t\t\t<ExtendedData>\n\t\t\t\t\t\t<SchemaData schemaUrl=\"#schema\">\n"; if (speedcol) { // gps speed data points outputStream << "\t\t\t\t\t\t\t<gx:SimpleArrayData name=\"GPSSpeed\">\n"; for (int i=1; i<n; i++) { outputStream << "\t\t\t\t\t\t\t\t<gx:value>"<< dataPoints.at(i).at(speedcol) <<"</gx:value>\n"; } outputStream << "\t\t\t\t\t\t\t</gx:SimpleArrayData>\n"; } // add values for additional fields for (int i=0; i<dataPoints.at(0).count()-2; i++) { if (ui->FieldsTW->item(0,i)->isSelected() && !nondataCols.contains(i+2)) { QString safeName = dataPoints.at(0).at(i+2);; safeName.replace(" ","_"); outputStream << "\t\t\t\t\t\t\t<gx:SimpleArrayData name=\""<< safeName <<"\">\n"; for (int j=1; j<n; j++) { outputStream << "\t\t\t\t\t\t\t\t<gx:value>"<< dataPoints.at(j).at(i+2) <<"</gx:value>\n"; } outputStream << "\t\t\t\t\t\t\t</gx:SimpleArrayData>\n"; } } outputStream << "\t\t\t\t\t\t</SchemaData>\n\t\t\t\t\t</ExtendedData>\n\t\t\t\t</gx:Track>\n\t\t\t</Placemark>\n\t\t</Folder>\n\t</Document>\n</kml>"; geFile.close(); QString gePath = g.gePath(); QStringList parameters; #ifdef __APPLE__ parameters << "-a"; parameters << gePath; gePath = "/usr/bin/open"; #endif parameters << geFilename; QProcess *process = new QProcess(this); process->start(gePath, parameters); }