#include "burnconfigdialog.h" #include "ui_burnconfigdialog.h" #include "avroutputdialog.h" #include "eeprominterface.h" #include "helpers.h" #include "appdata.h" #include #if !defined WIN32 && defined __GNUC__ #include #endif burnConfigDialog::burnConfigDialog(QWidget *parent) : QDialog(parent), ui(new Ui::burnConfigDialog) { ui->setupUi(this); setWindowIcon(CompanionIcon("configure.png")); ui->avrdude_programmer->model()->sort(0); getSettings(); populateProgrammers(); EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { setWindowTitle(tr("DFU-UTIL Configuration")); ui->avrArgs->hide(); ui->avrdude_location->hide(); ui->avrdude_port->hide(); ui->avrdude_programmer->hide(); ui->label_av1->hide(); ui->label_av2->hide(); ui->label_av4->hide(); ui->label_av5->hide(); ui->pushButton->hide(); ui->pushButton_3->hide(); ui->pushButton_4->hide(); ui->label_sb1->hide(); ui->label_sb3->hide(); ui->samba_location->hide(); ui->samba_port->hide(); ui->sb_browse->hide(); } else if (IS_SKY9X(eepromInterface->getBoard())) { setWindowTitle(tr("SAM-BA Configuration")); ui->avrArgs->hide(); ui->avrdude_location->hide(); ui->avrdude_port->hide(); ui->avrdude_programmer->hide(); ui->label_av1->hide(); ui->label_av2->hide(); ui->label_av4->hide(); ui->label_av5->hide(); ui->pushButton->hide(); ui->pushButton_3->hide(); ui->pushButton_4->hide(); ui->label_dfu1->hide(); ui->dfu_location->hide(); ui->dfu_browse->hide(); } else { setWindowTitle(tr("AVRDUDE Configuration")); ui->label_sb1->hide(); ui->label_sb3->hide(); ui->samba_location->hide(); ui->samba_port->hide(); ui->sb_browse->hide(); ui->label_dfu1->hide(); ui->label_dfu2->hide(); ui->dfu_location->hide(); ui->dfu_browse->hide(); } ui->label_av3->hide(); ui->avrdude_mcu->hide(); ui->label_sb2->hide(); ui->arm_mcu->hide(); ui->label_dfu2->hide(); ui->dfuArgs->hide(); QTimer::singleShot(0, this, SLOT(shrink())); connect(this,SIGNAL(accepted()),this,SLOT(putSettings())); } burnConfigDialog::~burnConfigDialog() { delete ui; } void burnConfigDialog::getSettings() { avrLoc = g.avrdudeLocation(); sambaLoc = g.sambaLocation(); dfuLoc = g.dfuLocation(); #if defined WIN32 || !defined __GNUC__ if ( avrLoc.isEmpty()) avrLoc = QFileInfo("avrdude.exe").absoluteFilePath(); if ( sambaLoc.isEmpty()) sambaLoc = QFileInfo("sam-ba.exe").absoluteFilePath(); if ( dfuLoc.isEmpty()) dfuLoc = QFileInfo("dfu-util.exe").absoluteFilePath(); #elif defined __APPLE__ if ( avrLoc.isEmpty()) avrLoc = "/usr/local/bin/avrdude"; if ( sambaLoc.isEmpty()) sambaLoc = "/usr/local/bin/sam-ba"; if ( dfuLoc.isEmpty()) dfuLoc = QFileInfo("/opt/local/bin/dfu-util").absoluteFilePath(); #else if ( avrLoc.isEmpty()) avrLoc = "/usr/bin/avrdude"; if ( sambaLoc.isEmpty()) sambaLoc = "/usr/bin/sam-ba"; if ( dfuLoc.isEmpty()) dfuLoc = QFileInfo("/usr/bin/dfu-util").absoluteFilePath(); #endif dfuArgs = g.dfuArguments().split(" ", QString::SkipEmptyParts); avrArgs = g.avrArguments().split(" ", QString::SkipEmptyParts); avrProgrammer = g.programmer(); avrPort = g.avrPort(); avrMCU = g.mcu(); armMCU = g.armMcu(); sambaPort = g.sambaPort(); ui->avrdude_location->setText(getAVRDUDE()); ui->avrArgs->setText(getAVRArgs().join(" ")); ui->samba_location->setText(getSAMBA()); ui->samba_port->setText(getSambaPort()); ui->dfu_location->setText(getDFU()); ui->dfuArgs->setText(getDFUArgs().join(" ")); int idx1 = ui->avrdude_programmer->findText(getProgrammer()); int idx2 = ui->avrdude_port->findText(getPort()); int idx3 = ui->avrdude_mcu->findText(getMCU()); int idx4 = ui->arm_mcu->findText(getArmMCU()); if(idx1>=0) ui->avrdude_programmer->setCurrentIndex(idx1); if(idx2>=0) ui->avrdude_port->setCurrentIndex(idx2); if(idx3>=0) ui->avrdude_mcu->setCurrentIndex(idx3); if(idx4>=0) ui->arm_mcu->setCurrentIndex(idx4); QFile file; if (file.exists(avrLoc)) { ui->pushButton_3->setEnabled(true); } else { ui->pushButton_3->setDisabled(true); } } void burnConfigDialog::putSettings() { g.avrdudeLocation( avrLoc ); g.programmer( avrProgrammer); g.mcu( avrMCU ); g.avrPort( avrPort ); g.avrArguments( avrArgs.join(" ") ); g.sambaLocation( sambaLoc ); g.sambaPort( sambaPort ); g.armMcu( armMCU ); g.dfuLocation( dfuLoc ); g.dfuArguments( dfuArgs.join(" ") ); } void burnConfigDialog::populateProgrammers() { QString fileName = QFileInfo(avrLoc).canonicalPath() + "/avrdude.conf"; //for windows if(!QFileInfo(fileName).exists()) fileName = "/etc/avrdude.conf"; //for linux if(!QFileInfo(fileName).exists()) fileName = "/etc/avrdude/avrdude.conf"; //for linux if(!QFileInfo(fileName).exists()) return; // not found avrdude.conf - returning QFile file(fileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; QStringList items; QString line = ""; QString prevline = ""; QTextStream in(&file); while (!in.atEnd()) { prevline = line; line = in.readLine(); if(prevline.left(10).toLower()=="programmer") items << line.section('"',1,1); } file.close(); items.sort(); QString avrProgrammer_temp = avrProgrammer; ui->avrdude_programmer->clear(); ui->avrdude_programmer->addItems(items); int idx1 = ui->avrdude_programmer->findText(avrProgrammer_temp); if(idx1>=0) ui->avrdude_programmer->setCurrentIndex(idx1); } void burnConfigDialog::on_avrdude_programmer_currentIndexChanged(QString ) { avrProgrammer = ui->avrdude_programmer->currentText(); } void burnConfigDialog::on_avrdude_mcu_currentIndexChanged(QString ) { avrMCU = ui->avrdude_mcu->currentText(); } void burnConfigDialog::on_avrdude_location_editingFinished() { avrLoc = ui->avrdude_location->text(); if (avrLoc.isEmpty()) { ui->pushButton_3->setDisabled(true); } else { QFile file; if (file.exists(avrLoc)) { ui->pushButton_3->setEnabled(true); } } } void burnConfigDialog::on_avrArgs_editingFinished() { avrArgs = ui->avrArgs->text().split(" ", QString::SkipEmptyParts); } void burnConfigDialog::on_avrdude_port_currentIndexChanged(QString ) { avrPort = ui->avrdude_port->currentText(); } void burnConfigDialog::on_samba_location_editingFinished() { sambaLoc = ui->samba_location->text(); } void burnConfigDialog::on_samba_port_editingFinished() { sambaPort = ui->samba_port->text(); } void burnConfigDialog::on_arm_mcu_currentIndexChanged(QString ) { armMCU = ui->arm_mcu->currentText(); } void burnConfigDialog::on_pushButton_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->avrdude_location->text()); if(!fileName.isEmpty()) { ui->avrdude_location->setText(fileName); avrLoc = fileName; } } void burnConfigDialog::on_sb_browse_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->samba_location->text()); if(!fileName.isEmpty()) { ui->samba_location->setText(fileName); sambaLoc = fileName; } } void burnConfigDialog::on_dfu_browse_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->dfu_location->text()); if(!fileName.isEmpty()) { ui->dfu_location->setText(fileName); dfuLoc = fileName; } } void burnConfigDialog::on_dfu_location_editingFinished() { dfuLoc = ui->dfu_location->text(); } void burnConfigDialog::on_dfuArgs_editingFinished() { dfuArgs = ui->dfuArgs->text().split(" ", QString::SkipEmptyParts); } void burnConfigDialog::listProgrammers() { QStringList arguments; arguments << "-c?"; avrOutputDialog *ad = new avrOutputDialog(this, ui->avrdude_location->text(), arguments, "List available programmers", AVR_DIALOG_KEEP_OPEN, TRUE); ad->setWindowIcon(CompanionIcon("list.png")); ad->show(); delete ad; } void burnConfigDialog::on_pushButton_3_clicked() { listProgrammers(); } void burnConfigDialog::on_pushButton_4_clicked() { QStringList arguments; arguments << "-?"; avrOutputDialog *ad = new avrOutputDialog(this, ui->avrdude_location->text(), arguments, "Show help", AVR_DIALOG_KEEP_OPEN,TRUE); ad->setWindowIcon(CompanionIcon("configure.png")); ad->show(); delete ad; } void burnConfigDialog::readFuses() { QStringList args = avrArgs; if(!avrPort.isEmpty()) args << "-P" << avrPort; QStringList str; str << "-U" << "lfuse:r:-:i" << "-U" << "hfuse:r:-:i" << "-U" << "efuse:r:-:i"; QStringList arguments; arguments << "-c" << avrProgrammer << "-p" << avrMCU << args << str; avrOutputDialog *ad = new avrOutputDialog(this, avrLoc, arguments, "Read Fuses",AVR_DIALOG_KEEP_OPEN,TRUE); ad->setWindowIcon(CompanionIcon("fuses.png")); ad->show(); delete ad; } 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("WARNING!
This will reset the fuses of %1 to the factory settings.
Writing fuses can mess up your radio.
Do this only if you are sure they are wrong!
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 tempDir = QDir::tempPath(); QString tempFile; QString lfuses; tempFile = tempDir + "/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(); unlink(tempFile.toAscii()); } 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 burnConfigDialog::on_advCtrChkB_toggled(bool checked) { EEPROMInterface *eepromInterface = GetEepromInterface(); if (checked) { if (IS_TARANIS(eepromInterface->getBoard())) { ui->label_dfu2->show(); ui->dfuArgs->show(); } else if (IS_SKY9X(eepromInterface->getBoard())) { ui->label_sb2->show(); ui->arm_mcu->show(); } else { ui->label_av3->show(); ui->avrdude_mcu->show(); QMessageBox::warning(this, tr("Companion"), tr("WARNING!
Normally CPU type is automatically selected according to the chosen firmware.
If you change the CPU type the resulting eeprom could be inconsistent."), QMessageBox::Ok); } } else { if (IS_TARANIS(eepromInterface->getBoard())) { ui->label_dfu2->hide(); ui->dfuArgs->hide(); } else if (IS_SKY9X(eepromInterface->getBoard())) { ui->label_sb2->hide(); ui->arm_mcu->hide(); } else { ui->label_av3->hide(); ui->avrdude_mcu->hide(); } } QTimer::singleShot(0, this, SLOT(shrink())); } void burnConfigDialog::shrink() { resize(0,0); }