SXXXXXXX_PyDownloadFwViaSRIO/_OLD/Vecchia_app/FpgaBeamMeUp/fgpaprogrammer.cpp
2026-01-22 17:10:05 +01:00

1445 lines
44 KiB
C++

#include "fgpaprogrammer.h"
#include <QTimer>
#include <QTimerEvent>
#include <QThread>
#include <QEventLoop>
#include <QEvent>
#include <QQueue>
#include <QApplication>
#include <QElapsedTimer>
#include <QMessageBox>
#include <QTimer>
#include "mydebug.h"
#include <QAbstractEventDispatcher>
#include <stdint.h>
#include <exception>
#include "fpgaflashengine.h"
#include "fpgarfifflashengine.h"
//#include "FpgaBridgeTftp.h"
#include "BupTFTP.h"
#include "fileutils.h"
#include "fpgabeammeupstring.h"
#include "historydb.h"
static unsigned char dummy_buffer[1024];
class my_exception: public std::exception
{
public:
int code;
my_exception(int c): code(c) {}
};
enum UserEventId
{
evn_start=QEvent::User+100,
evn_timeout,
evn_write_completed,
evn_read_completed,
evn_break,
evn_abort,
evn_error,
evn_erase,
evn_reset,
evn_readFlashID,
evn_readStatusSPI,
evn_terminate,
evn_program_finish
};
struct event_data_t
{
int type;
unsigned int len;
char data[DIM_DATA_BUFFER];
event_data_t(QEvent::Type type_=QEvent::User, const void* data_=0, unsigned int len_=0):
type(type_), len(len_)
{
(void)data_;
}
};
class MyEvent: public QEvent
{
public:
MyEvent(int type): QEvent(QEvent::Type(type)), data(QEvent::Type(type))
{
}
event_data_t data;
};
class FgpaProgrammer::FpgaProgrammerImplementation: public QThread,public FpgaFlashInterface
{
public:
//int tId;
QTimer* pTimer;
FgpaProgrammer* tFpgaProg;
BupTFTPID rId;
//FpgaBridgeTftp* tftp;
BupTFTP* tftp;
bool simulate;
bool SRIOMemory; //0 for address BASE_ADDRESS_IF
//=!0 for address BASE_ADDRESS_MEM
FpgaFlashEngine engine;
FpgaFlashEngineRFIF engineRFIF;
dbHistory *history;
FpgaFlashProfile profile;
QElapsedTimer elapsedTimer;
//FpgaFlashInterface
virtual unsigned long timeNowMs() override
{
return elapsedTimer.elapsed();
}
//***********************************************************************
// rtgWrite
// Input parameters: address = address to write
// data = buffer to write
// len = buffer's length
// mess = message to write into debug log
// Returns: true, no error, operation completed
// false, generic error into write function
//***********************************************************************
virtual bool rtgWriteDB(uint32_t address, const void* data, unsigned int len=DIM_DATA_BUFFER, unsigned int doorbell=0) override
{
if (tftp && !simulate)
{
QString remoteFile = "";
if (SRIOMemory)
{
remoteFile =QString("$SRIO:%1!0x%2/0x%3+%4").arg(profile.slotAddress).arg(doorbell, 0, 16).arg(BASE_ADDRESS_MEM+address, 0, 16);
}
else
{
remoteFile =QString("$SRIO:%1!0x%2/0x%3+%4").arg(profile.slotAddress).arg(doorbell, 0, 16).arg(address, 0, 16).arg(len);
}
MyDebug.logMsg( type_log_info,
origin_msg_srio ,
QString(STR_COMMAND_WRITE).arg(remoteFile));
Q_EMIT tFpgaProg->writeRequest(remoteFile, data, len);
bool ok=waitTxEvent();
int countRepeat = NUM_REPEAT_WRITE;
//repeatwrite until is ok or error
while ((!ok) && (countRepeat>0))
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TO_REPEAT_WRITE);
Q_EMIT tFpgaProg->writeRequest(remoteFile, data, len);
ok=waitTxEvent();
if (WAIT_TIME_AFTER_WR>0)
waitEventTimeout(WAIT_TIME_AFTER_WR);
countRepeat--;
}
if (countRepeat==0)
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TOO_WRITE);
return false;
}
if (WAIT_TIME_AFTER_WR>0)
waitEventTimeout(WAIT_TIME_AFTER_WR);
return ok;
}
if (simulate)
{
if (profile.isFpgaRFIF)
engineRFIF.simulateWrite(address, data, len);
else
engine.simulateWrite(address, data, len);
}
if (WAIT_TIME_AFTER_WR>0)
waitEventTimeout(WAIT_TIME_AFTER_WR);
return true;
}
//***********************************************************************
// rtgWrite
// Input parameters: address = address to write
// data = buffer to write
// len = buffer's length
// mess = message to write into debug log
// Returns: true, no error, operation completed
// false, generic error into write function
//***********************************************************************
virtual bool rtgWrite(uint32_t address, const void* data, unsigned int len=DIM_DATA_BUFFER) override
{
if (tftp && !simulate)
{
QString remoteFile = "";
if (SRIOMemory)
{
remoteFile =QString("$SRIO:%1/0x%2+%3").arg(profile.slotAddress).arg(BASE_ADDRESS_MEM+address, 0, 16).arg(len);
}
else
{
remoteFile =QString("$SRIO:%1/0x%2+%3").arg(profile.slotAddress).arg(BASE_ADDRESS_IF+address, 0, 16).arg(len);
}
MyDebug.logMsg( type_log_info,
origin_msg_srio ,
QString(STR_COMMAND_WRITE).arg(remoteFile));
Q_EMIT tFpgaProg->writeRequest(remoteFile, data, len);
bool ok=waitTxEvent();
int countRepeat = NUM_REPEAT_WRITE;
//repeatwrite until is ok or error
while ((!ok) && (countRepeat>0))
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TO_REPEAT_WRITE);
Q_EMIT tFpgaProg->writeRequest(remoteFile, data, len);
ok=waitTxEvent();
if (WAIT_TIME_AFTER_WR>0)
waitEventTimeout(WAIT_TIME_AFTER_WR);
countRepeat--;
}
if (countRepeat==0)
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TOO_WRITE);
return false;
}
if (WAIT_TIME_AFTER_WR>0)
waitEventTimeout(WAIT_TIME_AFTER_WR);
return ok;
}
if (simulate)
{
if (profile.isFpgaRFIF)
engineRFIF.simulateWrite(address, data, len);
else
engine.simulateWrite(address, data, len);
}
if (WAIT_TIME_AFTER_WR>0)
waitEventTimeout(WAIT_TIME_AFTER_WR);
return true;
}
//***********************************************************************
// rtgRead
// Input parameters: address = address to read
// data = ouput buffer
// len = buffer's length
//
// Returns: true, no error, operation completed
// false, generic error into read function
//***********************************************************************
virtual bool rtgReadDB(uint32_t address, void* data, unsigned int len=DIM_DATA_BUFFER, unsigned int doorbell=0) override
{
if (tftp && !simulate)
{
QString remoteFile= "";
if (SRIOMemory)
{
remoteFile=QString("$SRIO:%1!0x%2/0x%3+%4").arg(profile.slotAddress).arg(doorbell, 0, 16).arg(BASE_ADDRESS_MEM+address, 0, 16).arg(len);
}
else
{
remoteFile=QString("$SRIO:%1!0x%2/0x%3+%4").arg(profile.slotAddress).arg(doorbell, 0, 16).arg(address, 0, 16).arg(len);
}
MyDebug.logMsg( type_log_info,
origin_msg_srio ,
QString(STR_COMMAND_READ).arg(remoteFile));
Q_EMIT tFpgaProg->readRequest(remoteFile, data, len);
bool ok=waitRxEvent();
int countRepeat = NUM_REPEAT_READ;
//repeatwrite until is ok or error
while ((!ok) && (countRepeat>0))
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TO_REPEAT_READ);
Q_EMIT tFpgaProg->readRequest(remoteFile, data, len);
ok=waitTxEvent();
if (WAIT_TIME_AFTER_RD>0)
waitEventTimeout(WAIT_TIME_AFTER_RD);
countRepeat--;
}
if (countRepeat==0)
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TOO_READ );
return false;
}
if (WAIT_TIME_AFTER_RD>0)
waitEventTimeout(WAIT_TIME_AFTER_RD);
return ok;
}
if (simulate)
{
if (profile.isFpgaRFIF)
engineRFIF.simulateRead(address, data, len);
else
engine.simulateRead(address, data, len);
}
if (WAIT_TIME_AFTER_RD>0)
waitEventTimeout(WAIT_TIME_AFTER_RD);
return true;
}
//***********************************************************************
// rtgRead
// Input parameters: address = address to read
// data = ouput buffer
// len = buffer's length
//
// Returns: true, no error, operation completed
// false, generic error into read function
//***********************************************************************
virtual bool rtgRead(uint32_t address, void* data, unsigned int len=DIM_DATA_BUFFER) override
{
if (tftp && !simulate)
{
QString remoteFile= "";
if (SRIOMemory)
{
remoteFile=QString("$SRIO:%1/0x%2+%3").arg(profile.slotAddress).arg(BASE_ADDRESS_MEM+address, 0, 16).arg(len);
}
else
{
remoteFile=QString("$SRIO:%1/0x%2+%3").arg(profile.slotAddress).arg(BASE_ADDRESS_IF+address, 0, 16).arg(len);
}
MyDebug.logMsg( type_log_info,
origin_msg_srio ,
QString(STR_COMMAND_READ).arg(remoteFile));
Q_EMIT tFpgaProg->readRequest(remoteFile, data, len);
bool ok=waitRxEvent();
int countRepeat = NUM_REPEAT_READ;
//repeatwrite until is ok or error
while ((!ok) && (countRepeat>0))
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TO_REPEAT_READ);
Q_EMIT tFpgaProg->readRequest(remoteFile, data, len);
ok=waitTxEvent();
if (WAIT_TIME_AFTER_RD>0)
waitEventTimeout(WAIT_TIME_AFTER_RD);
countRepeat--;
}
if (countRepeat==0)
{
MyDebug.logMsg( type_log_error,
origin_msg_tftp ,
STR_TRY_TOO_READ );
return false;
}
if (WAIT_TIME_AFTER_RD>0)
waitEventTimeout(WAIT_TIME_AFTER_RD);
return ok;
}
if (simulate)
{
if (profile.isFpgaRFIF)
engineRFIF.simulateRead(address, data, len);
else
engine.simulateRead(address, data, len);
}
if (WAIT_TIME_AFTER_RD>0)
waitEventTimeout(WAIT_TIME_AFTER_RD);
return true;
}
//***********************************************************************
// rtgRead Direct
// Input parameters: address = address to read
// data = ouput buffer
// len = buffer's length
//
// Returns: true, no error, operation completed
// false, generic error into read function
//***********************************************************************
virtual bool rtgReadDirect(uint32_t address, void* data, unsigned int len=DIM_DATA_BUFFER) override
{
if (tftp && !simulate)
{
QString remoteFile= "";
remoteFile=QString("$SRIO:%1/0x%2+%3").arg(profile.slotAddress).arg(address, 0, 16).arg(len);
if (LOG_LEVEL>log_level_min)
{
MyDebug.logMsg( type_log_info,
origin_msg_srio ,
QString(STR_COMMAND_READ_DIRECT).arg(remoteFile));
}
Q_EMIT tFpgaProg->readRequest(remoteFile, data, len);
return waitRxEvent();
}
waitEventTimeout(100);
return true;
}
#if 0
virtual bool rtgErase(uint32_t address, void* data, unsigned int len=DIM_DATA_BUFFER) override
{
engine.simulateErase(address, data, len);
waitEventTimeout(100);
return true;
}
#endif
virtual bool rtgWaitEvent(unsigned int timeout_ms=5000)
{
if (timeout_ms==0)
return true;
/*event_data_t tmp=*/waitEvent(timeout_ms);
return true;
}
virtual void notify(step_t sts, int progress, const char* msg, ...) override
{
va_list args;
va_start(args, msg);
notifyStatus(sts, progress, QString::vasprintf(msg, args));
MyDebug.logMsg( type_log_info,
origin_msg_engine ,
QString::vasprintf(msg, args));
va_end(args);
}
virtual void log(type_log_t level, const char* msg, ...) override //level<0: error, ==0: info, >0: success
{
va_list args;
va_start(args, msg);
MyDebug.logMsg(level,
origin_msg_engine,
QString::vasprintf(msg, args));
va_end(args);
}
struct state_t
{
FpgaProgrammerDriver* driver;
int timer_pending;
int state;
};
state_t s;
volatile unsigned sectorSize;
volatile unsigned int baseAddress;
FpgaProgrammerImplementation():
//tId(0),
tFpgaProg(0),
tftp(0),
simulate(false),
history(0)
{
//pTimer.setSingleShot(true);
}
//***********************************************************************
// Set profile of the selected FPGA-flash
// Input parameters: _profile = parameters of selected fpga/flash
//
// Returns:
//***********************************************************************
void setProfile(const FpgaFlashProfile& _profile)
{
profile = _profile;
profile.BaseOffset = profile.user_address_start_area;
//
profile.SectorSize_KBytes = FLASH_SECTOR_DIM;
sectorSize = FLASH_SECTOR_DIM;
}
//***********************************************************************
// Inizialize programmer with default parameters
// Input parameters: _profile = parameters of selected fpga/flash
//
// Returns:
//***********************************************************************
void initialize(unsigned int /*write_size*/, int sector_size, int base_address)
{
sectorSize=sector_size;
baseAddress=base_address;
profile.reset();
profile.SectorSize_KBytes = sectorSize;
profile.BaseAddress = baseAddress;
profile.BaseOffset = 0;
}
void waitTxCompleted()
{
waitEventTimeout();
}
void waitSpiBusy()
{
event_data_t evn=waitEventTimeout();
if (evn.type!=evn_read_completed)
throw my_exception(1);
}
void waitSpiRdy()
{
event_data_t evn=waitEventTimeout();
if (evn.type!=evn_read_completed)
throw my_exception(1);
}
enum states_t
{
s_reset_wait=1,
s_id_request,
s_progr_enable,
s_erase_block,
s_program_block
};
void stateReset()
{
}
void state_RequestId()
{
}
void timerExpired()
{
//QCoreApplication::postEvent(this, new MyEvent(evn_timeout));
}
QQueue<event_data_t> qevn;
bool waitTxEvent(unsigned int tm_ms=0)
{
event_data_t e=waitEvent(tm_ms);
return e.type==evn_write_completed;
}
bool waitRxEvent(unsigned int tm_ms=0)
{
event_data_t e=waitEvent(tm_ms);
return e.type==evn_read_completed;
}
event_data_t waitEventTimeout(unsigned int tm_ms=5000)
{
if (tm_ms==0)
{
static event_data_t myeven;
myeven.type=evn_timeout;
return myeven;
}
return waitEvent(tm_ms);
}
event_data_t waitEvent(unsigned int tm_ms=0)
{
if (pTimer->isActive())
{
pTimer->stop();
}
#if 0
if (tId)
{
killTimer(tId);
tId=0;
}
#endif
#if 0
if (!qevn.isEmpty())
{
event_data_t evn=qevn.takeFirst();
//if (evn.type==evn_abort)
// throw(std::system_error(1));
MyDebug()<<"Event pending:"<<evn.type;
return evn;
}
#endif
if (tm_ms)
{
//tId=startTimer(tm_ms); //w->waitStart(tm_ms);
pTimer->start(tm_ms);
}
retry_:
/*MyDebug.logMsg(type_log_error,
origin_msg_generic,
"qui 1");*/
QEventLoop::ProcessEventsFlags flags=QEventLoop::WaitForMoreEvents;
bool processed=this->eventDispatcher()->processEvents(flags);
/*MyDebug.logMsg(type_log_error,
origin_msg_generic,
"qui 2");*/
int count_event = 0;
if (processed)
{
/*MyDebug.logMsg(type_log_error,
origin_msg_generic,
"qui 3");*/
if (!qevn.isEmpty())
{
count_event = qevn.count();
#if 0
if (tId)
{
killTimer(tId);
tId=0;
}
#endif
pTimer->stop();
event_data_t evn=qevn.takeFirst();
if (evn.type==evn_break)
{
QString msg = QString("%1 - %2").arg(STR_EXCP_BREAK).arg(MyDebug.getLastErrorStr());
MyDebug.logMsg(type_log_error,
origin_msg_generic,
msg);
throw my_exception(3);
}
switch (evn.type)
{
case evn_timeout:
MyDebug.logMsg(type_log_info,
origin_msg_event,
QString(STR_TIMEOUT_QUEUE).arg(count_event));
break;
case evn_write_completed:
/*MyDebug.logMsg(type_log_info,
origin_msg_event,
QString(STR_WRITE_COMPLETED_QUEUE).arg(count_event));*/
break;
case evn_read_completed:
/*MyDebug.logMsg(type_log_info,
origin_msg_event,
QString(STR_READ_COMPLETED_QUEUE).arg(count_event));*/
break;
default:
/*MyDebug.logMsg(type_log_info,
origin_msg_event,
QString(STR_QUEUE_EVENT).arg(evn.type).arg(count_event));*/
break;
}
return evn;
}
else
{
MyDebug.logMsg(type_log_info,
origin_msg_event,
STR_QUEUE_EVENT_EMPTY);
}
}
goto retry_;
return event_data_t(QEvent::User, 0, 0);
}
void customEvent(QEvent* evn) override
{
if (evn->type()>=QEvent::User)
{
MyEvent* me=reinterpret_cast<MyEvent*>(evn);
if (me)
qevn.append(me->data);
}
}
void timerEvent(QTimerEvent* evn)
{
if (evn->timerId()==pTimer->timerId()) //tId)
{
//tId=0;
//killTimer(tId);
pTimer->stop();
static event_data_t data;
data.type=evn_timeout;
qevn.append(data);
}
else
QThread::timerEvent(evn);
}
void run()
{
pTimer=new QTimer(this);
pTimer->setSingleShot(true);
pTimer->moveToThread(this);
connect(pTimer, &QTimer::timeout, this, [this]()
{
QCoreApplication::postEvent(this, new MyEvent(evn_timeout), Qt::HighEventPriority);
});
execute();
}
void notifyStatus(int sts, int progress, const QString& msg)
{
Q_EMIT tFpgaProg->statusChanged(sts, progress, msg);
//in case of error, update history work
/*if (sts==s_error)
{
history->changeErrorLast();
history->changeErrorLast();
}*/
}
//***********************************************************************
// Start program flash with erase first
// Input parameters:
//
// Returns:
//***********************************************************************
void startProgram()
{
//setto il profilo di fpga da processare
if (profile.isFpgaRFIF)
engineRFIF.setProfile(profile);
else
engine.setProfile(profile);
event_data_t evn;
bool ok_fpgaProgram = false;
//reset dummy_buffer
for(unsigned int i=0; i<sizeof dummy_buffer; ++i)
dummy_buffer[i]=0;
if (profile.writeRamp)
{
//notifico lo stato di start
notifyStatus(0, -1, STR_WRITE_RAMP);
elapsedTimer.start();
for(unsigned int i=0; i<sizeof dummy_buffer; ++i)
dummy_buffer[i]=i;
//inizio la programmazione
if (profile.isFpgaRFIF)
ok_fpgaProgram = engineRFIF.fpgaProgram(dummy_buffer, sizeof dummy_buffer);
else
ok_fpgaProgram = engine.fpgaProgram(dummy_buffer, sizeof dummy_buffer);
}
else
{
if (profile.FileToSend=="")
{
QCoreApplication::postEvent(this, new MyEvent(evn_error), Qt::HighEventPriority);
return;
}
//read binary file to write into flash
//notifico lo stato di start
QString msg = QString(STR_WRITE_FILE).arg(profile.FileToSend);
notifyStatus(0, -1, msg);
elapsedTimer.start();
binary_data_t *binary_data = read_file(profile.FileToSend.toStdString().c_str());
if (binary_data == NULL )
{
msg = QString(STR_ERROR_LOAD_FILE).arg(profile.FileToSend);
notifyStatus(0, -1, msg);
QCoreApplication::postEvent(this, new MyEvent(evn_error), Qt::HighEventPriority);
return;
}
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);
history->addNewFile(profile.FileToSend,
db_error_no_error,
profile.fName,
db_status_started,
address,
srio,
spi);
#ifdef DIM_FILE_WRITE
ok_fpgaProgram = engine.fpgaProgram(binary_data->data, DIM_FILE_WRITE);
#else
if (profile.isFpgaRFIF)
ok_fpgaProgram = engineRFIF.fpgaProgram(binary_data->data, binary_data->size);
else
ok_fpgaProgram = engine.fpgaProgram(binary_data->data, binary_data->size);
#endif
if (profile.write2Flash==1)
{
if (profile.FileToSend2=="")
{
QCoreApplication::postEvent(this, new MyEvent(evn_error), Qt::HighEventPriority);
return;
}
//set secondary spi
profile.spiport = secondarySpiPort;
//read binary file to write into flash
//notifico lo stato di start
QString msg = QString(STR_WRITE_FILE).arg(profile.FileToSend2);
notifyStatus(0, -1, msg);
elapsedTimer.start();
binary_data_t *binary_data = read_file(profile.FileToSend2.toStdString().c_str());
if (binary_data == NULL )
{
msg = QString(STR_ERROR_LOAD_FILE).arg(profile.FileToSend2);
notifyStatus(0, -1, msg);
QCoreApplication::postEvent(this, new MyEvent(evn_error), Qt::HighEventPriority);
return;
}
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);
history->addNewFile(profile.FileToSend,
db_error_no_error,
profile.fName,
db_status_started,
address,
srio,
spi);
if (profile.isFpgaRFIF)
ok_fpgaProgram = engineRFIF.fpgaProgram(binary_data->data, binary_data->size);
else
ok_fpgaProgram = engine.fpgaProgram(binary_data->data, binary_data->size);
}
}
for(;;)
{
if (ok_fpgaProgram)
{
QString msg = QString(STR_OK_PROGRAM).arg(profile.fName);
notifyStatus(s_end, -1, msg);
history->changeErrorLast(db_error_no_error, "");
history->changeStatusLast(db_status_programmed);
/*QEvent evn = ;
pushEvent();*/
return;
}
evn=waitEvent(5000);
if (evn.type==evn_break)
{
//se l'evento è break, vuol dire che ha finito di processare
notifyStatus(0, -1, STR_STOP_PROGRAM);
break;
}
if (evn.type==evn_timeout)
{
QString msg = QString("%1").arg(MyDebug.getLastErrorStr());
notifyStatus(s_error, -1, msg);
break;
}
//verifico se è stato richiesto un interrupt
if (isInterruptionRequested())
{
return;
}
}
}
//***********************************************************************
// Start esare flash
// Input parameters:
//
// Returns:
//***********************************************************************
void startErase()
{
//setto il profilo di fpga da processare
//FpgaFlashProfile profile={sectorSize, 0, baseAddress, 1};
if (profile.isFpgaRFIF)
engineRFIF.setProfile(profile);
else
engine.setProfile(profile);
//notifico lo stato di start
notifyStatus(s_erase, -1, STR_START_ERASE);
elapsedTimer.start();
//inizio la cancellazione
if (profile.isFpgaRFIF)
engineRFIF.fpgaErase(sizeof dummy_buffer);
else
engine.fpgaErase(sizeof dummy_buffer);
event_data_t evn;
for(;;)
{
evn=waitEvent(5000);
if (evn.type==evn_break)
{
//se l'evento è break, vuol dire che ha finito di processare
notifyStatus(s_erase, -1, STR_STOP_ERASE);
break;
}
//verifico se è stato richiesto un interrupt
if (isInterruptionRequested())
{
return;
}
}
}
//***********************************************************************
// Start reset flash communication with erase first
// Input parameters:
//
// Returns:
//***********************************************************************
void startReset()
{
//setto il profilo di fpga da processare
//FpgaFlashProfile profile={sectorSize, 0, baseAddress, 1};
if (profile.isFpgaRFIF)
engineRFIF.setProfile(profile);
else
engine.setProfile(profile);
//notifico lo stato di start
notifyStatus(s_reset, -1, STR_START_RESET);
elapsedTimer.start();
//inizio la cancellazione
if (profile.isFpgaRFIF)
engineRFIF.fpgaReset();
else
engine.fpgaReset();
event_data_t evn;
for(;;)
{
evn=waitEvent(5000);
if (evn.type==evn_break)
{
//se l'evento è break, vuol dire che ha finito di processare
notifyStatus(s_reset, -1, STR_STOP_RESET);
break;
}
//verifico se è stato richiesto un interrupt
if (isInterruptionRequested())
{
return;
}
}
}
//***********************************************************************
// Start read flash ID
// Input parameters:
//
// Returns:
//***********************************************************************
void startReadFlashID()
{
//setto il profilo di fpga da processare
//FpgaFlashProfile profile={sectorSize, 0, baseAddress, 1};
if (profile.isFpgaRFIF)
engineRFIF.setProfile(profile);
else
engine.setProfile(profile);
//notifico lo stato di start
notifyStatus(s_read_id, -1, STR_START_READ_FLASH_ID);
elapsedTimer.start();
//inizio la cancellazione
if (profile.isFpgaRFIF)
engineRFIF.readFlashID();
else
engine.readFlashID();
event_data_t evn;
for(;;)
{
evn=waitEvent(5000);
if (evn.type==evn_break)
{
//se l'evento è break, vuol dire che ha finito di processare
notifyStatus(s_read_id, -1, STR_STOP_READ_FLASH_ID);
break;
}
//verifico se è stato richiesto un interrupt
if (isInterruptionRequested())
{
return;
}
}
}
//***********************************************************************
// Return spi status
// Input parameters:
//
// Returns:
//***********************************************************************
void startStatusSPI()
{
//setto il profilo di fpga da processare
//FpgaFlashProfile profile={sectorSize, 0, baseAddress, 1};
if (profile.isFpgaRFIF)
engineRFIF.setProfile(profile);
else
engine.setProfile(profile);
//notifico lo stato di start
notifyStatus(s_status, -1, STR_START_READ_SPI_STATUS);
elapsedTimer.start();
//inizio la cancellazione
if (profile.isFpgaRFIF)
engineRFIF.readStatusSPI();
else
engine.readStatusSPI();
event_data_t evn;
for(;;)
{
evn=waitEvent(5000);
if (evn.type==evn_break)
{
//se l'evento è break, vuol dire che ha finito di processare
notifyStatus(s_status, -1, STR_STOP_READ_SPI_STATUS);
break;
}
//verifico se è stato richiesto un interrupt
if (isInterruptionRequested())
{
return;
}
}
}
//***********************************************************************
// terminate connection
// Input parameters:
//
// Returns:
//***********************************************************************
/*void startTerminate()
{
//setto il profilo di fpga da processare
//FpgaFlashProfile profile={sectorSize, 0, baseAddress, 1};
engine.setProfile(profile);
//notifico lo stato di start
notifyStatus(s_end, -1, STR_START_TERMINATE);
elapsedTimer.start();
//inizio la cancellazione
engine.fpgaTerminate();
event_data_t evn;
for(;;)
{
evn=waitEvent(5000);
if (evn.type==evn_break)
{
//se l'evento è break, vuol dire che ha finito di processare
notifyStatus(s_end, -1, STR_STOP_TERMINATE);
break;
}
//verifico se è stato richiesto un interrupt
if (isInterruptionRequested())
{
return;
}
}
}*/
//***********************************************************************
// main control for all operations
// Input parameters:
//
// Returns:
//***********************************************************************
void execute()
{
//if (profile.isFpgaRFIF)
engineRFIF.setInterface(this);
//else
engine.setInterface(this);
for(;;)
{
try
{
//attendo il prossimo evento, verificare il funzionamento
event_data_t evn=waitEvent(); //5000);
//se l'evento da processare non è l'evento di start, allora rimango in stato di idle.
if (evn.type!=evn_start &&
evn.type!=evn_erase &&
evn.type!=evn_reset &&
evn.type!=evn_readFlashID &&
evn.type!=evn_readStatusSPI &&
evn.type!=evn_terminate )
{
notifyStatus(0, -1, "idle");
if (evn.type==evn_error)
{
notifyStatus(0, -1, QString(STR_ENGINE_ERROR).arg(MyDebug.getLastErrorStr()));
history->changeErrorLast(db_error_generic);
history->changeStatusLast(db_status_error);
break;
}
continue;
}
try
{
if (evn.type==evn_start)
{
startProgram();
}
else
if (evn.type==evn_erase)
{
startErase();
}
else
if (evn.type==evn_reset)
{
startReset();
}
else
if (evn.type==evn_readFlashID)
{
startReadFlashID();
}
else
if (evn.type==evn_readStatusSPI)
{
startStatusSPI();
}
}
catch(my_exception& e)
{
QString msg1 = QString(STR_EXCEPTION).arg(e.code);
QString msg = QString("%1 - %2").arg(msg1).arg(MyDebug.getLastErrorStr());
//notifico eccezione durante la programmazione
notifyStatus(0, -1, msg);
history->changeErrorLast(db_error_generic, msg);
history->changeStatusLast(db_status_error);
}
}
catch(my_exception& e)
{
QString msg1 = QString(STR_EXCEPTION).arg(e.code);
QString msg = QString("%1 - %2").arg(msg1).arg(MyDebug.getLastErrorStr());
notifyStatus(0, -1, msg);
history->changeErrorLast(db_error_generic, msg);
history->changeStatusLast(db_status_error);
}
}
}
void pushEvent(QEvent* evn)
{
QApplication::sendEvent(this, evn);
}
};
FgpaProgrammer::FgpaProgrammer(QObject *parent) : QObject(parent), p_(*new FpgaProgrammerImplementation)
{
p_.tFpgaProg=this;
p_.initialize(0, 1, 0);
p_.moveToThread(&p_);
p_.start();
connect(this, &FgpaProgrammer::writeRequest, this, &FgpaProgrammer::onWriteRequest, Qt::QueuedConnection);
connect(this, &FgpaProgrammer::readRequest, this, &FgpaProgrammer::onReadRequest, Qt::QueuedConnection);
}
//***********************************************************************
// Set simulate flag for simulate write/read info
// Input parameters:
//
// Returns:
//***********************************************************************
void FgpaProgrammer::setSimulate(bool enable)
{
p_.simulate=enable;
}
//***********************************************************************
// Set SRIOMemory flag for select BASE_ADDRESS_IF(0x47000000) or BASE_ADDRESS_MEM(0xA0000000)
// Input parameters:
//
// Returns:
//***********************************************************************
void FgpaProgrammer::setSRIOMemory(bool enable)
{
p_.SRIOMemory=enable;
}
//***********************************************************************
// Connect programmer with tftp instance
// Input parameters:
//
// Returns:
//***********************************************************************
//void FgpaProgrammer::setTftp(FpgaBridgeTftp *tftp)
void FgpaProgrammer::setTftp(BupTFTP *tftp)
{
if (tftp!=p_.tftp)
{
p_.tftp=tftp;
//connect(p_.tftp, &FpgaBridgeTftp::sendTerminated, this, [this]()
connect(p_.tftp, &BupTFTP::sendTerminated, this, [this]()
{
if (p_.profile.isFpgaRFIF)
{
if (p_.engineRFIF.getEnableMsgBlk())
QMessageBox::information(0, STR_TFTP_WRITE_COMPLETED, STR_TFTP_WRITE_COMPLETED);
}
else
{
if (p_.engine.getEnableMsgBlk())
QMessageBox::information(0, STR_TFTP_WRITE_COMPLETED, STR_TFTP_WRITE_COMPLETED);
}
this->writeCompleted(true);
});
//connect(p_.tftp, &FpgaBridgeTftp::sendError, this, [this]()
connect(p_.tftp, &BupTFTP::sendError, this, [this]()
{
MyDebug.logMsg(type_log_error,
origin_msg_tftp,
STR_TFTP_SEND_ERROR);
QCoreApplication::postEvent(&p_, new MyEvent(evn_break), Qt::HighEventPriority);
});
//connect(p_.tftp, &FpgaBridgeTftp::transferError, this, [this](int code, const QString& codeError)
connect(p_.tftp, &BupTFTP::transferError, this, [this](BupTFTP*, BupTFTPID*, int code, const QString& msg)
{
QString msg1 = QString("Transfer Error, code %1 %2").arg(code).arg(msg);
MyDebug.logMsg(type_log_error,
origin_msg_tftp,
msg1.toStdString().c_str());
QCoreApplication::postEvent(&p_, new MyEvent(evn_break), Qt::HighEventPriority);
});
//connect(p_.tftp, &FpgaBridgeTftp::receiveTerminated, this, [this](int, const QHostAddress)
connect(p_.tftp, &BupTFTP::receiveTerminated, this, [this](BupTFTP*, BupTFTPID*, int, QHostAddress)
{
/*MyDebug.logMsg(type_log_info,
origin_msg_tftp,
STR_TFTP_RECEIVE_COMPLETED);*/
QCoreApplication::postEvent(&p_, new MyEvent(evn_read_completed), Qt::HighEventPriority);
});
}
}
void FgpaProgrammer::setHistory(dbHistory *db)
{
if (db!=p_.history)
{
p_.history=db;
}
}
void FgpaProgrammer::setDriver(FpgaProgrammerDriver* driver)
{
p_.s.driver=driver;
}
void FgpaProgrammer::start(unsigned long write_size, unsigned int sectorSize, unsigned int baseOffset)
{
MyDebug.logMsg(type_log_info,
origin_msg_generic,
QString(STR_START_REQUEST_SIZE).arg(write_size));
p_.initialize(write_size, sectorSize, baseOffset);
if (write_size==0)
QCoreApplication::postEvent(&p_, new MyEvent(evn_break), Qt::HighEventPriority);
else
QCoreApplication::postEvent(&p_, new MyEvent(evn_start), Qt::HighEventPriority);
}
void FgpaProgrammer::start(const FpgaFlashProfile& _profile)
{
MyDebug.logMsg(type_log_info,
origin_msg_generic,
QString(STR_START_REQUEST_FROM).arg(_profile.user_address_start_area,0, 16));
p_.setProfile(_profile);
QCoreApplication::postEvent(&p_, new MyEvent(evn_start), Qt::HighEventPriority);
}
void FgpaProgrammer::erase(unsigned long erase_size, unsigned int sectorSize, unsigned int baseOffset)
{
MyDebug.logMsg(type_log_info,
origin_msg_generic,
QString(STR_START_ERASE_SIZE).arg(erase_size));
p_.initialize(erase_size, sectorSize, baseOffset);
//TODO: agigungere la parte di codice per chiamare la funzione erase
QCoreApplication::postEvent(&p_, new MyEvent(evn_erase), Qt::HighEventPriority);
}
void FgpaProgrammer::reset(const FpgaFlashProfile& _profile)
{
MyDebug.logMsg(type_log_info,
origin_msg_generic,
STR_START_RESET);
p_.setProfile(_profile);
QCoreApplication::postEvent(&p_, new MyEvent(evn_reset), Qt::HighEventPriority);
}
void FgpaProgrammer::readFlashID(const FpgaFlashProfile& _profile)
{
MyDebug.logMsg(type_log_info,
origin_msg_generic,
STR_START_READ_FLASH_ID);
p_.setProfile(_profile);
QCoreApplication::postEvent(&p_, new MyEvent(evn_readFlashID), Qt::HighEventPriority);
}
void FgpaProgrammer::readStatusSPI(const FpgaFlashProfile& _profile)
{
MyDebug.logMsg(type_log_info,
origin_msg_generic,
STR_START_READ_SPI_STATUS);
p_.setProfile(_profile);
QCoreApplication::postEvent(&p_, new MyEvent(evn_readStatusSPI), Qt::HighEventPriority);
}
void FgpaProgrammer::terminate(const FpgaFlashProfile& _profile)
{
MyDebug.logMsg(type_log_info,
origin_msg_generic,
STR_START_TERMINATE);
p_.setProfile(_profile);
QCoreApplication::postEvent(&p_, new MyEvent(evn_terminate), Qt::HighEventPriority);
}
void FgpaProgrammer::abort(const FpgaFlashProfile& _profile)
{
p_.setProfile(_profile);
}
void FgpaProgrammer::writeCompleted(bool ok)
{
if (!ok)
QCoreApplication::postEvent(&p_, new MyEvent(evn_break), Qt::HighEventPriority);
else
QCoreApplication::postEvent(&p_, new MyEvent(evn_write_completed), Qt::HighEventPriority);
}
void FgpaProgrammer::readCompleted(bool ok)
{
if (!ok)
QCoreApplication::postEvent(&p_, new MyEvent(evn_break), Qt::HighEventPriority);
else
QCoreApplication::postEvent(&p_, new MyEvent(evn_read_completed), Qt::HighEventPriority);
}
#if 0
void FgpaProgrammer::eraseCompleted(bool ok, const void* data, unsigned int len)
{
QCoreApplication::postEvent(&p_, new MyEvent(evn_break), Qt::HighEventPriority);
}
#endif
void FgpaProgrammer::onWriteRequest(const QString& a, const void* src, unsigned int len)
{
p_.tftp->sendMemory(&p_.rId, (void*)src, len, a.toLatin1().constData());
}
void FgpaProgrammer::onReadRequest(const QString& a, void* dst, unsigned int len)
{
p_.tftp->receiveMemory(&p_.rId, dst, len, a.toLatin1().constData());
}