#include "fgpaprogrammer.h" #include #include #include #include #include #include #include #include #include #include #include "mydebug.h" #include #include #include #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 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:"<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(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; iaddNewFile(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()); }