1830 lines
55 KiB
C++
1830 lines
55 KiB
C++
#include "qggrifobeamupform.h"
|
|
#include "ui_qggrifobeamupform.h"
|
|
|
|
#include <qgnetworkinterface.h>
|
|
#include "qgpropertywidget.h"
|
|
|
|
#include <QTreeWidgetItem>
|
|
#include <QGridLayout>
|
|
#include <QCheckBox>
|
|
|
|
#include <QHostInfo>
|
|
#include <QHostAddress>
|
|
#include <QNetworkInterface>
|
|
|
|
#include <QFileDialog>
|
|
#include <QDir>
|
|
#include <QUrl>
|
|
#include <QMessageBox>
|
|
|
|
#include <QDebug>
|
|
#include <QSettings>
|
|
|
|
#include <QDropEvent>
|
|
#include <QDragEnterEvent>
|
|
#include <QMimeData>
|
|
#include <QStyle>
|
|
#include <QList>
|
|
#include <QInputDialog>
|
|
|
|
#include "qzip.h"
|
|
|
|
#include "bsk_tftp_pfs.h"
|
|
|
|
#include <QRegExp>
|
|
|
|
#include "downloadablefile.h"
|
|
|
|
#include "mydebug.h"
|
|
|
|
#include "historydbform.h"
|
|
|
|
#include "fpgabeammeupstring.h"
|
|
|
|
#include "fpgaflashxml.h"
|
|
|
|
|
|
#define TFTP_DEFAULT_PORT 50069
|
|
|
|
bool IS_TFTP_CONNECTED;
|
|
|
|
QString TMP_FOLDER;
|
|
|
|
struct fileToWrite_s
|
|
{
|
|
bool validConfig; // true if i read a valid config from xml file present into zip files
|
|
QString targetFlash; // namePrefix of valid config
|
|
QString primaryFile; // bin file to write on first spi port (primary)
|
|
QString primaryMD5; // md5 for primary file
|
|
bool primaryDone; // true if write is done
|
|
QString secondaryFile; // bin file to write on second spi port (secondary)
|
|
QString secondaryMD5; // md5 for secondary file
|
|
bool secondaryDone; //true if write is done
|
|
};
|
|
|
|
static fileToWrite_s fileToWrite;
|
|
|
|
void resetFileToWrite()
|
|
{
|
|
fileToWrite.validConfig = false;
|
|
fileToWrite.targetFlash = "";
|
|
fileToWrite.primaryDone = false;
|
|
fileToWrite.primaryFile = "";
|
|
fileToWrite.primaryMD5 = "";
|
|
fileToWrite.secondaryDone = false;
|
|
fileToWrite.secondaryFile = "";
|
|
fileToWrite.secondaryMD5 = "";
|
|
}
|
|
|
|
|
|
enum fpga_t
|
|
{
|
|
fpga_no_specific = 0,
|
|
fpga_carrier1_fpga1 = 1,
|
|
fpga_carrier1_fpga2 = 2,
|
|
fpga_carrier2_fpga1 = 3,
|
|
fpga_carrier2_fpga2 = 4,
|
|
fpga_digital_ctrl = 5
|
|
};
|
|
|
|
//QString ShowFileInfo(const QString& fname, bool popup=true);
|
|
|
|
static QString probeNetworks(const QString& prefered_net, QComboBox* cb)
|
|
{
|
|
unsigned int prefered_index=0;
|
|
static bool privateSubnet=false;
|
|
static QString preferedNetwork("127.0.0.1");
|
|
|
|
if (!prefered_net.isEmpty())
|
|
preferedNetwork=prefered_net;
|
|
|
|
QHostInfo hi=QHostInfo::fromName(QHostInfo::localHostName());
|
|
//ui->groupBox->setTitle(QString("Host: %1").arg(hi.hostName()));
|
|
QList<QNetworkInterface> hal=QNetworkInterface::allInterfaces();
|
|
if (hal.isEmpty())
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_generic,
|
|
"Network Config: NO HOST ADDRESSES");
|
|
cb->addItem("<No Interface>");
|
|
cb->setEnabled(false);
|
|
}
|
|
else
|
|
{
|
|
foreach(QNetworkInterface nif, hal)
|
|
{
|
|
//QList<QHostAddress> nhal=nif.allAddresses();
|
|
QList<QNetworkAddressEntry> nhal=nif.addressEntries();
|
|
foreach(QNetworkAddressEntry aentry, nhal)
|
|
{
|
|
bool private_subnet=false;
|
|
|
|
QHostAddress a=aentry.ip();
|
|
|
|
if (!(a.toString().startsWith("192.168") ||
|
|
a.toString().startsWith("169.254") ||
|
|
a.toString().startsWith("127.")))
|
|
continue;
|
|
|
|
cb->addItem(QString("%1 (%2) [%3]").arg(nif.humanReadableName()).arg(a.toString()).arg(nif.index()), a.toString());
|
|
int currentIndex=cb->count()-1;
|
|
//if (a.toString().startsWith("192.168.0") ||a.toString().startsWith("192.168.2"))
|
|
if (a.toString().startsWith(preferedNetwork))
|
|
{
|
|
prefered_index=currentIndex;
|
|
private_subnet=true;
|
|
privateSubnet=privateSubnet;
|
|
}
|
|
cb->setItemData(currentIndex, private_subnet, Qt::UserRole+1);
|
|
cb->setItemData(currentIndex, nif.index(), Qt::UserRole+2);
|
|
|
|
//ui->comboBoxInterface->seIif (nif.flags() & QNetworkInterface::IsUp)
|
|
}
|
|
}
|
|
if (prefered_index)
|
|
cb->setCurrentIndex(prefered_index);
|
|
}
|
|
return hi.hostName();
|
|
}
|
|
|
|
#define MAX_TARGETS 64
|
|
|
|
struct targets_t
|
|
{
|
|
unsigned int valid;
|
|
QgGrifoDownloadSite sites[MAX_TARGETS];
|
|
};
|
|
|
|
static targets_t targets;
|
|
|
|
struct PgmSteps
|
|
{
|
|
QLabel* lbl;
|
|
QCheckBox* chk;
|
|
};
|
|
static PgmSteps pgmSteps[10];
|
|
|
|
QgGrifoBeamUpForm::QgGrifoBeamUpForm(QWidget *parent) :
|
|
QWidget(parent),
|
|
props(QgGrifoBeamupProperties::instance()),
|
|
ui(new Ui::QgGrifoBeamUpForm),
|
|
settings("./grifo_beamup.ini", QSettings::IniFormat)
|
|
{
|
|
IS_TFTP_CONNECTED = false;
|
|
|
|
fileToWrite.validConfig = false;
|
|
|
|
QStyle* st=QApplication::style();
|
|
|
|
ui->setupUi(this);
|
|
|
|
ui->tbRefresh->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
|
|
ui->tbRefresh->setIcon(st->standardIcon(QStyle::SP_DriveNetIcon)
|
|
);
|
|
ui->tbRefresh->setText("Connect");
|
|
|
|
ui->tbFileSelect->setIcon(st->standardIcon(QStyle::SP_FileIcon)
|
|
);
|
|
|
|
ui->tbGo->setIcon(st->standardIcon(QStyle::SP_ArrowUp)
|
|
);
|
|
|
|
ui->tbDropSelect->setIcon(st->standardIcon(QStyle::SP_FileDialogNewFolder)
|
|
);
|
|
|
|
ui->tbSettings->setIcon(st->standardIcon(QStyle::SP_FileDialogListView)
|
|
);
|
|
|
|
ui->tbFileInfo->setIcon(st->standardIcon(QStyle::SP_FileDialogInfoView));
|
|
|
|
ui->tbHistory->setIcon(st->standardIcon(QStyle::SP_DirHomeIcon)
|
|
);
|
|
|
|
entitiesForm=new QgGrifoDownloadEntitiesForm;
|
|
|
|
int ipos=ui->verticalLayout->indexOf(ui->placeholder);
|
|
ui->verticalLayout->insertWidget(ipos, entitiesForm);
|
|
ui->placeholder->setVisible(false);
|
|
|
|
ui->leMsg->setMaximumBlockCount(5000);
|
|
|
|
entitiesForm->setVisible(false);
|
|
|
|
{
|
|
QHostInfo hi=QHostInfo::fromName(QHostInfo::localHostName());
|
|
QString host=QString("Host: %1").arg(hi.hostName());
|
|
|
|
ui->hostName->setText(host);
|
|
}
|
|
|
|
ui->progressBar->setValue(0);
|
|
ui->progressBar->setEnabled(false);
|
|
ui->progressBar->setTextVisible(false);
|
|
//setState(1);
|
|
|
|
fileSelector.setObjectName("GrifoBeamUpFileSelector");
|
|
fileSelector.setOption(QFileDialog::ReadOnly, true);
|
|
|
|
fileSelector.setViewMode(QFileDialog::Detail);
|
|
fileSelector.setNameFilters(
|
|
QStringList()<<"archive (*.zip)"<<"Binary (*.bin)"<<"ELF (*.elf *.out)"<<"Any files (*)");
|
|
|
|
connect(ui->tbFileSelect, &QToolButton::clicked, this,
|
|
[this](bool)
|
|
{
|
|
QString tmp=fileSelector.directory().absolutePath();
|
|
fileSelector.setOption(QFileDialog::ReadOnly, true);
|
|
fileSelector.setFileMode(QFileDialog::AnyFile);
|
|
fileSelector.setDirectory(tmp);
|
|
|
|
if (fileSelector.exec())
|
|
{
|
|
ui->leFile->setText(fileSelector.selectedFiles().at(0));
|
|
//stateReady();
|
|
selectByFile(fileSelector.selectedFiles().at(0));
|
|
}
|
|
}
|
|
);
|
|
connect(ui->tbDropSelect, &QToolButton::clicked, this,
|
|
[this](bool)
|
|
{
|
|
fileSelector.setFileMode(QFileDialog::Directory);
|
|
if (fileSelector.exec())
|
|
{
|
|
selectWatchDir(fileSelector.selectedFiles().at(0));
|
|
}
|
|
});
|
|
|
|
connect(&fileWatcher, &QFileSystemWatcher::directoryChanged, this, &QgGrifoBeamUpForm::updateWatchedDirectory);
|
|
connect(&fileWatcher, &QFileSystemWatcher::fileChanged, this, &QgGrifoBeamUpForm::updateWatchedFile);
|
|
|
|
connect(ui->tbGo, &QToolButton::clicked, this, &QgGrifoBeamUpForm::uploadGo);
|
|
#if 0
|
|
connect(&tftp, &QgGrifoBeamUpTftp::progressInfo, this,
|
|
[this](int n, const QString& msg)
|
|
{
|
|
if (n==-1)
|
|
ui->progressBar->setRange(0, 0);
|
|
else
|
|
{
|
|
ui->progressBar->setRange(0, 100);
|
|
ui->progressBar->setValue(n);
|
|
}
|
|
ui->progressLabel->setText(msg);
|
|
});
|
|
connect(&tftp, &QgGrifoBeamUpTftp::sendTerminated, this,
|
|
[this]()
|
|
{
|
|
ui->progressBar->setRange(0, 100);
|
|
ui->progressBar->setValue(100);
|
|
showMessage("Completed"); //ui->progressLabel->setText("Completed");
|
|
stateReady();
|
|
});
|
|
|
|
connect(&tftp, &QgGrifoBeamUpTftp::transferError, this,
|
|
[this](int code, const QString& msg)
|
|
{
|
|
showMessage(QString("%1 (%2)").arg(msg).arg(code)); //ui->progressLabel->setText(QString("%1 (%2)").arg(msg).arg(code));
|
|
ui->progressBar->reset();
|
|
ui->progressBar->setRange(0, 100);
|
|
ui->progressBar->setValue(0);
|
|
ui->progressBar->setEnabled(false);
|
|
QMessageBox::critical(this, QString(), QString("Transfer Error: %1 (%2)").arg(msg).arg(code));
|
|
stateReady();
|
|
});
|
|
|
|
connect(&tftp, &QgGrifoBeamUpTftp::serverHello, this,
|
|
[this](unsigned int ip, int port, const QString& msg)
|
|
{
|
|
ui->leMsg->appendPlainText(msg); //setText(msg);
|
|
serverHello(ip, port, msg);
|
|
});
|
|
#endif
|
|
|
|
//general configuration of app
|
|
{
|
|
QSettings& s=settings;//("./grifo_beamup.ini", QSettings::IniFormat);
|
|
s.beginGroup("GrifoBeamUp");
|
|
QString prefnet=s.value("preferedNetwork", QString("$127.0.0")).toString();
|
|
if (prefnet.startsWith('$'))
|
|
prefnet=prefnet.remove('$');
|
|
|
|
probeNetworks(prefnet, ui->cbNetwork);
|
|
|
|
QgNetworkInterface::setNetworkIP(prefnet);
|
|
|
|
ui->leFile->setText(s.value("file", QString()).toString());
|
|
fileSelector.restoreState(s.value("fileselector").toByteArray());
|
|
s.endGroup();
|
|
}
|
|
|
|
|
|
#if 0
|
|
tftp.bind(QHostAddress(QgNetworkInterface::networkIP()));
|
|
|
|
ui->tbNetwork->setText(netDlg->hostNetworkName());
|
|
QgNetworkInterface::setNetworkIP(netDlg->hostAddress());
|
|
|
|
connect(ui->tbNetwork, &QToolButton::clicked, this,
|
|
[this](bool)
|
|
{
|
|
netDlg->exec();
|
|
if (netDlg->result()==QDialog::Accepted)
|
|
{
|
|
QgNetworkInterface::setNetworkInterface(QHostAddress(netDlg->hostAddress()));
|
|
ui->tbNetwork->setText(netDlg->hostNetworkName()); //QgNetworkInterface::networkIP());
|
|
}
|
|
});
|
|
#endif
|
|
|
|
connect(ui->tbRefresh, &QToolButton::clicked, this,
|
|
[this](bool)
|
|
{
|
|
refreshServers();
|
|
});
|
|
|
|
connect(ui->tbSettings, &QToolButton::clicked, this,
|
|
[this](bool)
|
|
{
|
|
static QgPropertyDialog dlg(&props, this);
|
|
dlg.show();
|
|
|
|
});
|
|
|
|
props.restoreSettings(settings);
|
|
|
|
if (!props.property("lastDirectory").toString().isEmpty())
|
|
fileSelector.setDirectory(props.property("lastDirectory").toString());
|
|
|
|
pingTimer.setSingleShot(true);
|
|
pingTimer.setInterval(2000);
|
|
connect(&pingTimer, &QTimer::timeout, this,
|
|
[this]()
|
|
{
|
|
ui->tbRefresh->setEnabled(true);
|
|
});
|
|
|
|
ui->cbTarget->setDuplicatesEnabled(false);
|
|
ui->cbPartition->setDuplicatesEnabled(false);
|
|
|
|
ui->cbTarget->addItem(QgNetworkInterface::networkIP()+":"+QString("%1").arg(props.property("tftpFirstPort").toInt()));
|
|
|
|
connect(entitiesForm, &QgGrifoDownloadEntitiesForm::itemSelected, this,
|
|
[this](void*xs, void*xp)
|
|
{
|
|
bsk_download_site_t* s=(bsk_download_site_t*)xs;
|
|
bsk_download_partition_t* p=(bsk_download_partition_t*)xp;
|
|
updateSelected(s, p);
|
|
});
|
|
|
|
stateReady();
|
|
|
|
/*
|
|
* Configuration target from file
|
|
*/
|
|
|
|
flashTargets = flashTargetClass::instance();
|
|
|
|
if (flashTargets->readTargets())
|
|
{
|
|
//QStringList list = flashTargets->getInfoLists();
|
|
//ui->cbTgt->addItems(list);
|
|
setTargetOnScreen();
|
|
|
|
default_ip = flashTargets->getDefIp();
|
|
}
|
|
else
|
|
{
|
|
qDebug()<<"Error read targets file config!";
|
|
}
|
|
|
|
//readConfigFile();
|
|
|
|
programmer=new FgpaProgrammer;
|
|
|
|
connect(ui->leFile, &QLineEdit::editingFinished, this,
|
|
[this]()
|
|
{
|
|
selectByFile(ui->leFile->text());
|
|
});
|
|
|
|
selectWatchDir(props.property("watchedDirectory").toString());
|
|
|
|
setAcceptDrops(true);
|
|
|
|
ui->groupBox->setEnabled(false);
|
|
|
|
connect(entitiesForm, &QgGrifoDownloadEntitiesForm::fileDroppped, this, [this](QTreeWidgetItem* i, const QString& name)
|
|
{
|
|
selectByFile(name, i);
|
|
});
|
|
|
|
{
|
|
QGridLayout* g=ui->gridLayout_2;
|
|
for(int i=0; i<7; ++i)
|
|
{
|
|
pgmSteps[i].chk=new QCheckBox;
|
|
if (i<1)
|
|
pgmSteps[i].chk->setChecked(false);
|
|
else
|
|
pgmSteps[i].chk->setChecked(true);
|
|
|
|
pgmSteps[i].lbl=new QLabel("...");
|
|
g->addWidget(pgmSteps[i].chk, i+1, 0);
|
|
g->addWidget(pgmSteps[i].lbl, i+1, 2);
|
|
}
|
|
}
|
|
|
|
connect(programmer, &FgpaProgrammer::statusChanged, this, &QgGrifoBeamUpForm::statusUpdated, Qt::QueuedConnection);
|
|
|
|
programmer->setSimulate(ui->cbSimulate->isChecked());
|
|
programmer->setSRIOMemory(ui->cb_TargetAddress->isChecked());
|
|
|
|
_dbHistory = dbHistory::instance();
|
|
|
|
QHostInfo hi=QHostInfo::fromName(QHostInfo::localHostName());
|
|
_dbHistory->setParam(hi.hostName());
|
|
_dbHistory->refreshList();
|
|
|
|
ui->groupBox_3->hide();
|
|
ui->groupBox_2->hide();
|
|
ui->label_2->hide();
|
|
ui->leDir->hide();
|
|
ui->tbDropSelect->hide();
|
|
|
|
ui->tbGo->hide();
|
|
ui->cbPartition->hide();
|
|
ui->cbTarget->hide();
|
|
|
|
ui->lbServer->hide();
|
|
|
|
statusBar = new QStatusBar(this);
|
|
ui->verticalLayout->addWidget(statusBar);
|
|
statusBar->showMessage("Ready", 3000);
|
|
|
|
ui->leMsg->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
|
|
|
ui->tabWidget->setCurrentIndex(1);
|
|
|
|
ui->btnWrite->setStyleSheet("QPushButton { background-color: green; color:white; }\n"
|
|
"QPushButton:enabled { background-color: rgb(0,200,0); color:white; }\n");
|
|
|
|
TMP_FOLDER = QApplication::applicationDirPath() + "/tmp";
|
|
}
|
|
|
|
QgGrifoBeamUpForm::~QgGrifoBeamUpForm()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::updateSelected(const bsk_download_site_t* site,const bsk_download_partition_t* p)
|
|
{
|
|
if (!site)
|
|
return;
|
|
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("select: %1 %2").arg(site->name).arg(p->name));
|
|
|
|
ShowTargetInfo(true);
|
|
}
|
|
|
|
#include <QProgressBar>
|
|
|
|
void QgGrifoBeamUpForm::selectByFile(const QString& fname, QTreeWidgetItem*)
|
|
{
|
|
/*
|
|
* in base al file selezionato devo capire queste cose
|
|
*
|
|
* le flash da programmare sono EIF 1 con 2 flash da 128 mega 0x73, EIF 2 con altre due flash da 128 mega ????
|
|
* DFE 1 con 2 flash da 256 mega 0x16, DFE 2 con altre due flash da 256 mega ????
|
|
* Quindi in totale sono 8 flash da programmare.
|
|
*
|
|
* 1 se si tratta di un file binario devo chiedere su quale flash devo programmarlo in maniera selettiva tra le 8 disponibili, in quanto
|
|
* deve essere salvato su di una flash sola tra quelle disponibili, quindi occorre chiedere su quale scheda e se primaria o secondaria
|
|
*
|
|
* 2 se si tratta di un file zip, occorre verificare che si tratti di un file zip valido, con dentro i due file binari corretti, devi chiedere
|
|
* su quale scheda devo andare senza chiedere primaria/secondaria in quanto che ne sono due da caricare.
|
|
* DA FARE - Potrei chiedere se devo caricare entrambe le flash oppure sono una delle due
|
|
*
|
|
*
|
|
* IMPORTANTE:
|
|
* nell'history, inserire un bottone che mi permetta di recuperare una vecchia installazione per riprocessarla.
|
|
* Per semplificare la fase di recupero dovrei poter selezionare se rifare la programmazione su entrambe le flash, oppure solo su primaria/secondaria.
|
|
* */
|
|
|
|
QFileInfo finfo(fname);
|
|
QString n=finfo.fileName();
|
|
|
|
resetFileToWrite();
|
|
|
|
if (finfo.completeSuffix()=="zip")
|
|
{
|
|
// file zip with 2 binary file and xml info file.
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
"file zip with info");
|
|
|
|
if (!extractInfoFromZip(fname))
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_generic,
|
|
"Config present into zip file is not valid!");
|
|
}
|
|
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("target fpga-flash : %1").arg(fileToWrite.targetFlash));
|
|
|
|
entitiesForm->setUnCheckedAll();
|
|
|
|
//for every targets read from configuration files
|
|
for (int i = 0; i<flashTargets->countTarget(); i++)
|
|
{
|
|
targetItem tgt = flashTargets->getTarget(i);
|
|
if (tgt.filePrefix==fileToWrite.targetFlash)
|
|
{
|
|
entitiesForm->setChecked(tgt.name);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if (finfo.completeSuffix()=="bin")
|
|
{
|
|
// file binary, without info
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
"file binary without info");
|
|
|
|
}
|
|
}
|
|
|
|
//*************************************************
|
|
// connect to server selected from combobox
|
|
//*************************************************
|
|
void QgGrifoBeamUpForm::refreshServers()
|
|
{
|
|
if (ui->cbNetwork->count()<1)
|
|
return;
|
|
|
|
if (ui->cbNetwork->isEnabled())
|
|
{
|
|
QString ip=ui->cbNetwork->itemData(ui->cbNetwork->currentIndex()).toString();
|
|
|
|
bool match=ip.startsWith("127.0.", Qt::CaseInsensitive);
|
|
|
|
QString msg = "";
|
|
|
|
if (match)
|
|
{
|
|
tftp.bindRemote(QHostAddress("127.0.0.1"), TFTP_DEFAULT_PORT);
|
|
//ui->cbTarget->setCurrentText(QString("%1:%2").arg("127.0.0.1").arg(TFTP_DEFAULT_PORT));
|
|
ui->lbServer->setText(QString("TFTP server: %1:%2").arg("127.0.0.1").arg(TFTP_DEFAULT_PORT));
|
|
msg = QString("Connected to TFTP server at %1:%2").arg("127.0.0.1").arg(TFTP_DEFAULT_PORT);
|
|
}
|
|
else
|
|
{
|
|
tftp.bindRemote(QHostAddress(default_ip), TFTP_DEFAULT_PORT);
|
|
tftp.fixServerBug((default_ip==DSP_ETHERNET_IP) ? 2 : 0);
|
|
//ui->cbTarget->setCurrentText(QString("%1:%2").arg(default_ip).arg(TFTP_DEFAULT_PORT));
|
|
ui->lbServer->setText(QString("TFTP server: %1:%2").arg(default_ip).arg(TFTP_DEFAULT_PORT));
|
|
msg = QString("Connected to TFTP server at %1:%2").arg(default_ip).arg(TFTP_DEFAULT_PORT);
|
|
}
|
|
|
|
QgNetworkInterface::setNetworkInterface(QHostAddress(ip));
|
|
|
|
QgNetworkInterface::setNetworkIP(ip);
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_tftp,
|
|
QString("%1").arg(QgNetworkInterface::networkIP()));
|
|
tftp.bind(QHostAddress(QgNetworkInterface::networkIP()));
|
|
|
|
IS_TFTP_CONNECTED = true;
|
|
|
|
ui->cbNetwork->setEnabled(false);
|
|
//ui->groupBox->setEnabled(true);
|
|
|
|
ui->lbServer->show();
|
|
|
|
addToLog(msg);
|
|
|
|
statusBar->showMessage(msg);
|
|
}
|
|
|
|
ui->tbRefresh->setEnabled(false);
|
|
|
|
programmer->setTftp(&tftp);
|
|
programmer->setHistory(_dbHistory);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::serverHello(unsigned int /*ip*/, int /*port*/, const QString &/*msg*/)
|
|
{
|
|
#if 0
|
|
QgGrifoDownloadSite* s=&targets.sites[targets.valid];
|
|
|
|
memset(&s->site, 0, sizeof s->site);
|
|
bsk_download_site_t* site=&s->site;
|
|
|
|
int r=bsk_tftp_mfs_decode_site(site, msg.toLatin1().constData());
|
|
|
|
site->media_address=ip;
|
|
site->media_port=port;
|
|
s->tgt=0;
|
|
|
|
if (r==0)
|
|
{
|
|
TgtMatch* tgt=tgtMatchSet.lookupCSCI(site->name, site->address);
|
|
if (tgt)
|
|
s->tgt=tgt; //appName=tgt->appName;
|
|
|
|
entitiesForm->addSite(s);
|
|
QHostAddress ha(site->media_address);
|
|
QString n=QString("%1:%2/%3").arg(ha.toString()).arg(site->media_port).arg(site->name);
|
|
ui->cbTarget->addItem(n, (quint64)site);
|
|
|
|
++targets.valid;
|
|
|
|
for(int i=0; i<bsk_download_site_t::k_max_partitions; ++i)
|
|
{
|
|
if (site->partitions[i].name[0]==0)
|
|
break;
|
|
|
|
QString queryStr=QString("$PGM:%1/$version$").arg(site->partitions[i].name);
|
|
tftp.queryVersion(ip, port, queryStr);
|
|
}
|
|
pingTimer.start();
|
|
}
|
|
entitiesForm->setVisible(true);
|
|
#endif
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::partitionUpdate(unsigned int /*ip*/, int /*port*/, const QString& /*msg*/)
|
|
{
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::saveSettings()
|
|
{
|
|
{
|
|
QSettings& s=settings; //("./grifo_beamup.ini", QSettings::IniFormat);
|
|
s.beginGroup("GrifoBeamUp");
|
|
s.setValue("preferedNetwork", QString('$')+QgNetworkInterface::networkIP());
|
|
s.setValue("file", ui->leFile->text());
|
|
s.setValue("fileselector", fileSelector.saveState());
|
|
props.setProperty("lastDirectory", fileSelector.directory().absolutePath());
|
|
s.setValue("dirHistory", fileSelector.history());
|
|
s.endGroup();
|
|
|
|
props.saveSettings(settings);
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::updateWatchedDirectory(const QString& path)
|
|
{
|
|
QDir dir(path);
|
|
QStringList currentList=dir.entryList();
|
|
QStringList changed;
|
|
|
|
foreach(QString s, currentList)
|
|
{
|
|
bool hit=watchedFiles.contains(s);
|
|
if (!hit)
|
|
changed.append(s);
|
|
}
|
|
|
|
watchedFiles=currentList;
|
|
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("Directory update: %1 %2").arg(path).arg(changed.count()));
|
|
|
|
if (changed.size()>0)
|
|
{
|
|
for(int i=0; i<changed.size(); ++i)
|
|
{
|
|
addPendingList(dir.absoluteFilePath(changed.at(0)));
|
|
//ui->leFile->setText(dir.absoluteFilePath(changed.at(0)));
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::updateWatchedFile(const QString& path)
|
|
{
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("File update: %1").arg(path));
|
|
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::setState(int s)
|
|
{
|
|
state=s;
|
|
bool enable=false;
|
|
if (state==0)
|
|
{
|
|
enable=true;
|
|
//ui->cbNetowrkSelection->setEnabled(false);
|
|
ui->tbGo->setText("Upload...");
|
|
}
|
|
else
|
|
ui->tbGo->setText("Break...");
|
|
|
|
//ui->tbNetwork->setEnabled(enable);
|
|
ui->tbRefresh->setEnabled(enable);
|
|
//ui->tbGo->setEnabled(enable);
|
|
ui->tbFileSelect->setEnabled(enable);
|
|
ui->tbDropSelect->setEnabled(enable);
|
|
ui->leFile->setEnabled(enable);
|
|
//ui->leDir->setEnabled(enable);
|
|
ui->cbPartition->setEnabled(enable);
|
|
ui->cbTarget->setEnabled(enable);
|
|
|
|
entitiesForm->setEnabled(enable);
|
|
|
|
if (enable)
|
|
{
|
|
if (ui->progressBar->minimum()==ui->progressBar->maximum())
|
|
{
|
|
ui->progressBar->setRange(0, 100);
|
|
ui->progressBar->setValue(0);
|
|
ui->progressBar->setEnabled(false);
|
|
}
|
|
}
|
|
ui->groupBox->setEnabled(enable);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::stateReady()
|
|
{
|
|
setState(0);
|
|
if (pendingList.count())
|
|
{
|
|
QString tmp=pendingList.at(0);
|
|
pendingList.pop_front();
|
|
if (tmp.isEmpty())
|
|
{
|
|
return;
|
|
}
|
|
ui->leFile->setText(tmp);
|
|
selectByFile(tmp);
|
|
uploadGo();
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::stateBusy()
|
|
{
|
|
setState(1);
|
|
}
|
|
|
|
|
|
void QgGrifoBeamUpForm::uploadGo()
|
|
{
|
|
/*if (state!=0)
|
|
{
|
|
QMessageBox::question(this, QString(), QString("Break operation?"));
|
|
return;
|
|
}
|
|
int n=ui->cbTarget->currentIndex();
|
|
|
|
//controlla se è stato selezionato un indirizzo target valido
|
|
if (n<0)
|
|
{
|
|
ui->progressLabel->setText("Target not selected");
|
|
ui->leMsg->appendPlainText(QString("Target not selected"));
|
|
QMessageBox::critical(this, QString(), QString("Target not selected"));
|
|
return;
|
|
}
|
|
|
|
//controlla se il file da spedire è leggibile
|
|
QFileInfo finfo(ui->leFile->text());
|
|
if (!finfo.isReadable())
|
|
{
|
|
ui->leMsg->appendPlainText(QString("File not readable"));
|
|
QMessageBox::critical(this, QString(), QString("File not readable"));
|
|
return;
|
|
}
|
|
|
|
//controlla se l'indirizzo ftp del server a cui collegarci è valido
|
|
QString tgtStr=ui->cbTarget->currentText();
|
|
tgtStr="ftp://"+ui->cbTarget->currentText();
|
|
QUrl url(tgtStr);
|
|
if (!url.isValid())
|
|
{
|
|
QString msg=QString("Invalid URL %1").arg(tgtStr);
|
|
ui->progressLabel->setText(msg);
|
|
ui->leMsg->appendPlainText(msg);
|
|
QMessageBox::critical(this, QString(), msg);
|
|
return;
|
|
}
|
|
|
|
//apertura connessione con server tftp remoto
|
|
QHostAddress ha(url.host());
|
|
int port=url.port();
|
|
tftp.bindRemote(ha, port);
|
|
|
|
//ui->progressLabel->setText(tmp);
|
|
{
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("Upload to %1 %2@%3:%4...").arg(tgtStr).arg("?").arg(ha.toString()).arg(port));
|
|
}
|
|
|
|
QString partName;
|
|
n=ui->cbPartition->currentIndex();
|
|
if (n>=0)
|
|
{
|
|
unsigned long long p=ui->cbPartition->currentData().toULongLong();
|
|
if (p && !ui->cbPartition->currentText().isEmpty())
|
|
partName="$PGM:"+ui->cbPartition->currentText()+"/%1";
|
|
}
|
|
|
|
if (partName=="")
|
|
{
|
|
partName ="$PGM:uploadfile/%1";
|
|
}
|
|
QString fnameStr=finfo.fileName();
|
|
#if 0
|
|
{
|
|
QZipReader zip(ui->leFile->text());
|
|
QList<QZipReader::FileInfo> zlst=zip.fileInfoList();
|
|
if(zlst.size())
|
|
{
|
|
QString tmpname=zlst.at(0).filePath;
|
|
//standardDialog()->setFileInfo(QString("%1 (%2)").arg(tmpname).arg(params.simplifiedFileName));
|
|
fnameStr+="("+tmpname+")";
|
|
}
|
|
}
|
|
#endif
|
|
QString opmsg=QString("%1 -> %2/%3").arg(fnameStr).arg(ui->cbTarget->currentText()).arg(partName);
|
|
|
|
showMessage(opmsg);
|
|
|
|
int qr=QMessageBox::question(this, QString(), opmsg, QMessageBox::Yes|QMessageBox::No|QMessageBox::Abort);
|
|
if (qr!=QMessageBox::Yes)
|
|
{
|
|
if (qr==QMessageBox::Abort)
|
|
pendingList.clear();
|
|
return;
|
|
}
|
|
|
|
//ui->progressLabel->setText("Upload start...");
|
|
|
|
bool ok=tftp.sendFile(ui->leFile->text(), partName);
|
|
|
|
//ui->tbNetwork->setEnabled(false);
|
|
|
|
ui->lbOperation->setText(opmsg);
|
|
if (ok)
|
|
{
|
|
stateBusy();
|
|
//ui->tbGo->setEnabled(false);
|
|
ui->progressBar->reset();
|
|
ui->progressBar->setRange(0, 0);
|
|
ui->progressBar->setEnabled(true);
|
|
}*/
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::dragEnterEvent(QDragEnterEvent * event)
|
|
{
|
|
if (event->mimeData()->hasUrls())
|
|
{
|
|
QList<QUrl> lst=event->mimeData()->urls();
|
|
if ((lst.size()>0) && lst.size()<10)
|
|
{
|
|
//if (lst.at(0).isLocalFile())
|
|
event->acceptProposedAction();
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::dropEvent(QDropEvent * event)
|
|
{
|
|
QList<QUrl> lst=event->mimeData()->urls();
|
|
if (lst.size()>0)
|
|
{
|
|
for(int i=0; i<lst.size(); ++i)
|
|
{
|
|
if (lst.at(i).isLocalFile())
|
|
{
|
|
//ui->leFile->setText(lst.at(0).path());
|
|
//selectByFile(lst.at(0).path());
|
|
|
|
addPendingList(lst.at(i).toLocalFile());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::selectWatchDir(const QString& dName)
|
|
{
|
|
if (dName.isEmpty())
|
|
return;
|
|
|
|
QDir dir(dName);
|
|
if (!dir.isReadable())
|
|
return;
|
|
|
|
ui->leDir->setText(dName);
|
|
fileWatcher.removePaths(fileWatcher.directories());
|
|
fileWatcher.addPath(dName);
|
|
props.setProperty("watchedDirectory", dName);
|
|
watchedFiles.clear();
|
|
watchedFiles=dir.entryList(QDir::Files|QDir::NoDotAndDotDot);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::addPendingList(const QString& file)
|
|
{
|
|
pendingList.append(file);
|
|
|
|
if (state==0)
|
|
{
|
|
stateReady();
|
|
//ui->leFile->setText(lst.at(0).path());
|
|
selectByFile(file); //lst.at(0).path());
|
|
//uploadGo();
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::showMessage(const QString& msg)
|
|
{
|
|
//ui->progressLabel->setText(msg);
|
|
//ui->leMsg->appendPlainText(msg);
|
|
addToLog(msg);
|
|
}
|
|
|
|
QString QgGrifoBeamUpForm::ShowFileInfo(const QString& fname, bool popup)
|
|
{
|
|
QFileInfo finfo(fname);
|
|
if (!finfo.exists())
|
|
{
|
|
QMessageBox::critical(0, "ERROR open file", "File <p/>"+fname +"<p/> is not available.");
|
|
return "";
|
|
}
|
|
|
|
DownloadableFile df;
|
|
df.open(fname);
|
|
BinaryFileInfo bfi=df.info();
|
|
BinaryInfo bi=bfi.binaryInfo;
|
|
|
|
QString infoText="";
|
|
|
|
if (finfo.completeSuffix()=="zip")
|
|
{
|
|
if (!extractInfoFromZip(fname))
|
|
return "";
|
|
|
|
infoText=
|
|
"File: "+bfi.filename+"<p/>\n"
|
|
+"File CRC32: "+QString("%1").arg(bfi.zip_crc32, 0, 16).toUpper()+"<p/>\n";
|
|
|
|
infoText+=
|
|
+" target flash: <b>" +fileToWrite.targetFlash +"</b><p/>\n"
|
|
+" primary file: <b>" +QFileInfo( fileToWrite.primaryFile ).fileName() +"</b><p/>\n"
|
|
+" primary file MD5: <b>" +fileToWrite.primaryMD5 +"</b><p/>\n"
|
|
+" primary file: <b>" +QFileInfo( fileToWrite.secondaryFile ).fileName() +"</b><p/>\n"
|
|
+" primary file MD5: <b>" +fileToWrite.secondaryMD5 +"</b><p/>\n";
|
|
|
|
entitiesForm->setUnCheckedAll();
|
|
|
|
//for every targets read from configuration files
|
|
for (int i = 0; i<flashTargets->countTarget(); i++)
|
|
{
|
|
targetItem tgt = flashTargets->getTarget(i);
|
|
if (tgt.filePrefix==fileToWrite.targetFlash)
|
|
{
|
|
entitiesForm->setChecked(tgt.name);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if (finfo.completeSuffix()=="bin")
|
|
{
|
|
infoText=
|
|
"File: "+bfi.filename+"<p/>\n"
|
|
+"  Size: "+QString("%1").arg(bfi.uncompressed_size)+" ("+QString("%1").arg(bfi.compressed_size)+")<p/>\n"
|
|
+"  Container hash: "+bfi.file_md5+"<p/><p/>\n"
|
|
+"File CRC32: "+QString("%1").arg(bfi.zip_crc32, 0, 16).toUpper()+"<p/>\n";
|
|
|
|
infoText+=
|
|
" Name: <b>"+bi.m_name+"</b><p/>\n"
|
|
+" Version: <b>"+bi.m_version+" "+bi.m_bid+"</b><p/>\n"
|
|
+" Date: <b>"+bi.m_date+"</b><p/>\n"
|
|
+" IBC: "+bi.m_ibc+"<p/>\n"
|
|
+" P/N: "+bi.m_pn+"<p/>\n"
|
|
+" Part Type: "+bi.m_partType+"<p/>\n"
|
|
+" Architecture: "+bi.m_pn+" - "+bi.m_archName+"<p/>\n"
|
|
+" Format: "+bi.m_fmtName+"<p/>\n"
|
|
+" Generator: "+bi.m_generator+"<p/>\n"
|
|
//+" Version: "+bi.m_bid+"<p/>\n"
|
|
+" Info: "+bi.m_usr+"<p/>\n"
|
|
+" Host: "+bi.m_host+"<p/>\n"
|
|
+" Signature: "+bi.m_md5+"<p/>\n";
|
|
|
|
fileToWrite.validConfig = false;
|
|
}
|
|
|
|
|
|
if (popup)
|
|
QMessageBox::information(0, "File: "+bfi.sourcefile, infoText);
|
|
return infoText;
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_tbFileInfo_clicked()
|
|
{
|
|
ShowFileInfo(ui->leFile->text());
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::programWithProfile(bool checked)
|
|
{
|
|
/*QString address = QString("0x%1-0x%2").arg(profile.user_address_start_area, 0, 16).arg(profile.user_address_stop_area, 0, 16);
|
|
QString srio = QString("%1@%2:%3").arg(profile.slotAddress).arg(profile.ip).arg(profile.port);
|
|
int spi = int(profile.spiport);
|
|
|
|
_dbHistory->addNewFile(profile.FileToSend,
|
|
db_error_no_error,
|
|
profile.fName,
|
|
db_status_started,
|
|
address,
|
|
srio,
|
|
spi);*/
|
|
|
|
if (ui->cbSimulate->checkState()==Qt::Checked)
|
|
{
|
|
//è simulazione con dati di test
|
|
if (checked)
|
|
programmer->start(1, ui->sbSectorSize->value(), ui->sbBase->value());
|
|
else
|
|
programmer->start(0, ui->sbSectorSize->value(), ui->sbBase->value());
|
|
}
|
|
else
|
|
{
|
|
//non è simulazione
|
|
programmer->start(profile);
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::
|
|
on_btnStart_clicked(bool checked)
|
|
{
|
|
//indivisuare il profilo da usare per le operazione di programmazione
|
|
if (!getProfile(ui->sbSectorSize->value(),ui->sbBase->value()))
|
|
{
|
|
//profile not valid to program
|
|
return;
|
|
}
|
|
|
|
profile.writeRamp = (ui->cbWriteRamp->checkState()==Qt::Checked);
|
|
profile.verifyFinal = (ui->cbVerifyAll->checkState()==Qt::Checked);
|
|
profile.verifySector = (ui->cbVerifySector->checkState()==Qt::Checked);
|
|
|
|
if (fileToWrite.validConfig)
|
|
{
|
|
// spi port primary 0
|
|
profile.spiport = primarySpiPort;
|
|
profile.FileToSend = fileToWrite.primaryFile;
|
|
profile.FileToSend2 = fileToWrite.secondaryFile;
|
|
profile.write2Flash = true;
|
|
|
|
QString address = QString("0x%1 - 0x%2").arg(profile.user_address_start_area, 0, 16). arg(profile.user_address_stop_area, 0, 16);
|
|
QString msg = QString(STR_START_WORK).arg(fileToWrite.targetFlash).arg("primary").arg(address);
|
|
addToLog(msg);
|
|
|
|
/*//"... on %1 - spi port: %2 - address: %3."
|
|
|
|
programWithProfile(checked);
|
|
|
|
// spi port secondary 1
|
|
profile.spiport = secondarySpiPort;
|
|
profile.FileToSend = fileToWrite.secondaryFile;*/
|
|
|
|
address = QString("0x%1 - 0x%2").arg(profile.user_address_start_area, 0, 16). arg(profile.user_address_stop_area, 0, 16);
|
|
msg = QString(STR_START_WORK).arg(fileToWrite.targetFlash).arg("secondary").arg(address);
|
|
addToLog(msg);
|
|
|
|
programWithProfile(checked);
|
|
}
|
|
else
|
|
{
|
|
profile.FileToSend = ui->leFile->text();
|
|
profile.FileToSend2 = "";
|
|
profile.write2Flash = false;
|
|
|
|
QString msg = "";
|
|
QString address = QString("0x%1 - 0x%2").arg(profile.user_address_start_area, 0, 16). arg(profile.user_address_stop_area, 0, 16);
|
|
|
|
//controllo se si tratta di fpga dell'rfif
|
|
if (!profile.isFpgaRFIF)
|
|
{
|
|
//Se non lo è allora devo selezionare il canale spi dove installare
|
|
QInputDialog qDialogSpiPort ;
|
|
|
|
QStringList items;
|
|
items << QString("Primary");
|
|
items << QString("Secondary");
|
|
|
|
qDialogSpiPort.setComboBoxItems(items);
|
|
qDialogSpiPort.setWindowTitle("SPI");
|
|
qDialogSpiPort.setLabelText("Select spi-port: ");
|
|
|
|
if (qDialogSpiPort.exec())
|
|
{
|
|
QString value = qDialogSpiPort.textValue();
|
|
if (value=="Primary")
|
|
{
|
|
profile.spiport = primarySpiPort;
|
|
msg = QString(STR_START_WORK).arg(fileToWrite.targetFlash).arg("primary").arg(address);
|
|
}
|
|
else
|
|
{
|
|
profile.spiport = secondarySpiPort;
|
|
msg = QString(STR_START_WORK).arg(fileToWrite.targetFlash).arg("secondary").arg(address);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
startEnabled(true);
|
|
ui->btnWrite->setText("START");
|
|
ui->btnWrite->setStyleSheet("QPushButton { background-color: green; color:white; }\n"
|
|
"QPushButton:enabled { background-color: rgb(0,200,0); color:white; }\n");
|
|
return;
|
|
}
|
|
|
|
}
|
|
else //se si tratta della fpga dell'rfif allora devo configurare il profilo di download in altra maniera
|
|
{
|
|
//Se non lo è allora devo selezionare il canale spi dove installare
|
|
QInputDialog qDialogSpiPort ;
|
|
|
|
QStringList items;
|
|
items << QString("GOLDEN");
|
|
items << QString("UPDATE");
|
|
|
|
qDialogSpiPort.setComboBoxItems(items);
|
|
qDialogSpiPort.setWindowTitle("");
|
|
qDialogSpiPort.setLabelText("Select which part of RFIF fpga: ");
|
|
|
|
if (qDialogSpiPort.exec())
|
|
{
|
|
QString value = qDialogSpiPort.textValue();
|
|
if (value=="GOLDEN")
|
|
{
|
|
profile.spiport = primarySpiPort;
|
|
address = QString("0x%1 - 0x%2").arg(profile.golden_address_start_area, 0, 16). arg(profile.golden_address_stop_area, 0, 16);
|
|
msg = QString(STR_START_WORK).arg(fileToWrite.targetFlash).arg("GOLDEN").arg(address);
|
|
}
|
|
else
|
|
{
|
|
profile.spiport = secondarySpiPort;
|
|
address = QString("0x%1 - 0x%2").arg(profile.user_address_start_area, 0, 16). arg(profile.user_address_stop_area, 0, 16);
|
|
msg = QString(STR_START_WORK).arg(fileToWrite.targetFlash).arg("UPDATE").arg(address);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
startEnabled(true);
|
|
ui->btnWrite->setText("START");
|
|
ui->btnWrite->setStyleSheet("QPushButton { background-color: green; color:white; }\n"
|
|
"QPushButton:enabled { background-color: rgb(0,200,0); color:white; }\n");
|
|
return;
|
|
}
|
|
|
|
//profile.spiport = primarySpiPort;
|
|
//msg = QString(STR_START_WORK).arg(fileToWrite.targetFlash).arg("NC").arg(address);
|
|
}
|
|
addToLog(msg);
|
|
|
|
programWithProfile(checked);
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::statusUpdated(int sts, int progress, const QString& msg)
|
|
{
|
|
if (sts==s_erase || sts==s_write || sts==s_read)
|
|
{
|
|
ui->lbOperation->setText(QString("%1").arg(msg));
|
|
}
|
|
else
|
|
{
|
|
addToLog(msg,sts);
|
|
}
|
|
if (progress>0)
|
|
ui->progressBar->setValue(progress);
|
|
|
|
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnStart_clicked()
|
|
{
|
|
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnReset_clicked()
|
|
{
|
|
//indivisuare il profilo da usare per le operazione di programmazione
|
|
if (!getProfile(ui->sbSectorSize->value(),ui->sbBase->value()))
|
|
{
|
|
//profile not valid to program
|
|
return;
|
|
}
|
|
profile.FileToSend = ui->leFile->text();
|
|
|
|
programmer->reset(profile);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnErase_clicked()
|
|
{
|
|
programmer->erase(1, ui->sbSectorSize->value(), ui->sbBase->value());
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnFlashID_clicked()
|
|
{
|
|
//indivisuare il profilo da usare per le operazione di programmazione
|
|
if (!getProfile(ui->sbSectorSize->value(),ui->sbBase->value()))
|
|
{
|
|
//profile not valid to program
|
|
return;
|
|
}
|
|
profile.FileToSend = ui->leFile->text();
|
|
programmer->readFlashID(profile);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnGetStatus_clicked()
|
|
{
|
|
//indivisuare il profilo da usare per le operazione di programmazione
|
|
if (!getProfile(ui->sbSectorSize->value(),ui->sbBase->value()))
|
|
{
|
|
//profile not valid to program
|
|
return;
|
|
}
|
|
profile.FileToSend = ui->leFile->text();
|
|
programmer->readStatusSPI(profile);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnFinish_clicked()
|
|
{
|
|
//indivisuare il profilo da usare per le operazione di programmazione
|
|
if (!getProfile(ui->sbSectorSize->value(),ui->sbBase->value()))
|
|
{
|
|
//profile not valid to program
|
|
return;
|
|
}
|
|
profile.FileToSend = ui->leFile->text();
|
|
programmer->terminate(profile);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_cbSimulate_clicked(bool checked)
|
|
{
|
|
programmer->setSimulate(checked);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_tbGo_clicked()
|
|
{
|
|
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::clearTargets()
|
|
{
|
|
memset(&targets, 0, sizeof targets);
|
|
}
|
|
|
|
//***********************************************************************
|
|
// update Grifo Download Site
|
|
// Input parameters: checked = true if I also have to view the golden area of the flash
|
|
// false if I have to display only the user area of the flash
|
|
// Returns:
|
|
//***********************************************************************
|
|
void QgGrifoBeamUpForm::updateGrifoDownloadSite(Qt::CheckState checked)
|
|
{
|
|
//clear targets struct
|
|
clearTargets();
|
|
|
|
//clear treewidget for targets
|
|
entitiesForm->clear();
|
|
|
|
//for every targets read from configuration files
|
|
for (int i = 0; i<flashTargets->countTarget(); i++)
|
|
{
|
|
//TgtMatch tgt = tgtMatchSet.db[i];
|
|
targetItem tgt = flashTargets->getTarget(i);
|
|
|
|
if ((checked==Qt::Checked))
|
|
//||
|
|
//(checked==Qt::Unchecked && tgt.firmware_area!=flash_firmware_area_golden))
|
|
{
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("%1 %2 %3 %4").arg(tgt.name).arg(tgt.slotAddress).arg(tgt.description).arg(tgt.filePrefix));
|
|
|
|
{//Site
|
|
QgGrifoDownloadSite* s=&targets.sites[targets.valid];
|
|
|
|
memset(&s->site, 0, sizeof s->site);
|
|
bsk_download_site_t* site=&s->site;
|
|
strncpy(site->address, tgt.slotAddress.toLatin1(), sizeof site->address);
|
|
|
|
s->tgtFlash=&tgt;
|
|
|
|
s->site.media_address=QHostAddress(flashTargets->getDefIp()).toIPv4Address();
|
|
s->site.media_port=flashTargets->getDefPort();
|
|
|
|
strncpy(s->site.name, tgt.name.toLatin1().constData(), sizeof s->site.name);
|
|
++targets.valid;
|
|
|
|
entitiesForm->addSite(s);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_cb_GoldenFlash_stateChanged()
|
|
{
|
|
updateGrifoDownloadSite(ui->cb_GoldenFlash->checkState());
|
|
}
|
|
|
|
//***********************************************************************
|
|
// Show target info
|
|
// Input parameters:
|
|
// popup = display the dialog box
|
|
// Returns: the complete string of target information
|
|
//***********************************************************************
|
|
QString QgGrifoBeamUpForm::ShowTargetInfo(bool popup)
|
|
{
|
|
QString fName = entitiesForm->getFirstSelectedTarget();
|
|
|
|
const targetItem* tgt=flashTargets->getFromName(fName);
|
|
|
|
if (!tgt)
|
|
return QString("");
|
|
|
|
QString infoText=
|
|
"Target: <b>"+fName+"</b><p/>\n"
|
|
+"   Description: <b>"+QString("%1").arg(tgt->description)+"</b><p/>\n"
|
|
+"   Name: <b>"+QString("%1").arg(tgt->name)+"</b><p/>\n"
|
|
+"   Arch: <b>"+QString("%1").arg(tgt->arch)+"</b><p/>\n"
|
|
+"   Slot Address: <b>"+QString("%1").arg(tgt->slotAddress)+"</b><p/>\n"
|
|
+"   IP:PORT: <b>"+QString("%1").arg(flashTargets->getDefIp())+":"+QString("%1").arg(flashTargets->getDefPort())+"</b><p/>\n"
|
|
+" <p/>\n"
|
|
+" FLASH: <p/>\n";
|
|
|
|
if (tgt->model.type==flash_type_xcku040)
|
|
{
|
|
infoText+= " ->  Type: <b> XCKU040 </b><p/>\n";
|
|
}
|
|
else
|
|
if(tgt->model.type==flash_type_xcku060)
|
|
{
|
|
infoText+= " ->  Type: <b> XCKU060 </b><p/>\n";
|
|
}
|
|
else
|
|
{
|
|
infoText+= " ->  Type: <b> XC7A200 </b><p/>\n";
|
|
}
|
|
|
|
if (tgt->model.byte3_4==bytes3address)
|
|
{
|
|
infoText+= " ->  Address: <b> 3 bytes address </b><p/>\n";
|
|
}
|
|
else
|
|
{
|
|
infoText+= " ->  Address: <b> 4 bytes address </b><p/>\n";
|
|
}
|
|
|
|
infoText+= " ->  GOLDEN Start-Stop address: <b>"+QString("%1").arg(tgt->model.goldenAddressStartArea)+"-"+QString("%1").arg(tgt->model.goldenAddressStopArea)+"</b><p/>\n";
|
|
|
|
infoText+= " ->  USER Start-Stop address: <b>"+QString("%1").arg(tgt->model.userAddressStartArea)+"-"+QString("%1").arg(tgt->model.userAddressStopArea)+"</b><p/>\n";
|
|
|
|
|
|
if (popup)
|
|
QMessageBox::information(0, "Target: "+fName, infoText);
|
|
return infoText;
|
|
}
|
|
|
|
|
|
|
|
void QgGrifoBeamUpForm::on_btnGetTargetInfo_clicked()
|
|
{
|
|
ShowTargetInfo(true);
|
|
}
|
|
|
|
//***********************************************************************
|
|
// Set profile, read information form selected fpga
|
|
// Input parameters:
|
|
// Returns:
|
|
//***********************************************************************
|
|
bool QgGrifoBeamUpForm::getProfile(unsigned int sectorSize,
|
|
unsigned int baseOffset)
|
|
{
|
|
QString fName = entitiesForm->getFirstSelectedTarget();
|
|
|
|
const targetItem *tgt = flashTargets->getFromName(fName);
|
|
|
|
if (!tgt)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
profile.fName = fName;
|
|
|
|
bool bStatus= false;
|
|
profile.user_address_start_area = QString(tgt->model.userAddressStartArea).toUInt(&bStatus, 16);
|
|
if (!bStatus)
|
|
{
|
|
return false;
|
|
}
|
|
profile.user_address_stop_area = QString(tgt->model.userAddressStopArea).toUInt(&bStatus, 16);
|
|
if (!bStatus)
|
|
{
|
|
return false;
|
|
}
|
|
profile.golden_address_start_area = QString(tgt->model.goldenAddressStartArea).toUInt(&bStatus, 16);
|
|
if (!bStatus)
|
|
{
|
|
return false;
|
|
}
|
|
profile.golden_address_stop_area = QString(tgt->model.goldenAddressStopArea).toUInt(&bStatus, 16);
|
|
if (!bStatus)
|
|
{
|
|
return false;
|
|
}
|
|
profile.BaseAddress = QString(tgt->model.userAddressStartArea).toUInt(&bStatus, 16);
|
|
if (!bStatus)
|
|
{
|
|
return false;
|
|
}
|
|
profile.BaseOffset = baseOffset;
|
|
profile.byteddress = (reg_moder_byteaddress_t)tgt->model.byte3_4;
|
|
profile.ip = flashTargets->getDefIp();
|
|
profile.port = QString("%1").arg(flashTargets->getDefPort());
|
|
profile.SectorSize_KBytes = sectorSize;
|
|
profile.slotAddress = tgt->slotAddress;
|
|
//profile.spiport = tgt->spiPort;
|
|
|
|
/*if (tgt->model->type==flash_type_xcku040)
|
|
{
|
|
//xcku040
|
|
profile.dimMbit = FLASH_128Mbit;
|
|
}
|
|
else
|
|
{
|
|
//xc7a200 and xcku060
|
|
profile.dimMbit = FLASH_256Mbit;
|
|
}*/
|
|
|
|
profile.writeRamp = (ui->cbWriteRamp->checkState()==Qt::Checked);
|
|
profile.verifyFinal = (ui->cbVerifyAll->checkState()==Qt::Checked);
|
|
profile.verifySector = (ui->cbVerifySector->checkState()==Qt::Checked);
|
|
|
|
fileToWrite.targetFlash = tgt->filePrefix;
|
|
|
|
profile.isFpgaRFIF = false;
|
|
|
|
if (tgt->model.idModel==AESA_RFIF_MODEL)
|
|
profile.isFpgaRFIF = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_cb_TargetAddress_clicked(bool checked)
|
|
{
|
|
programmer->setSRIOMemory(checked);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnGetValue_clicked()
|
|
{
|
|
QString address = ui->sbGetValue->text();
|
|
unsigned int len=256;
|
|
char data[len];
|
|
|
|
uint32_t dataInt[256];
|
|
|
|
//legge mediante srio un valore presente in memoria all'indirizzo indicato
|
|
QString remoteFile=QString("$SRIO:%1/%2+%3").arg(profile.slotAddress).arg(address, 0, 16).arg(len);
|
|
|
|
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_srio,
|
|
QString("Command %1").arg(remoteFile));
|
|
|
|
|
|
try
|
|
{
|
|
Q_EMIT programmer->readRequest(remoteFile, dataInt, len);
|
|
|
|
//programmer->waitRxEvent();
|
|
}
|
|
catch (...)
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_tftp,
|
|
"not inizialized");
|
|
}
|
|
|
|
sprintf (data, "0x%8.8lX", (long unsigned int)dataInt[0]);
|
|
|
|
ui->lblGetValue->setText(data);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnMem_clicked()
|
|
{
|
|
ui->sbGetValue->setText(QString("0x%1").arg(BASE_ADDRESS_MEM,0,16));
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnFPGA_clicked()
|
|
{
|
|
ui->sbGetValue->setText(QString("0x%1").arg(BASE_ADDRESS_IF,0,16));
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnHistory_clicked()
|
|
{
|
|
_dbHistory->refreshList();
|
|
HistoryDBForm HistoryDBWindow;
|
|
|
|
HistoryDBWindow.setWindowTitle("History DB");
|
|
|
|
HistoryDBWindow.setDB(_dbHistory);
|
|
HistoryDBWindow.exec();
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnAddHistory_clicked()
|
|
{
|
|
//(QString _file, db_error_t _error, QString _where)
|
|
QString fileName = ui->leFile->text();
|
|
db_error_t _error = db_error_t(ui->cbError->currentIndex());
|
|
db_status_t _status = db_status_t(ui->cbStatus->currentIndex());
|
|
QString fName = entitiesForm->getFirstSelectedTarget();
|
|
|
|
const targetItem* tgt=flashTargets->getFromName(fName);
|
|
|
|
if (!tgt)
|
|
return;
|
|
|
|
QString address = QString("%1-%2").arg(tgt->model.userAddressStartArea).arg(tgt->model.userAddressStopArea);
|
|
QString srio = QString("%1@%2:%3").arg(tgt->slotAddress).arg(flashTargets->getDefIp()).arg(flashTargets->getDefPort());
|
|
int spi = int(profile.spiport);
|
|
|
|
_dbHistory->addNewFile(fileName,
|
|
_error,
|
|
fName,
|
|
_status,
|
|
address,
|
|
srio,
|
|
spi);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_tbRefresh_clicked()
|
|
{
|
|
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_tbHistory_clicked()
|
|
{
|
|
on_btnHistory_clicked();
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_tbFileSelect_clicked()
|
|
{
|
|
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::startEnabled(bool _status)
|
|
{
|
|
|
|
ui->tbRefresh->setEnabled(_status);
|
|
ui->tbFileSelect->setEnabled(_status);
|
|
ui->tbFileInfo->setEnabled(_status);
|
|
ui->tbHistory->setEnabled(_status);
|
|
entitiesForm->setEnabled(_status);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::on_btnWrite_clicked()
|
|
{
|
|
//check if connected
|
|
if (!IS_TFTP_CONNECTED)
|
|
{
|
|
QMessageBox::warning(0, STR_TITLE_SERVER, STR_SERVER_IS_NOT_CONNECTED);
|
|
return;
|
|
}
|
|
|
|
//check if one target is selected
|
|
QString fName = entitiesForm->getFirstSelectedTarget();
|
|
if (fName=="")
|
|
{
|
|
QMessageBox::warning(0, STR_TITLE_SELECTION, STR_SELECTION_NOT_VALID);
|
|
return;
|
|
}
|
|
|
|
//check if selected file exists
|
|
QFileInfo finfo(ui->leFile->text());
|
|
if (!finfo.exists())
|
|
{
|
|
QMessageBox::critical(0, "ERROR open file", "File <p/>"+ui->leFile->text() +"<p/> is not available.");
|
|
return;
|
|
}
|
|
|
|
if (ui->btnWrite->text()=="START")
|
|
{
|
|
ui->btnWrite->setText("STOP");
|
|
startEnabled(false);
|
|
on_btnStart_clicked(true);
|
|
ui->btnWrite->setStyleSheet("QPushButton { background-color: red; color:white; }\n"
|
|
"QPushButton:enabled { background-color: rgb(200,0,0); color:white; }\n");
|
|
}
|
|
else
|
|
{
|
|
startEnabled(true);
|
|
ui->btnWrite->setText("START");
|
|
ui->btnWrite->setStyleSheet("QPushButton { background-color: green; color:white; }\n"
|
|
"QPushButton:enabled { background-color: rgb(0,200,0); color:white; }\n");
|
|
}
|
|
|
|
}
|
|
|
|
/********************************************************************
|
|
* extract info about fpga-flash to programme with this file
|
|
* Input parameters: complete file zip path
|
|
* Return: true if config is ok
|
|
* false if config is not ok
|
|
*/
|
|
bool QgGrifoBeamUpForm::extractInfoFromZip(QString _fileName)
|
|
{
|
|
|
|
resetFileToWrite();
|
|
|
|
//check if tmp folder is already created
|
|
if (QDir(TMP_FOLDER).exists())
|
|
{
|
|
//delete tmp folder
|
|
if (QDir(TMP_FOLDER).removeRecursively())
|
|
{
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
"Tmp folder deleted.");
|
|
}
|
|
else
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_generic,
|
|
"Tmp folder is not deleted.");
|
|
}
|
|
}
|
|
if (!QDir().mkdir(TMP_FOLDER))
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_history,
|
|
QString("ERROR create tmp folder %1").arg(TMP_FOLDER));
|
|
return false;
|
|
}
|
|
|
|
//extract info from zip to tmp folder
|
|
|
|
QZipReader zipfile(_fileName);
|
|
|
|
if(zipfile.count()!=0)
|
|
{
|
|
for (int i = 0; i<zipfile.count(); i++)
|
|
{
|
|
QZipReader::FileInfo fileItem;
|
|
fileItem = zipfile.entryInfoAt(i);
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("file%1 %2").arg(i).arg(fileItem.filePath));
|
|
|
|
}
|
|
}
|
|
|
|
//extract all files into tmp folder
|
|
if (!zipfile.extractAll(TMP_FOLDER))
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_generic,
|
|
QString("ERROR unzip file: %1").arg(_fileName));
|
|
return false;
|
|
}
|
|
|
|
//extract info from xml file
|
|
QString fileXml = TMP_FOLDER+"/info.xml";
|
|
|
|
|
|
fpagFlashXmlClass fpagFlashXml;
|
|
fpagFlashXml.setXmlFile(fileXml);
|
|
|
|
if (!fpagFlashXml.readXML())
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_generic,
|
|
QString("ERROR xml file: %1").arg(fileXml));
|
|
return false;
|
|
}
|
|
|
|
fileToWrite.primaryFile = TMP_FOLDER+ "/" +fpagFlashXml.getPrimaryFile();
|
|
fileToWrite.secondaryFile = TMP_FOLDER+ "/" +fpagFlashXml.getSecondaryFile();
|
|
fileToWrite.primaryMD5 = fpagFlashXml.getPrimaryMD5();
|
|
fileToWrite.secondaryMD5 = fpagFlashXml.getSecondaryMD5();
|
|
|
|
//check binary files with md5 present into xml file
|
|
if (!checkMD5(fileToWrite.primaryFile, fileToWrite.primaryMD5))
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_generic,
|
|
QString("ERROR primary MD5 file: %1").arg(fileToWrite.primaryFile));
|
|
return false;
|
|
}
|
|
|
|
if (!checkMD5(fileToWrite.secondaryFile, fileToWrite.secondaryMD5))
|
|
{
|
|
MyDebug.logMsg(type_log_error,
|
|
origin_msg_generic,
|
|
QString("ERROR secondary MD5 file: %1").arg(fileToWrite.secondaryFile));
|
|
return false;
|
|
}
|
|
|
|
fileToWrite.validConfig = true;
|
|
|
|
fileToWrite.targetFlash = fpagFlashXml.getTarget();
|
|
|
|
return true;
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::setColorLog(QPlainTextEdit *logtext,Qt::GlobalColor newColor, Qt::GlobalColor newBckColor )
|
|
{
|
|
QTextCharFormat tf = logtext->currentCharFormat();
|
|
tf.setForeground(QBrush(newColor));
|
|
tf.setBackground(QBrush(newBckColor));
|
|
logtext->setCurrentCharFormat(tf);
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::addToLog(QString _msg, unsigned int sts)
|
|
{
|
|
QString tick = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
|
|
|
|
switch (sts)
|
|
{
|
|
case s_init:
|
|
case s_status:
|
|
case s_read_id:
|
|
case s_erase:
|
|
case s_write:
|
|
default:
|
|
ui->leMsg->appendPlainText(QString("%1 - %2").arg(tick).arg(_msg));
|
|
break;
|
|
case s_error:
|
|
setColorLog(ui->leMsg, Qt::red, Qt::black);
|
|
ui->leMsg->appendPlainText(QString("%1 - %2").arg(tick).arg(_msg));
|
|
setColorLog(ui->leMsg, Qt::black, Qt::white);
|
|
break;
|
|
case s_end:
|
|
setColorLog(ui->leMsg, Qt::green,Qt::black);
|
|
ui->leMsg->appendPlainText(QString("%1 - %2").arg(tick).arg(_msg));
|
|
setColorLog(ui->leMsg, Qt::black,Qt::white);
|
|
break;
|
|
case s_question:
|
|
setColorLog(ui->leMsg, Qt::cyan,Qt::black);
|
|
ui->leMsg->appendPlainText(QString("%1 - %2").arg(tick).arg(_msg));
|
|
setColorLog(ui->leMsg, Qt::black,Qt::white);
|
|
break;
|
|
case s_warning:
|
|
setColorLog(ui->leMsg, Qt::yellow,Qt::black);
|
|
ui->leMsg->appendPlainText(QString("%1 - %2").arg(tick).arg(_msg));
|
|
setColorLog(ui->leMsg, Qt::black,Qt::white);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void QgGrifoBeamUpForm::setTargetOnScreen()
|
|
{
|
|
unsigned int numTargets = flashTargets->countTarget();
|
|
|
|
targetItem tgt;
|
|
for (unsigned int i=0; i<numTargets; i++)
|
|
{
|
|
tgt = flashTargets->getTarget(i);
|
|
MyDebug.logMsg(type_log_info,
|
|
origin_msg_generic,
|
|
QString("%1 %2 %3 %4").arg(tgt.g).arg(tgt.name).arg(tgt.slotAddress).arg(tgt.arch));
|
|
|
|
{//Site
|
|
|
|
QgGrifoDownloadSite* s=&targets.sites[targets.valid];
|
|
|
|
memset(&s->site, 0, sizeof s->site);
|
|
|
|
bsk_download_site_t* site=&s->site;
|
|
|
|
strncpy(site->address, tgt.slotAddress.toLatin1(), sizeof site->address);
|
|
|
|
s->tgtFlash = &tgt;
|
|
s->site.media_address = QHostAddress(flashTargets->getDefIp()).toIPv4Address();
|
|
s->site.media_port = flashTargets->getDefPort();
|
|
|
|
strncpy(s->site.name, tgt.name.toLatin1().constData(), sizeof s->site.name);
|
|
|
|
++targets.valid;
|
|
|
|
entitiesForm->addSite(s);
|
|
|
|
}//Site
|
|
}
|
|
entitiesForm->setDefaultTarget(flashTargets->getDefTarget());
|
|
entitiesForm->setVisible(true);
|
|
}
|