diff --git a/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h index 3b9991a71..142fe5695 100644 --- a/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h +++ b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h @@ -40,8 +40,10 @@ int startWritingFPGAprogram(FILE **filefp); * When done writing the program, close file pointer and * notify FPGA to pick up the program from flash * @param filefp pointer to flash + * @return 0 for success, 1 for fail (time taken for fpga to touch flash + * exceeded) */ -void stopWritingFPGAprogram(FILE *filefp); +int stopWritingFPGAprogram(FILE *filefp); /** * Write FPGA Program to flash diff --git a/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c index 3001c976c..5ca2e9ca7 100644 --- a/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c +++ b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c @@ -7,7 +7,8 @@ #include // usleep /* global variables */ -#define MTDSIZE 10 +#define MTDSIZE 10 +#define MAX_TIME_FPGA_TOUCH_FLASH_US (10 * 1000 * 1000) // 10s int gpioDefined = 0; char mtdvalue[MTDSIZE] = {0}; @@ -99,32 +100,36 @@ int startWritingFPGAprogram(FILE **filefp) { return 0; } -void stopWritingFPGAprogram(FILE *filefp) { +int stopWritingFPGAprogram(FILE *filefp) { LOG(logDEBUG1, ("Stopping of writing FPGA program\n")); - int wait = 0; if (filefp != NULL) { fclose(filefp); - wait = 1; } // touch and program FPGATouchFlash(); - if (wait) { - LOG(logDEBUG1, ("Waiting for FPGA to program from flash\n")); - // waiting for success or done - char output[255]; - int res = 0; - while (res == 0) { - FILE *sysFile = popen("cat /sys/class/gpio/gpio7/value", "r"); - fgets(output, sizeof(output), sysFile); - pclose(sysFile); - sscanf(output, "%d", &res); - LOG(logDEBUG1, ("gpi07 returned %d\n", res)); + LOG(logINFO, ("Waiting for FPGA to program from flash\n")); + // waiting for success or done + char output[255]; + int res = 0; + int timeSpent = 0; + while (res == 0) { + // time taken for fpga to pick up from flash + usleep(1000); + timeSpent += 1000; + if (timeSpent >= MAX_TIME_FPGA_TOUCH_FLASH_US) { + return 1; } + FILE *sysFile = popen("cat /sys/class/gpio/gpio7/value", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + sscanf(output, "%d", &res); + LOG(logDEBUG1, ("gpi07 returned %d\n", res)); } LOG(logINFO, ("FPGA has picked up the program from flash\n")); + return 0; } int writeFPGAProgram(char *fpgasrc, uint64_t fsize, FILE *filefp) { diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 6e79824ca..436084fa1 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -3719,6 +3719,7 @@ int program_fpga(int file_des) { } // writing to flash part by part + int clientSocketCrash = 0; while (ret != FAIL && filesize) { unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb @@ -3729,42 +3730,61 @@ int program_fpga(int file_des) { (long long unsigned int)filesize)); // receive part of program - if (receiveData(file_des, fpgasrc, unitprogramsize, OTHER) < 0) - return printSocketReadError(); + if (receiveData(file_des, fpgasrc, unitprogramsize, OTHER) < 0) { + printSocketReadError(); + clientSocketCrash = 1; + ret = FAIL; + } + // client has not crashed yet, so write to flash and send ret + else { + if (!(unitprogramsize - filesize)) { + fpgasrc[unitprogramsize] = '\0'; + filesize -= unitprogramsize; + unitprogramsize++; + } else + filesize -= unitprogramsize; - if (!(unitprogramsize - filesize)) { - fpgasrc[unitprogramsize] = '\0'; - filesize -= unitprogramsize; - unitprogramsize++; - } else - filesize -= unitprogramsize; - - // write part to flash - ret = writeFPGAProgram(fpgasrc, unitprogramsize, fp); - Server_SendResult(file_des, INT32, NULL, 0); - if (ret == FAIL) { - LOG(logERROR, ("Failure: Breaking out of program receiving\n")); - } else { - // print progress - LOG(logINFO, - ("Writing to Flash:%d%%\r", - (int)(((double)(totalsize - filesize) / totalsize) * - 100))); - fflush(stdout); + // write part to flash + ret = writeFPGAProgram(fpgasrc, unitprogramsize, fp); + Server_SendResult(file_des, INT32, NULL, 0); + if (ret == FAIL) { + strcpy(mess, "Could not write to flash. Breaking out of " + "program receiving. Try to flash again " + "without rebooting.\n"); + LOG(logERROR, (mess)); + } else { + // print progress + LOG(logINFO, + ("Writing to Flash:%d%%\r", + (int)(((double)(totalsize - filesize) / totalsize) * + 100))); + fflush(stdout); + } } } + if (ret == OK) { LOG(logINFO, ("Done copying program\n")); + // closing file pointer to flash and informing FPGA + ret = stopWritingFPGAprogram(fp); + if (ret == FAIL) { + strcpy(mess, "Failed to program fpga. FPGA is taking too long " + "to pick up program from flash! Try to flash " + "again without rebooting!\n"); + LOG(logERROR, (mess)); + } } - // closing file pointer to flash and informing FPGA - stopWritingFPGAprogram(fp); - // free resources free(fpgasrc); if (fp != NULL) fclose(fp); + // send final ret (if no client crash) + if (clientSocketCrash == 0) { + Server_SendResult(file_des, INT32, NULL, 0); + } + #endif // end of Blackfin programming if (ret == FAIL) { LOG(logERROR, ("Program FPGA FAIL!\n")); diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 1cce4a841..82bc848fb 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -3166,6 +3166,15 @@ void Module::programFPGAviaBlackfin(std::vector buffer) { std::cout << std::flush; } std::cout << '\n'; + + // fpga has picked up from flash successfully + if (client.Receive() == FAIL) { + std::ostringstream os; + os << "Detector " << moduleId << " (" << shm()->hostname << ")" + << " returned error: " << client.readErrorMessage(); + throw RuntimeError(os.str()); + } + LOG(logINFO) << "FPGA programmed successfully"; rebootController(); }