mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-23 18:17:59 +02:00
conflict resolved, changed to using hex() instead of str() in configuremac
This commit is contained in:
@ -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"
|
||||
@ -1434,7 +1427,7 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
int setStoragecellStart(int pos = -1, int detPos = -1);
|
||||
|
||||
/**
|
||||
* Programs FPGA with pof file (Jungfrau)
|
||||
* Programs FPGA with pof file (Not Eiger)
|
||||
* @param fname file name
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns OK or FAIL
|
||||
@ -1442,12 +1435,38 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
int programFPGA(const std::string &fname, int detPos = -1);
|
||||
|
||||
/**
|
||||
* Resets FPGA (Jungfrau)
|
||||
* Resets FPGA (Not Eiger)
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int resetFPGA(int detPos = -1);
|
||||
|
||||
/**
|
||||
* Copies detector server from tftp and changes respawn server (Not Eiger)
|
||||
* @param fname name of detector server binary
|
||||
* @param hostname name of pc to tftp from
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int copyDetectorServer(const std::string &fname, const std::string &hostname, int detPos = -1);
|
||||
|
||||
/**
|
||||
* Reboot detector controller (Not Eiger)
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int rebootController(int detPos = -1);
|
||||
|
||||
/**
|
||||
* Updates the firmware, detector server and then reboots detector controller blackfin. (Not Eiger)
|
||||
* @param sname name of detector server binary
|
||||
* @param hostname name of pc to tftp from
|
||||
* @param fname programming file name
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int update(const std::string &sname, const std::string &hostname, const std::string &fname, int detPos = -1);
|
||||
|
||||
/**
|
||||
* Power on/off Chip (Jungfrau)
|
||||
* @param ival on is 1, off is 0, -1 to get
|
||||
@ -2010,11 +2029,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
|
||||
@ -2033,6 +2047,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<char> readPofFile(const std::string &fname);
|
||||
|
||||
|
||||
/** Multi detector Id */
|
||||
const int multiId;
|
||||
|
||||
@ -2091,4 +2114,3 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
void *pCallbackArg{nullptr};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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"
|
||||
@ -18,6 +9,7 @@
|
||||
class ClientInterface;
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
class multiSlsDetector;
|
||||
class ServerInterface;
|
||||
@ -796,7 +788,7 @@ class slsDetector : public virtual slsDetectorDefs{
|
||||
* @param detectorMAC detector MAC address
|
||||
* @returns the detector MAC address
|
||||
*/
|
||||
std::string setDetectorMAC(const std::string &address);
|
||||
std::string setDetectorMAC(const std::string &detectorMAC);
|
||||
|
||||
/**
|
||||
* Returns the detector MAC address\sa sharedSlsDetector
|
||||
@ -809,7 +801,7 @@ class slsDetector : public virtual slsDetectorDefs{
|
||||
* @param detectorMAC detector MAC address (bottom half)
|
||||
* @returns the detector MAC address (bottom half)
|
||||
*/
|
||||
std::string setDetectorMAC2(const std::string &address);
|
||||
std::string setDetectorMAC2(const std::string &detectorMAC);
|
||||
|
||||
/**
|
||||
* Returns the detector MAC address (bottom half) Jungfrau only
|
||||
@ -1283,11 +1275,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<char> buffer);
|
||||
|
||||
/**
|
||||
* Resets FPGA (Jungfrau)
|
||||
@ -1296,6 +1288,20 @@ class slsDetector : public virtual slsDetectorDefs{
|
||||
int resetFPGA();
|
||||
|
||||
/**
|
||||
* Copies detector server from tftp and changes respawn server (Not Eiger)
|
||||
* @param fname name of detector server binary
|
||||
* @param hostname name of pc to tftp from
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int copyDetectorServer(const std::string &fname, const std::string &hostname);
|
||||
|
||||
/**
|
||||
* Reboot detector controller (blackfin/ powerpc)
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int rebootController();
|
||||
|
||||
/**
|
||||
* Power on/off Chip (Jungfrau)
|
||||
* @param ival on is 1, off is 0, -1 to get
|
||||
* @returns OK or FAIL
|
||||
@ -1823,4 +1829,3 @@ class slsDetector : public virtual slsDetectorDefs{
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -2624,13 +2624,17 @@ int multiSlsDetector::setStoragecellStart(int pos, int detPos) {
|
||||
}
|
||||
|
||||
int multiSlsDetector::programFPGA(const std::string &fname, int detPos) {
|
||||
FILE_LOG(logINFO) << "This can take awhile. Please be patient...";
|
||||
// read pof file
|
||||
std::vector<char> 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<int>(OK)) ? OK : FAIL;
|
||||
}
|
||||
|
||||
@ -2645,6 +2649,47 @@ int multiSlsDetector::resetFPGA(int detPos) {
|
||||
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
|
||||
}
|
||||
|
||||
int multiSlsDetector::copyDetectorServer(const std::string &fname, const std::string &hostname, int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
detectors[detPos]->copyDetectorServer(fname, hostname);
|
||||
return detectors[detPos]->rebootController(); // reboot and copy should be independant for update command
|
||||
}
|
||||
|
||||
// multi
|
||||
parallelCall(&slsDetector::copyDetectorServer,fname, hostname);
|
||||
auto r = parallelCall(&slsDetector::rebootController);
|
||||
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
|
||||
}
|
||||
|
||||
int multiSlsDetector::rebootController(int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
return detectors[detPos]->rebootController();
|
||||
}
|
||||
|
||||
// multi
|
||||
auto r = parallelCall(&slsDetector::rebootController);
|
||||
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
|
||||
}
|
||||
|
||||
int multiSlsDetector::update(const std::string &sname, const std::string &hostname, const std::string &fname, int detPos) {
|
||||
FILE_LOG(logINFO) << "This can take awhile. Please be patient...";
|
||||
// read pof file
|
||||
std::vector<char> buffer = readPofFile(fname);
|
||||
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
detectors[detPos]->copyDetectorServer(sname, hostname);
|
||||
return detectors[detPos]->programFPGA(buffer);
|
||||
}
|
||||
|
||||
// multi
|
||||
parallelCall(&slsDetector::copyDetectorServer,sname, hostname);
|
||||
auto r = parallelCall(&slsDetector::programFPGA, buffer);
|
||||
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
|
||||
}
|
||||
|
||||
int multiSlsDetector::powerChip(int ival, int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
@ -4013,10 +4058,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) {
|
||||
@ -4077,3 +4118,107 @@ int multiSlsDetector::kbhit() {
|
||||
select(STDIN_FILENO + 1, &fds, nullptr, nullptr, &tv);
|
||||
return FD_ISSET(STDIN_FILENO, &fds);
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<char> 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<char> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -845,7 +845,9 @@ int slsDetector::execCommand(const std::string &cmd) {
|
||||
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
|
||||
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
|
||||
ret = client.sendCommandThenRead(fnum, arg, sizeof(arg), retval, sizeof(retval));
|
||||
FILE_LOG(logINFO) << "Detector " << detId << " returned:\n" << retval;
|
||||
if (strlen(retval)) {
|
||||
FILE_LOG(logINFO) << "Detector " << detId << " returned:\n" << retval;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1597,12 +1599,12 @@ int slsDetector::configureMAC() {
|
||||
|
||||
// copy to args and convert to hex
|
||||
snprintf(args[0], array_size, "%x", detector_shm()->receiverUDPPort);
|
||||
sls::strcpy_safe(args[1], getReceiverUDPIP().str()); //TODO! Why not hex?
|
||||
sls::strcpy_safe(args[1], getReceiverUDPIP().hex());
|
||||
sls::strcpy_safe(args[2], getReceiverUDPMAC().hex());
|
||||
sls::strcpy_safe(args[3], getDetectorIP().hex());
|
||||
sls::strcpy_safe(args[4], getDetectorMAC().hex());
|
||||
snprintf(args[5], array_size, "%x", detector_shm()->receiverUDPPort2);
|
||||
sls::strcpy_safe(args[6], getReceiverUDPIP2().str());
|
||||
sls::strcpy_safe(args[6], getReceiverUDPIP2().hex());
|
||||
sls::strcpy_safe(args[7], getReceiverUDPMAC2().hex());
|
||||
sls::strcpy_safe(args[8], getDetectorIP2().hex());
|
||||
sls::strcpy_safe(args[9], getDetectorMAC2().hex());
|
||||
@ -2036,14 +2038,14 @@ std::string slsDetector::setDetectorMAC(const std::string &address) {
|
||||
auto addr = MacAddr(address);
|
||||
if (addr == 0) {
|
||||
throw RuntimeError("server MAC Address should be in xx:xx:xx:xx:xx:xx format");
|
||||
} else {
|
||||
detector_shm()->detectorMAC = addr;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
}
|
||||
detector_shm()->detectorMAC = addr;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
|
||||
return getDetectorMAC().str();
|
||||
}
|
||||
|
||||
@ -2053,13 +2055,12 @@ std::string slsDetector::setDetectorMAC2(const std::string &address) {
|
||||
auto addr = MacAddr(address);
|
||||
if (addr == 0) {
|
||||
throw RuntimeError("server MAC Address 2 should be in xx:xx:xx:xx:xx:xx format");
|
||||
} else {
|
||||
detector_shm()->detectorMAC2 = addr;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
}
|
||||
detector_shm()->detectorMAC2 = addr;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
return getDetectorMAC2().str();
|
||||
}
|
||||
@ -2068,17 +2069,16 @@ MacAddr slsDetector::getDetectorMAC2() { return detector_shm()->detectorMAC2; }
|
||||
|
||||
std::string slsDetector::setDetectorIP(const std::string &ip) {
|
||||
auto addr = IpAddr(ip);
|
||||
if (addr != 0) {
|
||||
detector_shm()->detectorIP = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
} else {
|
||||
if (addr == 0) {
|
||||
throw RuntimeError("setDetectorIP: IP Address should be VALID and "
|
||||
"in xxx.xxx.xxx.xxx format");
|
||||
}
|
||||
detector_shm()->detectorIP = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
return getDetectorIP().str();
|
||||
}
|
||||
|
||||
@ -2086,17 +2086,16 @@ IpAddr slsDetector::getDetectorIP() const { return detector_shm()->detectorIP; }
|
||||
|
||||
std::string slsDetector::setDetectorIP2(const std::string &ip) {
|
||||
auto addr = IpAddr(ip);
|
||||
if (addr != 0) {
|
||||
detector_shm()->detectorIP2 = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
} else {
|
||||
if (addr == 0) {
|
||||
throw RuntimeError("setDetectorIP: IP2 Address should be VALID and "
|
||||
"in xxx.xxx.xxx.xxx format");
|
||||
}
|
||||
detector_shm()->detectorIP2 = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
return getDetectorIP().str();
|
||||
}
|
||||
|
||||
@ -2233,15 +2232,14 @@ std::string slsDetector::setReceiverUDPIP(const std::string &udpip) {
|
||||
if (ip == 0) {
|
||||
throw ReceiverError("setReceiverUDPIP: UDP IP Address should be "
|
||||
"VALID and in xxx.xxx.xxx.xxx format");
|
||||
} else {
|
||||
detector_shm()->receiverUDPIP = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
return getReceiverUDPIP().str();
|
||||
}
|
||||
detector_shm()->receiverUDPIP = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
return getReceiverUDPIP().str();
|
||||
}
|
||||
|
||||
sls::IpAddr slsDetector::getReceiverUDPIP() const { return detector_shm()->receiverUDPIP; }
|
||||
@ -2251,15 +2249,14 @@ std::string slsDetector::setReceiverUDPIP2(const std::string &udpip) {
|
||||
if (ip == 0) {
|
||||
throw ReceiverError("setReceiverUDPIP: UDP IP Address 2 should be "
|
||||
"VALID and in xxx.xxx.xxx.xxx format");
|
||||
} else {
|
||||
detector_shm()->receiverUDPIP2 = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
return getReceiverUDPIP2().str();
|
||||
}
|
||||
detector_shm()->receiverUDPIP2 = ip;
|
||||
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
|
||||
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
|
||||
} else if (setUDPConnection() == FAIL) {
|
||||
FILE_LOG(logWARNING) << "UDP connection set up failed";
|
||||
}
|
||||
return getReceiverUDPIP2().str();
|
||||
}
|
||||
|
||||
sls::IpAddr slsDetector::getReceiverUDPIP2() const { return detector_shm()->receiverUDPIP2; }
|
||||
@ -3259,223 +3256,99 @@ 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<char> 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 " << detId << " (" << 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));
|
||||
// error in detector at opening file pointer to flash
|
||||
if (ret == FAIL) {
|
||||
client.receiveData(mess, sizeof(mess));
|
||||
std::ostringstream os;
|
||||
os << "Detector " << detId << " (" << detector_shm()->hostname << ")" <<
|
||||
" returned error: " << mess;
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
|
||||
// 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) << "Erasing Flash for detector " << detId << " (" << detector_shm()->hostname << ")";
|
||||
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 to detector " << detId << " (" << detector_shm()->hostname << ")";
|
||||
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));
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// sending program in parts of 2mb each
|
||||
size_t unitprogramsize = 0;
|
||||
int currentPointer = 0;
|
||||
size_t totalsize = filesize;
|
||||
while (ret != FAIL && (filesize > 0)) {
|
||||
|
||||
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;
|
||||
// print progress
|
||||
printf("%d%%\r", (int)(((double)(totalsize - filesize) / totalsize) * 100));
|
||||
std::cout << std::flush;
|
||||
} else {
|
||||
printf("\n");
|
||||
client.receiveData(mess, sizeof(mess));
|
||||
std::ostringstream os;
|
||||
os << "Detector " << detId << " (" << detector_shm()->hostname << ")" <<
|
||||
" returned error: " << mess;
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (ret != FAIL) {
|
||||
ret = rebootController();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int slsDetector::resetFPGA() {
|
||||
int fnum = F_RESET_FPGA;
|
||||
int ret = FAIL;
|
||||
@ -3490,6 +3363,37 @@ int slsDetector::resetFPGA() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int slsDetector::copyDetectorServer(const std::string &fname, const std::string &hostname) {
|
||||
int fnum = F_COPY_DET_SERVER;
|
||||
int ret = FAIL;
|
||||
char args[2][MAX_STR_LENGTH] = {};
|
||||
sls::strcpy_safe(args[0], fname.c_str());
|
||||
sls::strcpy_safe(args[1], hostname.c_str());
|
||||
FILE_LOG(logINFO) << "Sending detector server " << args[0] << " from host " << args[1];
|
||||
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
|
||||
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
|
||||
ret = client.sendCommandThenRead(fnum, args, sizeof(args), nullptr, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int slsDetector::rebootController() {
|
||||
if (detector_shm()->myDetectorType == EIGER) {
|
||||
throw RuntimeError("Reboot controller not implemented for this detector");
|
||||
}
|
||||
|
||||
int fnum = F_REBOOT_CONTROLLER;
|
||||
int ret = FAIL;
|
||||
FILE_LOG(logINFO) << "Sending reboot controller to detector " << detId << " (" << detector_shm()->hostname << ")";
|
||||
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
|
||||
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
|
||||
client.sendData(&fnum, sizeof(fnum));
|
||||
ret = OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int slsDetector::powerChip(int ival) {
|
||||
int fnum = F_POWER_CHIP;
|
||||
int ret = FAIL;
|
||||
|
@ -405,6 +405,27 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
|
||||
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
|
||||
++i;
|
||||
|
||||
/*! \page config
|
||||
- <b>copydetectorserver [sname] [phost]</b> copies the detector server sname via tftp from pc with hostname phost and changes respawn server for all detector. Not for Eiger. Only put! \c Returns \c ("successful", "failed")
|
||||
*/
|
||||
descrToFuncMap[i].m_pFuncName = "copydetectorserver";
|
||||
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
|
||||
++i;
|
||||
|
||||
/*! \page config
|
||||
- <b>rebootdetpc </b> reboot detector controller blackfin. Only put! Not for Eiger. \c Returns \c ("successful", "failed")
|
||||
*/
|
||||
descrToFuncMap[i].m_pFuncName = "rebootcontroller";
|
||||
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
|
||||
++i;
|
||||
|
||||
/*! \page config
|
||||
- <b>update [sname] [phost] [file] </b> updates the firmware to file and detector server to sname from phost via tftp and then reboots controller (blackfin). Only put! Not for Eiger. \c Returns \c ("successful", "failed")
|
||||
*/
|
||||
descrToFuncMap[i].m_pFuncName = "update";
|
||||
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
|
||||
++i;
|
||||
|
||||
/* chip */
|
||||
/*! \page config
|
||||
\section configchip Chip
|
||||
@ -4753,9 +4774,6 @@ std::string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action,
|
||||
if (strstr(args[1], ".pof") == nullptr)
|
||||
return std::string("wrong usage: programming file should have .pof extension");
|
||||
std::string sval = std::string(args[1]);
|
||||
#ifdef VERBOSE
|
||||
std::cout << " programming file " << sval << std::endl;
|
||||
#endif
|
||||
myDet->setOnline(ONLINE_FLAG, detPos);
|
||||
if (myDet->programFPGA(sval, detPos) == OK)
|
||||
return std::string("successful");
|
||||
@ -4765,15 +4783,51 @@ std::string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action,
|
||||
else if (cmd == "resetfpga") {
|
||||
if (action == GET_ACTION)
|
||||
return std::string("cannot get");
|
||||
#ifdef VERBOSE
|
||||
std::cout << " resetting fpga " << std::endl;
|
||||
#endif
|
||||
myDet->setOnline(ONLINE_FLAG, detPos);
|
||||
if (myDet->resetFPGA(detPos) == OK)
|
||||
return std::string("successful");
|
||||
return std::string("failed");
|
||||
}
|
||||
|
||||
else if (cmd == "copydetectorserver") {
|
||||
if (action == GET_ACTION)
|
||||
return std::string("cannot get");
|
||||
if (narg < 3)
|
||||
return ("wrong usage." + helpAdvanced(PUT_ACTION));
|
||||
std::string sval = std::string(args[1]);
|
||||
std::string pval = std::string(args[2]);
|
||||
myDet->setOnline(ONLINE_FLAG, detPos);
|
||||
if (myDet->copyDetectorServer(sval, pval, detPos) == OK)
|
||||
return std::string("successful");
|
||||
return std::string("failed");
|
||||
}
|
||||
|
||||
else if (cmd == "rebootcontroller") {
|
||||
if (action == GET_ACTION)
|
||||
return std::string("cannot get");
|
||||
myDet->setOnline(ONLINE_FLAG, detPos);
|
||||
if (myDet->rebootController(detPos) == OK)
|
||||
return std::string("successful");
|
||||
return std::string("failed");
|
||||
}
|
||||
|
||||
else if (cmd == "update") {
|
||||
if (action == GET_ACTION)
|
||||
return std::string("cannot get");
|
||||
if (narg < 4)
|
||||
return ("wrong usage." + helpAdvanced(PUT_ACTION));
|
||||
// pof
|
||||
if (strstr(args[3], ".pof") == nullptr)
|
||||
return std::string("wrong usage: programming file should have .pof extension");
|
||||
std::string sval = std::string(args[1]);
|
||||
std::string pval = std::string(args[2]);
|
||||
std::string fval = std::string(args[3]);
|
||||
myDet->setOnline(ONLINE_FLAG, detPos);
|
||||
if (myDet->update(sval, pval, fval, detPos) == OK)
|
||||
return std::string("successful");
|
||||
return std::string("failed");
|
||||
}
|
||||
|
||||
else if (cmd == "powerchip") {
|
||||
char ans[100];
|
||||
myDet->setOnline(ONLINE_FLAG, detPos);
|
||||
@ -4842,7 +4896,9 @@ std::string slsDetectorCommand::helpAdvanced(int action) {
|
||||
|
||||
os << "programfpga f \t programs the fpga with file f (with .pof extension)." << std::endl;
|
||||
os << "resetfpga f \t resets fpga, f can be any value" << std::endl;
|
||||
|
||||
os << "copydetectorserver s p \t copies the detector server s via tftp from pc with hostname p and changes respawn server. Not for Eiger. " << std::endl;
|
||||
os << "rebootcontroller \t reboot controler blackfin of the detector. Not for Eiger." << std::endl;
|
||||
os << "update s p f \t updates the firmware to f and detector server to f from host p via tftp and then reboots controller (blackfin). Not for Eiger. " << std::endl;
|
||||
os << "led s \t sets led status (0 off, 1 on)" << std::endl;
|
||||
os << "diodelay m v \tsets the delay for the digital IO pins selected by mask m and delay set by v. mask is upto 64 bits in hex, delay max is 775ps, and set in steps of 25 ps. Used for MOENCH/CTB only." << std::endl;
|
||||
os << "powerchip i \t powers on or off the chip. i = 1 for on, i = 0 for off" << std::endl;
|
||||
|
Reference in New Issue
Block a user