mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-19 00:07:13 +02:00
gotthard2 and mythen3: programming fpga, reboot; jungfrau, ctb: modified programming (#74)
This commit is contained in:
@ -1807,7 +1807,8 @@ std::string CmdProxy::ProgramFpga(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[fname.pof]\n\t[Jungfrau][Ctb] Programs FPGA from pof file."
|
||||
os << "[fname.pof | fname.rbf]\n\t[Jungfrau][Ctb] Programs FPGA from pof file."
|
||||
<< "\n\t[Mythen3][Gotthard2] Programs FPGA from rbf file."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
@ -1815,9 +1816,6 @@ std::string CmdProxy::ProgramFpga(int action) {
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
if (args[0].find(".pof") == std::string::npos) {
|
||||
throw sls::RuntimeError("Programming file must be a pof file.");
|
||||
}
|
||||
det->programFPGA(args[0], {det_id});
|
||||
os << "successful\n";
|
||||
} else {
|
||||
|
@ -1696,7 +1696,7 @@ class CmdProxy {
|
||||
"\n\t[Jungfrau][Ctb] Reset FPGA.");
|
||||
|
||||
EXECUTE_SET_COMMAND(rebootcontroller, rebootController,
|
||||
"\n\t[Jungfrau][Ctb] Reboot controler (blackfin) of detector.");
|
||||
"\n\t[Jungfrau][Ctb][Gotthard][Mythen3][Gotthard2] Reboot controler (blackfin) of detector.");
|
||||
|
||||
EXECUTE_SET_COMMAND(firmwaretest, executeFirmwareTest,
|
||||
"\n\t[Jungfrau][Gotthard][Mythen3][Gotthard2][Ctb] Firmware test, ie. reads a read fixed pattern from a register.");
|
||||
|
@ -1652,9 +1652,7 @@ void Detector::setDetectorMode(defs::detectorModeType value, Positions pos) {
|
||||
// Advanced
|
||||
|
||||
void Detector::programFPGA(const std::string &fname, Positions pos) {
|
||||
FILE_LOG(logINFO)
|
||||
<< "Updating Firmware. This can take awhile. Please be patient...";
|
||||
std::vector<char> buffer = pimpl->readPofFile(fname);
|
||||
std::vector<char> buffer = pimpl->readProgrammingFile(fname);
|
||||
pimpl->Parallel(&slsDetector::programFPGA, pos, buffer);
|
||||
}
|
||||
|
||||
|
@ -1156,11 +1156,34 @@ int multiSlsDetector::kbhit() {
|
||||
return FD_ISSET(STDIN_FILENO, &fds);
|
||||
}
|
||||
|
||||
std::vector<char> multiSlsDetector::readPofFile(const std::string &fname) {
|
||||
std::vector<char> multiSlsDetector::readProgrammingFile(const std::string &fname) {
|
||||
// validate type of file
|
||||
bool isPof = false;
|
||||
switch (multi_shm()->multiDetectorType) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
if (fname.find(".pof") == std::string::npos) {
|
||||
throw RuntimeError("Programming file must be a pof file.");
|
||||
}
|
||||
isPof = true;
|
||||
break;
|
||||
case MYTHEN3:
|
||||
case GOTTHARD2:
|
||||
if (fname.find(".rbf") == std::string::npos) {
|
||||
throw RuntimeError("Programming file must be an rbf file.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Not implemented for this detector");
|
||||
}
|
||||
|
||||
FILE_LOG(logINFO)
|
||||
<< "Updating Firmware. This can take awhile. Please be patient...";
|
||||
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) != 0) {
|
||||
throw RuntimeError("Program FPGA: Programming file does not exist");
|
||||
@ -1188,35 +1211,50 @@ std::vector<char> multiSlsDetector::readPofFile(const std::string &fname) {
|
||||
// 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);
|
||||
const int pofNumHeaderBytes = 0x11C;
|
||||
const int pofNumPadding = 0x80;
|
||||
const int pofFooterOfst = 0x1000000;
|
||||
int dstFilePos = 0;
|
||||
if (isPof) {
|
||||
// Read header and discard
|
||||
for (int i = 0; i < pofNumHeaderBytes; ++i) {
|
||||
fgetc(src);
|
||||
}
|
||||
// Write 0xFF to destination 0x80 times (padding)
|
||||
{
|
||||
char c = 0xFF;
|
||||
while (dstFilePos < pofNumPadding) {
|
||||
write(dst, &c, 1);
|
||||
++dstFilePos;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Swap bits and write to file
|
||||
for (filepos = 0x80; filepos < 0x1000000; ++filepos) {
|
||||
x = fgetc(src);
|
||||
if (x < 0) {
|
||||
// Swap bits from source and write to dest
|
||||
while (!feof(src)) {
|
||||
// pof: exit early to discard footer
|
||||
if (isPof && dstFilePos >= pofFooterOfst) {
|
||||
break;
|
||||
}
|
||||
y = 0;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
y = y |
|
||||
(((x & (1 << i)) >> i) << (7 - i)); // This swaps the bits
|
||||
// read source
|
||||
int s = fgetc(src);
|
||||
if (s < 0) {
|
||||
break;
|
||||
}
|
||||
// swap bits
|
||||
int d = 0;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
d = d |
|
||||
(((s & (1 << i)) >> i) << (7 - i));
|
||||
}
|
||||
write(dst, &y, 1);
|
||||
write(dst, &d, 1);
|
||||
++dstFilePos;
|
||||
}
|
||||
if (filepos < 0x1000000) {
|
||||
// validate pof: read less than footer offset
|
||||
if (isPof && dstFilePos < pofFooterOfst) {
|
||||
throw RuntimeError(
|
||||
"Could not convert programming file. EOF before end of flash");
|
||||
}
|
||||
|
||||
}
|
||||
if (fclose(src) != 0) {
|
||||
throw RuntimeError("Program FPGA: Could not close source file");
|
||||
|
@ -323,11 +323,13 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* Convert raw file
|
||||
* @param fname name of pof file
|
||||
* @param fpgasrc pointer in memory to read pof to
|
||||
* [Jungfrau][Ctb] from pof file
|
||||
* [Mythen3][Gotthard2] from rbf file
|
||||
* @param fname name of pof/rbf file
|
||||
* @param fpgasrc pointer in memory to read programming file to
|
||||
* @returns file size
|
||||
*/
|
||||
std::vector<char> readPofFile(const std::string &fname);
|
||||
std::vector<char> readProgrammingFile(const std::string &fname);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -2888,23 +2888,28 @@ int slsDetector::setStoragecellStart(int pos) {
|
||||
}
|
||||
|
||||
void slsDetector::programFPGA(std::vector<char> buffer) {
|
||||
// validate type
|
||||
switch (shm()->myDetectorType) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
programFPGAviaBlackfin(buffer);
|
||||
break;
|
||||
case MYTHEN3:
|
||||
case GOTTHARD2:
|
||||
programFPGAviaNios(buffer);
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Program FPGA is not implemented for this detector");
|
||||
}
|
||||
}
|
||||
|
||||
size_t filesize = buffer.size();
|
||||
void slsDetector::programFPGAviaBlackfin(std::vector<char> buffer) {
|
||||
uint64_t filesize = buffer.size();
|
||||
|
||||
// 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
|
||||
FILE_LOG(logINFO) << "Sending programming binary (from pof) to detector " << detId
|
||||
<< " (" << shm()->hostname << ")";
|
||||
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
@ -2921,35 +2926,34 @@ void slsDetector::programFPGA(std::vector<char> buffer) {
|
||||
}
|
||||
|
||||
// erasing flash
|
||||
if (ret != FAIL) {
|
||||
FILE_LOG(logINFO) << "Erasing Flash for detector " << detId << " ("
|
||||
<< 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",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
|
||||
100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
FILE_LOG(logINFO) << "Writing to Flash to detector " << detId << " ("
|
||||
<< shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
FILE_LOG(logINFO) << "Erasing Flash for detector " << detId << " ("
|
||||
<< 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",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
|
||||
100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
FILE_LOG(logINFO) << "Writing to Flash to detector " << detId << " ("
|
||||
<< shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
|
||||
// sending program in parts of 2mb each
|
||||
size_t unitprogramsize = 0;
|
||||
|
||||
// sending program in parts of 2mb each
|
||||
uint64_t unitprogramsize = 0;
|
||||
int currentPointer = 0;
|
||||
size_t totalsize = filesize;
|
||||
uint64_t totalsize = filesize;
|
||||
while (filesize > 0) {
|
||||
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||
if (unitprogramsize > filesize) { // less than 2mb
|
||||
@ -2967,19 +2971,46 @@ void slsDetector::programFPGA(std::vector<char> buffer) {
|
||||
os << "Detector " << detId << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << mess;
|
||||
throw RuntimeError(os.str());
|
||||
} else {
|
||||
filesize -= unitprogramsize;
|
||||
currentPointer += unitprogramsize;
|
||||
|
||||
// print progress
|
||||
printf("%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(totalsize - filesize) / totalsize) *
|
||||
100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
filesize -= unitprogramsize;
|
||||
currentPointer += unitprogramsize;
|
||||
|
||||
// print progress
|
||||
printf("%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(totalsize - filesize) / totalsize) *
|
||||
100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
FILE_LOG(logINFO) << "FPGA programmed successfully";
|
||||
rebootController();
|
||||
}
|
||||
|
||||
void slsDetector::programFPGAviaNios(std::vector<char> buffer) {
|
||||
uint64_t filesize = buffer.size();
|
||||
|
||||
// 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 (from rbf) to detector " << detId
|
||||
<< " (" << shm()->hostname << ")";
|
||||
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(&fnum, sizeof(fnum));
|
||||
client.Send(&filesize, sizeof(filesize));
|
||||
client.Send(&buffer[0], filesize);
|
||||
client.Receive(&ret, sizeof(ret));
|
||||
if (ret == FAIL) {
|
||||
printf("\n");
|
||||
client.Receive(mess, sizeof(mess));
|
||||
std::ostringstream os;
|
||||
os << "Detector " << detId << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << mess;
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
FILE_LOG(logINFO) << "FPGA programmed successfully";
|
||||
rebootController();
|
||||
}
|
||||
|
||||
@ -2999,15 +3030,9 @@ void slsDetector::copyDetectorServer(const std::string &fname,
|
||||
}
|
||||
|
||||
void slsDetector::rebootController() {
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
throw RuntimeError(
|
||||
"Reboot controller not implemented for this detector");
|
||||
}
|
||||
int fnum = F_REBOOT_CONTROLLER;
|
||||
FILE_LOG(logINFO) << "Sending reboot controller to detector " << detId
|
||||
<< " (" << shm()->hostname << ")";
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(&fnum, sizeof(fnum));
|
||||
FILE_LOG(logDEBUG1) << "Rebooting Controller";
|
||||
sendToDetector(F_REBOOT_CONTROLLER, nullptr, nullptr);
|
||||
FILE_LOG(logINFO) << "Controller rebooted successfully!";
|
||||
}
|
||||
|
||||
int slsDetector::powerChip(int ival) {
|
||||
|
@ -1382,11 +1382,17 @@ class slsDetector : public virtual slsDetectorDefs {
|
||||
int setStoragecellStart(int pos = -1);
|
||||
|
||||
/**
|
||||
* Programs FPGA with pof file (Jungfrau, CTB, Moench)
|
||||
* [Jungfau][Ctb] Programs FPGA with raw file from pof file
|
||||
* [Mythen3][Gotthard2] Programs FPGA with raw file from rbf file
|
||||
* @param buffer programming file in memory
|
||||
*/
|
||||
void programFPGA(std::vector<char> buffer);
|
||||
|
||||
/** [Jungfau][Ctb] */
|
||||
void programFPGAviaBlackfin(std::vector<char> buffer);
|
||||
|
||||
/** [Mythen3][Gotthard2] */
|
||||
void programFPGAviaNios(std::vector<char> buffer);
|
||||
/**
|
||||
* Resets FPGA (Jungfrau)
|
||||
*/
|
||||
@ -1401,6 +1407,7 @@ class slsDetector : public virtual slsDetectorDefs {
|
||||
const std::string &hostname);
|
||||
|
||||
/**
|
||||
* [Jungfrau][Ctb][Gotthard][Mythen3][Gotthard2]
|
||||
* Reboot detector controller (blackfin/ powerpc)
|
||||
*/
|
||||
void rebootController();
|
||||
|
Reference in New Issue
Block a user