gotthard2 and mythen3: programming fpga, reboot; jungfrau, ctb: modified programming (#74)

This commit is contained in:
Dhanya Thattil
2020-01-31 04:52:35 +01:00
committed by GitHub
parent 7d7302a90c
commit 5ca3a1b685
39 changed files with 479 additions and 141 deletions

View File

@ -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 {

View File

@ -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.");

View File

@ -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);
}

View File

@ -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");

View 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:
/**

View File

@ -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) {

View File

@ -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();