diff --git a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h index 047f0c10b..d09ee273d 100644 --- a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h @@ -104,7 +104,9 @@ enum { F_GET_RATE_CORRECT, /** < get rate correction tau */ F_ACTIVATE, /** < activate/deactivate readout */ - F_SET_NETWORK_PARAMETER /**< set network parameters such as transmission delay, flow control */ + F_SET_NETWORK_PARAMETER, /**< set network parameters such as transmission delay, flow control */ + + F_PROGRAM_FPGA /**< program FPGA */ /* Always append functions hereafter!!! */ diff --git a/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt b/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt index 699f0201f..cd9d988a3 100644 --- a/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt +++ b/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsDetectorSoftware/eigerDetectorServer URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git/eigerDetectorServer Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git -Repsitory UUID: 372aa91aaff8c6acd0fb70a257774ac56974a4b1 -Revision: 233 -Branch: 2.1-rc +Repsitory UUID: d0ef24c35c9b677a297a0ebf7f19a0196df424b5 +Revision: 237 +Branch: developer Last Changed Author: Dhanya_Maliakal Last Changed Rev: 22 -Last Changed Date: 2016-09-22 17:16:49 +0200 +Last Changed Date: 2016-09-26 12:00:23 +0200 diff --git a/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h b/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h index 2f61cd1dc..530c99b36 100644 --- a/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h +++ b/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURL "git@git.psi.ch:sls_detectors_software/sls_detector_software.git/eigerDetectorServer" //#define SVNREPPATH "" -#define SVNREPUUID "372aa91aaff8c6acd0fb70a257774ac56974a4b1" +#define SVNREPUUID "d0ef24c35c9b677a297a0ebf7f19a0196df424b5" //#define SVNREV 0x22 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" #define SVNREV 0x22 -#define SVNDATE 0x20160922 +#define SVNDATE 0x20160926 // diff --git a/slsDetectorSoftware/jungfrauDetectorServer/README.txt b/slsDetectorSoftware/jungfrauDetectorServer/README.txt new file mode 100644 index 000000000..7785cee12 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/README.txt @@ -0,0 +1,11 @@ +add the following to /etc/rc before using programfpga command before cat motd + + +#registering 7th and 9th pin to linux kernel +echo 7 > /sys/class/gpio/export +echo 9 > /sys/class/gpio/export +#define direction for the linux kernel +echo in > /sys/class/gpio/gpio7/direction +echo out > /sys/class/gpio/gpio9/direction +#needed, else all write errors when server starts up, because linux tries to take control fof gpio +echo 1 > /sys/class/gpio/gpio9/value diff --git a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c index 1765f4662..39f5df976 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c +++ b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c @@ -114,6 +114,8 @@ int masterMode=NO_MASTER, syncMode=NO_SYNCHRONIZATION, timingMode=AUTO_TIMING; enum externalSignalFlag signals[4]={EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF}; int withGotthard = 0; +char mtdvalue[10]; + /**is not const because this value will change after initDetector, is removed from mcb_funcs.c cuz its not used anywhere * why is this used anywhere instead of macro*/ @@ -3377,4 +3379,120 @@ int setDac(int dacnum,int dacvalue){ } +void eraseFlash(){ +#ifdef VERY_VERBOSE + printf("\n at eraseFlash \n"); +#endif + + char command[255]; + sprintf(command,"flash_eraseall %s",mtdvalue); + system(command); + printf("flash erased\n"); +} + + +int startWritingFPGAprogram(FILE** filefp){ +#ifdef VERY_VERBOSE + printf("\n at startWritingFPGAprogram \n"); +#endif + + //getting the drive + char output[255]; + FILE* fp = popen("awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r"); + fgets(output, sizeof(output), fp); + pclose(fp); + strcpy(mtdvalue,"/dev/"); + char* pch = strtok(output,":"); + if(pch == NULL){ + cprintf(RED,"Could not get mtd value\n"); + return FAIL; + } + strcat(mtdvalue,pch); + printf ("\nWriting FPGA program to flash.\nThe drive is %s\n",mtdvalue); + + + //tell FPGA to not touch flash + system("echo 0 > /sys/class/gpio/gpio9/value"); + /* + char output2[255]; + fp = popen("echo 0 > /sys/class/gpio/gpio9/value","r"); + fgets(output2, sizeof(output2), fp); + pclose(fp); + printf("strlen output %d\n", strlen(output2)); //always 1 + printf("output got:%s\n",output2); + if(strstr (output2,"No such file or directory")!= NULL){ //doesnt notice + printf("matched!\n"); + return -1; + } + printf("not matched\n"); +*/ + + + //writing the program to flash + *filefp = fopen(mtdvalue, "w"); + if(*filefp == NULL){ + cprintf(RED,"Unable to open %s in write mode\n",mtdvalue); + return FAIL; + } + printf("flash ready for writing\n"); + + return OK; +} + +int stopWritingFPGAprogram(FILE* filefp){ +#ifdef VERY_VERBOSE + printf("\n at stopWritingFPGAprogram \n"); +#endif + + int wait = 0; + if(filefp!= NULL){ + fclose(filefp); + wait = 1; + } + + + //tell FPGA to touch flash to program itself + system("echo 1 > /sys/class/gpio/gpio9/value"); + + if(wait){ +#ifdef VERY_VERBOSE + printf("Waiting for FPGA to program from flash\n"); +#endif + //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); +#ifdef VERY_VERBOSE + printf("gpi07 returned %d\n",res); +#endif + } + } + printf("FPGA has picked up the program from flash\n\n"); + + return OK; +} + +int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp){ +#ifdef VERY_VERBOSE + printf("\n at writeFPGAProgram \n"); + cprintf(BLUE,"address of fpgasrc:%p\n",(void *)fpgasrc); + cprintf(BLUE,"fsize:%d\n",fsize); + cprintf(BLUE,"pointer:%p\n",(void*)filefp); +#endif + + if(fwrite((void*)fpgasrc , sizeof(char) , fsize , filefp )!= fsize){ + cprintf(RED,"Could not write FPGA source to flash\n"); + return FAIL; + } +#ifdef VERY_VERBOSE + cprintf(BLUE,"program written to flash\n"); +#endif + return OK; +} + + diff --git a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h index a9c6316c1..a7945678e 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h +++ b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h @@ -184,6 +184,11 @@ int setDac(int dacnum,int dacvalue); ROI *setROI(int nroi,ROI* arg,int *retvalsize, int *ret); int getChannels(); +void eraseFlash(); +int startWritingFPGAprogram(FILE** filefp); +int stopWritingFPGAprogram(FILE* filefp); +int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); + /* u_int32_t setNBits(u_int32_t); diff --git a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerTest b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerTest index a4574f51f..cf3566f1d 100755 Binary files a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerTest and b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerTest differ diff --git a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.0.3 b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.0.3 deleted file mode 100755 index a4574f51f..000000000 Binary files a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.0.3 and /dev/null differ diff --git a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.2.0 b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.2.0 new file mode 100755 index 000000000..caf0f06ee Binary files /dev/null and b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.2.0 differ diff --git a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c index e60cb1285..2d5b0336a 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c +++ b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c @@ -331,6 +331,7 @@ int function_table() { flist[F_CALIBRATE_PEDESTAL]=&calibrate_pedestal; flist[F_SET_CTB_PATTERN]=&set_ctb_pattern; flist[F_WRITE_ADC_REG]=&write_adc_register; + flist[F_PROGRAM_FPGA]=&program_fpga; return OK; } @@ -3501,3 +3502,136 @@ int write_adc_register(int file_des) { return ret; } + + + + + +int program_fpga(int file_des) { + int ret=OK; + int n; + const size_t maxprogramsize = 2 * 1024 *1024; + size_t unitprogramsize = 0; + int currentPointer = 0; + + char* fpgasrc = (char*)malloc(maxprogramsize); + size_t filesize = 0; + size_t totalsize = 0; + + FILE* fp = NULL; + + sprintf(mess,"Program FPGA\n"); + + //filesize + n = receiveDataOnly(file_des,&filesize,sizeof(filesize)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + totalsize = filesize; +#ifdef VERY_VERBOSE + printf("\n\n Total size is:%d\n",totalsize); +#endif + + //opening file pointer to flash and telling FPGA to not touch flash + int startret = startWritingFPGAprogram(&fp); + /*printf("startret:%d\n",startret);*/ + if(startret != OK){ + if(startret == FAIL){ + sprintf(mess,"Could not write to flash. Error at startup.\n"); + cprintf(RED,"%s",mess); + }/*else if (startret == -1){ + cprintf(RED,"Error: Please define the gpio pins and their direction in /etc/rc before rebooting\n"); + cprintf(RED,"%s",mess); + }*/ + ret=FAIL; + filesize = 0; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + + + //erasing flash + if(ret != FAIL) + eraseFlash(); + + + //writing to flash part by part + while(filesize){ + + unitprogramsize = maxprogramsize; //2mb + if(unitprogramsize > filesize) //less than 2mb + unitprogramsize = filesize; +#ifdef VERY_VERBOSE + printf("unit size to receive is:%d\n",unitprogramsize); + printf("filesize:%d currentpointer:%d\n",filesize,currentPointer); +#endif + //receive + n = receiveDataOnly(file_des,fpgasrc,unitprogramsize); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + if(!(unitprogramsize - filesize)){ + fpgasrc[unitprogramsize]='\0'; + filesize-=unitprogramsize; + unitprogramsize++; + }else + filesize-=unitprogramsize; + + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + ret = writeFPGAProgram(fpgasrc,unitprogramsize,fp); + } + } + + if(ret!=FAIL){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n += sendDataOnly(file_des,mess,sizeof(mess)); + cprintf(RED,"Failure: Breaking out of program receiving\n"); + break; + } + + //print progress + printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100) ); + fflush(stdout); + + } + printf("\n"); + + //closing file pointer to flash and informing FPGA + if(stopWritingFPGAprogram(fp) == FAIL){ + sprintf(mess,"Could not write to flash. Error at end.\n"); + cprintf(RED,"%s",mess); + ret=FAIL; + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + + + //free resources + free(fpgasrc); + if(fp!=NULL) + fclose(fp); +#ifdef VERY_VERBOSE + printf("Done with program receiving command\n"); +#endif + /*return ok/fail*/ + return ret; +} diff --git a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h index 2d674a1d0..154022e75 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h +++ b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h @@ -95,4 +95,6 @@ int set_roi(int); int set_ctb_pattern(int); int write_adc_register(int);; + +int program_fpga(int); #endif diff --git a/slsDetectorSoftware/slsDetector/gitInfoLib.h b/slsDetectorSoftware/slsDetector/gitInfoLib.h index a89498b61..fbcb75f9e 100644 --- a/slsDetectorSoftware/slsDetector/gitInfoLib.h +++ b/slsDetectorSoftware/slsDetector/gitInfoLib.h @@ -1,11 +1,11 @@ //#define SVNPATH "" #define SVNURLLIB "git@git.psi.ch:sls_detectors_software/sls_detector_software.git" //#define SVNREPPATH "" -#define SVNREPUUIDLIB "372aa91aaff8c6acd0fb70a257774ac56974a4b1" -//#define SVNREV 0x1154 +#define SVNREPUUIDLIB "d0ef24c35c9b677a297a0ebf7f19a0196df424b5" +//#define SVNREV 0x1164 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTHLIB "Dhanya_Maliakal" -#define SVNREVLIB 0x1154 -#define SVNDATELIB 0x20160922 +#define SVNREVLIB 0x1164 +#define SVNDATELIB 0x20160926 // diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index ed7c4e265..f35e0e64e 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -6383,8 +6383,9 @@ int slsDetector::writeSettingsFile(string fname, int imod, int* iodelay){ int slsDetector::programFPGA(string fname){ + int ret=FAIL; - if(thisDetector->myDetectorType != EIGER){/**jungfrau*/ + if(thisDetector->myDetectorType != JUNGFRAU){ std::cout << "Not implemented for this detector" << std::endl; return FAIL; } @@ -6397,12 +6398,19 @@ int slsDetector::programFPGA(string fname){ return FAIL; } - //convert it to rawbin - string destfname = fname; - destfname.replace(destfname.end()-4,destfname.end(),".rawbin"); //replace .pof with .rawbin -//#ifdef VERBOSE + //create destination file name,replaces original filename with Jungfrau.rawbin + string destfname; + size_t found = fname.find_last_of("/\\"); + if(found == string::npos) + destfname = ""; + else + destfname = fname.substr(0,found+1); + destfname.append("Jungfrau_MCB.rawbin"); + + +#ifdef VERBOSE std::cout << "Converting " << fname << " to " << destfname << std::endl; -//#endif +#endif int filepos,x,y,i; FILE* src = fopen(fname.c_str(),"rb"); FILE* dst = fopen(destfname.c_str(),"wb"); @@ -6424,25 +6432,141 @@ int slsDetector::programFPGA(string fname){ fputc(y,dst); } if (filepos < 0x1000000){ - std::cout << "ERROR: EOF before end of flash" << std::endl; + std::cout << "Could not convert programming file. EOF before end of flash" << std::endl; setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); return FAIL; } -//#ifdef VERBOSE - std::cout << "File has been converted to " << destfname << ". Sending it to /tftpboot" << std::endl; -//#endif +#ifdef VERBOSE + std::cout << "File has been converted to " << destfname << std::endl; +#endif - string copytoTftpboot = "cp " + destfname + " /tftpboot"; - system(copytoTftpboot.c_str()); -//#ifdef VERBOSE - std::cout << "File has been copied to /tftpboot" << std::endl; -//#endif + //loading file to memory + FILE* fp = fopen(destfname.c_str(),"r"); + if(fp == NULL){ + std::cout << "Could not open rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + if(fseek(fp,0,SEEK_END)){ + std::cout << "Seek error in rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + size_t filesize = ftell(fp); + if(filesize == -1){ + std::cout << "Could not get length of rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + rewind(fp); + char* fpgasrc = (char*)malloc(filesize+1); + if(fpgasrc == NULL){ + std::cout << "Could not allocate size of program" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + if(fread(fpgasrc, sizeof(char), filesize, fp) != filesize){ + std::cout << "Could not read rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } + + if(fclose(fp)){ + std::cout << "Could not close rawbin file" << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + return FAIL; + } +#ifdef VERBOSE + std::cout << "Successfully loaded the rawbin file" << std::endl; +#endif + + const size_t maxprogramsize = 2 * 1024 *1024; + size_t unitprogramsize = 0; + int currentPointer = 0; + size_t totalsize = filesize; + + int fnum=F_PROGRAM_FPGA; + char mess[MAX_STR_LENGTH]=""; + int64_t retval = -1; +#ifdef VERBOSE + std::cout<< "Sending programming binary to detector " << endl; +#endif + if (setOnline(ONLINE_FLAG)==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&filesize,sizeof(filesize)); + + //check opening error + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + filesize = 0; + } + + if(ret!=FAIL){ + std::cout<< "This can take awhile. Please be patient..." << endl; + printf("Erasing Flash:%d%%\r",0); + std::cout << flush; + int count = 65; + while(count>0){ + usleep(1 * 1000 * 1000); + count--; + printf("Erasing Flash:%d%%\r",(int) (((double)(65-count)/65)*100)); + std::cout << flush; + } + std::cout< 0){ + + unitprogramsize = maxprogramsize; //2mb + if(unitprogramsize > filesize) //less than 2mb + unitprogramsize = filesize; +#ifdef VERBOSE + std::cout << "unitprogramsize:" << unitprogramsize << "\t filesize:" << filesize << std::endl; +#endif + controlSocket->SendDataOnly(fpgasrc+currentPointer,unitprogramsize); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + break; + } + filesize-=unitprogramsize; + currentPointer+=unitprogramsize; + + //print progress + printf("Writing Program to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100)); + std::cout << flush; + + } + std::cout<ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } - return OK; + //free resources + free(fpgasrc); + + return ret; }