diff --git a/slsDetectorServers/jungfrauDetectorServer/gitInfo.txt b/slsDetectorServers/jungfrauDetectorServer/gitInfo.txt index 6e1688271..68e820fcd 100644 --- a/slsDetectorServers/jungfrauDetectorServer/gitInfo.txt +++ b/slsDetectorServers/jungfrauDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorPackage/slsDetectorServers/jungfrauDetectorServer URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -Repsitory UUID: 5a4122ae7c8dae1572e9db336de70183956e58c7 -Revision: 31 -Branch: refactor -Last Changed Author: Dhanya_Thattil -Last Changed Rev: 4481 -Last Changed Date: 2019-03-28 08:18:03.000000002 +0100 ../slsDetectorServer/slsDetectorFunctionList.h +Repsitory UUID: ed9dc3b386898603d74a489528292139d47aac1a +Revision: 32 +Branch: program +Last Changed Author: Erik_Frojdh +Last Changed Rev: 4488 +Last Changed Date: 2019-03-29 14:42:42.000000002 +0100 ../slsDetectorServer/slsDetectorServer_funcs.c diff --git a/slsDetectorServers/jungfrauDetectorServer/gitInfoJungfrau.h b/slsDetectorServers/jungfrauDetectorServer/gitInfoJungfrau.h index b7b7c4d4f..2f78fa4ac 100644 --- a/slsDetectorServers/jungfrauDetectorServer/gitInfoJungfrau.h +++ b/slsDetectorServers/jungfrauDetectorServer/gitInfoJungfrau.h @@ -1,6 +1,6 @@ #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" -#define GITREPUUID "5a4122ae7c8dae1572e9db336de70183956e58c7" -#define GITAUTH "Dhanya_Thattil" -#define GITREV 0x4481 -#define GITDATE 0x20190328 -#define GITBRANCH "refactor" +#define GITREPUUID "ed9dc3b386898603d74a489528292139d47aac1a" +#define GITAUTH "Erik_Frojdh" +#define GITREV 0x4488 +#define GITDATE 0x20190329 +#define GITBRANCH "program" diff --git a/slsDetectorSoftware/include/multiSlsDetector.h b/slsDetectorSoftware/include/multiSlsDetector.h index 13e2ae1e2..ee860a66f 100644 --- a/slsDetectorSoftware/include/multiSlsDetector.h +++ b/slsDetectorSoftware/include/multiSlsDetector.h @@ -1,12 +1,5 @@ -#ifndef MULTI_SLS_DETECTOR_H -#define MULTI_SLS_DETECTOR_H +#pragma once -/** - @libdoc The multiSlsDetector class is used to operate several slsDetectors in - parallel. - * @short This is the base class for multi detector system functionalities - * @author Anna Bergamaschi - */ #include "SharedMemory.h" #include "error_defs.h" #include "gitInfoLib.h" @@ -2002,11 +1995,6 @@ class multiSlsDetector : public virtual slsDetectorDefs { */ void startProcessingThread(); - // /** - // * Static function to call processing thread - // */ - // static void* startProcessData(void *n); - /** * Check if processing thread is ready to join main thread * @returns true if ready, else false @@ -2025,6 +2013,15 @@ class multiSlsDetector : public virtual slsDetectorDefs { */ int kbhit(); + /** + * Convert raw file + * @param fname name of pof file + * @param fpgasrc pointer in memory to read pof to + * @returns file size + */ + std::vector readPofFile(const std::string &fname); + + /** Multi detector Id */ const int multiId; @@ -2083,4 +2080,3 @@ class multiSlsDetector : public virtual slsDetectorDefs { void *pCallbackArg{nullptr}; }; -#endif diff --git a/slsDetectorSoftware/include/slsDetector.h b/slsDetectorSoftware/include/slsDetector.h index 055454c41..9f32780a5 100644 --- a/slsDetectorSoftware/include/slsDetector.h +++ b/slsDetectorSoftware/include/slsDetector.h @@ -1,13 +1,4 @@ -#ifndef SLS_DETECTOR_H -#define SLS_DETECTOR_H - -/** - * - * @short complete detector functionalities for a single module detector. - * The slsDetector class takes care of the communication with the - * detector and all kind actions related with a single detector controller - * @author Anna Bergamaschi - */ +#pragma once #include "ClientSocket.h" #include "SharedMemory.h" @@ -17,6 +8,7 @@ class ClientInterface; #include +#include class multiSlsDetector; class ServerInterface; @@ -1286,11 +1278,11 @@ class slsDetector : public virtual slsDetectorDefs{ int setStoragecellStart(int pos = -1); /** - * Programs FPGA with pof file (Jungfrau) - * @param fname file name + * Programs FPGA with pof file (Jungfrau, CTB, Moench) + * @param buffer programming file in memory * @returns OK or FAIL */ - int programFPGA(const std::string &fname); + int programFPGA(std::vector buffer); /** * Resets FPGA (Jungfrau) @@ -1826,4 +1818,3 @@ class slsDetector : public virtual slsDetectorDefs{ }; -#endif diff --git a/slsDetectorSoftware/src/multiSlsDetector.cpp b/slsDetectorSoftware/src/multiSlsDetector.cpp index 11bc0c456..1b67f7fbd 100644 --- a/slsDetectorSoftware/src/multiSlsDetector.cpp +++ b/slsDetectorSoftware/src/multiSlsDetector.cpp @@ -2597,13 +2597,16 @@ int multiSlsDetector::setStoragecellStart(int pos, int detPos) { } int multiSlsDetector::programFPGA(const std::string &fname, int detPos) { + // read pof file + std::vector buffer = readPofFile(fname); + // single if (detPos >= 0) { - return detectors[detPos]->programFPGA(fname); + return detectors[detPos]->programFPGA(buffer); } // multi - auto r = serialCall(&slsDetector::programFPGA, fname); + auto r = parallelCall(&slsDetector::programFPGA, buffer); return sls::allEqualTo(r, static_cast(OK)) ? OK : FAIL; } @@ -3986,10 +3989,6 @@ void multiSlsDetector::startProcessingThread() { dataProcessingThread = std::thread(&multiSlsDetector::processData, this); } -// void* multiSlsDetector::startProcessData(void *n) { -// ((multiSlsDetector*)n)->processData(); -// return n; -// } void multiSlsDetector::processData() { if (setReceiverOnline() == OFFLINE_FLAG) { @@ -4050,3 +4049,107 @@ int multiSlsDetector::kbhit() { select(STDIN_FILENO + 1, &fds, nullptr, nullptr, &tv); return FD_ISSET(STDIN_FILENO, &fds); } + + + +std::vector multiSlsDetector::readPofFile(const std::string &fname) { + FILE_LOG(logDEBUG1) << "Programming FPGA with file name:" << fname; + size_t filesize = 0; + // check if it exists + + struct stat st; + if (stat(fname.c_str(), &st)) { + throw RuntimeError("Program FPGA: Programming file does not exist"); + } + + + + // open src + FILE *src = fopen(fname.c_str(), "rb"); + if (src == nullptr) { + throw RuntimeError("Program FPGA: Could not open source file for programming: " + + fname); + } + + // create temp destination file + char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX"; + int dst = mkstemp(destfname); // create temporary file and open it in r/w + if (dst == -1) { + fclose(src); + throw RuntimeError( + std::string("Could not create destination file in /tmp for programming: ") + + destfname); + } + + // convert src to dst rawbin + FILE_LOG(logDEBUG1) << "Converting " << fname << " to " << destfname; + { + int filepos, x, y, i; + // Remove header (0...11C) + for (filepos = 0; filepos < 0x11C; ++filepos) { + fgetc(src); + } + // Write 0x80 times 0xFF (0...7F) + { + char c = 0xFF; + for (filepos = 0; filepos < 0x80; ++filepos) { + write(dst, &c, 1); + } + } + // Swap bits and write to file + for (filepos = 0x80; filepos < 0x1000000; ++filepos) { + x = fgetc(src); + if (x < 0) { + break; + } + y = 0; + for (i = 0; i < 8; ++i) { + y = y | (((x & (1 << i)) >> i) << (7 - i)); // This swaps the bits + } + write(dst, &y, 1); + } + if (filepos < 0x1000000) { + throw RuntimeError("Could not convert programming file. EOF before end of flash"); + } + } + if (fclose(src)) { + throw RuntimeError("Program FPGA: Could not close source file"); + } + if (close(dst)) { + throw RuntimeError("Program FPGA: Could not close destination file"); + } + FILE_LOG(logDEBUG1) << "File has been converted to " << destfname; + + // loading dst file to memory + FILE *fp = fopen(destfname, "r"); + if (fp == nullptr) { + throw RuntimeError("Program FPGA: Could not open rawbin file"); + } + if (fseek(fp, 0, SEEK_END)) { + throw RuntimeError("Program FPGA: Seek error in rawbin file"); + } + filesize = ftell(fp); + if (filesize <= 0) { + throw RuntimeError("Program FPGA: Could not get length of rawbin file"); + } + rewind(fp); + + std::vector buffer(filesize, 0); + if (fread(buffer.data(), sizeof(char), filesize, fp) != filesize) { + throw RuntimeError("Program FPGA: Could not read rawbin file"); + } + + if (fclose(fp)) { + throw RuntimeError("Program FPGA: Could not close destination file after converting"); + } + unlink(destfname); // delete temporary file + FILE_LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory"; + FILE_LOG(logINFO) << "Read file into memory"; + return buffer; +} + + + + + + diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index 01399d053..164833a83 100644 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -3386,221 +3386,126 @@ int slsDetector::setStoragecellStart(int pos) { return retval; } -int slsDetector::programFPGA(const std::string &fname) { - // TODO! make exception safe! - // now malloced memory can leak - // only jungfrau implemented (client processing, so check now) - if (detector_shm()->myDetectorType != JUNGFRAU && - detector_shm()->myDetectorType != CHIPTESTBOARD && - detector_shm()->myDetectorType != MOENCH) { - throw RuntimeError("Program FPGA is not implemented for this detector"); - } - FILE_LOG(logDEBUG1) << "Programming FPGA with file name:" << fname; - size_t filesize = 0; - char *fpgasrc = nullptr; +int slsDetector::programFPGA(std::vector buffer) { + // validate type + switch(detector_shm()->myDetectorType) { + case JUNGFRAU: + case CHIPTESTBOARD: + case MOENCH: + break; + default: + throw RuntimeError("Program FPGA is not implemented for this detector"); + } - // check if it exists - { - struct stat st; - if (stat(fname.c_str(), &st)) { - throw RuntimeError("Program FPGA: Programming file does not exist"); - } - } + size_t filesize = buffer.size(); - { - // open src - FILE *src = fopen(fname.c_str(), "rb"); - if (src == nullptr) { - throw RuntimeError("Program FPGA: Could not open source file for programming: " + - fname); - } + // send program from memory to detector + int fnum = F_PROGRAM_FPGA; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = {0}; + FILE_LOG(logINFO) << "Sending programming binary to detector " << detector_shm()->hostname; - // create temp destination file - char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX"; - int dst = mkstemp(destfname); // create temporary file and open it in r/w - if (dst == -1) { - fclose(src); - throw RuntimeError( - std::string("Could not create destination file in /tmp for programming: ") + - destfname); - } + if (detector_shm()->onlineFlag == ONLINE_FLAG) { + auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort); + client.sendData(&fnum, sizeof(fnum)); + client.sendData(&filesize, sizeof(filesize)); + client.receiveData(&ret, sizeof(ret)); + // opening error + if (ret == FAIL) { + client.receiveData(mess, sizeof(mess)); + throw RuntimeError("Detector " + std::to_string(detId) + + " returned error: " + std::string(mess)); + } - // convert src to dst rawbin - FILE_LOG(logDEBUG1) << "Converting " << fname << " to " << destfname; - { - int filepos, x, y, i; - // Remove header (0...11C) - for (filepos = 0; filepos < 0x11C; ++filepos) { - fgetc(src); - } - // Write 0x80 times 0xFF (0...7F) - { - char c = 0xFF; - for (filepos = 0; filepos < 0x80; ++filepos) { - write(dst, &c, 1); - } - } - // Swap bits and write to file - for (filepos = 0x80; filepos < 0x1000000; ++filepos) { - x = fgetc(src); - if (x < 0) { - break; - } - y = 0; - for (i = 0; i < 8; ++i) { - y = y | (((x & (1 << i)) >> i) << (7 - i)); // This swaps the bits - } - write(dst, &y, 1); - } - if (filepos < 0x1000000) { - throw RuntimeError("Could not convert programming file. EOF before end of flash"); - } - } - if (fclose(src)) { - throw RuntimeError("Program FPGA: Could not close source file"); - } - if (close(dst)) { - throw RuntimeError("Program FPGA: Could not close destination file"); - } - FILE_LOG(logDEBUG1) << "File has been converted to " << destfname; + // erasing flash + if (ret != FAIL) { + FILE_LOG(logINFO) << "This can take awhile. Please be patient..."; + FILE_LOG(logINFO) << detId << "Erasing Flash:"; + printf("%d%%\r", 0); + std::cout << std::flush; + // erasing takes 65 seconds, printing here (otherwise need threads + // in server-unnecessary) + const int ERASE_TIME = 65; + int count = ERASE_TIME + 1; + while (count > 0) { + usleep(1 * 1000 * 1000); + --count; + printf("%d%%\r", (int)(((double)(ERASE_TIME - count) / ERASE_TIME) * 100)); + std::cout << std::flush; + } + printf("\n"); + FILE_LOG(logINFO) << detId << "Writing to Flash:"; + printf("%d%%\r", 0); + std::cout << std::flush; + } - // loading dst file to memory - FILE *fp = fopen(destfname, "r"); - if (fp == nullptr) { - throw RuntimeError("Program FPGA: Could not open rawbin file"); - } - if (fseek(fp, 0, SEEK_END)) { - throw RuntimeError("Program FPGA: Seek error in rawbin file"); - } - filesize = ftell(fp); - if (filesize <= 0) { - throw RuntimeError("Program FPGA: Could not get length of rawbin file"); - } - rewind(fp); - fpgasrc = (char *)malloc(filesize + 1); //<------------------- MALLOC! - if (fpgasrc == nullptr) { - throw RuntimeError("Program FPGA: Could not allocate size of program"); - } - if (fread(fpgasrc, sizeof(char), filesize, fp) != filesize) { - free(fpgasrc); - throw RuntimeError("Program FPGA: Could not read rawbin file"); - } + // sending program in parts of 2mb each + size_t unitprogramsize = 0; + int currentPointer = 0; + size_t totalsize = filesize; + while (ret != FAIL && (filesize > 0)) { - if (fclose(fp)) { - free(fpgasrc); - throw RuntimeError("Program FPGA: Could not close destination file after converting"); - } - unlink(destfname); // delete temporary file - FILE_LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory"; - } + unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb + if (unitprogramsize > filesize) { // less than 2mb + unitprogramsize = filesize; + } + FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize + << "\t filesize:" << filesize; - // send program from memory to detector - int fnum = F_PROGRAM_FPGA; - int ret = FAIL; - char mess[MAX_STR_LENGTH] = {0}; - FILE_LOG(logDEBUG1) << "Sending programming binary to detector"; + client.sendData(&buffer[currentPointer], unitprogramsize); + client.receiveData(&ret, sizeof(ret)); + if (ret != FAIL) { + filesize -= unitprogramsize; + currentPointer += unitprogramsize; - if (detector_shm()->onlineFlag == ONLINE_FLAG) { - auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort); - client.sendData(&fnum, sizeof(fnum)); - client.sendData(&filesize, sizeof(filesize)); - client.receiveData(&ret, sizeof(ret)); - // opening error - if (ret == FAIL) { - client.receiveData(mess, sizeof(mess)); - free(fpgasrc); - throw RuntimeError("Detector " + std::to_string(detId) + - " returned error: " + std::string(mess)); - } + // print progress + printf("%d%%\r", (int)(((double)(totalsize - filesize) / totalsize) * 100)); + std::cout << std::flush; + } else { + printf("\n"); + client.receiveData(mess, sizeof(mess)); + throw RuntimeError("Detector " + std::to_string(detId) + + " returned error: " + std::string(mess)); + } + } + printf("\n"); - // erasing flash - if (ret != FAIL) { - FILE_LOG(logINFO) << "This can take awhile. Please be patient..."; - FILE_LOG(logINFO) << "Erasing Flash:"; - printf("%d%%\r", 0); - std::cout << std::flush; - // erasing takes 65 seconds, printing here (otherwise need threads - // in server-unnecessary) - const int ERASE_TIME = 65; - int count = ERASE_TIME + 1; - while (count > 0) { - usleep(1 * 1000 * 1000); - --count; - printf("%d%%\r", (int)(((double)(ERASE_TIME - count) / ERASE_TIME) * 100)); - std::cout << std::flush; - } - printf("\n"); - FILE_LOG(logINFO) << "Writing to Flash:"; - printf("%d%%\r", 0); - std::cout << std::flush; - } + // check ending error + if ((ret == FAIL) && (strstr(mess, "not implemented") == nullptr) && + (strstr(mess, "locked") == nullptr) && (strstr(mess, "-update") == nullptr)) { + client.receiveData(&ret, sizeof(ret)); + if (ret == FAIL) { + client.receiveData(mess, sizeof(mess)); + throw RuntimeError("Detector " + std::to_string(detId) + + " returned error: " + std::string(mess)); + } + } - // sending program in parts of 2mb each - size_t unitprogramsize = 0; - int currentPointer = 0; - size_t totalsize = filesize; - while (ret != FAIL && (filesize > 0)) { + if (ret == FORCE_UPDATE) { + updateDetector(); + } - unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb - if (unitprogramsize > filesize) { // less than 2mb - unitprogramsize = filesize; - } - FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize - << "\t filesize:" << filesize; - - client.sendData(fpgasrc + currentPointer, unitprogramsize); - client.receiveData(&ret, sizeof(ret)); - if (ret != FAIL) { - filesize -= unitprogramsize; - currentPointer += unitprogramsize; - - // print progress - printf("%d%%\r", (int)(((double)(totalsize - filesize) / totalsize) * 100)); - std::cout << std::flush; - } else { - printf("\n"); - client.receiveData(mess, sizeof(mess)); - free(fpgasrc); - throw RuntimeError("Detector returned error: " + std::string(mess)); - } - } - printf("\n"); - - // check ending error - if ((ret == FAIL) && (strstr(mess, "not implemented") == nullptr) && - (strstr(mess, "locked") == nullptr) && (strstr(mess, "-update") == nullptr)) { - client.receiveData(&ret, sizeof(ret)); - if (ret == FAIL) { - client.receiveData(mess, sizeof(mess)); - free(fpgasrc); - throw RuntimeError("Detector returned error: " + std::string(mess)); - } - } - - if (ret == FORCE_UPDATE) { - updateDetector(); - } - - // remapping stop server - if ((ret == FAIL) && (strstr(mess, "not implemented") == nullptr) && - (strstr(mess, "locked") == nullptr) && (strstr(mess, "-update") == nullptr)) { - fnum = F_RESET_FPGA; - int stopret = FAIL; - auto stop = DetectorSocket(detector_shm()->hostname, detector_shm()->stopPort); - stop.sendData(&fnum, sizeof(fnum)); - stop.receiveData(&stopret, sizeof(stopret)); - if (stopret == FAIL) { - client.receiveData(mess, sizeof(mess)); - free(fpgasrc); - throw RuntimeError("Detector returned error: " + std::string(mess)); - } - } - } - FILE_LOG(logINFO) << "You can now restart the detector servers in normal mode."; - free(fpgasrc); - return ret; + // remapping stop server + if ((ret == FAIL) && (strstr(mess, "not implemented") == nullptr) && + (strstr(mess, "locked") == nullptr) && (strstr(mess, "-update") == nullptr)) { + fnum = F_RESET_FPGA; + int stopret = FAIL; + auto stop = DetectorSocket(detector_shm()->hostname, detector_shm()->stopPort); + stop.sendData(&fnum, sizeof(fnum)); + stop.receiveData(&stopret, sizeof(stopret)); + if (stopret == FAIL) { + client.receiveData(mess, sizeof(mess)); + throw RuntimeError("Detector " + std::to_string(detId) + + " returned error: " + std::string(mess)); + } + } + } + FILE_LOG(logINFO) << "You can now restart the detector " + std::to_string(detId) + + " in normal mode."; + return ret; } + int slsDetector::resetFPGA() { int fnum = F_RESET_FPGA; int ret = FAIL;